Index: /code/branches/rocket2/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,120 @@
+ #
+ #             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:
+ #    Configures some basics and controls the configuration scripts
+ #
+
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6 FATAL_ERROR)
+
+# Keep devs from using the root directory as binary directory (messes up the source tree)
+IF(${CMAKE_CURRENT_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_BINARY_DIR})
+  MESSAGE(FATAL_ERROR "Please do not use the root directory as CMake output directory!
+  mkdir build; cd build; cmake ..
+  And you will have to clean the source directory by deleting CMakeCache.txt and the folder CMakeFiles")
+ENDIF()
+
+PROJECT(Orxonox C CXX)
+
+################ General Config #################
+
+# Version info
+SET(ORXONOX_VERSION_MAJOR 0)
+SET(ORXONOX_VERSION_MINOR 0)
+SET(ORXONOX_VERSION_PATCH 4)
+SET(ORXONOX_VERSION 0.0.4)
+SET(ORXONOX_VERSION_NAME "Arcturus")
+
+# Standard path suffixes
+SET(DEFAULT_RUNTIME_PATH bin)
+SET(DEFAULT_LIBRARY_PATH lib)
+SET(DEFAULT_ARCHIVE_PATH lib/static)
+SET(DEFAULT_MODULE_PATH  lib/modules)
+SET(DEFAULT_DOC_PATH     doc)
+SET(DEFAULT_DATA_PATH    data)
+SET(DEFAULT_CONFIG_PATH  config)
+SET(DEFAULT_LOG_PATH     log)
+
+# Set output directories
+SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${DEFAULT_RUNTIME_PATH})
+SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${DEFAULT_LIBRARY_PATH})
+SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${DEFAULT_ARCHIVE_PATH})
+SET(CMAKE_MODULE_OUTPUT_DIRECTORY  ${CMAKE_BINARY_DIR}/${DEFAULT_MODULE_PATH})
+SET(CMAKE_DOC_OUTPUT_DIRECTORY     ${CMAKE_BINARY_DIR}/${DEFAULT_DOC_PATH})
+# Data directories are only inputs, no delclaration here
+SET(CMAKE_CONFIG_OUTPUT_DIRECTORY  ${CMAKE_BINARY_DIR}/${DEFAULT_CONFIG_PATH})
+SET(CMAKE_LOG_OUTPUT_DIRECTORY     ${CMAKE_BINARY_DIR}/${DEFAULT_LOG_PATH})
+
+# Set the extension of the dynamic modules
+SET(ORXONOX_MODULE_EXTENSION ".module")
+
+# Sets where to find the external libraries like OgreMain.dll at runtime
+# On Unix you should not have to change this at all.
+# This only applies to development runs in the build tree
+SET(RUNTIME_LIBRARY_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+
+# Take care of some CMake 2.6.0 leftovers
+MARK_AS_ADVANCED(EXECUTABLE_OUTPUT_PATH LIBRARY_OUTPUT_PATH)
+
+# This sets where to look for CMake modules (e.g. "Find*.cmake" files)
+SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
+
+# Set Debug build to default when not having multi-config generator like msvc
+IF(NOT CMAKE_CONFIGURATION_TYPES)
+  IF(NOT CMAKE_BUILD_TYPE)
+    SET(CMAKE_BUILD_TYPE Debug CACHE STRING
+        "Build types are: Debug, Release, MinSizeRel, RelWithDebInfo" FORCE)
+  ENDIF()
+  MARK_AS_ADVANCED(CLEAR CMAKE_BUILD_TYPE)
+
+  MESSAGE(STATUS "*** Build type is ${CMAKE_BUILD_TYPE} ***")
+ELSE()
+  IF(CMAKE_BUILD_TYPE)
+    SET(CMAKE_BUILD_TYPE CACHE STRING FORCE)
+  ENDIF()
+  MARK_AS_ADVANCED(CMAKE_BUILD_TYPE)
+ENDIF()
+
+# Enable expensive optimisations: use this for a binary release build
+OPTION(ORXONOX_RELEASE "Enable when building restributable releases" FALSE)
+
+########### Subfolders and Subscripts ###########
+
+# Library finding
+INCLUDE(LibraryConfig)
+
+# General build and compiler options and configurations
+INCLUDE(CompilerConfig)
+
+# Configure installation paths and options
+INCLUDE(InstallConfig)
+
+# Configure data directory location and installation
+ADD_SUBDIRECTORY(data)
+
+# Create the actual project
+ADD_SUBDIRECTORY(src)
+
+# Configure the binary output directory. Do this after src!
+ADD_SUBDIRECTORY(bin)
+
+# Last but not least: Try to make a doc target with Doxygen
+ADD_SUBDIRECTORY(doc)
Index: /code/branches/rocket2/INSTALL
===================================================================
--- /code/branches/rocket2/INSTALL	(revision 6952)
+++ /code/branches/rocket2/INSTALL	(revision 6952)
@@ -0,0 +1,26 @@
+************* Build System **************
+To make platform support as easy as possible we have decided to use CMake as our build system.
+Therefore the first thing you need to do is to get
+CMake v.2.6 or later.
+
+************** Libraries ****************
+
+In order to compile Orxonox you will need the following libraries:
+(for windows there are already precompiled packages on the website)
+
+OGRE 3D Graphics Engine          1.4 (1.6 not yet supported)
+CEGUI (Crazy Eddie's GUI System) 0.5
+Boost libraries                  1.35
+ENet (Network library)           1.1
+Lua (scripting language)         5.0 or 5.1
+Tcl (shell script language)      8.4 or 8.5
+OpenAL (audio)                   (no version requirements specified yet)
+ALUT (audio)                     (no version requirements specified yet)
+LibOgg                           (no version requirements specified yet)
+LibVorbis                        (no version requirements specified yet)
+ZLib (compression)               (no version requirements specified yet)
+
+OGRE supports both OpenGL and DirectX9 rendering. You will also need OGRE for the dedicated server!
+
+Further information about installing and running this application can be found on
+http://www.orxonox.net/wiki/Running
Index: /code/branches/rocket2/LICENSE
===================================================================
--- /code/branches/rocket2/LICENSE	(revision 6952)
+++ /code/branches/rocket2/LICENSE	(revision 6952)
@@ -0,0 +1,344 @@
+
+        GNU GENERAL PUBLIC LICENSE
+           Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+          Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+        GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software
+    interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Program does not specify a
+version number of this License, you may choose any version ever
+published by the Free Software Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+          NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+         END OF TERMS AND CONDITIONS
+
+      How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these
+terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 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
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: /code/branches/rocket2/README
===================================================================
--- /code/branches/rocket2/README	(revision 6952)
+++ /code/branches/rocket2/README	(revision 6952)
@@ -0,0 +1,20 @@
+Hi there,
+
+We are proud to present you Orxonox - the most ferious 3D space shooter ever to exist.
+
+This game is free, if you have paid for this, get your money back! The source code of this game is licensed under the GPL (GNU General Public License).
+The game content is licensed under the Creative Commons Attribution-Sharealike 2.5 license. For more information read LICENSE in the same folder you found this file.
+
+For directions to install this game, please check out the file INSTALL or http://www.orxonox.net/wiki/Running
+
+This application uses the Ogre Graphics Engine (http://www.ogre3d.org), if you haven't already downloaded a precompiled version of Ogre with this package. Visit our webpage to get your Orxonox compatible version of the Ogre libraries.
+
+This is an open source game. If you want to contribute check out http://www.orxonox.net/wiki/development to find more information how you could help us making the game better. We are always looking for programmers and content designers, who like to contribute.
+
+We hope you have fun playing the game. Check out http://www.orxonox.net for news and newer versions of the game.
+
+Please contact us in our forum ( http://forum.orxonox.net ) or check out our contact page ( http://www.orxonox.net/wiki/about#Contact ). We hope to hear from you and are looking forward to your feedback.
+
+
+Cheers,
+The Orxonox Development Team
Index: /code/branches/rocket2/bin/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/bin/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/bin/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,72 @@
+ #
+ #             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:
+ #    Creates run scripts in the root directory of the build tree and
+ #    the runtime output directory.
+ #
+
+# Create run scripts for Windows to manually add the DLL path when executing
+SET(RUN_SCRIPTS run standalone client1 client2 server dedicated dedicatedClient)
+IF(WIN32)
+  FOREACH(_script ${RUN_SCRIPTS})
+    LIST(REMOVE_ITEM RUN_SCRIPTS ${_script})
+    LIST(APPEND RUN_SCRIPTS ${_script}.bat)
+  ENDFOREACH(_script)
+ENDIF()
+# Also copy vld.ini (visual leak detector config) for MSVC
+IF(MSVC)
+  LIST(APPEND RUN_SCRIPTS vld.ini)
+ENDIF()
+
+IF(NOT CMAKE_CONFIGURATION_TYPES)
+  SET(_subdirs .)
+  SEt(_default_subdir .)
+ELSE()
+  SET(_subdirs ${CMAKE_CONFIGURATION_TYPES})
+  SEt(_default_subdir) # No default subdir
+ENDIF()
+STRING(REPLACE "/" "\\" RUNTIME_LIBRARY_DIRECTORY_WINDOWS ${RUNTIME_LIBRARY_DIRECTORY})
+FOREACH(_subdir ${_subdirs})
+  GET_FILENAME_COMPONENT(CURRENT_RUNTIME_DIR ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${_subdir} ABSOLUTE)
+
+  # Note: Do not use FILE(TO_NATIVE_PATH) because it doesn't work for MinGW
+  STRING(REGEX REPLACE "^([A-Z]\\:)\\/.*$" "\\1" WINDOWS_DRIVE_CHANGE ${CURRENT_RUNTIME_DIR})
+  STRING(REPLACE "/" "\\" CURRENT_RUNTIME_DIR_WINDOWS ${CURRENT_RUNTIME_DIR})
+
+  FOREACH(_script ${RUN_SCRIPTS})
+    CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${_script}.in ${CURRENT_RUNTIME_DIR}/${_script} @ONLY)
+    IF(_subdir STREQUAL _default_subdir)
+      # Convenience script to be used when sitting in the binary directory. Does nothing for MSVC
+      CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${_script}.in ${CMAKE_BINARY_DIR}/${_script} @ONLY)
+    ENDIF()
+  ENDFOREACH(_script)
+
+  # In order to evaluate at run time whether it is a dev build in the build tree,
+  # we plant a special file
+  CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/orxonox_dev_build.keep_me ${CURRENT_RUNTIME_DIR}/orxonox_dev_build.keep_me)
+ENDFOREACH(_subdir)
+
+
+# Make a symlink to be able to run from the root directory when installing copyable on Unix
+IF(UNIX AND INSTALL_COPYABLE)
+  INSTAll(CODE "EXECUTE_PROCESS(COMMAND ln -sf ${RUNTIME_INSTALL_DIRECTORY}/${ORXONOX_EXECUTABLE_NAME} ${CMAKE_INSTALL_PREFIX}/orxonox)")
+ENDIF()
Index: /code/branches/rocket2/bin/client1.bat.in
===================================================================
--- /code/branches/rocket2/bin/client1.bat.in	(revision 6952)
+++ /code/branches/rocket2/bin/client1.bat.in	(revision 6952)
@@ -0,0 +1,4 @@
+title @PROJECT_NAME@
+path @RUNTIME_LIBRARY_DIRECTORY_WINDOWS@;%path%
+@CURRENT_RUNTIME_DIR_WINDOWS@\@ORXONOX_EXECUTABLE_NAME@ --client --writingPathSuffix client1
+pause
Index: /code/branches/rocket2/bin/client1.in
===================================================================
--- /code/branches/rocket2/bin/client1.in	(revision 6952)
+++ /code/branches/rocket2/bin/client1.in	(revision 6952)
@@ -0,0 +1,4 @@
+#!/bin/sh
+# convenience script for starting orxonox on Linux
+
+exec @CURRENT_RUNTIME_DIR@/@ORXONOX_EXECUTABLE_NAME@ --client --writingPathSuffix client1 $@
Index: /code/branches/rocket2/bin/client2.bat.in
===================================================================
--- /code/branches/rocket2/bin/client2.bat.in	(revision 6952)
+++ /code/branches/rocket2/bin/client2.bat.in	(revision 6952)
@@ -0,0 +1,4 @@
+title @PROJECT_NAME@
+path @RUNTIME_LIBRARY_DIRECTORY_WINDOWS@;%path%
+@CURRENT_RUNTIME_DIR_WINDOWS@\@ORXONOX_EXECUTABLE_NAME@ --client --writingPathSuffix client2
+pause
Index: /code/branches/rocket2/bin/client2.in
===================================================================
--- /code/branches/rocket2/bin/client2.in	(revision 6952)
+++ /code/branches/rocket2/bin/client2.in	(revision 6952)
@@ -0,0 +1,4 @@
+#!/bin/sh
+# convenience script for starting orxonox on Linux
+
+exec @CURRENT_RUNTIME_DIR@/@ORXONOX_EXECUTABLE_NAME@ --client --writingPathSuffix client2 $@
Index: /code/branches/rocket2/bin/dedicated.bat.in
===================================================================
--- /code/branches/rocket2/bin/dedicated.bat.in	(revision 6952)
+++ /code/branches/rocket2/bin/dedicated.bat.in	(revision 6952)
@@ -0,0 +1,4 @@
+title @PROJECT_NAME@
+path @RUNTIME_LIBRARY_DIRECTORY_WINDOWS@;%path%
+@CURRENT_RUNTIME_DIR_WINDOWS@\@ORXONOX_EXECUTABLE_NAME@ --dedicated --writingPathSuffix dedicated
+pause
Index: /code/branches/rocket2/bin/dedicated.in
===================================================================
--- /code/branches/rocket2/bin/dedicated.in	(revision 6952)
+++ /code/branches/rocket2/bin/dedicated.in	(revision 6952)
@@ -0,0 +1,4 @@
+#!/bin/sh
+# convenience script for starting orxonox on Linux
+
+exec @CURRENT_RUNTIME_DIR@/@ORXONOX_EXECUTABLE_NAME@ --dedicated --writingPathSuffix dedicated $@
Index: /code/branches/rocket2/bin/dedicatedClient.bat.in
===================================================================
--- /code/branches/rocket2/bin/dedicatedClient.bat.in	(revision 6952)
+++ /code/branches/rocket2/bin/dedicatedClient.bat.in	(revision 6952)
@@ -0,0 +1,4 @@
+title @PROJECT_NAME@
+path @RUNTIME_LIBRARY_DIRECTORY_WINDOWS@;%path%
+@CURRENT_RUNTIME_DIR_WINDOWS@\@ORXONOX_EXECUTABLE_NAME@ --dedicatedClient --writingPathSuffix dedicatedClient
+pause
Index: /code/branches/rocket2/bin/dedicatedClient.in
===================================================================
--- /code/branches/rocket2/bin/dedicatedClient.in	(revision 6952)
+++ /code/branches/rocket2/bin/dedicatedClient.in	(revision 6952)
@@ -0,0 +1,4 @@
+#!/bin/sh
+# convenience script for starting orxonox on Linux
+
+exec @CURRENT_RUNTIME_DIR@/@ORXONOX_EXECUTABLE_NAME@ --dedicatedClient --writingPathSuffix dedicatedClient $@
Index: /code/branches/rocket2/bin/run.bat.in
===================================================================
--- /code/branches/rocket2/bin/run.bat.in	(revision 6952)
+++ /code/branches/rocket2/bin/run.bat.in	(revision 6952)
@@ -0,0 +1,4 @@
+title @PROJECT_NAME@
+path @RUNTIME_LIBRARY_DIRECTORY_WINDOWS@;%path%
+@CURRENT_RUNTIME_DIR_WINDOWS@\@ORXONOX_EXECUTABLE_NAME@
+pause
Index: /code/branches/rocket2/bin/run.in
===================================================================
--- /code/branches/rocket2/bin/run.in	(revision 6952)
+++ /code/branches/rocket2/bin/run.in	(revision 6952)
@@ -0,0 +1,4 @@
+#!/bin/sh
+# convenience script for starting orxonox on Linux
+
+exec @CURRENT_RUNTIME_DIR@/@ORXONOX_EXECUTABLE_NAME@ $@
Index: /code/branches/rocket2/bin/server.bat.in
===================================================================
--- /code/branches/rocket2/bin/server.bat.in	(revision 6952)
+++ /code/branches/rocket2/bin/server.bat.in	(revision 6952)
@@ -0,0 +1,4 @@
+title @PROJECT_NAME@
+path @RUNTIME_LIBRARY_DIRECTORY_WINDOWS@;%path%
+@CURRENT_RUNTIME_DIR_WINDOWS@\@ORXONOX_EXECUTABLE_NAME@ --server --writingPathSuffix server
+pause
Index: /code/branches/rocket2/bin/server.in
===================================================================
--- /code/branches/rocket2/bin/server.in	(revision 6952)
+++ /code/branches/rocket2/bin/server.in	(revision 6952)
@@ -0,0 +1,4 @@
+#!/bin/sh
+# convenience script for starting orxonox on Linux
+
+exec @CURRENT_RUNTIME_DIR@/@ORXONOX_EXECUTABLE_NAME@ --server --writingPathSuffix server $@
Index: /code/branches/rocket2/bin/standalone.bat.in
===================================================================
--- /code/branches/rocket2/bin/standalone.bat.in	(revision 6952)
+++ /code/branches/rocket2/bin/standalone.bat.in	(revision 6952)
@@ -0,0 +1,4 @@
+title @PROJECT_NAME@
+path @RUNTIME_LIBRARY_DIRECTORY_WINDOWS@;%path%
+@CURRENT_RUNTIME_DIR_WINDOWS@\@ORXONOX_EXECUTABLE_NAME@ --standalone --writingPathSuffix standalone
+pause
Index: /code/branches/rocket2/bin/standalone.in
===================================================================
--- /code/branches/rocket2/bin/standalone.in	(revision 6952)
+++ /code/branches/rocket2/bin/standalone.in	(revision 6952)
@@ -0,0 +1,4 @@
+#!/bin/sh
+# convenience script for starting orxonox on Linux
+
+exec @CURRENT_RUNTIME_DIR@/@ORXONOX_EXECUTABLE_NAME@ --standalone --writingPathSuffix standalone $@
Index: /code/branches/rocket2/bin/vld.ini.in
===================================================================
--- /code/branches/rocket2/bin/vld.ini.in	(revision 6952)
+++ /code/branches/rocket2/bin/vld.ini.in	(revision 6952)
@@ -0,0 +1,155 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;;  Visual Leak Detector - Initialization/Configuration File
+;;  Copyright (c) 2006 Dan Moulding
+;;
+;;  This library is free software; you can redistribute it and/or
+;;  modify it under the terms of the GNU Lesser General Public
+;;  License as published by the Free Software Foundation; either
+;;  version 2.1 of the License, or (at your option) any later version.
+;;
+;;  This library 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
+;;  Lesser General Public License for more details.
+;;
+;;  You should have received a copy of the GNU Lesser General Public
+;;  License along with this library; if not, write to the Free Software
+;;  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+;;
+;;  See COPYING.txt for the full terms of the GNU Lesser General Public License.
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; Any options left blank or not present will revert to their default values.
+[Options]
+
+; The main on/off switch. If off, Visual Leak Detector will be completely
+; disabled. It will do nothing but print a message to the debugger indicating
+; that it has been turned off.
+;
+;  Valid Values: on, off
+;  Default: on
+;
+VLD = @VISUAL_LEAK_DETECTOR_ENABLE@ 
+
+; If yes, duplicate leaks (those that are identical) are not shown individually.
+; Only the first such leak is shown, along with a number indicating the total
+; number of duplicate leaks.
+;
+;   Valid Values: yes, no
+;   Default: no
+;
+AggregateDuplicates = yes
+
+; Lists any additional modules to be included in memory leak detection. This can
+; be useful for checking for memory leaks in debug builds of 3rd party modules
+; which can not be easily rebuilt with '#include "vld.h"'. This option should be
+; used only if absolutely necessary and only if you really know what you are
+; doing.
+;
+;   CAUTION: Avoid listing any modules that link with the release CRT libraries.
+;     Only modules that link with the debug CRT libraries should be listed here.
+;     Doing otherwise might result in false memory leak reports or even crashes.
+;
+;   Valid Values: Any list containing module names (i.e. names of EXEs or DLLs).
+;   Default: None.
+;
+ForceIncludeModules = boost_date_time-vc80-mt-gd-1_39.dll, boost_filesystem-vc80-mt-gd-1_39.dll, boost_system-vc80-mt-gd-1_39.dll, boost_thread-vc80-mt-gd-1_39.dll, enet_d.dll, lua_d.dll, ogg_d.dll, vorbis_d.dll, vorbifile_d.dll
+
+; Maximum number of data bytes to display for each leaked block. If zero, then
+; the data dump is completely suppressed and only call stacks are shown.
+; Limiting this to a low number can be useful if any of the leaked blocks are
+; very large and cause unnecessary clutter in the memory leak report.
+;
+;   Value Values: 0 - 4294967295
+;   Default: 4294967295
+;
+MaxDataDump = 0
+
+; Maximum number of call stack frames to trace back during leak detection.
+; Limiting this to a low number can reduce the CPU utilization overhead imposed
+; by memory leak detection, especially when using the slower "safe" stack
+; walking method (see StackWalkMethod below).
+;
+;   Valid Values: 1 - 4294967295
+;   Default: 4294967295
+;
+MaxTraceFrames = 
+
+; Sets the type of encoding to use for the generated memory leak report. This
+; option is really only useful in conjuction with sending the report to a file.
+; Sending a Unicode encoded report to the debugger is not useful because the
+; debugger cannot display Unicode characters. Using Unicode encoding might be
+; useful if the data contained in leaked blocks is likely to consist of Unicode
+; text.
+;
+;   Valid Values: ascii, unicode
+;   Default: ascii
+;
+ReportEncoding = ascii
+
+; Sets the report file destination, if reporting to file is enabled. A relative
+; path may be specified and is considered relative to the process' working
+; directory.
+;
+;   Valid Values: Any valid path and filename.
+;   Default: .\memory_leak_report.txt
+;
+ReportFile = 
+
+; Sets the report destination to either a file, the debugger, or both. If
+; reporting to file is enabled, the report is sent to the file specified by the
+; ReportFile option.
+;
+;   Valid Values: debugger, file, both
+;   Default: debugger
+;
+ReportTo = debugger
+
+; Turns on or off a self-test mode which is used to verify that VLD is able to
+; detect memory leaks in itself. Intended to be used for debugging VLD itself,
+; not for debugging other programs.
+;
+;   Valid Values: on, off
+;   Default: off
+;
+SelfTest = off
+
+; Selects the method to be used for walking the stack to obtain stack traces for
+; allocated memory blocks. The "fast" method may not always be able to
+; successfully trace completely through all call stacks. In such cases, the
+; "safe" method may prove to more reliably obtain the full stack trace. The
+; disadvantage is that the "safe" method is significantly slower than the "fast"
+; method and will probably result in very noticeable performance degradation of
+; the program being debugged.
+;
+;   Valid Values: fast, safe
+;   Default: fast
+; 
+StackWalkMethod = fast
+
+; Determines whether memory leak detection should be initially enabled for all
+; threads, or whether it should be initially disabled for all threads. If set
+; to "yes", then any threads requiring memory leak detection to be enabled will
+; need to call VLDEnable at some point to enable leak detection for those
+; threads.
+;
+;   Valid Values: yes, no
+;   Default: no
+;
+StartDisabled = no
+
+; Determines whether or not all frames, including frames internal to the heap,
+; are traced. There will always be a number of frames internal to Visual Leak
+; Detector and C/C++ or Win32 heap APIs that aren't generally useful for
+; determining the cause of a leak. Normally these frames are skipped during the
+; stack trace, which somewhat reduces the time spent tracing and amount of data
+; collected and stored in memory. Including all frames in the stack trace, all
+; the way down into VLD's own code can, however, be useful for debugging VLD
+; itself.
+;
+;   Valid Values: yes, no
+;   Default: no
+;
+TraceInternalFrames = no
Index: /code/branches/rocket2/cmake/CapitaliseName.cmake
===================================================================
--- /code/branches/rocket2/cmake/CapitaliseName.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/CapitaliseName.cmake	(revision 6952)
@@ -0,0 +1,33 @@
+ #
+ #             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
+ #  Examples:
+ #    "orxonox"  --> "Orxonox"
+ #    "ORXONOX"  --> "ORXONOX"
+ #    "1orxonox" --> "1orxonox"
+ #
+
+FUNCTION(CAPITALISE_NAME _name _output_var)
+  STRING(SUBSTRING "${_name}" 0 1 _first_letter)
+  STRING(TOUPPER "${_first_letter}" _first_letter)
+  STRING(REGEX REPLACE "^.(.*)$" "\\1" _rest "${_name}")
+  SET(${_output_var} "${_first_letter}${_rest}" PARENT_SCOPE)
+ENDFUNCTION(CAPITALISE_NAME)
Index: /code/branches/rocket2/cmake/CheckOGREPlugins.cmake
===================================================================
--- /code/branches/rocket2/cmake/CheckOGREPlugins.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/CheckOGREPlugins.cmake	(revision 6952)
@@ -0,0 +1,120 @@
+ #
+ #             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:
+ #    Function that checks each OGRE plugin for existance. Also looks for debug
+ #    versions and sets them accordingly.
+ #    All the plugins specified as function arguments have to be found or the
+ #    script will issue a fatal error. Additionally, all release plugins have
+ #    to be found in the same folder. Analogously for debug plugins.
+ #    Output:
+ #    OGRE_PLUGINS_FOLDER_DEBUG   Folder with the debug plugins
+ #    OGRE_PLUGINS_FOLDER_RELEASE Folder with the release plugins
+ #    OGRE_PLUGINS_DEBUG          Names of the debug plugins without extension
+ #    OGRE_PLUGINS_RELEASE        Names of the release plugins without ext.
+ #  Note:
+ #    You must not specify render systems as input. That will be taken care of
+ #    automatically.
+ #
+
+FUNCTION(CHECK_OGRE_PLUGINS)
+
+  SET(OGRE_PLUGINS ${ARGN})
+
+  IF(WIN32)
+    # On Windows we need only *.dll, not *.lib. Especially the MSVC generator doesn't look for *.dll
+    SET(CMAKE_FIND_LIBRARY_SUFFIXES .dll)
+  ENDIF(WIN32)
+  # Do not prefix "lib" on any platform
+  SET(CMAKE_FIND_LIBRARY_PREFIXES "")
+
+  SET(OGRE_RENDER_SYSTEMS RenderSystem_GL RenderSystem_Direct3D9)
+  SET(OGRE_RENDER_SYSTEM_FOUND FALSE)
+  FOREACH(_plugin ${OGRE_PLUGINS} ${OGRE_RENDER_SYSTEMS})
+    FIND_LIBRARY(OGRE_PLUGIN_${_plugin}_OPTIMIZED
+      NAMES ${_plugin}
+      PATHS $ENV{OGRE_HOME} $ENV{OGRE_PLUGIN_DIR}
+      PATH_SUFFIXES bin/Release bin/release Release release lib lib/OGRE bin
+    )
+    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
+    )
+    # We only need at least one render system. Check at the end.
+    IF(NOT ${_plugin} MATCHES "RenderSystem")
+      IF(NOT OGRE_PLUGIN_${_plugin}_OPTIMIZED)
+        MESSAGE(FATAL_ERROR "Could not find OGRE plugin named ${_plugin}")
+      ENDIF()
+    ELSEIF(OGRE_PLUGIN_${_plugin}_OPTIMIZED)
+      SET(OGRE_RENDER_SYSTEM_FOUND TRUE)
+    ENDIF()
+
+    IF(OGRE_PLUGIN_${_plugin}_OPTIMIZED)
+      # If debug version is not available, release will do as well
+      IF(OGRE_PLUGIN_${_plugin}_DEBUG STREQUAL OGRE_PLUGIN_${_plugin}_OPTIMIZED)
+        # In this case the library finder didn't find real debug versions
+        SET(OGRE_PLUGIN_${_plugin}_DEBUG "OGRE_PLUGIN_${_plugin}_DEBUG-NOTFOUND" CACHE STRING "" FORCE)
+      ENDIF()
+      MARK_AS_ADVANCED(OGRE_PLUGIN_${_plugin}_OPTIMIZED OGRE_PLUGIN_${_plugin}_DEBUG)
+
+      ### Set variables to configure orxonox.ini correctly afterwards in bin/ ###
+      # Check and set the folders
+      GET_FILENAME_COMPONENT(_plugins_folder ${OGRE_PLUGIN_${_plugin}_OPTIMIZED} PATH)
+      IF(OGRE_PLUGINS_FOLDER_RELEASE AND NOT OGRE_PLUGINS_FOLDER_RELEASE STREQUAL _plugins_folder)
+        MESSAGE(FATAL_ERROR "Ogre release plugins have to be in the same folder!")
+      ENDIF()
+      SET(OGRE_PLUGINS_FOLDER_RELEASE ${_plugins_folder})
+      IF(OGRE_PLUGIN_${_plugin}_DEBUG)
+        GET_FILENAME_COMPONENT(_plugins_folder ${OGRE_PLUGIN_${_plugin}_DEBUG} PATH)
+      ENDIF()
+      IF(OGRE_PLUGINS_FOLDER_DEBUG AND NOT OGRE_PLUGINS_FOLDER_DEBUG STREQUAL _plugins_folder)
+        MESSAGE(FATAL_ERROR "Ogre debug plugins have to be in the same folder!")
+      ENDIF()
+      SET(OGRE_PLUGINS_FOLDER_DEBUG ${_plugins_folder})
+
+      # Create a list with the plugins for release and debug configurations
+      LIST(APPEND OGRE_PLUGINS_RELEASE ${_plugin})
+      # Determine debug postfix ("d" or "_d" or none)
+      IF(OGRE_PLUGIN_${_plugin}_DEBUG MATCHES "_d\\.|_d$")
+        LIST(APPEND OGRE_PLUGINS_DEBUG "${_plugin}_d")
+      ELSEIF(OGRE_PLUGIN_${_plugin}_DEBUG MATCHES "d\\.|d$")
+        LIST(APPEND OGRE_PLUGINS_DEBUG "${_plugin}d")
+      ELSE()
+        LIST(APPEND OGRE_PLUGINS_DEBUG "${_plugin}")
+      ENDIF()
+    ENDIF(OGRE_PLUGIN_${_plugin}_OPTIMIZED)
+  ENDFOREACH(_plugin)
+  IF(NOT OGRE_RENDER_SYSTEM_FOUND)
+      MESSAGE(FATAL_ERROR "Could not find an OGRE render system plugin")
+  ENDIF()
+
+  # List has to be comma separated for orxonox.ini
+  STRING(REPLACE ";" ", " OGRE_PLUGINS_RELEASE "${OGRE_PLUGINS_RELEASE}")
+  STRING(REPLACE ";" ", " OGRE_PLUGINS_DEBUG   "${OGRE_PLUGINS_DEBUG}")
+
+  # Set variables outside function scope
+  SET(OGRE_PLUGINS_FOLDER_DEBUG ${OGRE_PLUGINS_FOLDER_DEBUG} PARENT_SCOPE)
+  SET(OGRE_PLUGINS_FOLDER_RELEASE ${OGRE_PLUGINS_FOLDER_RELEASE} PARENT_SCOPE)
+  SET(OGRE_PLUGINS_RELEASE ${OGRE_PLUGINS_RELEASE} PARENT_SCOPE)
+  SET(OGRE_PLUGINS_DEBUG ${OGRE_PLUGINS_DEBUG} PARENT_SCOPE)
+
+ENDFUNCTION(CHECK_OGRE_PLUGINS)
Index: /code/branches/rocket2/cmake/CompareVersionStrings.cmake
===================================================================
--- /code/branches/rocket2/cmake/CompareVersionStrings.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/CompareVersionStrings.cmake	(revision 6952)
@@ -0,0 +1,78 @@
+# Computes the relationship between two version strings.  A version
+# string is a number delineated by '.'s such as 1.3.2 and 0.99.9.1.
+# You can feed version strings with different number of dot versions,
+# and the shorter version number will be padded with zeros: 9.2 <
+# 9.2.1 will actually compare 9.2.0 < 9.2.1.
+#
+# Input: a_in - value, not variable
+#        b_in - value, not variable
+#        result_out - variable with value:
+#                         -1 : a_in <  b_in
+#                          0 : a_in == b_in
+#                          1 : a_in >  b_in
+#        optional argument - TRUE or default FALSE:
+#              When passing 1.2.3 and 1.2 and this switch is on
+#              the function will actually compare 1.2 < 1.2
+#              Caution: Only the first string is adjusted!
+#
+# Written by James Bigler.
+# Extended with an optional argument by Reto Grieder
+
+FUNCTION(COMPARE_VERSION_STRINGS a_in b_in result_out)
+  # Additional argument can be a switch to change compare behaviour
+  SET(cut_first ${ARGN})
+
+  # Replace '.' with ';' to allow easy tokenization of the string.
+  STRING(REPLACE "." ";" a ${a_in})
+  STRING(REPLACE "." ";" b ${b_in})
+
+  # Check the size of each list to see if they are equal.
+  LIST(LENGTH a a_length)
+  LIST(LENGTH b b_length)
+
+  # Pad the shorter list with zeros.
+
+  IF(a_length LESS b_length)
+    # a is shorter
+    SET(shorter a)
+    MATH(EXPR pad_range "${b_length} - ${a_length} - 1")
+  ELSE(a_length LESS b_length)
+    # b is shorter
+    SET(shorter b)
+    SET(first_longer a)
+    MATH(EXPR pad_range "${a_length} - ${b_length} - 1")
+  ENDIF(a_length LESS b_length)
+
+  # PAD out if we need to
+  IF(NOT pad_range LESS 0)
+    FOREACH(pad RANGE ${pad_range})
+      # Since shorter is an alias for b, we need to get to it by dereferencing shorter.
+      IF(cut_first AND first_longer)
+        LIST(REMOVE_AT a -1) # remove last element
+      ELSE(cut_first AND first_longer)
+        LIST(APPEND ${shorter} 0)
+      ENDIF(cut_first AND first_longer)
+    ENDFOREACH(pad)
+  ENDIF(NOT pad_range LESS 0)
+
+  SET(result 0)
+  SET(index 0)
+  FOREACH(a_version ${a})
+    IF(result EQUAL 0)
+      # Only continue to compare things as long as they are equal
+      LIST(GET b ${index} b_version)
+      # LESS
+      IF(a_version LESS b_version)
+        SET(result -1)
+      ENDIF(a_version LESS b_version)
+      # GREATER
+      IF(a_version GREATER b_version)
+        SET(result 1)
+      ENDIF(a_version GREATER b_version)
+    ENDIF(result EQUAL 0)
+    MATH(EXPR index "${index} + 1")
+  ENDFOREACH(a_version)
+
+  # Copy out the return result
+  SET(${result_out} ${result} PARENT_SCOPE)
+ENDFUNCTION(COMPARE_VERSION_STRINGS)
Index: /code/branches/rocket2/cmake/CompilerConfig.cmake
===================================================================
--- /code/branches/rocket2/cmake/CompilerConfig.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/CompilerConfig.cmake	(revision 6952)
@@ -0,0 +1,44 @@
+ #
+ #             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:
+ #    Calls a compiler specific script and sets some options.
+ #
+
+OPTION(EXTRA_COMPILER_WARNINGS "Enable some extra warnings (heavily pollutes the output)" FALSE)
+
+# Configure the compiler specific build options
+IF(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_GNUC)
+  INCLUDE(CompilerConfigGCC)
+ELSEIF(MSVC)
+  INCLUDE(CompilerConfigMSVC)
+ELSE()
+  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/rocket2/cmake/CompilerConfigGCC.cmake
===================================================================
--- /code/branches/rocket2/cmake/CompilerConfigGCC.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/CompilerConfigGCC.cmake	(revision 6952)
@@ -0,0 +1,101 @@
+ #
+ #             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, Adrian Friedli
+ #  Description:
+ #    Sets the right compiler and linker flags for GCC.
+ #
+
+INCLUDE(FlagUtilities)
+INCLUDE(CompareVersionStrings)
+
+# Shortcut for CMAKE_COMPILER_IS_GNUCXX and ..._GNUC
+SET(CMAKE_COMPILER_IS_GNU TRUE)
+
+# Determine compiler version
+EXEC_PROGRAM(
+  ${CMAKE_CXX_COMPILER}
+  ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
+  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
+# templates. According to Bugzilla, it was fixed March 07 but tests
+# have confirmed that GCC 4.0.0 does not pose a problem for our cases.
+COMPARE_VERSION_STRINGS("${GCC_VERSION}" "4.0.0" _compare_result)
+IF(_compare_result LESS 0)
+  SET(GCC_NO_SYSTEM_HEADER_SUPPORT TRUE)
+ENDIF()
+
+# GCC only supports PCH in versions 3.4 and above
+INCLUDE(CompareVersionStrings)
+COMPARE_VERSION_STRINGS("${GCC_VERSION}" "3.4.0" _compare_result)
+IF(_compare_result GREATER -1)
+  SET(PCH_COMPILER_SUPPORT TRUE)
+ENDIF()
+
+# Also include environment flags. Could cause conflicts though
+SET_COMPILER_FLAGS("$ENV{CXXFLAGS}" CXX CACHE)
+SET_COMPILER_FLAGS("$ENV{CFLAGS}"   C   CACHE)
+
+# These flags get added to the flags above
+SET_COMPILER_FLAGS("    -g -ggdb -D_DEBUG" Debug          CACHE)
+SET_COMPILER_FLAGS("             -DNDEBUG" ReleaseAll     CACHE)
+ADD_COMPILER_FLAGS("-O3"                   Release        CACHE)
+ADD_COMPILER_FLAGS("-O2 -g -ggdb"          RelWithDebInfo CACHE)
+ADD_COMPILER_FLAGS("-Os"                   MinSizeRel     CACHE)
+
+# CMake doesn't seem to set the PIC flags right on certain 64 bit systems
+IF(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "x86_64")
+  ADD_COMPILER_FLAGS("-fPIC" CACHE)
+ENDIF()
+
+# We have some uncoformant code, disable an optimisation feature
+ADD_COMPILER_FLAGS("-fno-strict-aliasing" CACHE)
+
+# For GCC older than version 4, do not display sign compare warings
+# because of boost::filesystem (which creates about a hundred per include)
+ADD_COMPILER_FLAGS("-Wno-sign-compare" GCC_NO_SYSTEM_HEADER_SUPPORT CACHE)
+
+# For newer GCC (4.3 and above), don't display hundreds of annoying deprecated
+# messages. Other versions don't seem to show any such warnings at all.
+ADD_COMPILER_FLAGS("-Wno-deprecated" CXX CACHE)
+
+# Always show why a precompiled header file could not be used
+ADD_COMPILER_FLAGS("-Winvalid-pch" CXX CACHE)
+
+# Increase warning level if requested
+IF(EXTRA_COMPILER_WARNINGS)
+  ADD_COMPILER_FLAGS("-Wall -Wextra -Wno-unused-parameter" CACHE)
+ELSE()
+  REMOVE_COMPILER_FLAGS("-Wextra -Wno-unused-parameter" CACHE)
+  ADD_COMPILER_FLAGS("-Wall" CACHE)
+ENDIF()
+
+# General linker flags
+SET_LINKER_FLAGS("--no-undefined" CACHE)
Index: /code/branches/rocket2/cmake/CompilerConfigMSVC.cmake
===================================================================
--- /code/branches/rocket2/cmake/CompilerConfigMSVC.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/CompilerConfigMSVC.cmake	(revision 6952)
@@ -0,0 +1,157 @@
+ #
+ #             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:
+ #    Sets the right compiler and linker flags for the Microsoft Compiler.
+ #
+
+INCLUDE(FlagUtilities)
+
+################### Compiler Version ####################
+
+# We make use of variadic macros, which is only supported by MSVC 8 and above
+IF(MSVC_VERSION LESS 1400)
+  MESSAGE(FATAL_ERROR "Microsoft Visual Studio versions below 8 (2005) are not supported because of missing compiler extensions.")
+ENDIF()
+
+
+######################## Options ########################
+
+# Currently VLD has a problem with MSVC9 although it actually is supported
+IF(MSVC80)
+  OPTION(VISUAL_LEAK_DETECTOR_ENABLE "Memory leak detector" off)
+ENDIF()
+# Make sure the value is "on" or "off" for vld.ini
+IF(VISUAL_LEAK_DETECTOR_ENABLE)
+  SET(VISUAL_LEAK_DETECTOR_ENABLE on)
+ELSE()
+  SET(VISUAL_LEAK_DETECTOR_ENABLE off)
+ENDIF()
+
+# Orxonox only supports MSVC 8 and above, which gets asserted above
+SET(PCH_COMPILER_SUPPORT TRUE)
+
+
+#################### Compiler Flags #####################
+
+# -MD    Minimal Rebuild
+# -RTC1  Both basic runtime checks
+# -MD[d] Multithreaded [debug] DLL
+# -Zi    Program Database
+# -ZI    Program Database for Edit & Continue
+# -WX    General warning Level X
+# -wdX   Disable specific warning X
+# -wnX   Set warning level of specific warning X to level n
+
+# Overwrite CMake default flags first. Be careful with this
+# Only add (not set) the general compiler flags.
+# CMake default flags : -DWIN32 -D_WINDOWS -W3 -Zm1000
+# additionally for CXX: -EHsc -GR
+ADD_COMPILER_FLAGS("-D__WIN32__ -D_WIN32"      CACHE)
+ADD_COMPILER_FLAGS("-D_CRT_SECURE_NO_WARNINGS" CACHE)
+
+# Overwrite CMake default flags here.
+SET_COMPILER_FLAGS("-MDd -Od -Zi -D_DEBUG -MP -RTC1" Debug          CACHE)
+SET_COMPILER_FLAGS("-MD  -O2     -DNDEBUG -MP"       Release        CACHE)
+SET_COMPILER_FLAGS("-MD  -O2 -Zi -DNDEBUG -MP"       RelWithDebInfo CACHE)
+SET_COMPILER_FLAGS("-MD  -O1     -DNDEBUG -MP"       MinSizeRel     CACHE)
+ADD_COMPILER_FLAGS("-D_SECURE_SCL=0" MSVC9 ReleaseAll CACHE)
+
+# Use Link time code generation for Release config if ORXONOX_RELEASE is defined
+IF(ORXONOX_RELEASE)
+  ADD_COMPILER_FLAGS("-GL" ReleaseAll CACHE)
+ENDIF()
+
+
+####################### Warnings ########################
+
+# Increase warning level if requested
+IF(EXTRA_COMPILER_WARNINGS)
+  REMOVE_COMPILER_FLAGS("-W1 -W2 -W3" CACHE)
+  ADD_COMPILER_FLAGS   ("-W4" CACHE)
+ELSE()
+  REMOVE_COMPILER_FLAGS("-W1 -W2 -W4" CACHE)
+  ADD_COMPILER_FLAGS   ("-W3" CACHE)
+ENDIF()
+
+# "<type> needs to have dll-interface to be used by clients'
+# Happens on STL member variables which are not public
+ADD_COMPILER_FLAGS("-w44251" CACHE)
+ADD_COMPILER_FLAGS("-w44275" CACHE) # For inheritance
+
+# Multiple assignment operators specified
+ADD_COMPILER_FLAGS("-w44522" CACHE)
+
+# Forcing values to bool
+ADD_COMPILER_FLAGS("-w44800" CACHE)
+
+# This warns about truncation to 255 characters in debug/browse info
+# ADD_COMPILER_FLAGS("-w44786 -w44503" CACHE)
+
+# conversion from 'double' to 'float', possible loss of data
+# conversion from 'ogg_int64_t' to 'long', possible loss of data
+# ADD_COMPILER_FLAGS("-w44244" CACHE)
+
+# "conversion from 'size_t' to 'unsigned int', possible loss of data
+# ADD_COMPILER_FLAGS("-w44267" CACHE)
+
+# "truncation from 'double' to 'float'
+# ADD_COMPILER_FLAGS("-w44305" CACHE)
+
+# "non dll-interface class used as base for dll-interface class"
+# ADD_COMPILER_FLAGS("-w44275" CACHE)
+
+# "C++ Exception Specification ignored"
+# This is because MSVC 6 did not implement all the C++ exception
+# specifications in the ANSI C++ draft.
+# ADD_COMPILER_FLAGS("-w44290" CACHE)
+
+# "no suitable definition provided for explicit template
+# instantiation request" Occurs in VC7 for no justifiable reason.
+# ADD_COMPILER_FLAGS("-w44661" CACHE)
+
+# Deprecation warnings when using CRT calls in VC8
+# These show up on all C runtime lib code in VC8, disable since they clutter
+# the warnings with things we may not be able to do anything about (e.g.
+# generated code from nvparse etc). I doubt very much that these calls
+# will ever be actually removed from VC anyway, it would break too much code.
+# Note: Probably handled by "-DCRT_SECURE_NO_WARNINGS"
+# ADD_COMPILER_FLAGS("-w44996" CACHE)
+
+# "conditional expression constant"
+# ADD_COMPILER_FLAGS("-w4201" CACHE)
+
+
+##################### Linker Flags ######################
+
+# CMake default flags: -MANIFEST -STACK:10000000 -machine:I386
+# and INCREMENTAL and DEBUG for debug versions
+ADD_LINKER_FLAGS("-OPT:REF -OPT:ICF" Release MinSizeRel CACHE)
+ADD_LINKER_FLAGS("-OPT:NOWIN98" MSVC80 CACHE)
+REMOVE_LINKER_FLAGS("-INCREMENTAL:NO"  RelWithDebInfo CACHE)
+ADD_LINKER_FLAGS   ("-INCREMENTAL:YES" RelWithDebInfo CACHE)
+
+# Use Link time code generation for Release config if ORXONOX_RELEASE is defined
+IF(ORXONOX_RELEASE)
+  REMOVE_LINKER_FLAGS("-INCREMENTAL:YES" ReleaseAll CACHE)
+  ADD_LINKER_FLAGS   ("-INCREMENTAL:NO"  ReleaseAll CACHE)
+  ADD_LINKER_FLAGS   ("-LTCG"            ReleaseAll CACHE)
+ENDIF()
Index: /code/branches/rocket2/cmake/DetermineVersion.cmake
===================================================================
--- /code/branches/rocket2/cmake/DetermineVersion.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/DetermineVersion.cmake	(revision 6952)
@@ -0,0 +1,58 @@
+ #
+ #             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:
+ #    Inspects a given file for the following expressions
+ #    "NAME_MAJOR_VERSION #"
+ #    "NAME_MINOR_VERSION #"
+ #    "NAME_PATCH_VERSION #"
+ #    and sets NAME_VERSION accordingly. NAME_PART_VERSION variables are also
+ #    set. If you wish to look for different parts (e.g. "first" "second", etc.)
+ #    simply deliver them as additional arguments (have to be three though).
+ #
+
+FUNCTION(DETERMINE_VERSION _name _file)
+  IF(EXISTS ${_file})
+    FILE(READ ${_file} _file_content)
+    SET(_parts ${ARGN})
+    LIST(LENGTH _parts _parts_length)
+    IF(NOT ${_parts_length} EQUAL 3)
+      SET(_parts MAJOR MINOR PATCH)
+    ENDIF()
+
+    FOREACH(_part ${_parts})
+      STRING(REGEX MATCH "${_name}_VERSION_${_part} +([0-9]+)" _match ${_file_content})
+      IF(_match)
+        SET(${_name}_VERSION_${_part} ${CMAKE_MATCH_1})
+        SET(${_name}_VERSION_${_part} ${CMAKE_MATCH_1} PARENT_SCOPE)
+      ELSE()
+        SET(${_name}_VERSION_${_part} "0")
+        SET(${_name}_VERSION_${_part} "0" PARENT_SCOPE)
+      ENDIF()
+      IF("${_parts}" MATCHES "^${_part}") # First?
+        SET(${_name}_VERSION "${${_name}_VERSION_${_part}}")
+      ELSE()
+        SET(${_name}_VERSION "${${_name}_VERSION}.${${_name}_VERSION_${_part}}")
+      ENDIF()
+    ENDFOREACH(_part)
+    SET(${_name}_VERSION "${${_name}_VERSION}" PARENT_SCOPE)
+  ENDIF(EXISTS ${_file})
+ENDFUNCTION(DETERMINE_VERSION)
Index: /code/branches/rocket2/cmake/FindALUT.cmake
===================================================================
--- /code/branches/rocket2/cmake/FindALUT.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/FindALUT.cmake	(revision 6952)
@@ -0,0 +1,80 @@
+# - 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 <
+
+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
+)
+
+# 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()
+
+# Handle the REQUIRED argument and set ALUT_FOUND
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(ALUT DEFAULT_MSG
+    ALUT_LIBRARY_OPTIMIZED
+    ALUT_INCLUDE_DIR
+)
+
+# Collect optimized and debug libraries
+HANDLE_LIBRARY_TYPES(ALUT)
+
+MARK_AS_ADVANCED(
+    ALUT_INCLUDE_DIR
+    ALUT_LIBRARY_OPTIMIZED
+    ALUT_LIBRARY_DEBUG
+)
Index: /code/branches/rocket2/cmake/FindCEGUI.cmake
===================================================================
--- /code/branches/rocket2/cmake/FindCEGUI.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/FindCEGUI.cmake	(revision 6952)
@@ -0,0 +1,103 @@
+# Find CEGUI includes and library
+#
+# This module defines
+#  CEGUI_INCLUDE_DIR
+#  CEGUI_LIBRARY, the library to link against to use CEGUI.
+#  CEGUI_FOUND, If false, do not try to use CEGUI
+#  CEGUI_VERSION, the version as string "x.y.z"
+#  CEGUILUA_LIBRARY, Script module library
+#  CEGUILUA_USE_INTERNAL_LIBRARY, True if CEGUILUA_LIBRARY was not defined here
+#
+# Input:
+#  ENV{CEGUIDIR}, CEGUI path, optional
+#  FIND CEGUILUA_INTERNAL_SUPPORT, List of all CEGUILua version supported
+#                                  in the source repository
+#  CEGUILUA_USE_EXTERNAL_LIBRARY, Force finding of CEGUILua
+#
+# Created by Matt Williams to find OGRE libraries
+# Copyright © 2007, Matt Williams
+#
+# Modified by Nicolas Schlumberger to find CEGUI libraries
+# and make it run on the Tardis-Infrastucture of the ETH Zurich
+# Copyright 2007, Nicolas Schlumberger
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+#
+# Several changes and additions by Fabian 'x3n' Landau
+# Lots of simplifications by Adrian Friedli and Reto Grieder
+# Version checking and CEGUILua finding by Reto Grieder
+#                 > www.orxonox.net <
+
+INCLUDE(DetermineVersion)
+INCLUDE(FindPackageHandleAdvancedArgs)
+INCLUDE(HandleLibraryTypes)
+
+FIND_PATH(CEGUI_INCLUDE_DIR CEGUI.h
+  PATHS $ENV{CEGUIDIR}
+  PATH_SUFFIXES include include/CEGUI CEGUI.framework/Headers
+)
+FIND_LIBRARY(CEGUI_LIBRARY_OPTIMIZED
+  NAMES CEGUIBase CEGUI
+  PATHS $ENV{CEGUIDIR}
+  PATH_SUFFIXES lib bin
+)
+FIND_LIBRARY(CEGUI_LIBRARY_DEBUG
+  NAMES
+    CEGUIBased CEGUIBase_d CEGUIBaseD CEGUIBase_D
+    CEGUId CEGUI_d CEGUID CEGUI_D
+  PATHS $ENV{CEGUIDIR}
+  PATH_SUFFIXES lib bin
+)
+
+# Inspect CEGUIVersion.h for the version number
+DETERMINE_VERSION(CEGUI ${CEGUI_INCLUDE_DIR}/CEGUIVersion.h)
+
+# Handle the REQUIRED argument and set CEGUI_FOUND
+# Also checks the version requirements if given
+FIND_PACKAGE_HANDLE_ADVANCED_ARGS(CEGUI DEFAULT_MSG "${CEGUI_VERSION}"
+  CEGUI_LIBRARY_OPTIMIZED
+  CEGUI_INCLUDE_DIR
+)
+
+# Collect optimized and debug libraries
+HANDLE_LIBRARY_TYPES(CEGUI)
+
+MARK_AS_ADVANCED(
+  CEGUI_INCLUDE_DIR
+  CEGUI_LIBRARY_OPTIMIZED
+  CEGUI_LIBRARY_DEBUG
+)
+
+LIST(FIND CEGUILUA_INTERNAL_SUPPORT "${CEGUI_VERSION}" _find_result)
+IF(CEGUILUA_USE_EXTERNAL_LIBRARY OR _find_result EQUAL -1)
+  # Also try to find the CEGUILua libraries.
+  # There would already be libraries in src/ for versions 0.5 and 0.6
+  FIND_LIBRARY(CEGUILUA_LIBRARY_OPTIMIZED
+    NAMES CEGUILua
+    PATHS $ENV{CEGUIDIR}
+    PATH_SUFFIXES lib bin
+  )
+  FIND_LIBRARY(CEGUILUA_LIBRARY_DEBUG
+    NAMES CEGUILuad CEGUILua_d
+    PATHS $ENV{CEGUIDIR}
+    PATH_SUFFIXES lib bin
+  )
+
+  SET(CEGUILua_FIND_REQUIRED ${CEGUI_FIND_REQUIRED})
+  # Handle the REQUIRED argument and set CEGUILUA_FOUND
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS(CEGUILua DEFAULT_MSG
+    CEGUILUA_LIBRARY_OPTIMIZED
+  )
+
+  # Collect optimized and debug libraries
+  HANDLE_LIBRARY_TYPES(CEGUILUA)
+
+  MARK_AS_ADVANCED(
+    CEGUILUA_LIBRARY_OPTIMIZED
+    CEGUILUA_LIBRARY_DEBUG
+  )
+
+ELSE(CEGUILUA_USE_EXTERNAL_LIBRARY OR _find_result EQUAL -1)
+  SET(CEGUILUA_USE_INTERNAL_LIBRARY TRUE)
+ENDIF(CEGUILUA_USE_EXTERNAL_LIBRARY OR _find_result EQUAL -1)
+
Index: /code/branches/rocket2/cmake/FindDirectX.cmake
===================================================================
--- /code/branches/rocket2/cmake/FindDirectX.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/FindDirectX.cmake	(revision 6952)
@@ -0,0 +1,53 @@
+# Find script for DirectX on Windows
+# Specifically designed to find dxguid and dinput8 for OIS
+# Once loaded this will define
+#   DIRECTX_FOUND        - system has DirectX
+#   DIRECTX_INCLUDE_DIR  - include directory for DirectX
+#   DIRECTX_LIBRARIES    - libraries for DirectX
+#
+# Set ENV{DXSD_DIR} if that has not been done the SDK installation.
+#
+# Several changes and additions by Fabian 'x3n' Landau
+# Simplifications and CMake 2.6.0 bugfix by Reto Grieder
+#                 > www.orxonox.net <
+
+INCLUDE(FindPackageHandleStandardArgs)
+INCLUDE(HandleLibraryTypes)
+
+FIND_PATH(DIRECTX_INCLUDE_DIR dinput.h
+  PATHS $ENV{DXSDK_DIR}
+  PATH_SUFFIXES include
+)
+FIND_LIBRARY(DIRECTX_LIBRARY_input dinput8
+  PATHS $ENV{DXSDK_DIR}
+  PATH_SUFFIXES lib Lib lib/x86 Lib/x86
+  NO_DEFAULT_PATH # Or else CMake 2.6.0 will find the dll in system32 on windows
+)
+FIND_LIBRARY(DIRECTX_LIBRARY_input dinput8
+  PATHS $ENV{DXSDK_DIR}
+  PATH_SUFFIXES lib Lib lib/x86 Lib/x86
+)
+FIND_LIBRARY(DIRECTX_LIBRARY_guid dxguid
+  PATHS $ENV{DXSDK_DIR}
+  PATH_SUFFIXES lib Lib lib/x86 Lib/x86
+  NO_DEFAULT_PATH # Or else CMake 2.6.0 will find the dll in system32 on windows
+)
+FIND_LIBRARY(DIRECTX_LIBRARY_guid dxguid
+  PATHS $ENV{DXSDK_DIR}
+  PATH_SUFFIXES lib Lib lib/x86 Lib/x86
+)
+
+# Handle the REQUIRED argument and set DIRECTX_FOUND
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(DirectX DEFAULT_MSG
+  DIRECTX_LIBRARY_input
+  DIRECTX_LIBRARY_guid
+  DIRECTX_INCLUDE_DIR
+)
+
+SET(DIRECTX_LIBRARIES ${DIRECTX_LIBRARY_input} ${DIRECTX_LIBRARY_guid})
+
+MARK_AS_ADVANCED(
+  DIRECTX_INCLUDE_DIR
+  DIRECTX_LIBRARY_input
+  DIRECTX_LIBRARY_guid
+)
Index: /code/branches/rocket2/cmake/FindENet.cmake
===================================================================
--- /code/branches/rocket2/cmake/FindENet.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/FindENet.cmake	(revision 6952)
@@ -0,0 +1,71 @@
+# - Try to find enet
+# Once done this will define
+#
+#  ENET_FOUND - system has enet
+#  ENet_INCLUDE_DIR - the enet include directory
+#  ENet_LIBRARY - the library needed to link against enet
+#
+# $ENETDIR is an environment variable used for finding enet.
+#
+#  Borrowed from The Mana World
+#  http://themanaworld.org/
+#
+# Several changes and additions by Fabian 'x3n' Landau
+# Lots of simplifications by Adrian Friedli and Reto Grieder
+# Version checking by Reto Grieder
+#                 > www.orxonox.net <
+
+INCLUDE(FindPackageHandleAdvancedArgs)
+INCLUDE(HandleLibraryTypes)
+
+FIND_PATH(ENET_INCLUDE_DIR enet/enet.h
+  PATHS $ENV{ENETDIR}
+  PATH_SUFFIXES include
+)
+FIND_LIBRARY(ENET_LIBRARY_OPTIMIZED
+  NAMES enet
+  PATHS $ENV{ENETDIR}
+  PATH_SUFFIXES lib
+)
+FIND_LIBRARY(ENET_LIBRARY_DEBUG
+  NAMES enetd enet_d enet_D
+  PATHS $ENV{ENETDIR}
+  PATH_SUFFIXES lib
+)
+
+# Try to determine the version. Note that enet only stores the major
+# version in the header file. So we check for existing functions.
+# Hence the this script only distinguishes between 1.0, 1.1 and 1.2
+FILE(STRINGS ${ENET_INCLUDE_DIR}/enet/enet.h _enet_header REGEX "ENET_")
+IF(_enet_header MATCHES "ENET_VERSION[ \t]*=[ \t]*1")
+  IF(_enet_header MATCHES "enet_socket_set_option")
+    SET(ENET_VERSION 1.2)
+  ELSEIF(_enet_header MATCHES "enet_peer_disconnect_later")
+    SET(ENET_VERSION 1.1)
+  ELSE()
+    SET(ENET_VERSION 1.0)
+  ENDIF()
+ELSE()
+  SET(ENET_VERSION 0) # Script doesn't support versions below 1.0
+ENDIF()
+
+# Handle the REQUIRED argument and set ENET_FOUND
+# Also check the the version requirements
+FIND_PACKAGE_HANDLE_ADVANCED_ARGS(ENet DEFAULT_MSG ${ENET_VERSION}
+  ENET_LIBRARY_OPTIMIZED
+  ENET_INCLUDE_DIR
+)
+
+# Collect optimized and debug libraries
+IF(NOT LINK_ENET_DYNAMIC AND WIN32)
+  # ENet is linked statically, hence we need to add some windows dependencies
+  HANDLE_LIBRARY_TYPES(ENET ws2_32 winmm)
+ELSE()
+  HANDLE_LIBRARY_TYPES(ENET)
+ENDIF()
+
+MARK_AS_ADVANCED(
+  ENET_INCLUDE_DIR
+  ENET_LIBRARY_OPTIMIZED
+  ENET_LIBRARY_DEBUG
+)
Index: /code/branches/rocket2/cmake/FindLua.cmake
===================================================================
--- /code/branches/rocket2/cmake/FindLua.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/FindLua.cmake	(revision 6952)
@@ -0,0 +1,184 @@
+ #
+ #             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:
+ #    Finds either Lua 5.0 or Lua 5.1 on the system. The script regards the
+ #    VERSION, EXACT, REQUIRED and QUIET arguments. A note about the EXACT
+ #    argument: EXACT 5 will match all Lua 5 versions.
+ #    When the search was successful, the following variables are set:
+ #    LUA_INCLUDE_DIR, LUA_LIBRARIES, LUA_VERSION, LUA_FOUND
+ #
+
+INCLUDE(CompareVersionStrings)
+INCLUDE(FindPackageHandleAdvancedArgs)
+INCLUDE(HandleLibraryTypes)
+
+# Macro that determines Lua version. Should work for versions 2.2 and above (current release: 5.1.4)
+FUNCTION(DETERMINE_LUA_VERSION _file _varname)
+  IF(EXISTS ${_file})
+    FILE(STRINGS ${_file} _file_content REGEX "LUA_VERSION|LUA_RELEASE")
+  ELSE()
+    SET(${_varname} "0" PARENT_SCOPE)
+    RETURN()
+  ENDIF()
+  STRING(REGEX REPLACE "^.*LUA_RELEASE[ \t]+\"Lua[ \t]+([.0-9]+)\".*$" "\\1" ${_varname} "${_file_content}")
+  IF(${_varname} STREQUAL "${_file_content}")
+    # At most version 5.1.0
+    STRING(REGEX REPLACE "^.*LUA_VERSION[ \t]+\"Lua[ \t]+([.0-9]+)\".*$" "\\1" ${_varname} "${_file_content}")
+    IF(${_varname} STREQUAL "${_file_content}")
+      MESSAGE(FATAL_ERROR "Could not determine Lua version which means this script has a bug")
+    ENDIF()
+    IF(${_varname} MATCHES "^[0-9]+\\.[0-9]+$")
+      SET(${_varname} "${${_varname}}.0") # E.g. "3.2" is "3.2.0" actually
+    ENDIF()
+  ENDIF()
+  SET(${_varname} "${${_varname}}" PARENT_SCOPE)
+ENDFUNCTION(DETERMINE_LUA_VERSION)
+
+
+# Find Lua 5.1
+FIND_PATH(LUA_5.1_INCLUDE_DIR lua.h
+  PATHS $ENV{LUA_DIR}
+  PATH_SUFFIXES include/lua51 include/lua5.1 include/lua include
+)
+IF(LUA_5.1_INCLUDE_DIR)
+  DETERMINE_LUA_VERSION(${LUA_5.1_INCLUDE_DIR}/lua.h LUA_5.1_VERSION)
+  COMPARE_VERSION_STRINGS("${LUA_5.1_VERSION}" "5.1" _version_compare TRUE)
+  IF(NOT _version_compare EQUAL 0)
+    # Incorrect version found, abort search
+    SET(LUA_5.1_INCLUDE_DIR "LUA_5.1_INCLUDE_DIR-NOTFOUND" CACHE PATH "" FORCE)
+  ELSE()
+    FIND_LIBRARY(LUA_5.1_LIBRARY_OPTIMIZED
+      NAMES lua51 lua5.1 lua
+      PATHS $ENV{LUA_DIR}
+      PATH_SUFFIXES lib64 lib
+    )
+    FIND_LIBRARY(LUA_5.1_LIBRARY_DEBUG
+      NAMES lua51d lua51_d lua5.1d lua5.1_d luad lua_d
+            lua51D lua51_D lua5.1D lua5.1_D luad lua_D
+      PATHS $ENV{LUA_DIR}
+      PATH_SUFFIXES lib64 lib
+    )
+    HANDLE_LIBRARY_TYPES(LUA_5.1)
+    SET(LUA_5.1_LIBRARIES ${LUA_5.1_LIBRARY})
+    IF(LUA_5.1_LIBRARIES)
+      SET(LUA_5.1_FOUND TRUE)
+    ENDIF()
+  ENDIF(NOT _version_compare EQUAL 0)
+ENDIF(LUA_5.1_INCLUDE_DIR)
+
+
+# Find Lua 5.0
+FIND_PATH(LUA_5.0_INCLUDE_DIR lua.h
+  PATHS $ENV{LUA_DIR}
+  PATH_SUFFIXES include/lua50 include/lua5.0 include/lua5 include/lua include
+)
+IF(LUA_5.0_INCLUDE_DIR)
+  DETERMINE_LUA_VERSION(${LUA_5.0_INCLUDE_DIR}/lua.h LUA_5.0_VERSION)
+  COMPARE_VERSION_STRINGS("${LUA_5.0_VERSION}" "5.0" _version_compare TRUE)
+  IF(NOT _version_compare EQUAL 0)
+    # Incorrect version found, abourt search
+    SET(LUA_5.0_INCLUDE_DIR "LUA_5.0_INCLUDE_DIR-NOTFOUND" CACHE PATH "" FORCE)
+  ELSE()
+    FIND_LIBRARY(LUA_5.0_LUA_LIBRARY_OPTIMIZED
+      NAMES lua50 lua5.0 lua5 lua
+      PATHS $ENV{LUA_DIR}
+      PATH_SUFFIXES lib64 lib
+    )
+    FIND_LIBRARY(LUA_5.0_LUA_LIBRARY_DEBUG
+      NAMES lua50d lua50_d lua5.0d lua5.0_d lua5d lua5_d luad lua_d
+            lua50D lua50_D lua5.0D lua5.0_D lua5d lua5_D luaD lua_D
+      PATHS $ENV{LUA_DIR}
+      PATH_SUFFIXES lib64 lib
+    )
+    HANDLE_LIBRARY_TYPES(LUA_5.0_LUA)
+
+    # In an OS X framework, lualib is usually included as part of the framework
+    # (like GLU in OpenGL.framework)
+    IF(${LUA_5.0_LUA_LIBRARY} MATCHES "framework")
+      SET(LUA_5.0_LIBRARIES ${LUA_5.0_LUA_LIBRARY})
+    ELSE()
+      FIND_LIBRARY(LUA_5.0_LUALIB_LIBRARY_OPTIMIZED
+        NAMES lualib50 lualib5.0 lualib5 lualib
+        PATHS $ENV{LUALIB_DIR} $ENV{LUA_DIR}
+        PATH_SUFFIXES lib64 lib
+      )
+      FIND_LIBRARY(LUA_5.0_LUALIB_LIBRARY_DEBUG
+        NAMES lualib50d lualib50_d lualib5.0d lualib5.0_d
+              lualib5d lualib5_d lualibd lualib_d
+              lualib50D lualib50_D lualib5.0D lualib5.0_D
+              lualib5D lualib5_D lualibD lualib_D
+        PATHS $ENV{LUALIB_DIR} $ENV{LUA_DIR}
+        PATH_SUFFIXES lib64 lib
+      )
+      HANDLE_LIBRARY_TYPES(LUA_5.0_LUALIB)
+      # Both libraries are required for Lua 5.0 to be found
+      IF(LUA_5.0_LUA_LIBRARY AND LUA_5.0_LUALIB_LIBRARY)
+        SET(LUA_5.0_LIBRARIES ${LUA_5.0_LUA_LIBRARY} ${LUA_5.0_LUALIB_LIBRARY})
+      ENDIF()
+    ENDIF(${LUA_5.0_LUA_LIBRARY} MATCHES "framework")
+
+    IF(LUA_5.0_LIBRARIES)
+      SET(LUA_5.0_FOUND TRUE)
+    ENDIF()
+  ENDIF(NOT _version_compare EQUAL 0)
+ENDIF(LUA_5.0_INCLUDE_DIR)
+
+# Pick the right version
+IF(Lua_FIND_VERSION_EXACT AND NOT Lua_FIND_VERSION MATCHES "^[0-9]*$")
+  STRING(REGEX REPLACE "^([0-9]+\\.[0-9]+)(\\..*)?$" "\\1" LUA_VERSION_SELECTION ${Lua_FIND_VERSION})
+ELSE()
+  IF(LUA_5.1_FOUND) # Prefer version 5.1 if found
+    SET(LUA_VERSION_SELECTION "5.1")
+  ELSEIF(LUA_5.0_FOUND)
+    SET(LUA_VERSION_SELECTION "5.0")
+  ENDIF()
+ENDIF()
+
+SET(LUA_INCLUDE_DIR "${LUA_${LUA_VERSION_SELECTION}_INCLUDE_DIR}")
+SET(LUA_LIBRARIES "${LUA_${LUA_VERSION_SELECTION}_LIBRARIES}")
+SET(LUA_VERSION_LONG "${LUA_${LUA_VERSION_SELECTION}_VERSION}")
+SET(LUA_VERSION "${LUA_VERSION_SELECTION}")
+
+FIND_PACKAGE_HANDLE_ADVANCED_ARGS(Lua DEFAULT_MSG "${LUA_VERSION_LONG}"
+  LUA_LIBRARIES
+  LUA_INCLUDE_DIR
+)
+
+# Include the math library for Unix only
+IF(LUA_FOUND)
+  IF(UNIX AND NOT APPLE)
+    FIND_LIBRARY(UNIX_MATH_LIBRARY m)
+    SET(LUA_LIBRARIES ${LUA_LIBRARIES} ${UNIX_MATH_LIBRARY})
+  ENDIF()
+ENDIF(LUA_FOUND)
+
+MARK_AS_ADVANCED(
+  LUA_5.0_INCLUDE_DIR
+  LUA_5.0_LUA_LIBRARY_OPTIMIZED
+  LUA_5.0_LUA_LIBRARY_DEBUG
+  LUA_5.0_LUALIB_LIBRARY_OPTIMIZED
+  LUA_5.0_LUALIB_LIBRARY_DEBUG
+  LUA_5.1_INCLUDE_DIR
+  LUA_5.1_LIBRARY_OPTIMIZED
+  LUA_5.1_LIBRARY_DEBUG
+  UNIX_MATH_LIBRARY
+)
Index: /code/branches/rocket2/cmake/FindOGRE.cmake
===================================================================
--- /code/branches/rocket2/cmake/FindOGRE.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/FindOGRE.cmake	(revision 6952)
@@ -0,0 +1,55 @@
+# Find OGRE includes and library
+#
+# This module defines
+#  OGRE_INCLUDE_DIR
+#  OGRE_LIBRARY, the library to link against to use OGRE.
+#  OGRE_FOUND, If false, do not try to use OGRE
+#
+# Copyright © 2007, Matt Williams
+# Modified by Nicolas Schlumberger to make it work on the Tardis-Infrastucture
+# of the ETH Zurich (removed later on)
+#
+# Redistribution and use is allowed according to the terms of the BSD license.
+#
+# Several changes and additions by Fabian 'x3n' Landau
+# Lots of simplifications by Adrian Friedli
+# Version checking by Reto Grieder
+#                 > www.orxonox.net <
+
+INCLUDE(DetermineVersion)
+INCLUDE(FindPackageHandleAdvancedArgs)
+INCLUDE(HandleLibraryTypes)
+
+FIND_PATH(OGRE_INCLUDE_DIR Ogre.h
+  PATHS $ENV{OGRE_HOME}
+  PATH_SUFFIXES include include/OGRE Ogre.framework/Headers
+)
+FIND_LIBRARY(OGRE_LIBRARY_OPTIMIZED
+  NAMES OgreMain Ogre
+  PATHS $ENV{OGRE_HOME}
+  PATH_SUFFIXES lib bin/Release bin/release Release release
+)
+FIND_LIBRARY(OGRE_LIBRARY_DEBUG
+  NAMES OgreMaind OgreMain_d OgreMainD OgreMain_D Ogred Ogre_d OgreD Ogre_d
+  PATHS $ENV{OGRE_HOME}
+  PATH_SUFFIXES lib bin/Debug bin/debug Debug debug Versions/A
+)
+
+# Inspect OgrePrerquisites.h for the version number
+DETERMINE_VERSION(OGRE ${OGRE_INCLUDE_DIR}/OgrePrerequisites.h)
+
+# Handle the REQUIRED argument and set OGRE_FOUND
+# Also check the version requirements
+FIND_PACKAGE_HANDLE_ADVANCED_ARGS(OGRE DEFAULT_MSG ${OGRE_VERSION}
+  OGRE_LIBRARY_OPTIMIZED
+  OGRE_INCLUDE_DIR
+)
+
+# Collect optimized and debug libraries
+HANDLE_LIBRARY_TYPES(OGRE)
+
+MARK_AS_ADVANCED(
+  OGRE_INCLUDE_DIR
+  OGRE_LIBRARY_OPTIMIZED
+  OGRE_LIBRARY_DEBUG
+)
Index: /code/branches/rocket2/cmake/FindOgg.cmake
===================================================================
--- /code/branches/rocket2/cmake/FindOgg.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/FindOgg.cmake	(revision 6952)
@@ -0,0 +1,47 @@
+# - Try to find ogg
+# Once done this will define
+#
+#  OGG_FOUND - system has ogg
+#  OGG_INCLUDE_DIR
+#  OGG_LIBRARY
+#
+# $OGGDIR is an environment variable used
+# for finding ogg.
+#
+# Several changes and additions by Fabian 'x3n' Landau
+# Most of all rewritten by Adrian Friedli
+# Debug versions and simplifications by Reto Grieder
+#                 > www.orxonox.net <
+
+INCLUDE(FindPackageHandleStandardArgs)
+INCLUDE(HandleLibraryTypes)
+
+FIND_PATH(OGG_INCLUDE_DIR ogg/ogg.h
+  PATHS $ENV{OGGDIR}
+  PATH_SUFFIXES include
+)
+FIND_LIBRARY(OGG_LIBRARY_OPTIMIZED
+  NAMES ogg
+  PATHS $ENV{OGGDIR}
+  PATH_SUFFIXES lib
+)
+FIND_LIBRARY(OGG_LIBRARY_DEBUG
+  NAMES oggd ogg_d oggD ogg_D
+  PATHS $ENV{OGGDIR}
+  PATH_SUFFIXES lib
+)
+
+# Handle the REQUIRED argument and set OGG_FOUND
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Ogg DEFAULT_MSG
+  OGG_LIBRARY_OPTIMIZED
+  OGG_INCLUDE_DIR
+)
+
+# Collect optimized and debug libraries
+HANDLE_LIBRARY_TYPES(OGG)
+
+MARK_AS_ADVANCED(
+  OGG_INCLUDE_DIR
+  OGG_LIBRARY_OPTIMIZED
+  OGG_LIBRARY_DEBUG
+)
Index: /code/branches/rocket2/cmake/FindPackageHandleAdvancedArgs.cmake
===================================================================
--- /code/branches/rocket2/cmake/FindPackageHandleAdvancedArgs.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/FindPackageHandleAdvancedArgs.cmake	(revision 6952)
@@ -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:
+ #    Extension of the standard module "FindPackageHandleStandardArgs".
+ #    This function also checks the version requirements. Also regards the
+ #    EXACT keyword if specified in FIND_PACKAGE(...).
+ #
+
+INCLUDE(FindPackageHandleStandardArgs)
+INCLUDE(CompareVersionStrings)
+
+FUNCTION(FIND_PACKAGE_HANDLE_ADVANCED_ARGS _name _fail_msg _version)
+
+  # Modify the message to include version requirements
+  IF("${_fail_msg}" STREQUAL "DEFAULT_MSG")
+    SET(_fail_msg_adv "Could NOT find ${_name}")
+  ELSE()
+    SET(_fail_msg_adv "${_fail_msg}")
+  ENDIF()
+  IF(${_name}_FIND_VERSION_EXACT)
+    SET(_fail_msg_adv "${_fail_msg_adv} (version requirements: exactly ${${_name}_FIND_VERSION})")
+  ELSE()
+    SET(_fail_msg_adv "${_fail_msg_adv} (version requirements: at least ${${_name}_FIND_VERSION})")
+  ENDIF()
+  FIND_PACKAGE_HANDLE_STANDARD_ARGS("${_name}" "${_fail_msg_adv}" ${ARGN})
+  STRING(TOUPPER ${_name} _NAME_UPPER)
+
+  # Also check version requirements if given to FindPackage(...)
+  IF(${_name}_FIND_VERSION)
+    # Note: the last argument of the function tells it to cut the first
+    #       version string instead of padding it with zeros if necessary
+    COMPARE_VERSION_STRINGS("${_version}" "${${_name}_FIND_VERSION}" _compatible TRUE)
+    IF(${_name}_FIND_VERSION_EXACT AND NOT _compatible EQUAL 0)
+      MESSAGE(FATAL_ERROR "Exact ${_name} version required is ${${_name}_FIND_VERSION}\n"
+                          "Your version is ${_version}")
+      SET(${_NAME_UPPER}_FOUND FALSE)
+    ELSEIF(_compatible LESS 0)
+      MESSAGE(FATAL_ERROR "Minimum ${_name} version required is ${${_name}_FIND_VERSION}\n"
+                          "Your version is ${_version}")
+      SET(${_NAME_UPPER}_FOUND FALSE)
+    ENDIF()
+  ENDIF(${_name}_FIND_VERSION)
+
+  # Raise scope (FindPackageHandleStandardArgs uses PARENT_SCOPE)
+  SET(${_NAME_UPPER}_FOUND ${${_NAME_UPPER}_FOUND} PARENT_SCOPE)
+
+ENDFUNCTION(FIND_PACKAGE_HANDLE_ADVANCED_ARGS)
Index: /code/branches/rocket2/cmake/FindVorbis.cmake
===================================================================
--- /code/branches/rocket2/cmake/FindVorbis.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/FindVorbis.cmake	(revision 6952)
@@ -0,0 +1,62 @@
+# - Try to find ogg/vorbis
+# Once done this will define
+#
+#  VORBIS_FOUND - system has vorbis
+#  VORBIS_INCLUDE_DIR
+#  VORBIS_LIBRARIES - vorbis and vorbisfile libraries
+#
+# $VORBISDIR is an environment variable used
+# for finding vorbis.
+#
+# Several changes and additions by Fabian 'x3n' Landau
+# Most of all rewritten by Adrian Friedli
+# Debug versions and simplifications by Reto Grieder
+#                 > www.orxonox.net <
+
+INCLUDE(FindPackageHandleStandardArgs)
+INCLUDE(HandleLibraryTypes)
+
+FIND_PATH(VORBIS_INCLUDE_DIR vorbis/codec.h
+  PATHS $ENV{VORBISDIR}
+  PATH_SUFFIXES include
+)
+FIND_LIBRARY(VORBIS_LIBRARY_OPTIMIZED
+  NAMES vorbis
+  PATHS $ENV{VORBISDIR}
+  PATH_SUFFIXES lib
+)
+FIND_LIBRARY(VORBIS_LIBRARY_DEBUG
+  NAMES vorbisd vorbis_d vorbisD vorbis_D
+  PATHS $ENV{VORBISDIR}
+  PATH_SUFFIXES lib
+)
+FIND_LIBRARY(VORBISFILE_LIBRARY_OPTIMIZED
+  NAMES vorbisfile
+  PATHS $ENV{VORBISDIR}
+  PATH_SUFFIXES lib
+)
+FIND_LIBRARY(VORBISFILE_LIBRARY_DEBUG
+  NAMES vorbisfiled vorbisfile_d vorbisfileD vorbisfile_D
+  PATHS $ENV{VORBISDIR}
+  PATH_SUFFIXES lib
+)
+
+# Handle the REQUIRED argument and set VORBIS_FOUND
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Vorbis DEFAULT_MSG
+  VORBIS_LIBRARY_OPTIMIZED
+  VORBISFILE_LIBRARY_OPTIMIZED
+  VORBIS_INCLUDE_DIR
+)
+
+# Collect optimized and debug libraries
+HANDLE_LIBRARY_TYPES(VORBIS)
+HANDLE_LIBRARY_TYPES(VORBISFILE)
+SET(VORBIS_LIBRARIES ${VORBIS_LIBRARY} ${VORBISFILE_LIBRARY})
+
+MARK_AS_ADVANCED(
+  VORBIS_INCLUDE_DIR
+  VORBIS_LIBRARY_OPTIMIZED
+  VORBIS_LIBRARY_DEBUG
+  VORBISFILE_LIBRARY_OPTIMIZED
+  VORBISFILE_LIBRARY_DEBUG
+)
Index: /code/branches/rocket2/cmake/FlagUtilities.cmake
===================================================================
--- /code/branches/rocket2/cmake/FlagUtilities.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/FlagUtilities.cmake	(revision 6952)
@@ -0,0 +1,177 @@
+ #
+ #             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:
+ #    Sets the compiler/linker flags. After the flags you can specify more args:
+ #    Release, Debug, RelWithDebInfo, MinSizeRel: Build configs (inclusive)
+ #    ReleaseAll: Sets the flags of all three release builds
+ #    CACHE: Values are witten with SET_CACHE_ADVANCED
+ #    FORCE: When writing to the cache, the values are set anyway
+ #    Any variable names (like WIN32, MSVC, etc.): Condition (combined with AND)
+ #    You can suffix the condition with a NOT if you wish
+ #  Function names:
+ #    [ADD/SET/REMOVE]_[COMPILER/LINKER]_FLAGS
+ #  Caution: -If you use CACHE after calling the macro without CACHE, the value
+ #            Will not be written unless FORCE is specified.
+ #          - Also be aware to always specify the flags in quotes.
+ #  Example:
+ #    REMOVE_COMPILER_FLAGS("/Gm "asdf" -q"test -foo" CXX ReleaseAll NOT UNIX)
+ #    This will only remove the CXX (C++) flags on a non Unix system for the
+ #    Release, RelWithDebInfo and MinSizeRel configurations. The macros should
+ #    be able to cope with "test -foo" as string argument for a flag.
+ #
+
+INCLUDE(SeparateFlags)
+INCLUDE(SetCacheAdvanced)
+
+# Compiler flags, additional arguments:
+# C, CXX: Specify a language, default is both
+MACRO(SET_COMPILER_FLAGS _flags)
+  _INTERNAL_PARSE_FLAGS_ARGS(SET "C;CXX" "" "${_flags}" "${ARGN}")
+ENDMACRO(SET_COMPILER_FLAGS)
+# Add flags (flags don't get added twice)
+MACRO(ADD_COMPILER_FLAGS _flags)
+  _INTERNAL_PARSE_FLAGS_ARGS(APPEND "C;CXX" "" "${_flags}" "${ARGN}")
+ENDMACRO(ADD_COMPILER_FLAGS)
+# Remove flags
+MACRO(REMOVE_COMPILER_FLAGS _flags)
+  _INTERNAL_PARSE_FLAGS_ARGS(REMOVE_ITEM "C;CXX" "" "${_flags}" "${ARGN}")
+ENDMACRO(REMOVE_COMPILER_FLAGS)
+
+
+# Linker flags, additional arguments:
+# EXE, SHARED, MODULE: Specify a linker mode, default is all three
+MACRO(SET_LINKER_FLAGS _flags)
+  _INTERNAL_PARSE_FLAGS_ARGS(SET "EXE;SHARED;MODULE" "_LINKER" "${_flags}" "${ARGN}")
+ENDMACRO(SET_LINKER_FLAGS)
+# Add flags (flags don't get added twice)
+MACRO(ADD_LINKER_FLAGS _flags)
+  _INTERNAL_PARSE_FLAGS_ARGS(APPEND "EXE;SHARED;MODULE" "_LINKER" "${_flags}" "${ARGN}")
+ENDMACRO(ADD_LINKER_FLAGS)
+# Remove flags
+MACRO(REMOVE_LINKER_FLAGS _flags)
+  _INTERNAL_PARSE_FLAGS_ARGS(REMOVE_ITEM "EXE;SHARED;MODULE" "_LINKER" "${_flags}" "${ARGN}")
+ENDMACRO(REMOVE_LINKER_FLAGS)
+
+
+# Internal macro, do not use
+# Parses the given additional arguments and sets the flags to the
+# corresponding variables.
+MACRO(_INTERNAL_PARSE_FLAGS_ARGS _mode _keys _key_postfix _flags)
+  SET(_langs)
+  SET(_build_types)
+  SET(_cond TRUE)
+  SET(_invert_condition FALSE)
+  SET(_write_to_cache FALSE)
+  SET(_force FALSE)
+  STRING(REPLACE ";" "|" _key_regex "${_keys}")
+  SET(_key_regex "^(${_key_regex})$")
+
+  FOREACH(_arg ${ARGN})
+    IF(_arg MATCHES "${_key_regex}")
+      LIST(APPEND _langs "${_arg}")
+    ELSEIF(   _arg MATCHES "^(Debug|Release|MinSizeRel|RelWithDebInfo)$"
+           OR _arg MATCHES "^(DEBUG|RELEASE|MINSIZEREL|RELWITHDEBINFO)$")
+      STRING(TOUPPER "${_arg}" _upper_arg)
+      LIST(APPEND _build_types ${_upper_arg})
+    ELSEIF(_arg STREQUAL "ReleaseAll")
+      LIST(APPEND _build_types RELEASE MINSIZEREL RELWITHDEBINFO)
+    ELSEIF(_arg STREQUAL "CACHE")
+      SET(_write_to_cache TRUE)
+    ELSEIF(_arg STREQUAL "FORCE")
+      SET(_force TRUE)
+    ELSEIF(_arg MATCHES "^[Nn][Oo][Tt]$")
+      SET(_invert_condition TRUE)
+    ELSE()
+      IF(_invert_condition)
+        SET(_invert_condition FALSE)
+        IF(${_arg})
+          SET(_arg_cond FALSE)
+        ELSE()
+          SET(_arg_cond TRUE)
+       ENDIF()
+      ELSE()
+        SET(_arg_cond ${${_arg}})
+      ENDIF()
+      IF(_cond AND _arg_cond)
+        SET(_cond TRUE)
+      ELSE()
+        SET(_cond FALSE)
+      ENDIF()
+    ENDIF()
+  ENDFOREACH(_arg)
+
+  # No language specified, use all: C and CXX or EXE, SHARED and MODULE
+  IF(NOT DEFINED _langs)
+    SET(_langs ${_keys})
+  ENDIF()
+
+  IF(_cond)
+    FOREACH(_lang ${_langs})
+      SET(_varname "CMAKE_${_lang}${_key_postfix}_FLAGS")
+      IF(DEFINED _build_types)
+        FOREACH(_build_type ${_build_types})
+          _INTERNAL_PARSE_FLAGS(${_mode} "${_flags}" ${_varname}_${_build_type} ${_write_to_cache} ${_force})
+        ENDFOREACH(_build_type)
+      ELSE()
+        _INTERNAL_PARSE_FLAGS(${_mode} "${_flags}" ${_varname} ${_write_to_cache} ${_force})
+      ENDIF()
+    ENDFOREACH(_lang ${_langs})
+  ENDIF(_cond)
+ENDMACRO(_INTERNAL_PARSE_FLAGS_ARGS)
+
+
+# Internal macro, do not use
+# Modifies the flags according to the mode: set, add or remove
+# Also sets flags according to the CACHE and FORCE parameter.
+# If only CACHE is specified, SET_CACHE_ADVANCED() is used.
+MACRO(_INTERNAL_PARSE_FLAGS _mode _flags _varname _write_to_cache _force)
+  SEPARATE_FLAGS("${_flags}" _arg_flag_list)
+
+  IF("${_mode}" STREQUAL "SET")
+    # SET
+    SET(_flag_list "${_arg_flag_list}")
+  ELSE()
+    # ADD or REMOVE
+    SEPARATE_FLAGS("${${_varname}}" _flag_list)
+    IF(NOT _flag_list)
+      SET(_flag_list "") # LIST command requires a list in any case
+    ENDIF()
+    FOREACH(_flag ${_arg_flag_list})
+      LIST(${_mode} _flag_list "${_flag}")
+    ENDFOREACH(_flag)
+  ENDIF()
+
+  LIST(REMOVE_DUPLICATES _flag_list)
+  LIST(SORT _flag_list)
+  STRING(REPLACE ";" " " _flag_list "${_flag_list}")
+
+  IF(_write_to_cache)
+    IF(_force)
+      SET(${_varname} "${_flag_list}" CACHE STRING "${${_varname}}" FORCE)
+      SET(${_varname} "${_flag_list}" CACHE STRING "${${_varname}}" FORCE)
+    ELSE()
+      SET_CACHE_ADVANCED(${_varname} STRING "${${_varname}}" "${_flag_list}")
+    ENDIF()
+  ELSE()
+    SET(${_varname} "${_flag_list}")
+  ENDIF()
+ENDMACRO(_INTERNAL_PARSE_FLAGS)
Index: /code/branches/rocket2/cmake/GenerateToluaBindings.cmake
===================================================================
--- /code/branches/rocket2/cmake/GenerateToluaBindings.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/GenerateToluaBindings.cmake	(revision 6952)
@@ -0,0 +1,79 @@
+ #
+ #             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:
+ #    Adrian Friedli
+ #  Description:
+ #    Sets the CMake options that will generate Tolua++ bindings.
+ #  Parameters:
+ #    _tolua_package - Name of the package, e.g. "Core"
+ #    _target_source_files - Variable name of the target source files, the
+ #                           script will add the generated files to this list.
+ #    ARGN - The header files in the style "INTPUTFILES Foo.h Bar.h"
+ #  Global Variables: (need to be set before)
+ #    TOLUA_PARSER_SOURCE - Lua file with the parser source code
+ #    TOLUA_PARSER_DEPENDENCIES - All the dependent lua files
+ #    RUNTIME_LIBRARY_DIRECTORY - Working directory
+ #
+
+FUNCTION(GENERATE_TOLUA_BINDINGS _tolua_package _target_source_files)
+  SET(_tolua_inputfiles ${ARGN})
+  LIST(REMOVE_ITEM _tolua_inputfiles "INPUTFILES")
+
+  SET(_tolua_pkgfile "${CMAKE_CURRENT_BINARY_DIR}/tolua.pkg")
+  SET(_tolua_cxxfile "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/ToluaBind${_tolua_package}.cc")
+  SET(_tolua_hfile   "${CMAKE_BINARY_DIR}/src/toluabind/${CMAKE_CFG_INTDIR}/ToluaBind${_tolua_package}.h")
+
+  SET(${_target_source_files}
+    ${${_target_source_files}}
+    ${_tolua_cxxfile}
+    ${_tolua_hfile}
+    PARENT_SCOPE
+  )
+  SOURCE_GROUP("Tolua" FILES ${_tolua_cxxfile} ${_tolua_hfile})
+  # Disable annoying GCC warnings
+  IF(CMAKE_COMPILER_IS_GNU)
+    SET_SOURCE_FILES_PROPERTIES(${_tolua_cxxfile} PROPERTIES COMPILE_FLAGS "-w")
+  ENDIF()
+  # Tolua binding speedup if required
+  IF(ORXONOX_RELEASE)
+    SET_SOURCE_FILES_PROPERTIES(${_tolua_cxxfile} PROPERTIES COMPILE_FLAGS "-DTOLUA_RELEASE")
+  ENDIF()
+
+  # Create temporary package file and implicit dependencies
+  FILE(REMOVE ${_tolua_pkgfile})
+  FOREACH(_tolua_inputfile ${_tolua_inputfiles})
+    FILE(APPEND ${_tolua_pkgfile} "\$cfile \"${_tolua_inputfile}\"\n")
+    LIST(APPEND _implicit_dependencies CXX ${_tolua_inputfile})
+  ENDFOREACH(_tolua_inputfile)
+
+  ADD_CUSTOM_COMMAND(
+    OUTPUT ${_tolua_cxxfile} ${_tolua_hfile}
+    COMMAND tolua++app_orxonox -n ${_tolua_package}
+                               -w ${CMAKE_CURRENT_SOURCE_DIR}
+                               -o ${_tolua_cxxfile}
+                               -H ${_tolua_hfile}
+                               -s ${TOLUA_PARSER_SOURCE}
+                                  ${_tolua_pkgfile}
+    DEPENDS           ${TOLUA_PARSER_DEPENDENCIES}
+    IMPLICIT_DEPENDS  ${_implicit_dependencies}
+    WORKING_DIRECTORY ${RUNTIME_LIBRARY_DIRECTORY}
+    COMMENT "Generating tolua bind files for package ${_tolua_package}"
+  )
+ENDFUNCTION(GENERATE_TOLUA_BINDINGS)
Index: /code/branches/rocket2/cmake/GetGCCCompilerFlags.cmake
===================================================================
--- /code/branches/rocket2/cmake/GetGCCCompilerFlags.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/GetGCCCompilerFlags.cmake	(revision 6952)
@@ -0,0 +1,73 @@
+ #
+ #             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:
+ #    Tries to return all GCC compiler flags set for a target. This also
+ #    all definitions of the current directory.
+ #
+
+INCLUDE(SeparateFlags)
+
+FUNCTION(GET_GCC_COMPILER_FLAGS _target _flagsvar)
+
+  # General flags
+  STRING(TOUPPER "${CMAKE_BUILD_TYPE}" _build_type_upper)
+  SET(_flag_str "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${_build_type_upper}}")
+
+  # Include directories
+  GET_DIRECTORY_PROPERTY(_include_dirs INCLUDE_DIRECTORIES)
+  IF(_include_dirs)
+    FOREACH(_directory ${_include_dirs})
+      SET(_flag_str "${_flag_str} -I${_directory}")
+    ENDFOREACH(_directory)
+  ENDIF()
+
+  # For shared libraries linked with gcc, we have to add -fPIC
+  GET_TARGET_PROPERTY(_target_type ${_target} TYPE)
+  IF(NOT MINGW AND ${_target_type} STREQUAL SHARED_LIBRARY)
+    SET(_flag_str "${_flag_str} -fPIC")
+  ENDIF()
+
+  # Target compile flags
+  GET_TARGET_PROPERTY(_target_flags ${_target} COMPILE_FLAGS)
+  IF(_target_flags)
+    SET(_flag_str "${_flag_str} ${_target_flags}")
+  ENDIF()
+
+  # Definitions from target and directory
+  GET_DIRECTORY_PROPERTY(_directory_defs                 COMPILE_DEFINITIONS)
+  GET_DIRECTORY_PROPERTY(_directory_defs_build_type      COMPILE_DEFINITIONS_${_build_type_upper})
+  GET_TARGET_PROPERTY(_target_defs            ${_target} COMPILE_DEFINITIONS)
+  GET_TARGET_PROPERTY(_target_defs_build_type ${_target} COMPILE_DEFINITIONS_${_build_type_upper})
+  GET_TARGET_PROPERTY(_target_def_symbol      ${_target} DEFINE_SYMBOL)
+  # Prefix them all with a "-D" if the property was found
+  FOREACH(_def ${_directory_defs} ${_directory_defs_build_type} ${_target_defs}
+               ${_target_defs_build_type} ${_target_def_symbol})
+    IF(_def)
+      SET(_flag_str "${_flag_str} -D${_def}")
+    ENDIF(_def)
+  ENDFOREACH(_def)
+
+  SEPARATE_FLAGS("${_flag_str}" _flags)
+  LIST(REMOVE_DUPLICATES _flags)
+  SET(${_flagsvar} ${_flags} PARENT_SCOPE)
+
+ENDFUNCTION(GET_GCC_COMPILER_FLAGS)
Index: /code/branches/rocket2/cmake/HandleLibraryTypes.cmake
===================================================================
--- /code/branches/rocket2/cmake/HandleLibraryTypes.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/HandleLibraryTypes.cmake	(revision 6952)
@@ -0,0 +1,42 @@
+ #
+ #             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:
+ #    Checks debug and optimized libaries and sets the variable ${_name}_LIBRARY
+ #    accordingly. If only an optimized library was found, the "optimized"
+ #    keyword is omitted to support the debug version too.
+ #
+
+FUNCTION(HANDLE_LIBRARY_TYPES _name)
+  # Additional libraries can be added as additional arguments
+  IF(${_name}_LIBRARY_DEBUG AND ${_name}_LIBRARY_OPTIMIZED)
+    SET(${_name}_LIBRARY
+      optimized ${${_name}_LIBRARY_OPTIMIZED} ${ARGN}
+      debug     ${${_name}_LIBRARY_DEBUG}     ${ARGN}
+      PARENT_SCOPE
+    )
+  ELSE()
+    SET(${_name}_LIBRARY
+      ${${_name}_LIBRARY_OPTIMIZED} ${ARGN}
+      PARENT_SCOPE
+     )
+  ENDIF()
+ENDFUNCTION(HANDLE_LIBRARY_TYPES)
Index: /code/branches/rocket2/cmake/InstallConfig.cmake
===================================================================
--- /code/branches/rocket2/cmake/InstallConfig.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/InstallConfig.cmake	(revision 6952)
@@ -0,0 +1,82 @@
+ #
+ #             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:
+ #    Configures the installation (paths, rpaths, options)
+ #
+
+IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) # Variable provided by CMake
+  IF("$ENV{ORXONOX_DEV}" OR TARDIS)
+    SET(_install_prefix_changed 1)
+    SET(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/install CACHE PATH
+        "Install path prefix, prepended onto install directories." FORCE)
+  ENDIF()
+ENDIF()
+
+SET(_info_text "Puts all installed files in subfolders of the install prefix path. That root folder can then be moved, copied and renamed as you wish. The executable will not write to folders like ~/.orxonox or \"Applictation Data\"")
+IF(UNIX AND NOT _install_prefix_changed)
+  OPTION(INSTALL_COPYABLE "${_info_text}" FALSE)
+ELSE()
+  OPTION(INSTALL_COPYABLE "${_info_text}" TRUE)
+ENDIF()
+
+# Default installation paths
+SET(RUNTIME_INSTALL_DIRECTORY ${CMAKE_INSTALL_PREFIX}/${DEFAULT_RUNTIME_PATH})
+SET(LIBRARY_INSTALL_DIRECTORY ${CMAKE_INSTALL_PREFIX}/${DEFAULT_LIBRARY_PATH})
+SET(ARCHIVE_INSTALL_DIRECTORY ${CMAKE_INSTALL_PREFIX}/${DEFAULT_ARCHIVE_PATH})
+SET(MODULE_INSTALL_DIRECTORY  ${CMAKE_INSTALL_PREFIX}/${DEFAULT_MODULE_PATH})
+SET(DOC_INSTALL_DIRECTORY     ${CMAKE_INSTALL_PREFIX}/${DEFAULT_DOC_PATH})
+SET(DATA_INSTALL_DIRECTORY    ${CMAKE_INSTALL_PREFIX}/${DEFAULT_DATA_PATH})
+SET(CONFIG_INSTALL_DIRECTORY  ${CMAKE_INSTALL_PREFIX}/${DEFAULT_CONFIG_PATH})
+SET(LOG_INSTALL_DIRECTORY     ${CMAKE_INSTALL_PREFIX}/${DEFAULT_LOG_PATH})
+
+IF(NOT INSTALL_COPYABLE)
+  IF(UNIX) # Apple too?
+    # Using absolute paths
+    SET(RUNTIME_INSTALL_DIRECTORY ${CMAKE_INSTALL_PREFIX}/bin)
+    SET(LIBRARY_INSTALL_DIRECTORY ${CMAKE_INSTALL_PREFIX}/lib/orxonox)
+    SET(ARCHIVE_INSTALL_DIRECTORY ${CMAKE_INSTALL_PREFIX}/lib/orxonox/static)
+    SET(MODULE_INSTALL_DIRECTORY  ${CMAKE_INSTALL_PREFIX}/lib/orxonox/modules)
+    SET(DOC_INSTALL_DIRECTORY     ${CMAKE_INSTALL_PREFIX}/share/doc/orxonox)
+    SET(DATA_INSTALL_DIRECTORY    ${CMAKE_INSTALL_PREFIX}/share/orxonox)
+  ENDIF()
+
+  # Leave empty because it is user and therefore runtime dependent
+  SET(CONFIG_INSTALL_DIRECTORY)
+  SET(LOG_INSTALL_DIRECTORY)
+ENDIF()
+
+################## Unix rpath ###################
+
+# When building, don't use the install RPATH already
+# (but later on when installing)
+SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
+
+# The RPATH to be used when installing
+IF(INSTALL_COPYABLE)
+  SET(CMAKE_INSTALL_RPATH ${DEFAULT_LIBRARY_PATH})
+ELSE()
+  SET(CMAKE_INSTALL_RPATH ${LIBRARY_INSTALL_DIRECTORY})
+ENDIF()
+
+# Add the automatically determined parts of the RPATH
+# which point to directories outside the build tree to the install RPATH
+SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
Index: /code/branches/rocket2/cmake/LibraryConfig.cmake
===================================================================
--- /code/branches/rocket2/cmake/LibraryConfig.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/LibraryConfig.cmake	(revision 6952)
@@ -0,0 +1,202 @@
+ #
+ #             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:
+ #    Configures the external libraries. Whenever possible, the find scripts
+ #    from the CMake module path are used, but that required some adjustments
+ #    for certain libraries (Boost, OpenAL, TCL)
+ #
+
+INCLUDE(CompareVersionStrings)
+INCLUDE(FindPackageHandleStandardArgs)
+
+# Prevent CMake from finding libraries in the installation folder on Windows.
+# There might already be an installation from another compiler
+IF(WIN32)
+  LIST(REMOVE_ITEM CMAKE_SYSTEM_PREFIX_PATH  "${CMAKE_INSTALL_PREFIX}")
+  LIST(REMOVE_ITEM CMAKE_SYSTEM_LIBRARY_PATH "${CMAKE_INSTALL_PREFIX}/bin")
+ENDIF()
+
+############## Platform Scripts #################
+
+# On Windows using a package causes way less problems
+SET(_option_msg "Set this to true to use precompiled dependecy archives")
+IF(WIN32)
+  OPTION(DEPENDENCY_PACKAGE_ENABLE "${_option_msg}" ON)
+ELSE(WIN32)
+  OPTION(DEPENDENCY_PACKAGE_ENABLE "${_option_msg}" FALSE)
+ENDIF(WIN32)
+
+# Scripts for specific library and CMake config
+INCLUDE(LibraryConfigTardis)
+INCLUDE(LibraryConfigApple)
+
+IF(DEPENDENCY_PACKAGE_ENABLE)
+  GET_FILENAME_COMPONENT(_dep_dir_1 ${CMAKE_SOURCE_DIR}/../dependencies ABSOLUTE)
+  GET_FILENAME_COMPONENT(_dep_dir_2 ${CMAKE_SOURCE_DIR}/../lib_dist/dependencies ABSOLUTE)
+  FIND_PATH(DEPENDENCY_PACKAGE_DIR
+    NAMES include
+    PATHS
+      ${CMAKE_SOURCE_DIR}/dependencies
+      ${_dep_dir_1}
+      ${_dep_dir_2}
+    NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH
+  )
+  IF(NOT DEPENDENCY_PACKAGE_DIR)
+    MESSAGE(STATUS "Warning: Could not find dependency directory."
+                   "Disable LIBRARY_USE_PACKAGE if you have none intalled.")
+  ELSE()
+    INCLUDE(PackageConfigMinGW)
+    INCLUDE(PackageConfigMSVC)
+    INCLUDE(PackageConfig) # For both msvc and mingw
+  ENDIF()
+ENDIF(DEPENDENCY_PACKAGE_ENABLE)
+
+# User script
+SET(LIBRARY_CONFIG_USER_SCRIPT "" CACHE FILEPATH
+    "Specify a CMake script if you wish to write your own library path config.
+     See LibraryConfigTardis.cmake for an example.")
+IF(LIBRARY_CONFIG_USER_SCRIPT)
+  IF(EXISTS ${CMAKE_MODULE_PATH}/${LIBRARY_CONFIG_USER_SCRIPT})
+    INCLUDE(${CMAKE_MODULE_PATH}/${LIBRARY_CONFIG_USER_SCRIPT})
+  ENDIF()
+ENDIF(LIBRARY_CONFIG_USER_SCRIPT)
+
+
+############### Library finding #################
+# Performs the search and sets the variables    #
+
+FIND_PACKAGE(OGRE  1.4       REQUIRED)
+FIND_PACKAGE(ENet  1.1       REQUIRED)
+FIND_PACKAGE(Ogg             REQUIRED)
+FIND_PACKAGE(Vorbis          REQUIRED)
+FIND_PACKAGE(ALUT            REQUIRED)
+FIND_PACKAGE(ZLIB            REQUIRED)
+IF(WIN32)
+  FIND_PACKAGE(DirectX       REQUIRED)
+ENDIF(WIN32)
+
+##### CEGUI #####
+# We make use of the CEGUI script module called CEGUILua.
+# However there is a small issue with that: We use Tolua, a C++ binding
+# generator ourselves. And we also have to use our bindings in the same
+# lua state is CEGUILua's. Unfortunately this implies that both lua runtime
+# version are equal or else you get segmentation faults.
+# In order to match the Lua versions we decided to ship CEGUILua in our
+# repository, mainly because there is no way to determine which version of
+# Lua CEGUILua was linked against (you'd have to specify yourself) and secondly
+# because we can then choose the Lua version. Future plans might involve only
+# accepting Lua 5.1.
+
+# Insert all internally supported CEGUILua versions here
+SET(CEGUILUA_INTERNAL_SUPPORT 0.5.0 0.6.0 0.6.1 0.6.2)
+OPTION(CEGUILUA_USE_EXTERNAL_LIBRARY "Force the use of external CEGUILua library" OFF)
+FIND_PACKAGE(CEGUI 0.5 REQUIRED)
+
+##### Lua #####
+IF(CEGUILUA_USE_EXTERNAL_LIBRARY)
+  COMPARE_VERSION_STRINGS(${CEGUI_VERSION} "0.6" _version_comparison)
+  IF(version_comparison LESS 0)
+    SET(LUA_VERSION_REQUEST 5.0)
+  ELSE()
+    SET(LUA_VERSION_REQUEST 5.1)
+  ENDIF()
+ELSE()
+  SET(LUA_VERSION_REQUEST 5)
+ENDIF()
+FIND_PACKAGE(Lua ${LUA_VERSION_REQUEST} EXACT REQUIRED)
+
+##### OpenAL #####
+FIND_PACKAGE(OpenAL REQUIRED)
+# Also use parent include dir (without AL/) for ALUT
+IF(OPENAL_INCLUDE_DIR MATCHES "/AL$")
+  GET_FILENAME_COMPONENT(ALT_OPENAL_INCLUDE_DIR ${OPENAL_INCLUDE_DIR} PATH)
+ENDIF()
+SET(OPENAL_INCLUDE_DIRS ${OPENAL_INCLUDE_DIR} ${ALT_OPENAL_INCLUDE_DIR})
+# Notfiy user
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenAL DEFAULT_MSG OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
+# Hide variables created by the script
+MARK_AS_ADVANCED(OPENAL_INCLUDE_DIR OPENAL_LIBRARY)
+
+##### Tcl #####
+# We only require Tcl, so avoid confusing user about other Tcl stuff by
+# applying a little workaround
+SET(Tclsh_FIND_QUIETLY TRUE)
+FIND_PACKAGE(TCL QUIET)
+# Display messages separately
+SET(TCL_FIND_QUIETLY FALSE)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(TCL DEFAULT_MSG TCL_LIBRARY TCL_INCLUDE_PATH)
+
+##### Boost #####
+# Expand the next statement if newer boost versions than 1.36.1 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)
+IF( NOT TARDIS )
+  FIND_PACKAGE(Boost 1.35 REQUIRED thread filesystem system date_time)
+ENDIF()
+# No auto linking, so this option is useless anyway
+MARK_AS_ADVANCED(Boost_LIB_DIAGNOSTIC_DEFINITIONS)
+
+
+####### Static/Dynamic linking options ##########
+
+# On Windows dynamically linked libraries need some special treatment
+# You may want to edit these settings if you provide your own libraries
+# Note: Default option in the libraries vary, but our default option is dynamic
+IF(WIN32)
+  OPTION(LINK_BOOST_DYNAMIC "Link Boost dynamically on Windows" TRUE)
+  OPTION(LINK_CEGUI_DYNAMIC "Link CEGUI dynamicylly on Windows" TRUE)
+  OPTION(LINK_ENET_DYNAMIC  "Link ENet dynamically on Windows" TRUE)
+  OPTION(LINK_OGRE_DYNAMIC  "Link OGRE dynamically on Windows" TRUE)
+  OPTION(LINK_TCL_DYNAMIC   "Link TCL dynamically on Windows" TRUE)
+  OPTION(LINK_ZLIB_DYNAMIC  "Link ZLib dynamically on Windows" TRUE)
+  COMPARE_VERSION_STRINGS("${LUA_VERSION}" "5.1" _version_comparison)
+  IF(_version_comparison LESS 0)
+    OPTION(LINK_LUA_DYNAMIC "Link Lua dynamically on Windows" FALSE)
+  ELSE(_version_comparison LESS 0)
+    OPTION(LINK_LUA_DYNAMIC "Link Lua dynamically on Windows" TRUE)
+  ENDIF(_version_comparison LESS 0)
+
+  IF(DEPENDENCY_PACKAGE_ENABLE)
+    MARK_AS_ADVANCED(
+      LINK_BOOST_DYNAMIC LINK_CEGUI_DYNAMIC LINK_ENET_DYNAMIC
+      LINK_OGRE_DYNAMIC  LINK_TCL_DYNAMIC   LINK_ZLIB_DYNAMIC
+      LINK_LUA_DYNAMIC
+    )
+  ENDIF()
+ENDIF(WIN32)
+
+
+################# OGRE Plugins ##################
+
+# More plugins: Plugin_BSPSceneManager, Plugin_OctreeSceneManager
+SET(OGRE_PLUGINS_INT Plugin_ParticleFX)
+IF(WIN32)
+  # CG program manager is probably DirectX related (not available under unix)
+  LIST(APPEND OGRE_PLUGINS_INT Plugin_CgProgramManager)
+ENDIF(WIN32)
+SET(OGRE_PLUGINS ${OGRE_PLUGINS_INT} CACHE STRING
+   "Specify which OGRE plugins to load. Existance check is performed.")
+
+# Check the plugins and determine the plugin folder
+# You can give a hint by setting the environment variable ENV{OGRE_PLUGIN_DIR}
+INCLUDE(CheckOGREPlugins)
+CHECK_OGRE_PLUGINS(${OGRE_PLUGINS})
+
Index: /code/branches/rocket2/cmake/LibraryConfigApple.cmake
===================================================================
--- /code/branches/rocket2/cmake/LibraryConfigApple.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/LibraryConfigApple.cmake	(revision 6952)
@@ -0,0 +1,43 @@
+ #
+ #             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/rocket2/cmake/LibraryConfigTardis.cmake
===================================================================
--- /code/branches/rocket2/cmake/LibraryConfigTardis.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/LibraryConfigTardis.cmake	(revision 6952)
@@ -0,0 +1,83 @@
+ #
+ #             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:
+ #    Adrian Friedli
+ #  Description:
+ #    Sets the correct find script paths on the ETH Tardis workstations.
+ #    Also sets the TARDIS variable.
+ #
+
+IF(UNIX AND NOT APPLE)
+  IF(EXISTS /etc/hostname)
+    FILE(STRINGS /etc/hostname HOSTNAME LIMIT_COUNT 1)
+    IF(${HOSTNAME} MATCHES "^tardis-[a-z][0-9][0-9]$")
+      SET (TARDIS ON)
+    ENDIF()
+  ENDIF()
+ENDIF()
+
+IF(TARDIS)
+  MESSAGE(STATUS "Running on D-ITET isg.ee Tardis Computer. Using customized paths.")
+
+#  SET(CMAKE_C_COMPILER "gcc-4.1.1")
+#  SET(CMAKE_CXX_COMPILER "g++-4.1.1")
+
+  # Note: When setting ENV${} variables, make sure to use quotes when
+  #       having multiple directories.
+  #SET(BOOST_INCLUDEDIR "/usr/pack/boost-1.42.0-bs/include")
+  #SET(BOOST_LIBRARYDIR "/usr/pack/boost-1.42.0-bs/i686-debian-linux4.0/lib")
+  SET(Boost_VERSION 104200)
+  SET(Boost_INCLUDE_DIRS "/usr/pack/boost-1.42.0-bs/include" CACHE PATH "")
+  SET(Boost_SYSTEM_LIBRARY_RELEASE "/usr/pack/boost-1.42.0-bs/i686-debian-linux5.0/lib/libboost_system.so" CACHE PATH "")
+  SET(Boost_SYSTEM_LIBRARY_DEBUG "/usr/pack/boost-1.42.0-bs/i686-debian-linux5.0/lib/libboost_system-d.so" CACHE PATH "")
+  SET(Boost_DATE_TIME_LIBRARY_RELEASE "/usr/pack/boost-1.42.0-bs/i686-debian-linux5.0/lib/libboost_date_time.so" CACHE PATH "")
+  SET(Boost_DATE_TIME_LIBRARY_DEBUG "/usr/pack/boost-1.42.0-bs/i686-debian-linux5.0/lib/libboost_date_time-d.so" CACHE PATH "")
+  SET(Boost_FILESYSTEM_LIBRARY_RELEASE "/usr/pack/boost-1.42.0-bs/i686-debian-linux5.0/lib/libboost_filesystem.so" CACHE PATH "")
+  SET(Boost_FILESYSTEM_LIBRARY_DEBUG "/usr/pack/boost-1.42.0-bs/i686-debian-linux5.0/lib/libboost_filesystem-d.so" CACHE PATH "")
+  SET(Boost_THREAD_LIBRARY_RELEASE "/usr/pack/boost-1.42.0-bs/i686-debian-linux5.0/lib/libboost_thread-mt.so" CACHE PATH "")
+  SET(Boost_THREAD_LIBRARY_DEBUG "/usr/pack/boost-1.42.0-bs/i686-debian-linux5.0/lib/libboost_thread-mt-d.so" CACHE PATH "")
+
+  SET(Boost_SYSTEM_LIBRARY "debug;${Boost_SYSTEM_LIBRARY_DEBUG};optimized;${Boost_SYSTEM_LIBRARY_RELEASE}" CACHE PATH "" FORCE)
+  SET(Boost_DATE_TIME_LIBRARY "debug;${Boost_DATE_TIME_LIBRARY_DEBUG};optimized;${Boost_DATE_TIME_LIBRARY_RELEASE}" CACHE PATH "" FORCE)
+  SET(Boost_FILESYSTEM_LIBRARY "debug;${Boost_FILESYSTEM_LIBRARY_DEBUG};optimized;${Boost_FILESYSTEM_LIBRARY_RELEASE}" CACHE PATH "" FORCE)
+  SET(Boost_THREAD_LIBRARY "debug;${Boost_THREAD_LIBRARY_DEBUG};optimized;${Boost_THREAD_LIBRARY_RELEASE}" CACHE PATH "" FORCE)
+
+  MARK_AS_ADVANCED( Boost_INCLUDE_DIRS )
+  MARK_AS_ADVANCED( Boost_SYSTEM_LIBRARY Boost_SYSTEM_LIBRARY_RELEASE Boost_SYSTEM_LIBRARY_DEBUG )
+  MARK_AS_ADVANCED( Boost_DATE_TIME_LIBRARY Boost_DATE_TIME_LIBRARY_RELEASE Boost_DATE_TIME_LIBRARY_DEBUG )
+  MARK_AS_ADVANCED( Boost_FILESYSTEM_LIBRARY Boost_FILESYSTEM_LIBRARY_RELEASE Boost_FILESYSTEM_LIBRARY_DEBUG )
+  MARK_AS_ADVANCED( Boost_THREAD_LIBRARY Boost_THREAD_LIBRARY_RELEASE Boost_THREAD_LIBRARY_DEBUG )
+
+
+  LIST(APPEND CMAKE_INCLUDE_PATH "/usr/pack/cegui-0.6.2-sd")
+  LIST(APPEND CMAKE_LIBRARY_PATH "/usr/pack/cegui-0.6.2-sd/i686-debian-linux5.0")
+  LIST(APPEND CMAKE_INCLUDE_PATH "/usr/pack/ogre-1.6.1-sd")
+  LIST(APPEND CMAKE_LIBRARY_PATH "/usr/pack/ogre-1.6.1-sd/i686-debian-linux5.0")
+
+  #SET(ENV{CEGUIDIR}    "/usr/pack/cegui-0.6.2-sd;/usr/pack/cegui-0.6.2-sd/i686-debian-linux5.0")
+  #SET(ENV{ENETDIR}     "/usr/pack/enet-1.2-sd;/usr/pack/enet-1.2-sd/i686-debian-linux4.0")
+  #SET(ENV{ALUTDIR}     "/usr/pack/openal-0.0.8-cl;/usr/pack/openal-0.0.8-cl/i686-debian-linux3.1")
+  #SET(ENV{OGGDIR}      "/usr/pack/oggvorbis-1.0-ds;/usr/pack/oggvorbis-1.0-ds/i686-debian-linux3.0")
+  #SET(ENV{VORBISDIR}   "/usr/pack/oggvorbis-1.0-ds;/usr/pack/oggvorbis-1.0-ds/i686-debian-linux3.0")
+  #SET(ENV{LUA_DIR}     "/usr/pack/lua-5.1.4-sd;/usr/pack/lua-5.1.4-sd/i686-debian-linux4.0")
+  #SET(ENV{OGRE_HOME}   "/usr/pack/ogre-1.4.9-sd;/usr/pack/ogre-1.4.9-sd/i686-debian-linux4.0")
+  #SET(ENV{OPENALDIR}   "/usr/pack/openal-0.0.8-cl;/usr/pack/openal-0.0.8-cl/i686-debian-linux3.1")
+  #SET(TCL_INCLUDE_PATH "/usr/pack/tcltk-8.4.9.linux-mo/include")
+ENDIF(TARDIS)
Index: /code/branches/rocket2/cmake/PackageConfig.cmake
===================================================================
--- /code/branches/rocket2/cmake/PackageConfig.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/PackageConfig.cmake	(revision 6952)
@@ -0,0 +1,118 @@
+ #
+ #             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:
+ #    General package configuration. Merely sets the include paths.
+ #    Library files are treated separately.
+ #
+
+# 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).
+SET(ALLOWED_MINIMUM_VERSIONS 3.1 4.0 5.0)
+
+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.")
+  SET(_INTERNAL_PACKAGE_MESSAGE 1 CACHE INTERNAL "Do not edit!" FORCE)
+ENDIF()
+
+# Include paths and other special treatments
+SET(ENV{ALUTDIR}               ${DEP_INCLUDE_DIR}/freealut)
+SET(ENV{BOOST_ROOT}            ${DEP_INCLUDE_DIR}/boost)
+SET(ENV{CEGUIDIR}              ${DEP_INCLUDE_DIR}/cegui)
+SET(ENV{DXSDK_DIR}             ${DEP_INCLUDE_DIR}/directx)
+SET(ENV{ENETDIR}               ${DEP_INCLUDE_DIR}/enet)
+SET(ENV{LUA_DIR}               ${DEP_INCLUDE_DIR}/lua)
+SET(ENV{OGGDIR}                ${DEP_INCLUDE_DIR}/libogg)
+SET(ENV{VORBISDIR}             ${DEP_INCLUDE_DIR}/libvorbis)
+SET(ENV{OGRE_HOME}             ${DEP_INCLUDE_DIR}/ogre)
+SET(ENV{OGRE_PLUGIN_DIR}       ${DEP_BINARY_DIR})
+SET(ENV{OPENALDIR}             ${DEP_INCLUDE_DIR}/openal)
+LIST(APPEND CMAKE_INCLUDE_PATH ${DEP_INCLUDE_DIR}/tcl/include)
+LIST(APPEND CMAKE_INCLUDE_PATH ${DEP_INCLUDE_DIR}/zlib/include)
+
+### INSTALL ###
+
+# Tcl script library
+INSTALL(
+  DIRECTORY ${DEP_LIBRARY_DIR}/tcl/
+  DESTINATION lib/tcl
+)
+
+# On Windows, DLLs have to be in the executable folder, install them
+IF(WIN32 AND DEP_BINARY_DIR)
+  ## 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/rocket2/cmake/PackageConfigMSVC.cmake
===================================================================
--- /code/branches/rocket2/cmake/PackageConfigMSVC.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/PackageConfigMSVC.cmake	(revision 6952)
@@ -0,0 +1,65 @@
+ #
+ #             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:
+ #    Sets the library directories when using precompiled dependency archives
+ #  Note:
+ #    When setting ENV${} variables, make sure to use quotes for lists
+ #
+
+IF(MSVC)
+
+  # 64 bit system?
+  IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
+    SET(BINARY_POSTFIX x64)
+  ELSE()
+    SET(BINARY_POSTFIX x86)
+  ENDIF()
+
+  # Choose right MSVC version
+  STRING(REGEX REPLACE "^Visual Studio ([0-9][0-9]?) .*$" "\\1"
+         _msvc_version "${CMAKE_GENERATOR}")
+
+  SET(DEP_INCLUDE_DIR ${DEPENDENCY_PACKAGE_DIR}/include)
+  SET(DEP_LIBRARY_DIR ${DEPENDENCY_PACKAGE_DIR}/lib/msvc${_msvc_version}-${BINARY_POSTFIX})
+  SET(DEP_BINARY_DIR  ${DEPENDENCY_PACKAGE_DIR}/bin/msvc${_msvc_version}-${BINARY_POSTFIX})
+  IF(NOT EXISTS ${DEP_LIBRARY_DIR})
+    message(FATAL_ERROR "No binaries found for your MSVC Version (${CMAKE_GENERATOR})")
+  ENDIF()
+
+  # Also the directory with the runtime libraries
+  SET(RUNTIME_LIBRARY_DIRECTORY ${DEP_BINARY_DIR})
+
+  # Sets the library path for the FIND_LIBRARY
+  SET(CMAKE_LIBRARY_PATH ${DEP_LIBRARY_DIR})
+
+  # Certain find scripts don't behave as ecpected to we have
+  # to specify the libraries ourselves.
+  SET(TCL_LIBRARY  ${DEP_LIBRARY_DIR}/tcl85.lib CACHE FILEPATH "")
+  SET(ZLIB_LIBRARY ${DEP_LIBRARY_DIR}/zdll.lib  CACHE FILEPATH "")
+
+  # Visual Leak Detector
+  SET(VLD_INCLUDE_DIR  ${DEP_INCLUDE_DIR}/vld   CACHE PATH "")
+  SET(VLD_LIBRARY_DIR  ${DEP_LIBRARY_DIR}       CACHE PATH "")
+  LINK_DIRECTORIES(${VLD_LIBRARY_DIR}) # Used for auto-linking
+  MARK_AS_ADVANCED(VLD_INCLUDE_DIR VLD_LIBRARY_DIR)
+
+ENDIF(MSVC)
Index: /code/branches/rocket2/cmake/PackageConfigMinGW.cmake
===================================================================
--- /code/branches/rocket2/cmake/PackageConfigMinGW.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/PackageConfigMinGW.cmake	(revision 6952)
@@ -0,0 +1,52 @@
+ #
+ #             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:
+ #    Sets the library directories when using precompiled dependency archives
+ #  Note:
+ #    When setting ENV${} variables, make sure to use quotes for lists
+ #
+
+IF(MINGW)
+
+  # 64 bit system?
+  IF(CMAKE_SIZEOF_VOID_P EQUAL 8)
+    SET(BINARY_POSTFIX x64)
+  ELSE()
+    SET(BINARY_POSTFIX x86)
+  ENDIF()
+
+  SET(DEP_INCLUDE_DIR ${DEPENDENCY_PACKAGE_DIR}/include)
+  SET(DEP_LIBRARY_DIR ${DEPENDENCY_PACKAGE_DIR}/lib/mingw-${BINARY_POSTFIX})
+  SET(DEP_BINARY_DIR  ${DEPENDENCY_PACKAGE_DIR}/bin/mingw-${BINARY_POSTFIX})
+
+  # Also the directory with the runtime libraries
+  SET(RUNTIME_LIBRARY_DIRECTORY ${DEP_BINARY_DIR})
+
+  # Sets the library path for the FIND_LIBRARY
+  SET(CMAKE_LIBRARY_PATH ${DEP_LIBRARY_DIR} ${DEP_BINARY_DIR})
+
+  # Certain find scripts don't behave as ecpected to we have
+  # 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 "")
+
+ENDIF(MINGW)
Index: /code/branches/rocket2/cmake/ParseMacroArguments.cmake
===================================================================
--- /code/branches/rocket2/cmake/ParseMacroArguments.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/ParseMacroArguments.cmake	(revision 6952)
@@ -0,0 +1,91 @@
+ #
+ #             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:
+ #    Parses a list of macro arguments which are separated by keywords and
+ #    writes the result to the _arg_KEYWORD variable. Switches are set to their
+ #    literal name if found and the lists contain their elements.
+ #    The order of the arguments is arbitrary.
+ #  Note:
+ #    You have to specify the switches and list_names as a
+ #    semicolon separated list or all hell breaks loose!
+ #  Example:
+ #    The arguments  BLUBB_FILES foo.cc bar.c NO_ASDF  will do the following:
+ #    SET(_arg_NO_ASDF _arg_NO_ASDF)
+ #    SET(_arg_BLUBB_FILES foo.cc bar.c)
+ #    But NO_FOO will not be set at all if it was specified as a switch
+ #
+
+MACRO(PARSE_MACRO_ARGUMENTS _switches _list_names)
+
+  # Using LIST(FIND ...) speeds up the process
+  SET(_keywords ${_switches} ${_list_names})
+
+  # Reset all arguments
+  FOREACH(_arg ${_switches} ${_list_names})
+    SET(_arg_${_arg})
+  ENDFOREACH(_arg)
+
+  # Parse all the arguments and set the corresponding variable
+  # If the option is just a switch, set the variable to its name for later use
+  FOREACH(_arg ${ARGN})
+
+    # Is the argument a keyword?
+    LIST(FIND _keywords ${_arg} _keyword_index)
+    IF(NOT _keyword_index EQUAL -1)
+
+      # Another optimisation
+      SET(_arg_found FALSE)
+      # Switches
+      FOREACH(_switch ${_switches})
+        IF(${_switch} STREQUAL ${_arg})
+          SET(_arg_${_switch} ${_switch})
+          SET(_arg_found TRUE)
+          # Avoid interpreting arguments after this one as options args for the previous one
+          SET(_storage_var)
+          BREAK()
+        ENDIF()
+      ENDFOREACH(_switch)
+
+      # Input options
+      IF(NOT _arg_found)
+        FOREACH(_list_name ${_list_names})
+          IF(${_list_name} STREQUAL ${_arg})
+            SET(_storage_var _arg_${_list_name})
+            BREAK()
+          ENDIF()
+        ENDFOREACH(_list_name)
+      ENDIF(NOT _arg_found)
+
+    ELSE()
+
+      # Arguments of an input option (like source files for SOURCE_FILES)
+      IF(_storage_var)
+        # Store in variable define above in the foreach loop
+        SET(${_storage_var} ${${_storage_var}} ${_arg})
+      ELSE()
+        MESSAGE(FATAL_ERROR "ORXONOX_ADD_${_target_type} was given a non compliant argument: ${_arg}")
+      ENDIF(_storage_var)
+
+    ENDIF()
+
+  ENDFOREACH(_arg)
+ENDMACRO(PARSE_MACRO_ARGUMENTS)
Index: /code/branches/rocket2/cmake/PrecompiledHeaderFiles.cmake
===================================================================
--- /code/branches/rocket2/cmake/PrecompiledHeaderFiles.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/PrecompiledHeaderFiles.cmake	(revision 6952)
@@ -0,0 +1,161 @@
+ #
+ #             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
+ #
+
+INCLUDE(GetGCCCompilerFlags)
+
+MACRO(PRECOMPILED_HEADER_FILES_PRE_TARGET _target_name _header_file_arg _sourcefile_var)
+
+  GET_FILENAME_COMPONENT(_pch_header_file ${_header_file_arg} ABSOLUTE)
+  GET_FILENAME_COMPONENT(_pch_header_filename ${_pch_header_file} NAME)
+  GET_FILENAME_COMPONENT(_pch_header_filename_we ${_pch_header_file} NAME_WE)
+
+  IF(NOT EXISTS ${_pch_header_file})
+    MESSAGE(FATAL_ERROR "Specified precompiled headerfile '${_header_file_arg}' does not exist.")
+  ENDIF()
+
+  # Extract arguments from ARGN
+  FOREACH(_arg ${ARGN})
+    IF(NOT "${_arg}" STREQUAL "EXCLUDE")
+      IF(NOT _arg_second)
+        # Source files with PCH support
+        SET(_included_files ${_included_files} ${_arg})
+      ELSE()
+        # Source files to be excluded from PCH support (easier syntax this way)
+        SET(_excluded files ${_excluded_files} ${_arg})
+      ENDIF()
+    ELSE()
+      SET(_arg_second TRUE)
+    ENDIF()
+  ENDFOREACH(_arg)
+
+  # Use ${_sourcefile_var} if no files were specified explicitely
+  IF(NOT _included_files)
+    SET(_source_files ${${_sourcefile_var}})
+  ELSE()
+    SET(_source_files ${_included_files})
+  ENDIF()
+
+  # Exclude files (if specified)
+  FOREACH(_file ${_excluded_files})
+    LIST(FIND _source_files ${_file} _list_index)
+    IF(_list_index GREATER -1)
+      LIST(REMOVE_AT _source_files _list_index)
+    ELSE()
+      MESSAGE(FATAL_ERROR "Could not exclude file ${_file} in target ${_target_name}")
+    ENDIF()
+  ENDFOREACH(_file)
+
+  LIST(FIND ${_sourcefile_var} ${_pch_header_file} _list_index)
+  IF(_list_index EQUAL -1) # Header file could already be included with GET_ALL_HEADER_FILES
+    LIST(APPEND ${_sourcefile_var} ${_pch_header_file})
+  ENDIF()
+  SOURCE_GROUP("PCH" FILES ${_pch_header_file})
+
+  IF(MSVC)
+
+    # Write and add one source file, which generates the precompiled header file
+    SET(_pch_source_file "${CMAKE_CURRENT_BINARY_DIR}/${_pch_header_filename_we}.cc")
+    IF(NOT EXISTS ${_pch_source_file})
+      FILE(WRITE ${_pch_source_file} "#include \"${_pch_header_file}\"\n")
+    ENDIF()
+    SET_SOURCE_FILES_PROPERTIES(_pch_source_file PROPERTIES GENERATED TRUE)
+    LIST(APPEND ${_sourcefile_var} ${_pch_source_file})
+    SOURCE_GROUP("PCH" FILES ${_pch_source_file})
+
+    SET(_pch_file "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${_pch_header_filename}.pch")
+    # Set compile flags for generated source file
+    SET_SOURCE_FILES_PROPERTIES(${_pch_source_file} PROPERTIES COMPILE_FLAGS "/c /Yc\"${_pch_header_file}\" /Fp\"${_pch_file}\"")
+    # Set Compile flags for the other source files
+    FOREACH(_file ${_source_files})
+      GET_SOURCE_FILE_PROPERTY(_is_header ${_file} HEADER_FILE_ONLY)
+      IF(NOT _is_header)
+        GET_SOURCE_FILE_PROPERTY(_old_flags ${_file} COMPILE_FLAGS)
+        IF(NOT _old_flags)
+          SET(_old_flags "")
+        ENDIF()
+        SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES COMPILE_FLAGS "${_old_flags} /FI\"${_pch_header_file}\" /Yu\"${_pch_header_file}\" /Fp\"${_pch_file}\"")
+      ENDIF(NOT _is_header)
+    ENDFOREACH(_file)
+
+  ELSEIF(CMAKE_COMPILER_IS_GNU)
+
+    SET(_pch_file "${CMAKE_CURRENT_BINARY_DIR}/${_pch_header_filename}.gch")
+    SET(_pch_dep_helper_file "${CMAKE_CURRENT_BINARY_DIR}/${_target_name}PCHDependencyHelper.h")
+
+    # Append the gch-dir to make sure gcc finds the pch file
+    INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+
+    # Get compiler flags of the source files (target does not yet exist!)
+    # This is just the best possible opportunity to address this dependency issue
+    GET_GCC_COMPILER_FLAGS(${_target_name} _pch_gcc_flags)
+    # Make sure we recompile the pch file even if only the flags change
+    IF(NOT "${_pch_gcc_flags}" STREQUAL "${_INTERNAL_${_target_name}_PCH_GCC_FLAGS}" OR NOT EXISTS "${_pch_dep_helper_file}")
+      SET(_INTERNAL_${_target_name}_PCH_GCC_FLAGS "${_pch_gcc_flags}" CACHE INTERNAL "")
+      FILE(WRITE ${_pch_dep_helper_file} "/* ${_pch_gcc_flags} */")
+    ENDIF()
+
+    # Set Compile flags for the other source files
+    FOREACH(_file ${_source_files})
+      GET_SOURCE_FILE_PROPERTY(_is_header ${_file} HEADER_FILE_ONLY)
+      IF(NOT _is_header)
+        GET_SOURCE_FILE_PROPERTY(_old_flags ${_file} COMPILE_FLAGS)
+        IF(NOT _old_flags)
+          SET(_old_flags "")
+        ENDIF()
+        SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES
+          COMPILE_FLAGS "${_old_flags} -include ${_pch_header_filename}"
+          OBJECT_DEPENDS "${_pch_header_file};${_pch_file}"
+        )
+      ENDIF(NOT _is_header)
+    ENDFOREACH(_file)
+
+  ENDIF()
+
+ENDMACRO(PRECOMPILED_HEADER_FILES_PRE_TARGET)
+
+FUNCTION(PRECOMPILED_HEADER_FILES_POST_TARGET _target_name)
+    # This macro is only necessary for GCC
+    IF(CMAKE_COMPILER_IS_GNU)
+
+      # Workaround for distcc
+      IF(CMAKE_CXX_COMPILER_ARG1)
+        # remove leading space in compiler argument
+        STRING(REGEX REPLACE "^ +" "" _pch_cmake_cxx_compiler_arg1 "${CMAKE_CXX_COMPILER_ARG1}")
+      ENDIF()
+
+      # Get compiler flags of the source files again (target exists this time)
+      GET_GCC_COMPILER_FLAGS(${_target_name} _pch_gcc_flags)
+
+      # Compile the header file
+      ADD_CUSTOM_COMMAND(
+        OUTPUT ${_pch_file}
+        COMMAND ${CMAKE_CXX_COMPILER}
+        ARGS ${pchsupport_compiler_cxx_arg1} ${_pch_gcc_flags} -c -x c++-header -o ${_pch_file} ${_pch_header_file}
+        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+        DEPENDS ${_pch_dep_helper_file}
+        IMPLICIT_DEPENDS CXX ${_pch_header_file}
+        VERBATIM
+      )
+
+    ENDIF(CMAKE_COMPILER_IS_GNU)
+ENDFUNCTION(PRECOMPILED_HEADER_FILES_POST_TARGET)
Index: /code/branches/rocket2/cmake/SeparateFlags.cmake
===================================================================
--- /code/branches/rocket2/cmake/SeparateFlags.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/SeparateFlags.cmake	(revision 6952)
@@ -0,0 +1,63 @@
+ #
+ #             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:
+ #    Separates a string of program flags like "--blubb -test -D AA".
+ #    " -" or " /" denotes the start of a flag.
+ #    The same sequence inside double quotation marks is being ignored.
+ #    Spaces not within quotes are cleaned meaningfully.
+ #  Note:
+ #    This macro cannot cope with semicolons in the flag string!
+
+FUNCTION(SEPARATE_FLAGS _flags _output_variable)
+  # Visual studio (esp. IntelliSense) doesn't like dashes to specify arguments
+  # Always use foward slashes instead
+  IF(MSVC)
+    SET(_argument_starter "/")
+  ELSE()
+    SET(_argument_starter "-")
+  ENDIF(MSVC)
+
+  SET(_flags_prep " ${_flags} -")
+  # Separate the chunks
+  STRING(REPLACE " " " ;" _flag_chunks "${_flags_prep}") # Max loop iterations
+  SET(_flag_string)
+  SET(_parsed_flags)
+  # Loop is necessary because the regex engine is greedy
+  FOREACH(_chunk ${_flag_chunks})
+    SET(_flag_string "${_flag_string}${_chunk}")
+    # Replace all " -" and " /" inside quotation marks
+    STRING(REGEX REPLACE "^(([^\"]*\"[^\"]*\")*[^\"]*\"[^\"]*) [/-]([^\"]*\")"
+           "\\1@39535493@\\3" _flag_string "${_flag_string}")
+    # Extract one flag if possible
+    SET(_flag)
+    STRING(REGEX REPLACE "^.* [/-](.+)( [/-].*$)" "${_argument_starter}\\1" _flag "${_flag_string}")
+    STRING(REGEX REPLACE "^.* [/-](.+)( [/-].*$)" "\\2"  _flag_string "${_flag_string}")
+    IF(NOT _flag STREQUAL _flag_string)
+      STRING(STRIP "${_flag}" _flag_stripped)
+      LIST(APPEND _parsed_flags "${_flag_stripped}")
+    ENDIF(NOT _flag STREQUAL _flag_string)
+  ENDFOREACH(_chunk)
+
+  # Re-replace all " -" and " /" inside quotation marks
+  STRING(REGEX REPLACE "@39535493@" " -" _parsed_flags "${_parsed_flags}")
+  SET(${_output_variable} "${_parsed_flags}" PARENT_SCOPE)
+ENDFUNCTION(SEPARATE_FLAGS)
Index: /code/branches/rocket2/cmake/SetCacheAdvanced.cmake
===================================================================
--- /code/branches/rocket2/cmake/SetCacheAdvanced.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/SetCacheAdvanced.cmake	(revision 6952)
@@ -0,0 +1,36 @@
+ #
+ #             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:
+ #    Write to the cache by force, but only if the user hasn't changed the value
+ #    Additional argument is the value (may also be a list)
+
+FUNCTION(SET_CACHE_ADVANCED _varname _type _docstring)
+  SET(_value ${ARGN})
+  IF(NOT "${_type}" MATCHES "^(STRING|BOOL|PATH|FILEPATH)$")
+    MESSAGE(FATAL_ERROR "${_type} is not a valid CACHE entry type")
+  ENDIF()
+
+  IF(NOT DEFINED _INTERNAL_${_varname} OR "${_INTERNAL_${_varname}}" STREQUAL "${${_varname}}")
+    SET(${_varname} "${_value}" CACHE ${_type} "${_docstring}" FORCE)
+    SET(_INTERNAL_${_varname} "${_value}" CACHE INTERNAL "Do not edit in any case!")
+  ENDIF()
+ENDFUNCTION(SET_CACHE_ADVANCED)
Index: /code/branches/rocket2/cmake/SourceFileUtilities.cmake
===================================================================
--- /code/branches/rocket2/cmake/SourceFileUtilities.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/SourceFileUtilities.cmake	(revision 6952)
@@ -0,0 +1,123 @@
+ #
+ #             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:
+ #    Several functions that help organising the source tree.
+ #    [ADD/SET]_SOURCE_FILES - Writes source files to the cache by force and
+ #                             adds the current directory.
+ #                             Also compiles multiple source files into a single
+ #                             one by including them
+ #                             Use COMPILATION_[BEGIN|END] in
+ #                             [ADD|SET]_SOURCE_FILES and specify the name of
+ #                             the new source file after COMPILATION_BEGIN
+ #    GET_ALL_HEADER_FILES   - Finds all header files recursively.
+ #    GENERATE_SOURCE_GROUPS - Set Visual Studio source groups.
+ #
+
+FUNCTION(PREPARE_SOURCE_FILES)
+  SET(_fullpath_sources)
+  FOREACH(_file ${ARGN})
+    IF(_file STREQUAL "COMPILATION_BEGIN")
+      SET(_compile TRUE)
+      # Next file is the name of the compilation
+      SET(_get_name TRUE)
+    ELSEIF(_get_name)
+      SET(_get_name FALSE)
+      SET(_compilation_name ${_file})
+    ELSEIF(_file STREQUAL "COMPILATION_END")
+      IF(NOT _compilation_name)
+        MESSAGE(FATAL_ERROR "No name provided for source file compilation")
+      ENDIF()
+      IF(NOT DISABLE_COMPILATIONS)
+        SET(_compilation_file ${CMAKE_CURRENT_BINARY_DIR}/${_compilation_name})
+        SET(_include_string)
+        FOREACH(_file2 ${_compilation})
+          SET(_include_string "${_include_string}#include \"${_file2}\"\n")
+        ENDFOREACH(_file2)
+        IF(EXISTS ${_compilation_file})
+          FILE(READ ${_compilation_file} _include_string_file)
+        ENDIF()
+        IF(NOT _include_string STREQUAL "${_include_string_file}")
+          FILE(WRITE ${_compilation_file} "${_include_string}")
+        ENDIF()
+        LIST(APPEND _fullpath_sources ${_compilation_file})
+        # MSVC hack that excludes the compilations from the intellisense database
+        # (There is a bug with the "-" instead of "/". Only works for "Zm#" argument)
+        IF(MSVC)
+          SET_SOURCE_FILES_PROPERTIES(${_compilation_file} PROPERTIES COMPILE_FLAGS "-Zm1000")
+        ENDIF()
+      ENDIF()
+      SET(_compilation_name)
+      SET(_compilation)
+      SET(_compile FALSE)
+    ELSE()
+      # Prefix the full path
+      GET_SOURCE_FILE_PROPERTY(_filepath ${_file} LOCATION)
+      LIST(APPEND _fullpath_sources ${_filepath})
+      IF(_compile AND NOT DISABLE_COMPILATIONS)
+        LIST(APPEND _compilation ${_filepath})
+        LIST(APPEND _fullpath_sources "H")
+      ENDIF()
+    ENDIF()
+  ENDFOREACH(_file)
+  SET(_fullpath_sources ${_fullpath_sources} PARENT_SCOPE)
+ENDFUNCTION(PREPARE_SOURCE_FILES)
+
+
+# Adds source files with the full path to a list
+FUNCTION(ADD_SOURCE_FILES _varname)
+  PREPARE_SOURCE_FILES(${ARGN})
+  # Write into the cache to avoid variable scoping in subdirs
+  SET(${_varname} ${${_varname}} ${_fullpath_sources} CACHE INTERNAL "Do not edit")
+ENDFUNCTION(ADD_SOURCE_FILES)
+
+
+# Sets source files with the full path
+FUNCTION(SET_SOURCE_FILES _varname)
+  PREPARE_SOURCE_FILES(${ARGN})
+  # Write into the cache to avoid variable scoping in subdirs
+  SET(${_varname} ${_fullpath_sources} CACHE INTERNAL "Do not edit")
+ENDFUNCTION(SET_SOURCE_FILES)
+
+
+# Search the entire directory tree for header files and add them to a variable
+MACRO(GET_ALL_HEADER_FILES _target_varname)
+  FILE(GLOB_RECURSE ${_target_varname} ${CMAKE_CURRENT_SOURCE_DIR} "*.h")
+ENDMACRO(GET_ALL_HEADER_FILES)
+
+
+# Generate source groups according to the directory structure
+FUNCTION(GENERATE_SOURCE_GROUPS)
+
+  FOREACH(_file ${ARGN})
+    GET_SOURCE_FILE_PROPERTY(_full_filepath ${_file} LOCATION)
+    FILE(RELATIVE_PATH _relative_path ${CMAKE_CURRENT_SOURCE_DIR} ${_full_filepath})
+    IF(NOT _relative_path MATCHES "^\\.\\.")
+      GET_FILENAME_COMPONENT(_relative_path ${_relative_path} PATH)
+      STRING(REPLACE "/" "\\\\" _group_path "${_relative_path}")
+      SOURCE_GROUP("Source\\${_group_path}" FILES ${_file})
+    ELSE()
+      # Has to be a compilation
+      SOURCE_GROUP("Compilations" FILES ${_file})
+    ENDIF()
+  ENDFOREACH(_file)
+
+ENDFUNCTION(GENERATE_SOURCE_GROUPS)
Index: /code/branches/rocket2/cmake/TargetUtilities.cmake
===================================================================
--- /code/branches/rocket2/cmake/TargetUtilities.cmake	(revision 6952)
+++ /code/branches/rocket2/cmake/TargetUtilities.cmake	(revision 6952)
@@ -0,0 +1,295 @@
+ #
+ #             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:
+ #    Adds a library or an executable like ADD_LIBRARY/ADD_EXECUTABLE, but
+ #    accepts a lot more input information. Simply supply the keywords
+ #    described below in any order you wish.
+ #    The output is then stored in "_arg_ARGNAME" where ARGNAME is the the
+ #    name of the switch or list.
+ #
+ #    Switches: (when given --> TRUE, FALSE otherwise)
+ #      FIND_HEADER_FILES: Searches the current directory for all header files
+ #                         and adds them to the target.
+ #      EXCLUDE_FROM_ALL:  Inherited from ADD_LIBRARY/ADD_EXECUTABLE
+ #      ORXONOX_EXTERNAL:  Specify this for third party libraries
+ #      NO_DLL_INTERFACE:  Link statically with MSVC
+ #      NO_SOURCE_GROUPS:  Don't create msvc source groups
+ #      STATIC/SHARED:     Inherited from ADD_LIBRARY
+ #      MODULE:            For dynamic module libraries
+ #      WIN32:             Inherited from ADD_EXECUTABLE
+ #      PCH_NO_DEFAULT:    Do not make precompiled header files default if
+ #                         specified with PCH_FILE
+ #      NO_INSTALL:        Do not install the target at all
+ #
+ #    Lists:
+ #      LINK_LIBRARIES:    Redirects to TARGET_LINK_LIBRARIES
+ #      VERSION:           Set version to the binary
+ #      SOURCE_FILES:      Source files for the target
+ #      DEFINE_SYMBOL:     Sets the DEFINE_SYMBOL target property
+ #      TOLUA_FILES:       Files with tolua interface
+ #      PCH_FILE:          Precompiled header file
+ #      PCH_EXCLUDE:       Source files to be excluded from PCH support
+ #      OUTPUT_NAME:       If you want a different name than the target name
+ #  Note:
+ #    This function also installs the target!
+ #  Prerequisistes:
+ #    ORXONOX_DEFAULT_LINK, ORXONOX_CONFIG_FILES
+ #  Parameters:
+ #    _target_name, ARGN for the macro arguments
+ #
+
+INCLUDE(CMakeDependentOption)
+INCLUDE(CapitaliseName)
+INCLUDE(GenerateToluaBindings)
+INCLUDE(ParseMacroArguments)
+INCLUDE(SourceFileUtilities)
+IF(PCH_COMPILER_SUPPORT)
+  INCLUDE(PrecompiledHeaderFiles)
+ENDIF()
+
+MACRO(ORXONOX_ADD_LIBRARY _target_name)
+  TU_ADD_TARGET(${_target_name} LIBRARY "STATIC;SHARED" ${ARGN})
+ENDMACRO(ORXONOX_ADD_LIBRARY)
+
+MACRO(ORXONOX_ADD_EXECUTABLE _target_name)
+  TU_ADD_TARGET(${_target_name} EXECUTABLE "WIN32" ${ARGN})
+ENDMACRO(ORXONOX_ADD_EXECUTABLE)
+
+
+MACRO(TU_ADD_TARGET _target_name _target_type _additional_switches)
+  CAPITALISE_NAME(${_target_name} _target_name_capitalised)
+
+  # Specify all possible options (either switch or with add. arguments)
+  SET(_switches   FIND_HEADER_FILES  EXCLUDE_FROM_ALL  ORXONOX_EXTERNAL
+                  NO_DLL_INTERFACE   NO_SOURCE_GROUPS  ${_additional_switches}
+                  PCH_NO_DEFAULT     NO_INSTALL        MODULE)
+  SET(_list_names LINK_LIBRARIES  VERSION   SOURCE_FILES  DEFINE_SYMBOL
+                  TOLUA_FILES     PCH_FILE  PCH_EXCLUDE OUTPUT_NAME)
+  PARSE_MACRO_ARGUMENTS("${_switches}" "${_list_names}" ${ARGN})
+
+
+  # Workaround: Source file properties get lost when leaving a subdirectory
+  # Therefore an "H" after a file means we have to set it as HEADER_FILE_ONLY
+  FOREACH(_file ${_arg_SOURCE_FILES})
+    IF(_file STREQUAL "H")
+      SET_SOURCE_FILES_PROPERTIES(${_last_file} PROPERTIES HEADER_FILE_ONLY TRUE)
+    ELSE()
+      SET(_last_file ${_file})
+      LIST(APPEND _${_target_name}_source_files ${_file})
+    ENDIF()
+  ENDFOREACH(_file)
+
+  # Assemble all header files of the library
+  IF(_arg_FIND_HEADER_FILES)
+    GET_ALL_HEADER_FILES(_${_target_name}_header_files)
+  ENDIF()
+
+  # Remove potential duplicates
+  SET(_${_target_name}_files ${_${_target_name}_header_files} ${_${_target_name}_source_files})
+  LIST(REMOVE_DUPLICATES _${_target_name}_files)
+
+  # Generate the source groups
+  IF(NOT _arg_NO_SOURCE_GROUPS)
+    GENERATE_SOURCE_GROUPS(${_${_target_name}_files})
+
+    IF(NOT _arg_ORXONOX_EXTERNAL)
+      # Move the prereqs.h file 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 the config files in a special source group
+      LIST(APPEND _${_target_name}_files ${ORXONOX_CONFIG_FILES})
+      SOURCE_GROUP("Config" FILES ${ORXONOX_CONFIG_FILES})
+    ENDIF()
+  ENDIF(NOT _arg_NO_SOURCE_GROUPS)
+
+  # TOLUA_FILES
+  IF(_arg_TOLUA_FILES)
+    GENERATE_TOLUA_BINDINGS(${_target_name_capitalised} _${_target_name}_files
+                            INPUTFILES ${_arg_TOLUA_FILES})
+  ENDIF()
+
+  # First part (pre target) of precompiled header files
+  IF(PCH_COMPILER_SUPPORT AND _arg_PCH_FILE)
+    # Provide convenient option to control PCH
+    STRING(TOUPPER "${_target_name}" _target_name_upper)
+    IF(_arg_PCH_NO_DEFAULT)
+      SET(PCH_DEFAULT FALSE)
+    ELSE()
+      SET(PCH_DEFAULT TRUE)
+    ENDIF()
+    CMAKE_DEPENDENT_OPTION(PCH_ENABLE_${_target_name_upper}
+      "Enable using precompiled header files for library ${_target_name}." ${PCH_DEFAULT} PCH_ENABLE OFF)
+
+    IF(PCH_ENABLE_${_target_name_upper})
+      PRECOMPILED_HEADER_FILES_PRE_TARGET(${_target_name} ${_arg_PCH_FILE} _${_target_name}_files EXCLUDE ${_arg_PCH_EXCLUDE})
+    ENDIF()
+  ENDIF()
+
+  # Certain libraries don't have dllexport/dllimport and can't be linked shared with msvc
+  IF(MSVC AND _arg_NO_DLL_INTERFACE)
+    SET(_arg_SHARED)
+    SET(_arg_STATIC STATIC)
+  ENDIF()
+
+  # No warnings needed from third party libraries
+  IF(_arg_ORXONOX_EXTERNAL)
+    REMOVE_COMPILER_FLAGS("-W3 -W4" MSVC)
+    ADD_COMPILER_FLAGS("-w")
+  ENDIF()
+
+  # Set default linking if required
+  IF(NOT _arg_SHARED AND NOT _arg_STATIC)
+    IF("${ORXONOX_DEFAULT_LINK}" STREQUAL "STATIC")
+      SET(_arg_STATIC STATIC)
+    ELSEIF("${ORXONOX_DEFAULT_LINK}" STREQUAL "SHARED")
+      SET(_arg_SHARED SHARED)
+    ENDIF()
+  ENDIF()
+
+  # MODULE A
+  # Always create shared libraries
+  IF(_arg_MODULE)
+    SET(_arg_SHARED SHARED)
+    SET(_arg_STATIC)
+  ENDIF()
+
+  # Don't compile header files
+  FOREACH(_file ${_${_target_name}_files})
+    IF(NOT _file MATCHES "\\.(c|cc|cpp)")
+      SET_SOURCE_FILES_PROPERTIES(${_file} PROPERTIES HEADER_FILE_ONLY TRUE)
+    ENDIF()
+  ENDFOREACH(_file)
+
+
+
+  # Add the library/executable
+  IF("${_target_type}" STREQUAL "LIBRARY")
+    ADD_LIBRARY(${_target_name} ${_arg_STATIC} ${_arg_SHARED}
+                ${_arg_EXCLUDE_FROM_ALL} ${_${_target_name}_files})
+  ELSE()
+    ADD_EXECUTABLE(${_target_name} ${_arg_WIN32} ${_arg_EXCLUDE_FROM_ALL}
+                   ${_${_target_name}_files})
+  ENDIF()
+
+
+
+  # Change library prefix to "lib"
+  IF(MSVC AND ${_target_type} STREQUAL "LIBRARY")
+    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES
+      PREFIX "lib"
+    )
+  ENDIF()
+
+  # MSVC hack to exclude external library sources from the intellisense database
+  # (IntelliSense stops working when adding "-Zm1000" as compile flag. "/Zm1000"
+  # would not work because of the slash)
+  IF(_arg_ORXONOX_EXTERNAL AND MSVC)
+    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES COMPILE_FLAGS "-Zm1000")
+  ENDIF()
+
+  # MODULE B
+  IF (_arg_MODULE)
+    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES
+      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_MODULE_OUTPUT_DIRECTORY} # Windows
+      LIBRARY_OUTPUT_DIRECTORY ${CMAKE_MODULE_OUTPUT_DIRECTORY} # Unix
+    )
+    ADD_MODULE(${_target_name})
+  ENDIF()
+
+  # LINK_LIBRARIES
+  IF(_arg_LINK_LIBRARIES)
+    TARGET_LINK_LIBRARIES(${_target_name} ${_arg_LINK_LIBRARIES})
+  ENDIF()
+
+  # DEFINE_SYMBOL
+  IF(_arg_DEFINE_SYMBOL)
+    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES DEFINE_SYMBOL ${_arg_DEFINE_SYMBOL})
+  ENDIF()
+
+  # VERSION
+  IF(_arg_VERSION)
+    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES VERSION ${_arg_VERSION})
+  ELSEIF(NOT _arg_ORXONOX_EXTERNAL)
+    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES VERSION ${ORXONOX_VERSION})
+  ENDIF()
+
+  # OUTPUT_NAME
+  IF(_arg_OUTPUT_NAME)
+    SET_TARGET_PROPERTIES(${_target_name} PROPERTIES OUTPUT_NAME  ${_arg_OUTPUT_NAME})
+  ENDIF()
+
+  # Second part of precompiled header files
+  IF(PCH_COMPILER_SUPPORT AND PCH_ENABLE_${_target_name_upper} AND _arg_PCH_FILE)
+    PRECOMPILED_HEADER_FILES_POST_TARGET(${_target_name} ${_arg_PCH_FILE})
+  ENDIF()
+
+  IF(NOT _arg_STATIC AND NOT _arg_NO_INSTALL)
+    IF(_arg_MODULE)
+      INSTALL(TARGETS ${_target_name}
+        RUNTIME DESTINATION ${MODULE_INSTALL_DIRECTORY}
+        LIBRARY DESTINATION ${MODULE_INSTALL_DIRECTORY}
+      )
+    ELSE()
+      INSTALL(TARGETS ${_target_name}
+        RUNTIME DESTINATION ${RUNTIME_INSTALL_DIRECTORY}
+        LIBRARY DESTINATION ${LIBRARY_INSTALL_DIRECTORY}
+      )
+    ENDIF()
+  ENDIF()
+
+ENDMACRO(TU_ADD_TARGET)
+
+
+# Creates a helper file with name <name_of_the_library>${ORXONOX_MODULE_EXTENSION}
+# This helps finding dynamically loadable modules at runtime
+
+FUNCTION(ADD_MODULE _target)
+  # We use the properties to get the name because the librarys name may differ from
+  # the target name (for example orxonox <-> liborxonox)
+
+  GET_TARGET_PROPERTY(_target_loc ${_target} LOCATION)
+  GET_FILENAME_COMPONENT(_target_name ${_target_loc} NAME_WE)
+
+  IF(CMAKE_CONFIGURATION_TYPES)
+    FOREACH(_config ${CMAKE_CONFIGURATION_TYPES})
+      SET(_module_filename ${CMAKE_MODULE_OUTPUT_DIRECTORY}/${_config}/${_target_name}${ORXONOX_MODULE_EXTENSION})
+
+      FILE(WRITE ${_module_filename})
+
+      INSTALL(
+        FILES ${_module_filename}
+        DESTINATION ${MODULE_INSTALL_DIRECTORY}
+        CONFIGURATIONS ${_config}
+      )
+    ENDFOREACH()
+  ELSE()
+    SET(_module_filename ${CMAKE_MODULE_OUTPUT_DIRECTORY}/${_target_name}${ORXONOX_MODULE_EXTENSION})
+
+    FILE(WRITE ${_module_filename})
+
+    INSTALL(
+      FILES ${_module_filename}
+      DESTINATION ${MODULE_INSTALL_DIRECTORY}
+    )
+  ENDIF()
+ENDFUNCTION(ADD_MODULE)
Index: /code/branches/rocket2/data/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/data/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/data/CMakeLists.txt	(revision 6952)
@@ -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:
+ #    Finds the external data directory and configures the data installation.
+ #    Default search paths are: ../../data and ../data_extern
+ #
+
+# For dev runs we've got two data directories. The one from the other repository root folder
+# is called EXTERNAL_DATA
+SET(DATA_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+SET(DATA_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE)
+
+# Specify data directory
+GET_FILENAME_COMPONENT(_search_path_1 ${CMAKE_SOURCE_DIR}/../data_extern ABSOLUTE)
+FIND_PATH(EXTERNAL_DATA_DIRECTORY resources.oxr
+  PATHS
+    ${CMAKE_SOURCE_DIR}/data_extern
+    ${_search_path_1}
+  NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH
+)
+
+IF(NOT EXTERNAL_DATA_DIRECTORY)
+  MESSAGE(STATUS "Warning: External data directory not found. If you want to compile while downloading the data files, you will have to recompile about four files afterwards and relink everything.")
+  MESSAGE(STATUS "You can specify your own folder with the EXTERNAL_DATA_DIRECTORY variable. Default location for the path is orxonox_root/data_extern")
+  # Temporary override to the default location.
+  SET(EXTERNAL_DATA_DIRECTORY ${CMAKE_SOURCE_DIR}/data_extern)
+ENDIF()
+
+
+################ Installation #################
+
+# Internal directory
+INSTALL(
+  DIRECTORY ${DATA_DIRECTORY}/
+  DESTINATION ${DATA_INSTALL_DIRECTORY}
+  REGEX "\\.svn$|_svn$|CMakeLists.txt|InstallScript.cmake" EXCLUDE
+)
+# External directory
+INSTALL(
+  DIRECTORY ${EXTERNAL_DATA_DIRECTORY}/
+  DESTINATION ${DATA_INSTALL_DIRECTORY}
+  REGEX "\\.svn$|_svn$|resources\\.oxr" EXCLUDE
+)
+# Configure the install scripts (variables not available during installation)
+CONFIGURE_FILE(DataInstallScript.cmake ${CMAKE_CURRENT_BINARY_DIR}/DataInstallScript.cmake @ONLY)
+# Join both resources.oxr files
+INSTALL(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/DataInstallScript.cmake)
Index: /code/branches/rocket2/data/DataInstallScript.cmake
===================================================================
--- /code/branches/rocket2/data/DataInstallScript.cmake	(revision 6952)
+++ /code/branches/rocket2/data/DataInstallScript.cmake	(revision 6952)
@@ -0,0 +1,37 @@
+ #
+ #             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:
+ #    Joins both resources.oxr files together
+ #  Caution:
+ #    Variables are declared with @...@ because they don't exist anymore
+ #    during the installation. But we still require variables (_external_file)
+ #    so we can only replace @...@ but not ${...}
+ #
+
+# Write some comment
+FILE(APPEND @DATA_INSTALL_DIRECTORY@/DefaultResources.oxr "\n\n\n <!-- ---------------------------------------- -->")
+FILE(APPEND @DATA_INSTALL_DIRECTORY@/DefaultResources.oxr     "\n <!-- Content from the external data directory -->")
+FILE(APPEND @DATA_INSTALL_DIRECTORY@/DefaultResources.oxr     "\n <!-- ---------------------------------------- -->\n\n")
+
+# Append the external file
+FILE(READ   @EXTERNAL_DATA_DIRECTORY@/resources.oxr _external_file)
+FILE(APPEND @DATA_INSTALL_DIRECTORY@/DefaultResources.oxr ${_external_file})
Index: /code/branches/rocket2/data/DefaultResources.oxr
===================================================================
--- /code/branches/rocket2/data/DefaultResources.oxr	(revision 6952)
+++ /code/branches/rocket2/data/DefaultResources.oxr	(revision 6952)
@@ -0,0 +1,14 @@
+<ResourceCollection resourceGroup = "General" >
+    <ResourceLocation path = "levels" />
+    <ResourceLocation path = "lua" />
+    <ResourceLocation path = "overlays" />
+    <ResourceLocation path = "particle" />
+    <ResourceLocation path = "tcl" />
+</ResourceCollection>
+
+<ResourceCollection resourceGroup = "GUI" >
+    <ResourceLocation path = "gui/configs" />
+    <ResourceLocation path = "gui/layouts" />
+    <ResourceLocation path = "gui/schemes" />
+    <ResourceLocation path = "gui/scripts" />
+</ResourceCollection>
Index: /code/branches/rocket2/data/defaultConfig/keybindings.ini
===================================================================
--- /code/branches/rocket2/data/defaultConfig/keybindings.ini	(revision 6952)
+++ /code/branches/rocket2/data/defaultConfig/keybindings.ini	(revision 6952)
@@ -0,0 +1,172 @@
+[Keys]
+KeyA="scale -1 moveRightLeft"
+KeyABNT_C1=
+KeyABNT_C2=
+KeyAT=
+KeyAX=
+KeyApostrophe=
+KeyApps=
+KeyB =
+KeyBack=
+KeyBackslash=
+KeyC=switchCamera
+KeyCalculator=
+KeyCapsLock=
+KeyColon=
+KeyComma=
+KeyConvert=
+KeyD="scale 1 moveRightLeft"
+KeyDelete="scale 1 rotateRoll"
+KeyDivide=
+KeyDown="scale -1 moveFrontBack"
+KeyE="scale -1 rotateRoll"
+KeyEnd=boost
+KeyEquals=
+KeyEscape="keyESC"
+KeyF="scale -1 moveUpDown"
+KeyF1="OverlayGroup toggleVisibility Debug"
+KeyF3 = "OrxonoxOverlay toggleVisibility QuestGUI"
+KeyF10=
+KeyF11=
+KeyF12=
+KeyF13=
+KeyF14=
+KeyF15=
+KeyF2="OverlayGroup toggleVisibility Stats"
+KeyF3=
+KeyF4=
+KeyF5=
+KeyF6=
+KeyF7=
+KeyF8=
+KeyF9=
+KeyG=greet
+KeyGrave="openConsole"
+KeyH=
+KeyHome=
+KeyI=
+KeyInsert=
+KeyJ=
+KeyK=
+KeyKana=
+KeyKanji=
+KeyL=dropItems
+KeyLeft="scale -1 moveRightLeft"
+KeyLeftAlt=
+KeyLeftBracket=
+KeyLeftControl=mouseLook
+KeyLeftShift=
+KeyLeftWindows=
+KeyLessThan=
+KeyM=openMap
+KeyMail=
+KeyMediaSelect=
+KeyMediaStop=
+KeyMinus=
+KeyMultiply=
+KeyMute=
+KeyMyComputer=
+KeyN=
+KeyNextTrack=
+KeyNoConvert=
+KeyNumLock=
+KeyNumRow0=
+KeyNumRow1=
+KeyNumRow2=
+KeyNumRow3=
+KeyNumRow4=
+KeyNumRow5=
+KeyNumRow6=
+KeyNumRow7=
+KeyNumRow8=
+KeyNumRow9=
+KeyNumpad0=
+KeyNumpad1=
+KeyNumpad2=
+KeyNumpad3=
+KeyNumpad4=
+KeyNumpad5=
+KeyNumpad6=
+KeyNumpad7=
+KeyNumpad8=
+KeyNumpad9=
+KeyNumpadAdd=
+KeyNumpadComma=
+KeyNumpadEnter=
+KeyNumpadEquals=
+KeyNumpadPeriod=
+KeyNumpadSubtract=
+KeyO=
+KeyP=
+KeyPageDown="scale -1 rotateRoll"
+KeyPageUp=
+KeyPause=pause
+KeyPeriod=
+KeyPlayPause=
+KeyPower=
+KeyPreviousTrack=
+KeyQ="scale 1 rotateRoll"
+KeyR="scale 1 moveUpDown"
+KeyReturn=
+KeyRight="scale 1 moveRightLeft"
+KeyRightAlt=
+KeyRightBracket=
+KeyRightControl="scale -1 moveUpDown"
+KeyRightShift="scale 1 moveUpDown"
+KeyRightWindows=
+KeyS="scale -1 moveFrontBack"
+KeyScrollLock=
+KeySemicolon=
+KeySlash=
+KeySleep=
+KeySpace=boost
+KeyStop=
+KeySystemRequest=
+KeyT="onpress fire 2"
+KeyTab="NewHumanController changeMode"
+KeyU=""
+KeyUP="scale 1 moveFrontBack"
+KeyUnassigned="openConsole"
+KeyUnderline=
+KeyUnlabeled=
+KeyV=
+KeyVolumeDown=
+KeyVolumeUp=
+KeyW="scale 1 moveFrontBack"
+KeyWake=
+KeyWebBack=
+KeyWebFavorites=
+KeyWebForward=
+KeyWebHome=
+KeyWebRefresh=
+KeyWebSearch=
+KeyWebStop=
+KeyX=
+KeyY=
+KeyYen=
+KeyZ=
+
+[MouseButtons]
+Button3=
+Button4=
+Button5=
+Button6=
+Button7=
+Left="fire 0"
+Middle=
+Right= fire 1 | unfire
+Wheel1Down="NewHumanController decelerate"
+Wheel1Up="NewHumanController accelerate"
+Wheel2Down=
+Wheel2Up=
+
+[MouseAxes]
+MouseXNeg="scale 1 rotateYaw"
+MouseXPos="scale -1 rotateYaw"
+MouseYNeg="scale -1 rotatePitch"
+MouseYPos="scale 1 rotatePitch"
+XNeg="scale 1 rotateYaw"
+XPos="scale -1 rotateYaw"
+YNeg="scale -1 rotatePitch"
+YPos="scale 1 rotatePitch"
+
Index: /code/branches/rocket2/data/gui/configs/CEGUIConfig.xsd
===================================================================
--- /code/branches/rocket2/data/gui/configs/CEGUIConfig.xsd	(revision 6952)
+++ /code/branches/rocket2/data/gui/configs/CEGUIConfig.xsd	(revision 6952)
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+
+	<xsd:element name="CEGUIConfig" type="CEGUIConfigType"/>
+
+    <xsd:simpleType name="LogLevel">
+        <xsd:restriction base="xsd:string">
+            <xsd:enumeration value="Errors"/>
+            <xsd:enumeration value="Standard"/>
+            <xsd:enumeration value="Informative"/>
+            <xsd:enumeration value="Insane"/>
+        </xsd:restriction>
+    </xsd:simpleType>
+    
+	<xsd:complexType name="CEGUIConfigType">
+		<xsd:attribute name="Logfile" type="xsd:string" use="optional" default=""/>
+		<xsd:attribute name="Scheme" type="xsd:string" use="optional" default=""/>
+		<xsd:attribute name="DefaultFont" type="xsd:string" use="optional" default=""/>
+		<xsd:attribute name="Layout" type="xsd:string" use="optional" default=""/>
+		<xsd:attribute name="InitScript" type="xsd:string" use="optional" default=""/>
+		<xsd:attribute name="TerminateScript" type="xsd:string" use="optional" default=""/>
+		<xsd:attribute name="DefaultResourceGroup" type="xsd:string" use="optional"  default="" />
+        <xsd:attribute name="LoggingLevel" type="LogLevel" use="optional"  default="Standard" />
+	</xsd:complexType>
+	
+</xsd:schema>
+
+
Index: /code/branches/rocket2/data/gui/layouts/AudioMenu.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/AudioMenu.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/AudioMenu.layout	(revision 6952)
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="MenuWidgets/StaticImage" Name="orxonox/AudioBackground" >
+        <Property Name="FrameEnabled" Value="False" />
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Property Name="BackgroundEnabled" Value="False" />
+        <Window Type="MenuWidgets/StaticText" Name="orxonox/AudioWindow" >
+            <Property Name="Text" Value="Audio" />
+            <Property Name="Alpha" Value="0.8" />
+            <Property Name="InheritsAlpha" Value="False" />
+            <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="VertFormatting" Value="TopAligned" />
+            <Property Name="UnifiedAreaRect" Value="{{0.2,0},{0.2875,0},{0.8,0},{0.6375,0}}" />
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/MasterVolume" >
+                <Property Name="Text" Value="Master volume               " />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.041666,0},{0.15,0},{0.5625,0},{0.3525,0}}" />
+                <Window Type="MenuWidgets/HorizontalScrollbar" Name="orxonox/MasterScrollbar" >
+                    <Property Name="PageSize" Value="0" />
+                    <Property Name="StepSize" Value="1" />
+                    <Property Name="OverlapSize" Value="0" />
+                    <Property Name="DocumentSize" Value="1" />
+                    <Property Name="ScrollPosition" Value="0" />
+                    <Property Name="StepSize" Value="0.1" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.04,0},{0.6,0},{0.71,0},{0.8,0}}" />
+                    <Event Name="ThumbTrackStarted" Function="AudioMenu.AudioMasterScrollbar_started" />
+                    <Event Name="ThumbTrackEnded" Function="AudioMenu.AudioMasterScrollbar_ended" />
+                    <Event Name="ScrollPosChanged" Function="AudioMenu.AudioMasterScrollbar_changed" />
+                </Window>
+                <Window Type="MenuWidgets/Checkbox" Name="orxonox/MasterCheckbox" >
+                    <Property Name="Text" Value="Mute" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.775,0},{0.45,0},{0.96,0},{0.9,0}}" />
+                    <Event Name="CheckStateChanged" Function="AudioMenu.AudioMuteMasterCheckbox_clicked"/>
+                </Window>
+            </Window>
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/MusicVolume" >
+                <Property Name="Text" Value="Music volume               " />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.041666,0},{0.4335,0},{0.5625,0},{0.636,0}}" />
+                <Window Type="MenuWidgets/HorizontalScrollbar" Name="orxonox/MusicScrollbar" >
+                    <Property Name="PageSize" Value="0" />
+                    <Property Name="StepSize" Value="1" />
+                    <Property Name="OverlapSize" Value="0" />
+                    <Property Name="DocumentSize" Value="1" />
+                    <Property Name="ScrollPosition" Value="0" />
+                    <Property Name="StepSize" Value="0.1" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.04,0},{0.6,0},{0.71,0},{0.8,0}}" />
+                    <Event Name="ThumbTrackStarted" Function="AudioMenu.AudioMusicScrollbar_started" />
+                    <Event Name="ThumbTrackEnded" Function="AudioMenu.AudioMusicScrollbar_ended" />
+                    <Event Name="ScrollPosChanged" Function="AudioMenu.AudioMusicScrollbar_changed" />
+                </Window>
+                <Window Type="MenuWidgets/Checkbox" Name="orxonox/MusicCheckbox" >
+                    <Property Name="Text" Value="Mute" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.775,0},{0.45,0},{0.96,0},{0.9,0}}" />
+                    <Event Name="CheckStateChanged" Function="AudioMenu.AudioMuteMusicCheckbox_clicked"/>
+                </Window>
+            </Window>
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/EffectsVolume" >
+                <Property Name="Text" Value="Effects volume               " />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.041666,0},{0.717,0},{0.5625,0},{0.9195,0}}" />
+                <Window Type="MenuWidgets/HorizontalScrollbar" Name="orxonox/EffectsScrollbar" >
+                    <Property Name="PageSize" Value="0" />
+                    <Property Name="StepSize" Value="1" />
+                    <Property Name="OverlapSize" Value="0" />
+                    <Property Name="DocumentSize" Value="1" />
+                    <Property Name="ScrollPosition" Value="0" />
+                    <Property Name="StepSize" Value="0.1" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.04,0},{0.6,0},{0.71,0},{0.8,0}}" />
+                    <Event Name="ThumbTrackStarted" Function="AudioMenu.AudioEffectsScrollbar_started" />
+                    <Event Name="ThumbTrackEnded" Function="AudioMenu.AudioEffectsScrollbar_ended" />
+                    <Event Name="ScrollPosChanged" Function="AudioMenu.AudioEffectsScrollbar_changed" />
+                </Window>
+                <Window Type="MenuWidgets/Checkbox" Name="orxonox/EffectsCheckbox" >
+                    <Property Name="Text" Value="Mute" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.775,0},{0.45,0},{0.96,0},{0.9,0}}" />
+                    <Event Name="CheckStateChanged" Function="AudioMenu.AudioMuteEffectsCheckbox_clicked"/>
+                </Window>
+            </Window>
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/AudioTheme" >
+                <Property Name="Text" Value="Theme" />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.604166,0},{0.15,0},{0.958333,0},{0.636,0}}" />
+                <Window Type="MenuWidgets/Listbox" Name="orxonox/AudioThemeListbox" >
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.225,0},{0.95,0},{0.92,0}}" />
+                    <Event Name="ItemSelectionChanged" Function="AudioMenu.AudioThemeListbox_changed" />
+                </Window>
+            </Window>
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/AudioInfo" >
+                <Property Name="Text" >Theme changes might take
+up to a minute.</Property>
+                <Property Name="TextColours" Value="FF4444FF" />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.604166,0},{0.717,0},{0.958333,0},{0.9195,0}}" />
+            </Window>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/AudioBackButton" >
+            <Property Name="Text" Value="Back" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.6625,0},{0.6,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="AudioMenu.AudioBackButton_clicked" />
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/ChatBox-inputonly.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/ChatBox-inputonly.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/ChatBox-inputonly.layout	(revision 6952)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="DefaultWindow" Name="orxonox/ChatBox-inputonly/Root" >
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Window Type="MenuWidgets/Editbox" Name="orxonox/ChatBox-inputonly/input" >
+            <Property Name="Text" Value="" />
+            <Property Name="Font" Value="Monofur-10" />
+            <Property Name="AlwaysOnTop" Value="True" />
+            <Property Name="MaxTextLength" Value="12981298" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.02,0},{0,5},{0.98,0},{0,30}}" />
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/ChatBox.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/ChatBox.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/ChatBox.layout	(revision 6952)
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="DefaultWindow" Name="orxonox/ChatBox/Root" >
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Window Type="MenuWidgets/FrameWindow" Name="/ChatBox" >
+            <Property Name="Text" Value="Chat" />
+            <Property Name="InheritsAlpha" Value="False" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="TitlebarEnabled" Value="True" />
+            <!--<Property Name="UnifiedAreaRect" Value="{{0.01,0},{0.03,0},{0.6,0},{0.69375,0}}" />-->
+            <Property Name="UnifiedAreaRect" Value="{{0.35,0},{0.10,0},{0.98,0},{0.65,0}}" />
+            <Window Type="MenuWidgets/Listbox" Name="orxonox/ChatBox/history" >
+                <Property Name="Font" Value="Monofur-10" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.02,0},{0.078,0},{0.98,0},{1,-30}}" />
+            </Window>
+            <Window Type="MenuWidgets/Editbox" Name="orxonox/ChatBox/input" >
+                <Property Name="Text" Value="" />
+                <Property Name="Font" Value="Monofur-10" />
+                <Property Name="MaxTextLength" Value="1073741823" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.02,0},{1,-30},{0.98,0},{1,-5}}" />
+            </Window>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/ControlsMenu.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/ControlsMenu.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/ControlsMenu.layout	(revision 6952)
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="MenuWidgets/StaticImage" Name="orxonox/ControlsBackground" >
+        <Property Name="FrameEnabled" Value="False" />
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Property Name="BackgroundEnabled" Value="False" />
+        <Window Type="MenuWidgets/StaticText" Name="orxonox/ControlsWindow" >
+            <Property Name="Text" Value="Controls" />
+            <Property Name="Alpha" Value="0.8" />
+            <Property Name="InheritsAlpha" Value="False" />
+            <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="VertFormatting" Value="TopAligned" />
+            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.3625,0},{0.75,0},{0.6375,0}}" />
+            <Window Type="MenuWidgets/Button" Name="orxonox/MouseControlsButton" >
+                <Property Name="Text" Value="Mouse controls" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.3,0},{0.318181,0},{0.7,0},{0.5,0}}" />
+                <Event Name="Clicked" Function="ControlsMenu.ControlsMouseControlsButton_clicked"/>
+            </Window>
+            <Window Type="MenuWidgets/Button" Name="orxonox/KeybindingsButton" >
+                <Property Name="Text" Value="Keybindings" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.3,0},{0.590909,0},{0.7,0},{0.772727,0}}" />
+                <Event Name="Clicked" Function="ControlsMenu.ControlsKeyboardControlsButton_clicked"/>
+            </Window>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/ControlsBackButton" >
+            <Property Name="Text" Value="Back" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.6625,0},{0.6,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="ControlsMenu.ControlsBackButton_clicked"/>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/CreditsMenu.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/CreditsMenu.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/CreditsMenu.layout	(revision 6952)
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="MenuWidgets/StaticImage" Name="orxonox/CreditsBackground" >
+        <Property Name="FrameEnabled" Value="False" />
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Property Name="BackgroundEnabled" Value="False" />
+        <Window Type="MenuWidgets/StaticText" Name="orxonox/CreditsWindow" >
+            <Property Name="Text" Value="Credits" />
+            <Property Name="Alpha" Value="0.8" />
+            <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="InheritsAlpha" Value="False" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="VertFormatting" Value="TopAligned" />
+            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.3625,0},{0.75,0},{0.6375,0}}" />
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/CreditsText" >
+                <Property Name="Text">Orxonox version 0.0.3
+
+Programming Language:  C++ - lua - tcl
+Environment:  OpenAL - Ogre - OIS - CEGUI - enet - ODE
+Licence:  GNU General Public Licence - Creative Commons
+
+http://www.orxonox.net</Property>
+                <Property Name="TextColours" Value="FF4444FF" />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.2,0},{0.95,0},{0.9,0}}" />
+            </Window>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/CreditsBackButton" >
+            <Property Name="Text" Value="Back" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.6625,0},{0.6,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="CreditsMenu.CreditsBackButton_clicked"/>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/DecisionPopup.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/DecisionPopup.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/DecisionPopup.layout	(revision 6952)
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="DefaultWindow" Name="orxonox/DecisionPopup_RootWindow" >
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Window Type="MenuWidgets/StaticImage" Name="orxonox/DecisionPopup_Background" >
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+            <Property Name="Alpha" Value="0.6" />
+            <Window Type="MenuWidgets/Button" Name="orxonox/DecisionPopup_button_yes" >
+                <Property Name="Text" Value="Yes" />
+                <Property Name="Alpha" Value="0.7" />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.2875,0},{0.5625,0},{0.4875,0},{0.6125,0}}" />
+                <Event Name="Clicked" Function="DecisionPopup.button_yes"/>
+            </Window>
+            <Window Type="MenuWidgets/Button" Name="orxonox/DecisionPopup_button_no" >
+                <Property Name="Text" Value="No" />
+                <Property Name="Alpha" Value="0.8" />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.5125,0},{0.5625,0},{0.7125,0},{0.6125,0}}" />
+                <Event Name="Clicked" Function="DecisionPopup.button_no"/>
+            </Window>
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/DecisionPopup_text" >
+                <Property Name="Text" Value="Template text" />
+                <Property Name="HorzFormatting" Value="WordWrapCentred" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.4375,0},{0.75,0},{0.5375,0}}" />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="Alpha" Value="0.8" />
+            </Window>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/GUILayout.xsd
===================================================================
--- /code/branches/rocket2/data/gui/layouts/GUILayout.xsd	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/GUILayout.xsd	(revision 6952)
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+
+	<xsd:element name="GUILayout" type="GUILayoutType"/>
+	
+	<xsd:complexType name="GUILayoutType">
+		<xsd:sequence>
+			<xsd:element name="Window" type="WindowType" />
+		</xsd:sequence>
+		<xsd:attribute name="Parent" type="xsd:string" use="optional" default=""/>
+	</xsd:complexType>
+	
+	<xsd:complexType name="WindowType">
+		<xsd:sequence>
+			<xsd:element name="LayoutImport" type="LayoutImportType"  minOccurs="0" maxOccurs="unbounded" />
+			<xsd:element name="Property" type="PropertyType"  minOccurs="0" maxOccurs="unbounded" />
+			<xsd:element name="Event" type="EventType"  minOccurs="0" maxOccurs="unbounded" />
+			<xsd:choice minOccurs="0" maxOccurs="unbounded">
+				<xsd:element name="Window" type="WindowType" />
+				<xsd:element name="AutoWindow" type="AutoWindowType" />
+			</xsd:choice>
+			<xsd:element name="Property" type="PropertyType"  minOccurs="0" maxOccurs="unbounded" />
+		</xsd:sequence>
+		<xsd:attribute name="Type" type="xsd:string" use="required"/>
+		<xsd:attribute name="Name" type="xsd:string" use="optional" default="" />
+	</xsd:complexType>
+
+	<xsd:complexType name="AutoWindowType">
+		<xsd:sequence>
+			<xsd:element name="LayoutImport" type="LayoutImportType"  minOccurs="0" maxOccurs="unbounded" />
+			<xsd:element name="Property" type="PropertyType"  minOccurs="0" maxOccurs="unbounded" />
+			<xsd:element name="Event" type="EventType"  minOccurs="0" maxOccurs="unbounded" />
+			<xsd:choice minOccurs="0" maxOccurs="unbounded">
+				<xsd:element name="Window" type="WindowType" />
+				<xsd:element name="AutoWindow" type="AutoWindowType" />
+			</xsd:choice>
+			<xsd:element name="Property" type="PropertyType"  minOccurs="0" maxOccurs="unbounded" />
+		</xsd:sequence>
+		<xsd:attribute name="NameSuffix" type="xsd:string" use="required"/>
+	</xsd:complexType>
+
+	<xsd:complexType name="PropertyType">
+		<xsd:simpleContent>
+			<xsd:extension base="xsd:string">
+				<xsd:attribute name="Name" type="xsd:string" use="required"/>
+				<xsd:attribute name="Value" type="xsd:string" use="optional"/>
+			</xsd:extension>
+		</xsd:simpleContent> 
+	</xsd:complexType>
+
+	<xsd:complexType name="LayoutImportType">
+		<xsd:attribute name="Filename" type="xsd:string" use="required"/>
+		<xsd:attribute name="Prefix" type="xsd:string" use="optional" default="" />
+		<xsd:attribute name="ResourceGroup" type="xsd:string" use="optional"  default="" />
+	</xsd:complexType>
+
+	<xsd:complexType name="EventType">
+		<xsd:attribute name="Name" type="xsd:string" use="required"/>
+		<xsd:attribute name="Function" type="xsd:string" use="required"/>
+	</xsd:complexType>
+
+</xsd:schema>
+
Index: /code/branches/rocket2/data/gui/layouts/GameplayMenu.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/GameplayMenu.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/GameplayMenu.layout	(revision 6952)
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="MenuWidgets/StaticImage" Name="orxonox/GameplayBackground" >
+        <Property Name="FrameEnabled" Value="False" />
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Property Name="BackgroundEnabled" Value="False" />
+        <Window Type="MenuWidgets/StaticText" Name="orxonox/GameplayWindow" >
+            <Property Name="Text" Value="Gameplay" />
+            <Property Name="Alpha" Value="0.8" />
+            <Property Name="InheritsAlpha" Value="False" />
+            <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="VertFormatting" Value="TopAligned" />
+            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.3625,0},{0.75,0},{0.6375,0}}" />
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/Difficulty" >
+                <Property Name="Text" Value="Difficulty" />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.2,0},{0.475,0},{0.9,0}}" />
+                <Window Type="MenuWidgets/RadioButton" Name="orxonox/DifficultyEasyButton" >
+                    <Property Name="Text" Value="Easy" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.325,0},{0.325,0},{0.675,0},{0.45,0}}" />
+                    <Event Name="SelectStateChanged" Function="GameplayMenu.GameplayDifficultyEasyButton_clicked"/>
+                </Window>
+                <Window Type="MenuWidgets/RadioButton" Name="orxonox/DifficultyNormalButton" >
+                    <Property Name="Text" Value="Normal" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.325,0},{0.525,0},{0.675,0},{0.65,0}}" />
+                    <Event Name="SelectStateChanged" Function="GameplayMenu.GameplayDifficultyNormalButton_clicked"/>
+                </Window>
+                <Window Type="MenuWidgets/RadioButton" Name="orxonox/DifficultyHardButton" >
+                    <Property Name="Text" Value="Hard" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.325,0},{0.725,0},{0.675,0},{0.85,0}}" />
+                    <Event Name="SelectStateChanged" Function="GameplayMenu.GameplayDifficultyHardButton_clicked"/>
+                </Window>
+            </Window>
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/Theme" >
+                <Property Name="Text" Value="Theme" />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.525,0},{0.2,0},{0.95,0},{0.9,0}}" />
+                <Window Type="MenuWidgets/Combobox" Name="orxonox/ThemeCombobox" >
+                    <Property Name="AlwaysOnTop" Value="True" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.21,0},{0.95,0},{0.9,0}}" />
+                    <Property Name="MaxEditTextLength" Value="1073741823" />
+                    <Property Name="ReadOnly" Value="True" />
+                    <Event Name="ListSelectionAccepted" Function="GameplayMenu.GameplayThemeCombobox_changed" />
+                </Window>
+            </Window>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/GameplayBackButton" >
+            <Property Name="Text" Value="Back" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.6625,0},{0.6,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="GameplayMenu.GameplayBackButton_clicked"/>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/GraphicsMenu.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/GraphicsMenu.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/GraphicsMenu.layout	(revision 6952)
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="MenuWidgets/StaticImage" Name="orxonox/GraphicsBackground" >
+        <Property Name="FrameEnabled" Value="False" />
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Property Name="BackgroundEnabled" Value="False" />
+        <Window Type="MenuWidgets/StaticText" Name="orxonox/GraphicsWindow" >
+            <Property Name="Text" Value="Graphics" />
+            <Property Name="Alpha" Value="0.8" />
+            <Property Name="InheritsAlpha" Value="False" />
+            <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="VertFormatting" Value="TopAligned" />
+            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.2875,0},{0.75,0},{0.6375,0}}" />
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/Resolution" >
+                <Property Name="Text" Value="Resolution" />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.15,0},{0.475,0},{0.92,0}}" />
+                <Window Type="MenuWidgets/Listbox" Name="orxonox/ResolutionListbox" >
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.15,0},{0.95,0},{0.95,0}}" />
+                    <Event Name="ItemSelectionChanged" Function="GraphicsMenu.GraphicsResolutionListbox_changed"/>
+                </Window>
+            </Window>
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/Brightness" >
+                <Property Name="Text" Value="Brightness" />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.525,0},{0.15,0},{0.95,0},{0.35,0}}" />
+                <Window Type="MenuWidgets/HorizontalScrollbar" Name="orxonox/BrightnessScrollbar" >
+                    <Property Name="Disabled" Value="true" />
+                    <Property Name="PageSize" Value="0" />
+                    <Property Name="StepSize" Value="0.1" />
+                    <Property Name="OverlapSize" Value="0" />
+                    <Property Name="DocumentSize" Value="1" />
+                    <Property Name="ScrollPosition" Value="0" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.6,0},{0.95,0},{0.8,0}}" />
+                    <Event Name="ThumbTrackStarted" Function="GraphicsMenu.GraphicsBrightnessScrollbar_started" />
+                    <Event Name="ThumbTrackEnded" Function="GraphicsMenu.GraphicsBrightnessScrollbar_ended" />
+                    <Event Name="ScrollPosChanged" Function="GraphicsMenu.GraphicsBrightnessScrollbar_changed" />
+                </Window>
+            </Window>
+            <Window Type="MenuWidgets/Checkbox" Name="orxonox/FullscreenCheckbox" >
+                <Property Name="Text" Value="Fullscreen" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.65,0},{0.4,0},{0.85,0},{0.475,0}}" />
+                <Event Name="CheckStateChanged" Function="GraphicsMenu.GraphicsFullscreenCheckbox_clicked"/>
+            </Window>
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/GraphicsInfo" >
+                <Property Name="Text" >
+Changes in graphics
+settings require
+a game restart.</Property>
+                <Property Name="TextColours" Value="FF4444FF" />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.525,0},{0.525,0},{0.95,0},{0.92,0}}" />
+            </Window>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/GraphicsBackButton" >
+            <Property Name="Text" Value="Back" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.6625,0},{0.6,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="GraphicsMenu.GraphicsBackButton_clicked"/>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/InGameMenu.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/InGameMenu.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/InGameMenu.layout	(revision 6952)
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="DefaultWindow" Name="orxonox/InGameMenu_RootWindow" >
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Window Type="MenuWidgets/Button" Name="orxonox/InGameMenu_ReturnButton" >
+            <Property Name="Text" Value="Return to Game" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.3625,0},{0.6,0},{0.4125,0}}" />
+            <Property Name="Alpha" Value="0.7" />
+            <Event Name="Clicked" Function="InGameMenu.button_return_clicked"/>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/InGameMenu_MainMenuButton" >
+            <Property Name="Text" Value="Main Menu" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.4625,0},{0.6,0},{0.5125,0}}" />
+            <Property Name="Alpha" Value="0.7" />
+            <Event Name="Clicked" Function="InGameMenu.button_mainmenu_clicked"/>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/InGameMenu_SettingsButton" >
+            <Property Name="Text" Value="Settings" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.5625,0},{0.6,0},{0.6125,0}}" />
+            <Property Name="Alpha" Value="0.7" />
+            <Event Name="Clicked" Function="InGameMenu.button_settings_clicked"/>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/InGameMenu_QuitButton" >
+            <Property Name="Text" Value="Quit" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.6625,0},{0.6,0},{0.7125,0}}" />
+            <Property Name="Alpha" Value="0.7" />
+            <Event Name="Clicked" Function="InGameMenu.button_quit_clicked"/>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/InGamePickupHUD.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/InGamePickupHUD.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/InGamePickupHUD.layout	(revision 6952)
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout>
+	<Window Type="DefaultWindow" Name="orxonox/InGamePickupHUD_RootWindow" >
+		<Property Name="InheritsAlpha" Value="False" />
+		<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+		<Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+		<Window Type="TaharezLook/StaticImage" Name="orxonox/InGamePickupHUD_Overview" >
+			<Property Name="Font" Value="BlueHighway-12" />
+			<Property Name="Text" Value="Pickup List" />
+			<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+			<Property Name="UnifiedAreaRect" Value="{{0,5},{0.15,0},{0.2,0},{0.45,0}}" />
+			<Property Name="Alpha" Value="0.3" />
+			<!--Event Name="Clicked" Function="InGameMenu.button_return_clicked"/-->
+			<Window Type="TaharezLook/StaticText" Name="orxonox/InGamePickupHUD_PickupTitle" >
+				<Property Name="Alpha" Value="0.8"/>
+				<Property Name="Text" Value="Pickup List" />
+				<Property Name="Font" Value="BlueHighway-10" />
+				<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+				<Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,-20},{0,20}}" />
+			</Window>
+			<Window Type="TaharezLook/Button" Name="orxonox/InGamePickupHUD_closeButton" >
+			        <Property Name="Alpha" Value="0.8" />
+				<Property Name="Font" Value="BlueHighway-12" />
+				<Property Name="Text" Value="X" />
+				<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+				<Property Name="UnifiedAreaRect" Value="{{1,-20},{0,0},{1,0},{0,20}}" />
+				<!-- alle Grössen / anordnungen angepasst - da überschneidungen von absoluten
+				und relativen Positionsangaben (problematisch bei kleinen auflösungen) -->
+				<Event Name="Clicked" Function="InGamePickupHUD.close_button_clicked"/>
+			</Window>
+			<Window Type="TaharezLook/Listbox" Name="orxonox/InGamePickupHUD_PickupListBox">
+			        <Property Name="Alpha" Value="0.8" />
+				<Property Name="Font" Value="BlueHighway-12" />
+				<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+				<Property Name="UnifiedAreaRect" Value="{{0,5},{0,25},{1,-5},{1,-5}}" />	
+				<!--
+				<Window Type="TaharezLook/ListboxItem" Name="orxonox/InGamePickupHUD_TestPickupOne">
+					<Property Name="Alpha" Value="0.8" />
+					<Property Name="Font" Value="BlueHighway-12" />
+					<Property Name="Text" Value="First Pickup" />
+					<Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+					<Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{0,30},{1,0}}" />	
+				</Window>
+				-->
+			</Window>
+			
+		</Window>
+		
+	
+	</Window>
+	
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/InGameTest.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/InGameTest.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/InGameTest.layout	(revision 6952)
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<GUILayout>
+    <Window Type="DefaultGUISheet" Name="orxonox/TestWindow">
+    <Property Name="UnifiedSize" Value="{{1.0,0},{1.0,0}}"/>
+
+        <Window Type="MenuWidgets/Button" Name="orxonox/TestButton">
+            <Property Name="UnifiedPosition" Value="{{0.11,0},{0.528,0}}"/>
+            <Property Name="UnifiedSize" Value="{{0.15,0},{0.05,0}}"/>
+            <Property Name="Text" Value="NoFunction"/>
+        </Window>
+
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/InfoPopup.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/InfoPopup.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/InfoPopup.layout	(revision 6952)
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="DefaultWindow" Name="orxonox/InfoPopup_RootWindow" >
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Window Type="MenuWidgets/StaticImage" Name="orxonox/InfoPopup_Background" >
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+            <Property Name="Alpha" Value="0.7" />
+            <Window Type="MenuWidgets/Button" Name="orxonox/InfoPopup_close" >
+                <Property Name="Text" Value="Close" />
+                <Property Name="Alpha" Value="0.7" />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.5,0},{0.6,0},{0.55,0}}" />
+                <Event Name="Clicked" Function="InfoPopup.close"/>
+            </Window>
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/InfoPopup_text" >
+                <Property Name="Text" Value="Template text" />
+                <Property Name="TextColours" Value="FF4444FF" />
+                <Property Name="HorzFormatting" Value="WordWrapCentred" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.375,0},{0.75,0},{0.475,0}}" />
+                <Property Name="InheritsAlpha" Value="False" />
+               <Property Name="Alpha" Value="0.8" />
+            </Window>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/KeyBindMenu.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/KeyBindMenu.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/KeyBindMenu.layout	(revision 6952)
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="DefaultWindow" Name="orxonox/KeyBindMenu/Background" >
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Window Type="MenuWidgets/StaticText" Name="orxonox/KeyBindWindow" >
+            <Property Name="Text" Value="Keybindings" />
+            <Property Name="Alpha" Value="0.8" />
+            <Property Name="InheritsAlpha" Value="False" />
+            <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="VertFormatting" Value="TopAligned" />
+            <Property Name="UnifiedAreaRect" Value="{{0.15,0},{0.2125,0},{0.85,0},{0.6375,0}}" />
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/KeyBindWrapper" >
+                <Property Name="TextColours" Value="FF4444FF" />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.15,0},{0.95,0},{0.92,0}}" />
+                <Window Type="MenuWidgets/ScrollablePane" Name="orxonox/KeyBindPane" >
+                    <Property Name="ContentArea" Value="l:0 t:0 r:0 b:0" />
+                    <Property Name="HorzStepSize" Value="0.005" />
+                    <Property Name="VertStepSize" Value="0.005" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="HorzOverlapSize" Value="0.01" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.005,0},{0.01,0},{0.995,0},{0.99,0}}" />
+                    <Property Name="VertOverlapSize" Value="0.01" />
+                    <Property Name="HorzScrollPosition" Value="0" />
+                    <Property Name="VertScrollPosition" Value="0" />
+                </Window>
+            </Window>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/KeyBindBackButton" >
+            <Property Name="Text" Value="Back" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.6625,0},{0.6,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="KeyBindMenu.KeyBindBackButton_clicked"/>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/MainMenu.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/MainMenu.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/MainMenu.layout	(revision 6952)
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="MenuWidgets/StaticImage" Name="orxonox/MainMenuBackground" >
+        <Property Name="FrameEnabled" Value="False" />
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1.0,0},{1.0,0}}" />
+        <Property Name="BackgroundEnabled" Value="False" />
+        <Window Type="MenuWidgets/Button" Name="orxonox/QuickGameTestButton" >
+            <Property Name="Text" Value="Quickstart" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.2875,0},{0.6,0},{0.3375,0}}" />
+            <Event Name="Clicked" Function="MainMenu.QuickGameTestButton_clicked"/>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/SingleplayerButton" >
+            <Property Name="Text" Value="Singleplayer" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.3625,0},{0.6,0},{0.4125,0}}" />
+            <Event Name="Clicked" Function="MainMenu.SingleplayerButton_clicked"/>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/MultiplayerButton" >
+            <Property Name="Text" Value="Multiplayer" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.4375,0},{0.6,0},{0.4875,0}}" />
+            <Event Name="Clicked" Function="MainMenu.MultiplayerButton_clicked"/>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/SettingsButton" >
+            <Property Name="Text" Value="Settings" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.5125,0},{0.6,0},{0.5625,0}}" />
+            <Event Name="Clicked" Function="MainMenu.SettingsButton_clicked"/>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/CreditsButton" >
+            <Property Name="Text" Value="Credits" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.5875,0},{0.6,0},{0.6375,0}}" />
+            <Event Name="Clicked" Function="MainMenu.CreditsButton_clicked"/>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/ExitButton" >
+            <Property Name="Text" Value="Exit" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.6625,0},{0.6,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="MainMenu.ExitButton_clicked"/>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/MainMenuBackground.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/MainMenuBackground.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/MainMenuBackground.layout	(revision 6952)
@@ -0,0 +1,10 @@
+<?xml version="1.0" ?>
+<GUILayout>
+    <Window Type="MenuWidgets/StaticImage" Name="orxonox/Background">
+    <Property Name="UnifiedSize" Value="{{1.0,0},{1.0,0}}"/>
+    <Property Name="Image" Value="set:MainMenuBackground image:Background"/>
+    <Property Name="FrameEnabled" Value="set:true"/>
+    <Property Name="BackgroundEnabled" Value="set:false"/>
+    <Property Name="InheritsAlpha" Value="False" />
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/MouseControlsMenu.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/MouseControlsMenu.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/MouseControlsMenu.layout	(revision 6952)
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="MenuWidgets/StaticImage" Name="orxonox/MouseControlsBackground" >
+        <Property Name="FrameEnabled" Value="False" />
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Property Name="BackgroundEnabled" Value="False" />
+        <Window Type="MenuWidgets/StaticText" Name="orxonox/MouseControlsWindow" >
+            <Property Name="Text" Value="Mouse controls" />
+            <Property Name="Alpha" Value="0.8" />
+            <Property Name="InheritsAlpha" Value="False" />
+            <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="VertFormatting" Value="TopAligned" />
+            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.3625,0},{0.75,0},{0.6375,0}}" />
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/MouseNormalSensitivity" >
+                <Property Name="Text" Value="Sensitivity (normal mode)                                      " />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.2,0},{0.95,0},{0.45,0}}" />
+                <Window Type="MenuWidgets/HorizontalScrollbar" Name="orxonox/MouseNormalScrollbar" >
+                    <Property Name="PageSize" Value="0" />
+                    <Property Name="StepSize" Value="1" />
+                    <Property Name="OverlapSize" Value="0" />
+                    <Property Name="DocumentSize" Value="1" />
+                    <Property Name="ScrollPosition" Value="0" />
+                    <Property Name="StepSize" Value="0.1" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.02,0},{0.6,0},{0.565,0},{0.8,0}}" />
+                    <Event Name="ThumbTrackStarted" Function="MouseControlsMenu.MouseControlsMouseNormalScrollbar_started" />
+                    <Event Name="ThumbTrackEnded" Function="MouseControlsMenu.MouseControlsMouseNormalScrollbar_ended" />
+                    <Event Name="ScrollPosChanged" Function="MouseControlsMenu.MouseControlsMouseNormalScrollbar_changed" />
+                </Window>
+                <Window Type="MenuWidgets/RadioButton" Name="orxonox/MouseNormalButton" >
+                    <Property Name="Text" Value="Normal mouse input" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.61,0},{0.5,0},{0.975,0},{0.85,0}}" />
+                    <Event Name="SelectStateChanged" Function="MouseControlsMenu.MouseNormalButton_clicked" />
+                </Window>
+            </Window>
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/MouseDeriveSensitivity" >
+                <Property Name="Text" Value="Sensitivity (derive mode)                                      " />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.55,0},{0.95,0},{0.8,0}}" />
+                <Window Type="MenuWidgets/HorizontalScrollbar" Name="orxonox/MouseDeriveScrollbar" >
+                    <Property Name="PageSize" Value="0" />
+                    <Property Name="StepSize" Value="1" />
+                    <Property Name="OverlapSize" Value="0" />
+                    <Property Name="DocumentSize" Value="1" />
+                    <Property Name="ScrollPosition" Value="0" />
+                    <Property Name="StepSize" Value="0.1" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.02,0},{0.6,0},{0.565,0},{0.8,0}}" />
+                    <Event Name="ThumbTrackStarted" Function="MouseControlsMenu.MouseControlsMouseDeriveScrollbar_started" />
+                    <Event Name="ThumbTrackEnded" Function="MouseControlsMenu.MouseControlsMouseDeriveScrollbar_ended" />
+                    <Event Name="ScrollPosChanged" Function="MouseControlsMenu.MouseControlsMouseDeriveScrollbar_changed" />
+                </Window>
+                <Window Type="MenuWidgets/RadioButton" Name="orxonox/MouseDeriveButton" >
+                    <Property Name="Text" Value="Derive mouse input" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.61,0},{0.5,0},{0.975,0},{0.85,0}}" />
+                    <Event Name="SelectStateChanged" Function="MouseControlsMenu.MouseDeriveButton_clicked" />
+                </Window>
+            </Window>
+            <Window Type="MenuWidgets/Checkbox" Name="orxonox/MouseInvertCheckbox" >
+                <Property Name="Text" Value="Invert mouse" />
+                <Property Name="Disabled" Value="true" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.39,0},{0.85,0},{0.61,0},{0.95,0}}" />
+                <Event Name="CheckStateChanged" Function="MouseControlsMenu.MouseInvertCheckbox_clicked" />
+            </Window>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/MouseControlsBackButton" >
+            <Property Name="Text" Value="Back" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.6625,0},{0.6,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="MouseControlsMenu.MouseControlsBackButton_clicked"/>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/MultiplayerMenu.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/MultiplayerMenu.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/MultiplayerMenu.layout	(revision 6952)
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="MenuWidgets/StaticImage" Name="orxonox/MultiplayerBackground" >
+        <Property Name="FrameEnabled" Value="False" />
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Property Name="BackgroundEnabled" Value="False" />
+        <Window Type="MenuWidgets/StaticText" Name="orxonox/MultiplayerWindow" >
+            <Property Name="Text" Value="Multiplayer" />
+            <Property Name="Alpha" Value="0.8" />
+            <Property Name="InheritsAlpha" Value="False" />
+            <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="VertFormatting" Value="TopAligned" />
+            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.2875,0},{0.75,0},{0.6375,0}}" />
+            <Window Type="MenuWidgets/Listbox" Name="orxonox/MultiplayerLevelListbox" >
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.15,0},{0.95,0},{0.8,0}}" />
+            </Window>
+            <Window Type="MenuWidgets/RadioButton" Name="orxonox/MultiplayerJoinButton" >
+                <Property Name="Text" Value="Join" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.1,0},{0.85,0},{0.3,0},{0.95,0}}" />
+                <Event Name="SelectStateChanged" Function="MultiplayerMenu.MultiplayerJoinButton_clicked"/>
+            </Window>
+            <Window Type="MenuWidgets/RadioButton" Name="orxonox/MultiplayerHostButton" >
+                <Property Name="Text" Value="Host" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.85,0},{0.6,0},{0.95,0}}" />
+                <Event Name="SelectStateChanged" Function="MultiplayerMenu.MultiplayerHostButton_clicked"/>
+            </Window>
+            <Window Type="MenuWidgets/RadioButton" Name="orxonox/MultiplayerDedicatedButton" >
+                <Property Name="Text" Value="Dedicated" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.7,0},{0.85,0},{0.9,0},{0.95,0}}" />
+                <Event Name="SelectStateChanged" Function="MultiplayerMenu.MultiplayerDedicatedButton_clicked"/>
+            </Window>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/MultiplayerStartButton" >
+            <Property Name="Text" Value="Start" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.2875,0},{0.6625,0},{0.4875,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="MultiplayerMenu.MultiplayerStartButton_clicked"/>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/MultiplayerBackButton" >
+            <Property Name="Text" Value="Back" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.5125,0},{0.6625,0},{0.7125,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="MultiplayerMenu.MultiplayerBackButton_clicked"/>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/MultiplayerOptionsMenu.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/MultiplayerOptionsMenu.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/MultiplayerOptionsMenu.layout	(revision 6952)
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="MenuWidgets/StaticImage" Name="orxonox/MultiplayerOptionsBackground" >
+        <Property Name="FrameEnabled" Value="False" />
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Property Name="BackgroundEnabled" Value="False" />
+        <Window Type="MenuWidgets/StaticText" Name="orxonox/MultiplayerOptionsWindow" >
+            <Property Name="Text" Value="Multiplayer options" />
+            <Property Name="Alpha" Value="0.8" />
+            <Property Name="InheritsAlpha" Value="False" />
+            <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="VertFormatting" Value="TopAligned" />
+            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.3625,0},{0.75,0},{0.6375,0}}" />
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/MultiplayerOptionsBackButton" >
+            <Property Name="Text" Value="Back" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.625,0},{0.6,0},{0.675,0}}" />
+            <Event Name="Clicked" Function="MultiplayerOptionsMenu.MultiplayerOptionsBackButton_clicked"/>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/PickupInventory.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/PickupInventory.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/PickupInventory.layout	(revision 6952)
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="DefaultWindow" Name="orxonox/PickupInventory/Background" >
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Window Type="MenuWidgets/StaticText" Name="orxonox/PickupInventory/PickupInventory" >
+            <Property Name="Text" Value="Pickup Inventory" />
+            <Property Name="Alpha" Value="0.8" />
+            <Property Name="InheritsAlpha" Value="False" />
+            <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="VertFormatting" Value="TopAligned" />
+            <Property Name="UnifiedAreaRect" Value="{{0.15,0},{0.15,0},{0.85,0},{0.8,0}}" />
+            <Window Type="MenuWidgets/StaticText" Name="orxonox/PickupInventory/Wrapper" >
+                <Property Name="TextColours" Value="FF4444FF" />
+                <Property Name="InheritsAlpha" Value="False" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="HorzFormatting" Value="HorzCentred" />
+                <Property Name="VertFormatting" Value="TopAligned" />
+                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.15,0},{0.95,0},{0.92,0}}" />
+                <Window Type="MenuWidgets/ScrollablePane" Name="orxonox/PickupInventory/Inventory" >
+                    <Property Name="ContentArea" Value="l:0 t:0 r:0 b:0" />
+                    <Property Name="HorzStepSize" Value="0.005" />
+                    <Property Name="VertStepSize" Value="0.005" />
+                    <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                    <Property Name="HorzOverlapSize" Value="0.01" />
+                    <Property Name="UnifiedAreaRect" Value="{{0.005,0},{0.01,0},{0.995,0},{0.99,0}}" />
+                    <Property Name="VertOverlapSize" Value="0.01" />
+                    <Property Name="HorzScrollPosition" Value="0" />
+                    <Property Name="VertScrollPosition" Value="0" />
+                </Window>
+            </Window>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/PickupInventory/InventoryBackButton" >
+            <Property Name="Text" Value="Back" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.8350,0},{0.6,0},{0.8800,0}}" />
+            <Event Name="Clicked" Function="PickupInventory.InventoryBackButton_clicked"/>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/QuestGUI.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/QuestGUI.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/QuestGUI.layout	(revision 6952)
@@ -0,0 +1,23 @@
+<?xml version="1.0" ?>
+<GUILayout>
+    <Window Type="MenuWidgets/StaticImage" Name="orxonox/QuestGUI/Background">
+    <Property Name="UnifiedSize" Value="{{1.0,0},{1.0,0}}"/>
+    <Property Name="Image" Value="set:MainMenuBackground image:Background"/>
+    <Property Name="FrameEnabled" Value="set:true"/>
+    <Property Name="BackgroundEnabled" Value="set:false"/>
+    <Property Name="InheritsAlpha" Value="False" />
+
+        <Window Type="MenuWidgets/Titlebar" Name="orxonox/QuestGUI/Title">
+            <Property Name="UnifiedPosition" Value="{{0.05,0},{0.05,0}}"/>
+            <Property Name="UnifiedSize" Value="{{0.9,0},{0.05,0}}"/>
+            <Property Name="Text" Value="Your Quests"/>
+        </Window>
+
+        <Window Type="MenuWidgets/Listbox" Name="orxonox/QuestGUI/QuestsList">
+            <Property Name="UnifiedPosition" Value="{{0.07,0},{0.18,0}}" />
+            <Property Name="UnifiedSize" Value="{{0.86,0},{0.8,0}}" />
+            <Property Name="Alpha" Value="0.8" />
+        </Window>
+
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/SettingsMenu.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/SettingsMenu.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/SettingsMenu.layout	(revision 6952)
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="MenuWidgets/StaticImage" Name="orxonox/SettingsBackground" >
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="FrameEnabled" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Property Name="BackgroundEnabled" Value="False" />
+        <Window Type="MenuWidgets/StaticText" Name="orxonox/SettingsWindow" >
+            <Property Name="Text" Value="Settings" />
+            <Property Name="Alpha" Value="0.8" />
+            <Property Name="InheritsAlpha" Value="False" />
+            <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="VertFormatting" Value="TopAligned" />
+            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.3625,0},{0.75,0},{0.6375,0}}" />
+            <Window Type="MenuWidgets/Button" Name="orxonox/GameplayButton" >
+                <Property Name="Text" Value="Gameplay" />
+                <Property Name="Disabled" Value="True" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.181818,0},{0.45,0},{0.363636,0}}" />
+                <Event Name="Clicked" Function="SettingsMenu.SettingsGameplayButton_clicked"/>
+            </Window>
+            <Window Type="MenuWidgets/Button" Name="orxonox/MultiplayerOptionsButton" >
+                <Property Name="Text" Value="Multiplayer options" />
+                <Property Name="Disabled" Value="True" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.454545,0},{0.45,0},{0.636363,0}}" />
+                <Event Name="Clicked" Function="SettingsMenu.SettingsMultiplayerOptionsButton_clicked"/>
+            </Window>
+            <Window Type="MenuWidgets/Button" Name="orxonox/ControlsButton" >
+                <Property Name="Text" Value="Controls" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.727272,0},{0.45,0},{0.909090,0}}" />
+                <Event Name="Clicked" Function="SettingsMenu.SettingsControlsButton_clicked"/>
+            </Window>
+            <Window Type="MenuWidgets/Button" Name="orxonox/GraphicsButton" >
+                <Property Name="Text" Value="Graphics" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.55,0},{0.181818,0},{0.95,0},{0.363636,0}}" />
+                <Event Name="Clicked" Function="SettingsMenu.SettingsGraphicsButton_clicked"/>
+            </Window>
+            <Window Type="MenuWidgets/Button" Name="orxonox/AudioButton" >
+                <Property Name="Text" Value="Audio" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.55,0},{0.454545,0},{0.95,0},{0.636363,0}}" />
+                <Event Name="Clicked" Function="SettingsMenu.SettingsAudioButton_clicked"/>
+            </Window>
+            <Window Type="MenuWidgets/Button" Name="orxonox/ResetSettingsButton" >
+                <Property Name="Text" Value="Reset settings" />
+                <Property Name="Disabled" Value="True" />
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.55,0},{0.727272,0},{0.95,0},{0.909090,0}}" />
+                <Event Name="Clicked" Function="SettingsMenu.SettingsResetSettingsButton_clicked"/>
+            </Window>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/SettingsBackButton" >
+            <Property Name="Text" Value="Back" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.4,0},{0.6625,0},{0.6,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="SettingsMenu.SettingsBackButton_clicked"/>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/layouts/SingleplayerMenu.layout
===================================================================
--- /code/branches/rocket2/data/gui/layouts/SingleplayerMenu.layout	(revision 6952)
+++ /code/branches/rocket2/data/gui/layouts/SingleplayerMenu.layout	(revision 6952)
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<GUILayout >
+    <Window Type="MenuWidgets/StaticImage" Name="orxonox/SingleplayerBackground" >
+        <Property Name="FrameEnabled" Value="False" />
+        <Property Name="InheritsAlpha" Value="False" />
+        <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+        <Property Name="UnifiedAreaRect" Value="{{0,0},{0,0},{1,0},{1,0}}" />
+        <Property Name="BackgroundEnabled" Value="False" />
+        <Window Type="MenuWidgets/StaticText" Name="orxonox/SingleplayerWindow" >
+            <Property Name="Text" Value="Singleplayer" />
+            <Property Name="Alpha" Value="0.8" />
+            <Property Name="InheritsAlpha" Value="False" />
+            <Property Name="HorzFormatting" Value="HorzCentred" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="VertFormatting" Value="TopAligned" />
+            <Property Name="UnifiedAreaRect" Value="{{0.25,0},{0.2875,0},{0.75,0},{0.6375,0}}" />
+            <Window Type="MenuWidgets/Listbox" Name="orxonox/SingleplayerLevelListbox" >
+                <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+                <Property Name="UnifiedAreaRect" Value="{{0.05,0},{0.15,0},{0.95,0},{0.92,0}}" />
+            </Window>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/SingleplayerStartButton" >
+            <Property Name="Text" Value="Start" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.2875,0},{0.6625,0},{0.4875,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="SingleplayerMenu.SingleplayerStartButton_clicked"/>
+        </Window>
+        <Window Type="MenuWidgets/Button" Name="orxonox/SingleplayerBackButton" >
+            <Property Name="Text" Value="Back" />
+            <Property Name="UnifiedMaxSize" Value="{{1,0},{1,0}}" />
+            <Property Name="UnifiedAreaRect" Value="{{0.5125,0},{0.6625,0},{0.7125,0},{0.7125,0}}" />
+            <Event Name="Clicked" Function="SingleplayerMenu.SingleplayerBackButton_clicked"/>
+        </Window>
+    </Window>
+</GUILayout>
Index: /code/branches/rocket2/data/gui/schemes/GUIScheme.xsd
===================================================================
--- /code/branches/rocket2/data/gui/schemes/GUIScheme.xsd	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/GUIScheme.xsd	(revision 6952)
@@ -0,0 +1,54 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+	<xsd:element name="GUIScheme" type="SchemeType" />
+	<xsd:complexType name="SchemeType">
+        <xsd:choice minOccurs="0" maxOccurs="unbounded">
+			<xsd:element name="Imageset" type="NamedDataType" />
+            <xsd:element name="ImagesetFromImage" type="NamedDataType" />
+			<xsd:element name="Font" type="NamedDataType" />
+            <xsd:element name="LookNFeel" type="FileDataType" />
+			<xsd:element name="WindowSet" type="WindowSetType" />
+			<xsd:element name="WindowRendererSet" type="WindowRendererSetType" />
+			<xsd:element name="WindowAlias" type="WindowAliasType" />
+            <xsd:element name="FalagardMapping" type="FalagardMapType" />
+		</xsd:choice>
+		<xsd:attribute name="Name" type="xsd:string" use="required" />
+	</xsd:complexType>
+	<xsd:complexType name="WindowSetType">
+		<xsd:sequence>
+            <xsd:element name="WindowFactory" type="WindowFactoryType" minOccurs="0" maxOccurs="unbounded" />
+		</xsd:sequence>
+		<xsd:attribute name="Filename" type="xsd:string" use="required" />
+	</xsd:complexType>
+	<xsd:complexType name="WindowRendererSetType">
+		<xsd:sequence>
+            <xsd:element name="WindowRendererFactory" type="WindowRendererFactoryType" minOccurs="0" maxOccurs="unbounded" />
+		</xsd:sequence>
+		<xsd:attribute name="Filename" type="xsd:string" use="required" />
+	</xsd:complexType>
+    <xsd:complexType name="FileDataType">
+        <xsd:attribute name="Filename" type="xsd:string" use="required" />
+        <xsd:attribute name="ResourceGroup" type="xsd:string" use="optional"  default="" />
+    </xsd:complexType>
+	<xsd:complexType name="NamedDataType">
+		<xsd:attribute name="Name" type="xsd:string" use="required" />
+		<xsd:attribute name="Filename" type="xsd:string" use="required" />
+		<xsd:attribute name="ResourceGroup" type="xsd:string" use="optional"  default="" />
+	</xsd:complexType>
+	<xsd:complexType name="WindowFactoryType">
+		<xsd:attribute name="Name" type="xsd:string" use="required" />
+	</xsd:complexType>
+	<xsd:complexType name="WindowRendererFactoryType">
+		<xsd:attribute name="Name" type="xsd:string" use="required" />
+	</xsd:complexType>
+	<xsd:complexType name="WindowAliasType">
+		<xsd:attribute name="Alias" type="xsd:string" use="required" />
+		<xsd:attribute name="Target" type="xsd:string" use="required" />
+	</xsd:complexType>
+    <xsd:complexType name="FalagardMapType">
+        <xsd:attribute name="WindowType" type="xsd:string" use="required" />
+        <xsd:attribute name="TargetType" type="xsd:string" use="required" />
+		<xsd:attribute name="Renderer" type="xsd:string" use="required" />
+        <xsd:attribute name="LookNFeel" type="xsd:string" use="required" />
+    </xsd:complexType>
+</xsd:schema>
Index: /code/branches/rocket2/data/gui/schemes/Looks.txt
===================================================================
--- /code/branches/rocket2/data/gui/schemes/Looks.txt	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/Looks.txt	(revision 6952)
@@ -0,0 +1,28 @@
+We use TaharezLook as default and reference. That means each new look ideally
+has to implement all widgets from TaharezLook except 4 (see below).
+If not, please use the Taharez version in the look files.
+
+
+*******
+*LOOKS*
+*******
+
+Taharez
+'''''''
+Missing   :
+Additional: AlternateProgressBar, LargeVerticalScrollbar,
+            LargeVerticalScrollbarThumb
+
+Windows
+'''''''
+Missing   : ComboEditbox, ImageButton, Tree
+Additional: IconButton, Static
+
+SleekSpace
+''''''''''
+LookNFeel file does not yet work with CEGUI > 0.4 because of missing property
+definitions.
+
+Vanilla
+'''''''
+LookNFeel file also misses some property definitions.
Index: /code/branches/rocket2/data/gui/schemes/OrxonoxGUIScheme.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/OrxonoxGUIScheme.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/OrxonoxGUIScheme.scheme	(revision 6952)
@@ -0,0 +1,9 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="OrxonoxGUI">
+    <Imageset Name="MainMenuBackground" Filename="MainMenuBackground.imageset"/>
+    <Imageset Name="PickupInventory" Filename="PickupInventory.imageset"/>
+    <Font Name="BlueHighway-12" Filename="bluehighway-12.font" />
+    <Font Name="BlueHighway-10" Filename="bluehighway-10.font" />
+    <Font Name="BlueHighway-8"  Filename="bluehighway-8.font"  />
+    <Font Name="Monofur-10"     Filename="Monofur-10.font" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/SleekSpaceHUDWidgets.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/SleekSpaceHUDWidgets.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/SleekSpaceHUDWidgets.scheme	(revision 6952)
@@ -0,0 +1,42 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="SleekSpaceHUDWidgets">
+    <WindowAlias Alias="HUDWidgets/StaticImage"              Target="SleekSpace/StaticImage" />
+    <WindowAlias Alias="HUDWidgets/StaticText"               Target="SleekSpace/StaticText" />
+    <WindowAlias Alias="HUDWidgets/TabButtonPane"            Target="SleekSpace/TabButtonPane" />
+    <WindowAlias Alias="HUDWidgets/TabContentPane"           Target="SleekSpace/TabContentPane" />
+    <WindowAlias Alias="HUDWidgets/Checkbox"                 Target="SleekSpace/Checkbox" />
+    <WindowAlias Alias="HUDWidgets/Combobox"                 Target="SleekSpace/Combobox" />
+    <WindowAlias Alias="HUDWidgets/ComboDropList"            Target="SleekSpace/ComboDropList" />
+    <WindowAlias Alias="HUDWidgets/ComboEditbox"             Target="SleekSpace/ComboEditbox" />
+    <WindowAlias Alias="HUDWidgets/Editbox"                  Target="SleekSpace/Editbox" />
+    <WindowAlias Alias="HUDWidgets/FrameWindow"              Target="SleekSpace/FrameWindow" />
+    <WindowAlias Alias="HUDWidgets/GroupBox"                 Target="SleekSpace/GroupBox" />
+    <WindowAlias Alias="HUDWidgets/ItemListbox"              Target="SleekSpace/ItemListbox" />
+    <WindowAlias Alias="HUDWidgets/ListboxItem"              Target="SleekSpace/ListboxItem" />
+    <WindowAlias Alias="HUDWidgets/Listbox"                  Target="SleekSpace/Listbox" />
+    <WindowAlias Alias="HUDWidgets/ListHeader"               Target="SleekSpace/ListHeader" />
+    <WindowAlias Alias="HUDWidgets/ListHeaderSegment"        Target="SleekSpace/ListHeaderSegment" />
+    <WindowAlias Alias="HUDWidgets/MultiLineEditbox"         Target="SleekSpace/MultiLineEditbox" />
+    <WindowAlias Alias="HUDWidgets/Menubar"                  Target="SleekSpace/Menubar" />
+    <WindowAlias Alias="HUDWidgets/MenuItem"                 Target="SleekSpace/MenuItem" />
+    <WindowAlias Alias="HUDWidgets/MultiColumnList"          Target="SleekSpace/MultiColumnList" />
+    <WindowAlias Alias="HUDWidgets/PopupMenu"                Target="SleekSpace/PopupMenu" />
+    <WindowAlias Alias="HUDWidgets/ProgressBar"              Target="SleekSpace/ProgressBar" />
+    <WindowAlias Alias="HUDWidgets/Button"                   Target="SleekSpace/Button" />
+    <WindowAlias Alias="HUDWidgets/ImageButton"              Target="SleekSpace/ImageButton" />
+    <WindowAlias Alias="HUDWidgets/RadioButton"              Target="SleekSpace/RadioButton" />
+    <WindowAlias Alias="HUDWidgets/SystemButton"             Target="SleekSpace/SystemButton" />
+    <WindowAlias Alias="HUDWidgets/ScrollablePane"           Target="SleekSpace/ScrollablePane" />
+    <WindowAlias Alias="HUDWidgets/HorizontalScrollbar"      Target="SleekSpace/HorizontalScrollbar" />
+    <WindowAlias Alias="HUDWidgets/VerticalScrollbar"        Target="SleekSpace/VerticalScrollbar" />
+    <WindowAlias Alias="HUDWidgets/Slider"                   Target="SleekSpace/Slider" />
+    <WindowAlias Alias="HUDWidgets/Spinner"                  Target="SleekSpace/Spinner" />
+    <WindowAlias Alias="HUDWidgets/TabButton"                Target="SleekSpace/TabButton" />
+    <WindowAlias Alias="HUDWidgets/TabControl"               Target="SleekSpace/TabControl" />
+    <WindowAlias Alias="HUDWidgets/HorizontalScrollbarThumb" Target="SleekSpace/HorizontalScrollbarThumb" />
+    <WindowAlias Alias="HUDWidgets/SliderThumb"              Target="SleekSpace/SliderThumb" />
+    <WindowAlias Alias="HUDWidgets/VerticalScrollbarThumb"   Target="SleekSpace/VerticalScrollbarThumb" />
+    <WindowAlias Alias="HUDWidgets/Titlebar"                 Target="SleekSpace/Titlebar" />
+    <WindowAlias Alias="HUDWidgets/Tooltip"                  Target="SleekSpace/Tooltip" />
+    <WindowAlias Alias="HUDWidgets/Tree"                     Target="SleekSpace/Tree" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/SleekSpaceLook.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/SleekSpaceLook.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/SleekSpaceLook.scheme	(revision 6952)
@@ -0,0 +1,61 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="SleekSpaceLook">
+    <Imageset Name="SleekSpace" Filename="SleekSpace.imageset" />
+    <Imageset Name="TaharezLook" Filename="TaharezLook.imageset" />
+    <LookNFeel Filename="SleekSpace.looknfeel" />
+    <LookNFeel Filename="TaharezLook.looknfeel" />
+    <WindowRendererSet Filename="CEGUIFalagardWRBase" />
+
+    <!-- Standard widgets -->
+    <FalagardMapping WindowType="SleekSpace/StaticImage"                 TargetType="DefaultWindow"           Renderer="Falagard/StaticImage"       LookNFeel="SleekSpace/StaticImage" />
+    <FalagardMapping WindowType="SleekSpace/StaticText"                  TargetType="DefaultWindow"           Renderer="Falagard/StaticText"        LookNFeel="SleekSpace/StaticText" />
+    <FalagardMapping WindowType="SleekSpace/Checkbox"                    TargetType="CEGUI/Checkbox"          Renderer="Falagard/ToggleButton"      LookNFeel="SleekSpace/Checkbox" />
+    <FalagardMapping WindowType="SleekSpace/Combobox"                    TargetType="CEGUI/Combobox"          Renderer="Falagard/Default"           LookNFeel="SleekSpace/Combobox" />
+    <FalagardMapping WindowType="SleekSpace/ComboDropList"               TargetType="CEGUI/ComboDropList"     Renderer="Falagard/Listbox"           LookNFeel="SleekSpace/ComboDropList" />
+    <FalagardMapping WindowType="SleekSpace/ComboEditbox"                TargetType="CEGUI/Editbox"           Renderer="Falagard/Editbox"           LookNFeel="SleekSpace/ComboEditbox" />
+    <FalagardMapping WindowType="SleekSpace/Editbox"                     TargetType="CEGUI/Editbox"           Renderer="Falagard/Editbox"           LookNFeel="SleekSpace/Editbox" />
+    <FalagardMapping WindowType="SleekSpace/FrameWindow"                 TargetType="CEGUI/FrameWindow"       Renderer="Falagard/FrameWindow"       LookNFeel="SleekSpace/FrameWindow" />
+    <FalagardMapping WindowType="SleekSpace/Listbox"                     TargetType="CEGUI/Listbox"           Renderer="Falagard/Listbox"           LookNFeel="SleekSpace/Listbox" />
+    <FalagardMapping WindowType="SleekSpace/ListHeader"                  TargetType="CEGUI/ListHeader"        Renderer="Falagard/ListHeader"        LookNFeel="SleekSpace/ListHeader" />
+    <FalagardMapping WindowType="SleekSpace/ListHeaderSegment"           TargetType="CEGUI/ListHeaderSegment" Renderer="Falagard/ListHeaderSegment" LookNFeel="SleekSpace/ListHeaderSegment" />
+    <FalagardMapping WindowType="SleekSpace/MultiLineEditbox"            TargetType="CEGUI/MultiLineEditbox"  Renderer="Falagard/MultiLineEditbox"  LookNFeel="SleekSpace/MultiLineEditbox" />
+    <FalagardMapping WindowType="SleekSpace/Menubar"                     TargetType="CEGUI/Menubar"           Renderer="Falagard/Menubar"           LookNFeel="SleekSpace/Menubar" />
+    <FalagardMapping WindowType="SleekSpace/MenuItem"                    TargetType="CEGUI/MenuItem"          Renderer="Falagard/MenuItem"          LookNFeel="SleekSpace/MenuItem" />
+    <FalagardMapping WindowType="SleekSpace/MultiColumnList"             TargetType="CEGUI/MultiColumnList"   Renderer="Falagard/MultiColumnList"   LookNFeel="SleekSpace/MultiColumnList" />
+    <FalagardMapping WindowType="SleekSpace/PopupMenu"                   TargetType="CEGUI/PopupMenu"         Renderer="Falagard/PopupMenu"         LookNFeel="SleekSpace/PopupMenu" />
+    <FalagardMapping WindowType="SleekSpace/ProgressBar"                 TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="SleekSpace/ProgressBar" />
+    <FalagardMapping WindowType="SleekSpace/Button"                      TargetType="CEGUI/PushButton"        Renderer="Falagard/Button"            LookNFeel="SleekSpace/Button" />
+    <FalagardMapping WindowType="SleekSpace/RadioButton"                 TargetType="CEGUI/RadioButton"       Renderer="Falagard/ToggleButton"      LookNFeel="SleekSpace/RadioButton" />
+    <FalagardMapping WindowType="SleekSpace/SystemButton"                TargetType="CEGUI/PushButton"        Renderer="Falagard/SystemButton"      LookNFeel="SleekSpace/Button" />
+    <FalagardMapping WindowType="SleekSpace/ScrollablePane"              TargetType="CEGUI/ScrollablePane"    Renderer="Falagard/ScrollablePane"    LookNFeel="SleekSpace/ScrollablePane" />
+    <FalagardMapping WindowType="SleekSpace/HorizontalScrollbar"         TargetType="CEGUI/Scrollbar"         Renderer="Falagard/Scrollbar"         LookNFeel="SleekSpace/HorizontalScrollbar" />
+    <FalagardMapping WindowType="SleekSpace/VerticalScrollbar"           TargetType="CEGUI/Scrollbar"         Renderer="Falagard/Scrollbar"         LookNFeel="SleekSpace/VerticalScrollbar" />
+    <FalagardMapping WindowType="SleekSpace/Slider"                      TargetType="CEGUI/Slider"            Renderer="Falagard/Slider"            LookNFeel="SleekSpace/Slider" />
+    <FalagardMapping WindowType="SleekSpace/Spinner"                     TargetType="CEGUI/Spinner"           Renderer="Falagard/Default"           LookNFeel="SleekSpace/Spinner" />
+    <FalagardMapping WindowType="SleekSpace/TabButton"                   TargetType="CEGUI/TabButton"         Renderer="Falagard/TabButton"         LookNFeel="SleekSpace/TabButton" />
+    <FalagardMapping WindowType="SleekSpace/TabControl"                  TargetType="CEGUI/TabControl"        Renderer="Falagard/TabControl"        LookNFeel="SleekSpace/TabControl" />
+    <FalagardMapping WindowType="SleekSpace/HorizontalScrollbarThumb"    TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="SleekSpace/HorizontalScrollbarThumb" />
+    <FalagardMapping WindowType="SleekSpace/SliderThumb"                 TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="SleekSpace/SliderThumb" />
+    <FalagardMapping WindowType="SleekSpace/VerticalScrollbarThumb"      TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="SleekSpace/VerticalScrollbarThumb" />
+    <FalagardMapping WindowType="SleekSpace/Titlebar"                    TargetType="CEGUI/Titlebar"          Renderer="Falagard/Titlebar"          LookNFeel="SleekSpace/Titlebar" />
+    <FalagardMapping WindowType="SleekSpace/Tooltip"                     TargetType="CEGUI/Tooltip"           Renderer="Falagard/Tooltip"           LookNFeel="SleekSpace/Tooltip" />
+    
+    <!-- Missing widgets (using Taharez LookNFeel) -->
+    <FalagardMapping WindowType="SleekSpace/TabButtonPane"               TargetType="DefaultWindow"           Renderer="Falagard/Default"           LookNFeel="TaharezLook/TabButtonPane" />
+    <FalagardMapping WindowType="SleekSpace/TabContentPane"              TargetType="DefaultWindow"           Renderer="Falagard/Default"           LookNFeel="TaharezLook/TabContentPane" />
+    <FalagardMapping WindowType="SleekSpace/GroupBox"                    TargetType="CEGUI/GroupBox"          Renderer="Falagard/Default"           LookNFeel="TaharezLook/GroupBox" />
+    <FalagardMapping WindowType="SleekSpace/ListboxItem"                 TargetType="CEGUI/ItemEntry"         Renderer="Falagard/ItemEntry"         LookNFeel="TaharezLook/ListboxItem" />
+    <FalagardMapping WindowType="SleekSpace/ItemListbox"                 TargetType="CEGUI/ItemListbox"       Renderer="Falagard/ItemListbox"       LookNFeel="TaharezLook/ItemListbox" />
+    <FalagardMapping WindowType="SleekSpace/ImageButton"                 TargetType="CEGUI/PushButton"        Renderer="Falagard/Button"            LookNFeel="TaharezLook/ImageButton" />
+    <FalagardMapping WindowType="SleekSpace/Tree"                        TargetType="CEGUI/Tree"              Renderer="Falagard/Tree"              LookNFeel="TaharezLook/Tree" />
+
+    <!-- Additional widgets -->
+    <FalagardMapping WindowType="SleekSpace/TabPane"                     TargetType="DefaultWindow"           Renderer="Falagard/TabPane"           LookNFeel="SleekSpace/TabPane" />
+    <FalagardMapping WindowType="SleekSpace/ReticleWindow"               TargetType="CEGUI/FrameWindow"       Renderer="Falagard/FrameWindow"       LookNFeel="SleekSpace/ReticleWindow" />
+    <FalagardMapping WindowType="SleekSpace/AlternateProgressBar"        TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="SleekSpace/AltProgressBar" />
+    <FalagardMapping WindowType="SleekSpace/VUMeter"                     TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="SleekSpace/VUMeter" />
+    <FalagardMapping WindowType="SleekSpace/LargeVerticalScrollbar"      TargetType="CEGUI/Scrollbar"         Renderer="Falagard/Scrollbar"         LookNFeel="SleekSpace/LargeVerticalScrollbar" />
+    <FalagardMapping WindowType="SleekSpace/VSlider"                     TargetType="CEGUI/Slider"            Renderer="Falagard/Slider"            LookNFeel="SleekSpace/VSlider" />
+    <FalagardMapping WindowType="SleekSpace/LargeVerticalScrollbarThumb" TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="SleekSpace/LargeVerticalScrollbarThumb" />
+    <FalagardMapping WindowType="SleekSpace/VSliderThumb"                TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="SleekSpace/VSliderThumb" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/SleekSpaceMenuWidgets.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/SleekSpaceMenuWidgets.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/SleekSpaceMenuWidgets.scheme	(revision 6952)
@@ -0,0 +1,42 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="SleekSpaceMenuWidgets">
+    <WindowAlias Alias="MenuWidgets/StaticImage"              Target="SleekSpace/StaticImage" />
+    <WindowAlias Alias="MenuWidgets/StaticText"               Target="SleekSpace/StaticText" />
+    <WindowAlias Alias="MenuWidgets/TabButtonPane"            Target="SleekSpace/TabButtonPane" />
+    <WindowAlias Alias="MenuWidgets/TabContentPane"           Target="SleekSpace/TabContentPane" />
+    <WindowAlias Alias="MenuWidgets/Checkbox"                 Target="SleekSpace/Checkbox" />
+    <WindowAlias Alias="MenuWidgets/Combobox"                 Target="SleekSpace/Combobox" />
+    <WindowAlias Alias="MenuWidgets/ComboDropList"            Target="SleekSpace/ComboDropList" />
+    <WindowAlias Alias="MenuWidgets/ComboEditbox"             Target="SleekSpace/ComboEditbox" />
+    <WindowAlias Alias="MenuWidgets/Editbox"                  Target="SleekSpace/Editbox" />
+    <WindowAlias Alias="MenuWidgets/FrameWindow"              Target="SleekSpace/FrameWindow" />
+    <WindowAlias Alias="MenuWidgets/GroupBox"                 Target="SleekSpace/GroupBox" />
+    <WindowAlias Alias="MenuWidgets/ItemListbox"              Target="SleekSpace/ItemListbox" />
+    <WindowAlias Alias="MenuWidgets/ListboxItem"              Target="SleekSpace/ListboxItem" />
+    <WindowAlias Alias="MenuWidgets/Listbox"                  Target="SleekSpace/Listbox" />
+    <WindowAlias Alias="MenuWidgets/ListHeader"               Target="SleekSpace/ListHeader" />
+    <WindowAlias Alias="MenuWidgets/ListHeaderSegment"        Target="SleekSpace/ListHeaderSegment" />
+    <WindowAlias Alias="MenuWidgets/MultiLineEditbox"         Target="SleekSpace/MultiLineEditbox" />
+    <WindowAlias Alias="MenuWidgets/Menubar"                  Target="SleekSpace/Menubar" />
+    <WindowAlias Alias="MenuWidgets/MenuItem"                 Target="SleekSpace/MenuItem" />
+    <WindowAlias Alias="MenuWidgets/MultiColumnList"          Target="SleekSpace/MultiColumnList" />
+    <WindowAlias Alias="MenuWidgets/PopupMenu"                Target="SleekSpace/PopupMenu" />
+    <WindowAlias Alias="MenuWidgets/ProgressBar"              Target="SleekSpace/ProgressBar" />
+    <WindowAlias Alias="MenuWidgets/Button"                   Target="SleekSpace/Button" />
+    <WindowAlias Alias="MenuWidgets/ImageButton"              Target="SleekSpace/ImageButton" />
+    <WindowAlias Alias="MenuWidgets/RadioButton"              Target="SleekSpace/RadioButton" />
+    <WindowAlias Alias="MenuWidgets/SystemButton"             Target="SleekSpace/SystemButton" />
+    <WindowAlias Alias="MenuWidgets/ScrollablePane"           Target="SleekSpace/ScrollablePane" />
+    <WindowAlias Alias="MenuWidgets/HorizontalScrollbar"      Target="SleekSpace/HorizontalScrollbar" />
+    <WindowAlias Alias="MenuWidgets/VerticalScrollbar"        Target="SleekSpace/VerticalScrollbar" />
+    <WindowAlias Alias="MenuWidgets/Slider"                   Target="SleekSpace/Slider" />
+    <WindowAlias Alias="MenuWidgets/Spinner"                  Target="SleekSpace/Spinner" />
+    <WindowAlias Alias="MenuWidgets/TabButton"                Target="SleekSpace/TabButton" />
+    <WindowAlias Alias="MenuWidgets/TabControl"               Target="SleekSpace/TabControl" />
+    <WindowAlias Alias="MenuWidgets/HorizontalScrollbarThumb" Target="SleekSpace/HorizontalScrollbarThumb" />
+    <WindowAlias Alias="MenuWidgets/SliderThumb"              Target="SleekSpace/SliderThumb" />
+    <WindowAlias Alias="MenuWidgets/VerticalScrollbarThumb"   Target="SleekSpace/VerticalScrollbarThumb" />
+    <WindowAlias Alias="MenuWidgets/Titlebar"                 Target="SleekSpace/Titlebar" />
+    <WindowAlias Alias="MenuWidgets/Tooltip"                  Target="SleekSpace/Tooltip" />
+    <WindowAlias Alias="MenuWidgets/Tree"                     Target="SleekSpace/Tree" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/TaharezGreenHUDWidgets.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/TaharezGreenHUDWidgets.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/TaharezGreenHUDWidgets.scheme	(revision 6952)
@@ -0,0 +1,42 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="TaharezGreenHUDWidgets">
+    <WindowAlias Alias="HUDWidgets/StaticImage"              Target="TaharezGreenLook/StaticImage" />
+    <WindowAlias Alias="HUDWidgets/StaticText"               Target="TaharezGreenLook/StaticText" />
+    <WindowAlias Alias="HUDWidgets/TabButtonPane"            Target="TaharezGreenLook/TabButtonPane" />
+    <WindowAlias Alias="HUDWidgets/TabContentPane"           Target="TaharezGreenLook/TabContentPane" />
+    <WindowAlias Alias="HUDWidgets/Checkbox"                 Target="TaharezGreenLook/Checkbox" />
+    <WindowAlias Alias="HUDWidgets/Combobox"                 Target="TaharezGreenLook/Combobox" />
+    <WindowAlias Alias="HUDWidgets/ComboDropList"            Target="TaharezGreenLook/ComboDropList" />
+    <WindowAlias Alias="HUDWidgets/ComboEditbox"             Target="TaharezGreenLook/ComboEditbox" />
+    <WindowAlias Alias="HUDWidgets/Editbox"                  Target="TaharezGreenLook/Editbox" />
+    <WindowAlias Alias="HUDWidgets/FrameWindow"              Target="TaharezGreenLook/FrameWindow" />
+    <WindowAlias Alias="HUDWidgets/GroupBox"                 Target="TaharezGreenLook/GroupBox" />
+    <WindowAlias Alias="HUDWidgets/ItemListbox"              Target="TaharezGreenLook/ItemListbox" />
+    <WindowAlias Alias="HUDWidgets/ListboxItem"              Target="TaharezGreenLook/ListboxItem" />
+    <WindowAlias Alias="HUDWidgets/Listbox"                  Target="TaharezGreenLook/Listbox" />
+    <WindowAlias Alias="HUDWidgets/ListHeader"               Target="TaharezGreenLook/ListHeader" />
+    <WindowAlias Alias="HUDWidgets/ListHeaderSegment"        Target="TaharezGreenLook/ListHeaderSegment" />
+    <WindowAlias Alias="HUDWidgets/MultiLineEditbox"         Target="TaharezGreenLook/MultiLineEditbox" />
+    <WindowAlias Alias="HUDWidgets/Menubar"                  Target="TaharezGreenLook/Menubar" />
+    <WindowAlias Alias="HUDWidgets/MenuItem"                 Target="TaharezGreenLook/MenuItem" />
+    <WindowAlias Alias="HUDWidgets/MultiColumnList"          Target="TaharezGreenLook/MultiColumnList" />
+    <WindowAlias Alias="HUDWidgets/PopupMenu"                Target="TaharezGreenLook/PopupMenu" />
+    <WindowAlias Alias="HUDWidgets/ProgressBar"              Target="TaharezGreenLook/ProgressBar" />
+    <WindowAlias Alias="HUDWidgets/Button"                   Target="TaharezGreenLook/Button" />
+    <WindowAlias Alias="HUDWidgets/ImageButton"              Target="TaharezGreenLook/ImageButton" />
+    <WindowAlias Alias="HUDWidgets/RadioButton"              Target="TaharezGreenLook/RadioButton" />
+    <WindowAlias Alias="HUDWidgets/SystemButton"             Target="TaharezGreenLook/SystemButton" />
+    <WindowAlias Alias="HUDWidgets/ScrollablePane"           Target="TaharezGreenLook/ScrollablePane" />
+    <WindowAlias Alias="HUDWidgets/HorizontalScrollbar"      Target="TaharezGreenLook/HorizontalScrollbar" />
+    <WindowAlias Alias="HUDWidgets/VerticalScrollbar"        Target="TaharezGreenLook/VerticalScrollbar" />
+    <WindowAlias Alias="HUDWidgets/Slider"                   Target="TaharezGreenLook/Slider" />
+    <WindowAlias Alias="HUDWidgets/Spinner"                  Target="TaharezGreenLook/Spinner" />
+    <WindowAlias Alias="HUDWidgets/TabButton"                Target="TaharezGreenLook/TabButton" />
+    <WindowAlias Alias="HUDWidgets/TabControl"               Target="TaharezGreenLook/TabControl" />
+    <WindowAlias Alias="HUDWidgets/HorizontalScrollbarThumb" Target="TaharezGreenLook/HorizontalScrollbarThumb" />
+    <WindowAlias Alias="HUDWidgets/SliderThumb"              Target="TaharezGreenLook/SliderThumb" />
+    <WindowAlias Alias="HUDWidgets/VerticalScrollbarThumb"   Target="TaharezGreenLook/VerticalScrollbarThumb" />
+    <WindowAlias Alias="HUDWidgets/Titlebar"                 Target="TaharezGreenLook/Titlebar" />
+    <WindowAlias Alias="HUDWidgets/Tooltip"                  Target="TaharezGreenLook/Tooltip" />
+    <WindowAlias Alias="HUDWidgets/Tree"                     Target="TaharezGreenLook/Tree" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/TaharezGreenLook.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/TaharezGreenLook.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/TaharezGreenLook.scheme	(revision 6952)
@@ -0,0 +1,53 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="TaharezGreenLook">
+	<Imageset Name="TaharezGreenLook" Filename="TaharezGreenLook.imageset" />
+	<LookNFeel Filename="TaharezGreenLook.looknfeel" />
+	<WindowRendererSet Filename="CEGUIFalagardWRBase" />
+
+    <!-- Standard widgets -->
+    <FalagardMapping WindowType="TaharezGreenLook/StaticImage"              TargetType="DefaultWindow"           Renderer="Falagard/StaticImage"       LookNFeel="TaharezGreenLook/StaticImage" />
+    <FalagardMapping WindowType="TaharezGreenLook/StaticText"               TargetType="DefaultWindow"           Renderer="Falagard/StaticText"        LookNFeel="TaharezGreenLook/StaticText" />
+    <FalagardMapping WindowType="TaharezGreenLook/TabButtonPane"            TargetType="DefaultWindow"           Renderer="Falagard/Default"           LookNFeel="TaharezGreenLook/TabButtonPane" />
+    <FalagardMapping WindowType="TaharezGreenLook/TabContentPane"           TargetType="DefaultWindow"           Renderer="Falagard/Default"           LookNFeel="TaharezGreenLook/TabContentPane" />
+    <FalagardMapping WindowType="TaharezGreenLook/Checkbox"                 TargetType="CEGUI/Checkbox"          Renderer="Falagard/ToggleButton"      LookNFeel="TaharezGreenLook/Checkbox" />
+    <FalagardMapping WindowType="TaharezGreenLook/Combobox"                 TargetType="CEGUI/Combobox"          Renderer="Falagard/Default"           LookNFeel="TaharezGreenLook/Combobox" />
+    <FalagardMapping WindowType="TaharezGreenLook/ComboDropList"            TargetType="CEGUI/ComboDropList"     Renderer="Falagard/Listbox"           LookNFeel="TaharezGreenLook/ComboDropList" />
+    <FalagardMapping WindowType="TaharezGreenLook/ComboEditbox"             TargetType="CEGUI/Editbox"           Renderer="Falagard/Editbox"           LookNFeel="TaharezGreenLook/ComboEditbox" />
+    <FalagardMapping WindowType="TaharezGreenLook/Editbox"                  TargetType="CEGUI/Editbox"           Renderer="Falagard/Editbox"           LookNFeel="TaharezGreenLook/Editbox" />
+    <FalagardMapping WindowType="TaharezGreenLook/FrameWindow"              TargetType="CEGUI/FrameWindow"       Renderer="Falagard/FrameWindow"       LookNFeel="TaharezGreenLook/FrameWindow" />
+    <FalagardMapping WindowType="TaharezGreenLook/GroupBox"                 TargetType="CEGUI/GroupBox"          Renderer="Falagard/Default"           LookNFeel="TaharezGreenLook/GroupBox" />
+    <FalagardMapping WindowType="TaharezGreenLook/ItemListbox"              TargetType="CEGUI/ItemListbox"       Renderer="Falagard/ItemListbox"       LookNFeel="TaharezGreenLook/ItemListbox" />
+    <FalagardMapping WindowType="TaharezGreenLook/ListboxItem"              TargetType="CEGUI/ItemEntry"         Renderer="Falagard/ItemEntry"         LookNFeel="TaharezGreenLook/ListboxItem" />
+    <FalagardMapping WindowType="TaharezGreenLook/Listbox"                  TargetType="CEGUI/Listbox"           Renderer="Falagard/Listbox"           LookNFeel="TaharezGreenLook/Listbox" />
+    <FalagardMapping WindowType="TaharezGreenLook/ListHeader"               TargetType="CEGUI/ListHeader"        Renderer="Falagard/ListHeader"        LookNFeel="TaharezGreenLook/ListHeader" />
+    <FalagardMapping WindowType="TaharezGreenLook/ListHeaderSegment"        TargetType="CEGUI/ListHeaderSegment" Renderer="Falagard/ListHeaderSegment" LookNFeel="TaharezGreenLook/ListHeaderSegment" />
+    <FalagardMapping WindowType="TaharezGreenLook/MultiLineEditbox"         TargetType="CEGUI/MultiLineEditbox"  Renderer="Falagard/MultiLineEditbox"  LookNFeel="TaharezGreenLook/MultiLineEditbox" />
+    <FalagardMapping WindowType="TaharezGreenLook/Menubar"                  TargetType="CEGUI/Menubar"           Renderer="Falagard/Menubar"           LookNFeel="TaharezGreenLook/Menubar" />
+    <FalagardMapping WindowType="TaharezGreenLook/MenuItem"                 TargetType="CEGUI/MenuItem"          Renderer="Falagard/MenuItem"          LookNFeel="TaharezGreenLook/MenuItem" />
+    <FalagardMapping WindowType="TaharezGreenLook/MultiColumnList"          TargetType="CEGUI/MultiColumnList"   Renderer="Falagard/MultiColumnList"   LookNFeel="TaharezGreenLook/MultiColumnList" />
+    <FalagardMapping WindowType="TaharezGreenLook/PopupMenu"                TargetType="CEGUI/PopupMenu"         Renderer="Falagard/PopupMenu"         LookNFeel="TaharezGreenLook/PopupMenu" />
+    <FalagardMapping WindowType="TaharezGreenLook/ProgressBar"              TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="TaharezGreenLook/ProgressBar" />
+    <FalagardMapping WindowType="TaharezGreenLook/Button"                   TargetType="CEGUI/PushButton"        Renderer="Falagard/Button"            LookNFeel="TaharezGreenLook/Button" />
+    <FalagardMapping WindowType="TaharezGreenLook/ImageButton"              TargetType="CEGUI/PushButton"        Renderer="Falagard/Button"            LookNFeel="TaharezGreenLook/ImageButton" />
+    <FalagardMapping WindowType="TaharezGreenLook/RadioButton"              TargetType="CEGUI/RadioButton"       Renderer="Falagard/ToggleButton"      LookNFeel="TaharezGreenLook/RadioButton" />
+    <FalagardMapping WindowType="TaharezGreenLook/SystemButton"             TargetType="CEGUI/PushButton"        Renderer="Falagard/SystemButton"      LookNFeel="TaharezGreenLook/Button" />
+    <FalagardMapping WindowType="TaharezGreenLook/ScrollablePane"           TargetType="CEGUI/ScrollablePane"    Renderer="Falagard/ScrollablePane"    LookNFeel="TaharezGreenLook/ScrollablePane" />
+    <FalagardMapping WindowType="TaharezGreenLook/HorizontalScrollbar"      TargetType="CEGUI/Scrollbar"         Renderer="Falagard/Scrollbar"         LookNFeel="TaharezGreenLook/HorizontalScrollbar" />
+    <FalagardMapping WindowType="TaharezGreenLook/VerticalScrollbar"        TargetType="CEGUI/Scrollbar"         Renderer="Falagard/Scrollbar"         LookNFeel="TaharezGreenLook/VerticalScrollbar" />
+    <FalagardMapping WindowType="TaharezGreenLook/Slider"                   TargetType="CEGUI/Slider"            Renderer="Falagard/Slider"            LookNFeel="TaharezGreenLook/Slider" />
+    <FalagardMapping WindowType="TaharezGreenLook/Spinner"                  TargetType="CEGUI/Spinner"           Renderer="Falagard/Default"           LookNFeel="TaharezGreenLook/Spinner" />
+    <FalagardMapping WindowType="TaharezGreenLook/TabButton"                TargetType="CEGUI/TabButton"         Renderer="Falagard/TabButton"         LookNFeel="TaharezGreenLook/TabButton" />
+    <FalagardMapping WindowType="TaharezGreenLook/TabControl"               TargetType="CEGUI/TabControl"        Renderer="Falagard/TabControl"        LookNFeel="TaharezGreenLook/TabControl" />
+    <FalagardMapping WindowType="TaharezGreenLook/HorizontalScrollbarThumb" TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="TaharezGreenLook/HorizontalScrollbarThumb" />
+    <FalagardMapping WindowType="TaharezGreenLook/SliderThumb"              TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="TaharezGreenLook/SliderThumb" />
+    <FalagardMapping WindowType="TaharezGreenLook/VerticalScrollbarThumb"   TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="TaharezGreenLook/VerticalScrollbarThumb" />
+    <FalagardMapping WindowType="TaharezGreenLook/Titlebar"                 TargetType="CEGUI/Titlebar"          Renderer="Falagard/Titlebar"          LookNFeel="TaharezGreenLook/Titlebar" />
+    <FalagardMapping WindowType="TaharezGreenLook/Tooltip"                  TargetType="CEGUI/Tooltip"           Renderer="Falagard/Tooltip"           LookNFeel="TaharezGreenLook/Tooltip" />
+    <FalagardMapping WindowType="TaharezGreenLook/Tree"                     TargetType="CEGUI/Tree"              Renderer="Falagard/Tree"              LookNFeel="TaharezGreenLook/Tree" />
+    
+    <!-- Additional widgets -->
+    <FalagardMapping WindowType="TaharezGreenLook/AlternateProgressBar"        TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="TaharezGreenLook/AltProgressBar" />
+    <FalagardMapping WindowType="TaharezGreenLook/VUMeter"                     TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="TaharezGreenLook/VUMeter" />
+    <FalagardMapping WindowType="TaharezGreenLook/LargeVerticalScrollbar"      TargetType="CEGUI/Scrollbar"         Renderer="Falagard/Scrollbar"         LookNFeel="TaharezGreenLook/LargeVerticalScrollbar" />
+    <FalagardMapping WindowType="TaharezGreenLook/LargeVerticalScrollbarThumb" TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="TaharezGreenLook/LargeVerticalScrollbarThumb" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/TaharezGreenMenuWidgets.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/TaharezGreenMenuWidgets.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/TaharezGreenMenuWidgets.scheme	(revision 6952)
@@ -0,0 +1,42 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="TaharezGreenMenuWidgets">
+    <WindowAlias Alias="MenuWidgets/StaticImage"              Target="TaharezGreenLook/StaticImage" />
+    <WindowAlias Alias="MenuWidgets/StaticText"               Target="TaharezGreenLook/StaticText" />
+    <WindowAlias Alias="MenuWidgets/TabButtonPane"            Target="TaharezGreenLook/TabButtonPane" />
+    <WindowAlias Alias="MenuWidgets/TabContentPane"           Target="TaharezGreenLook/TabContentPane" />
+    <WindowAlias Alias="MenuWidgets/Checkbox"                 Target="TaharezGreenLook/Checkbox" />
+    <WindowAlias Alias="MenuWidgets/Combobox"                 Target="TaharezGreenLook/Combobox" />
+    <WindowAlias Alias="MenuWidgets/ComboDropList"            Target="TaharezGreenLook/ComboDropList" />
+    <WindowAlias Alias="MenuWidgets/ComboEditbox"             Target="TaharezGreenLook/ComboEditbox" />
+    <WindowAlias Alias="MenuWidgets/Editbox"                  Target="TaharezGreenLook/Editbox" />
+    <WindowAlias Alias="MenuWidgets/FrameWindow"              Target="TaharezGreenLook/FrameWindow" />
+    <WindowAlias Alias="MenuWidgets/GroupBox"                 Target="TaharezGreenLook/GroupBox" />
+    <WindowAlias Alias="MenuWidgets/ItemListbox"              Target="TaharezGreenLook/ItemListbox" />
+    <WindowAlias Alias="MenuWidgets/ListboxItem"              Target="TaharezGreenLook/ListboxItem" />
+    <WindowAlias Alias="MenuWidgets/Listbox"                  Target="TaharezGreenLook/Listbox" />
+    <WindowAlias Alias="MenuWidgets/ListHeader"               Target="TaharezGreenLook/ListHeader" />
+    <WindowAlias Alias="MenuWidgets/ListHeaderSegment"        Target="TaharezGreenLook/ListHeaderSegment" />
+    <WindowAlias Alias="MenuWidgets/MultiLineEditbox"         Target="TaharezGreenLook/MultiLineEditbox" />
+    <WindowAlias Alias="MenuWidgets/Menubar"                  Target="TaharezGreenLook/Menubar" />
+    <WindowAlias Alias="MenuWidgets/MenuItem"                 Target="TaharezGreenLook/MenuItem" />
+    <WindowAlias Alias="MenuWidgets/MultiColumnList"          Target="TaharezGreenLook/MultiColumnList" />
+    <WindowAlias Alias="MenuWidgets/PopupMenu"                Target="TaharezGreenLook/PopupMenu" />
+    <WindowAlias Alias="MenuWidgets/ProgressBar"              Target="TaharezGreenLook/ProgressBar" />
+    <WindowAlias Alias="MenuWidgets/Button"                   Target="TaharezGreenLook/Button" />
+    <WindowAlias Alias="MenuWidgets/ImageButton"              Target="TaharezGreenLook/ImageButton" />
+    <WindowAlias Alias="MenuWidgets/RadioButton"              Target="TaharezGreenLook/RadioButton" />
+    <WindowAlias Alias="MenuWidgets/SystemButton"             Target="TaharezGreenLook/SystemButton" />
+    <WindowAlias Alias="MenuWidgets/ScrollablePane"           Target="TaharezGreenLook/ScrollablePane" />
+    <WindowAlias Alias="MenuWidgets/HorizontalScrollbar"      Target="TaharezGreenLook/HorizontalScrollbar" />
+    <WindowAlias Alias="MenuWidgets/VerticalScrollbar"        Target="TaharezGreenLook/VerticalScrollbar" />
+    <WindowAlias Alias="MenuWidgets/Slider"                   Target="TaharezGreenLook/Slider" />
+    <WindowAlias Alias="MenuWidgets/Spinner"                  Target="TaharezGreenLook/Spinner" />
+    <WindowAlias Alias="MenuWidgets/TabButton"                Target="TaharezGreenLook/TabButton" />
+    <WindowAlias Alias="MenuWidgets/TabControl"               Target="TaharezGreenLook/TabControl" />
+    <WindowAlias Alias="MenuWidgets/HorizontalScrollbarThumb" Target="TaharezGreenLook/HorizontalScrollbarThumb" />
+    <WindowAlias Alias="MenuWidgets/SliderThumb"              Target="TaharezGreenLook/SliderThumb" />
+    <WindowAlias Alias="MenuWidgets/VerticalScrollbarThumb"   Target="TaharezGreenLook/VerticalScrollbarThumb" />
+    <WindowAlias Alias="MenuWidgets/Titlebar"                 Target="TaharezGreenLook/Titlebar" />
+    <WindowAlias Alias="MenuWidgets/Tooltip"                  Target="TaharezGreenLook/Tooltip" />
+    <WindowAlias Alias="MenuWidgets/Tree"                     Target="TaharezGreenLook/Tree" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/TaharezHUDWidgets.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/TaharezHUDWidgets.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/TaharezHUDWidgets.scheme	(revision 6952)
@@ -0,0 +1,42 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="TaharezHUDWidgets">
+    <WindowAlias Alias="HUDWidgets/StaticImage"              Target="TaharezLook/StaticImage" />
+    <WindowAlias Alias="HUDWidgets/StaticText"               Target="TaharezLook/StaticText" />
+    <WindowAlias Alias="HUDWidgets/TabButtonPane"            Target="TaharezLook/TabButtonPane" />
+    <WindowAlias Alias="HUDWidgets/TabContentPane"           Target="TaharezLook/TabContentPane" />
+    <WindowAlias Alias="HUDWidgets/Checkbox"                 Target="TaharezLook/Checkbox" />
+    <WindowAlias Alias="HUDWidgets/Combobox"                 Target="TaharezLook/Combobox" />
+    <WindowAlias Alias="HUDWidgets/ComboDropList"            Target="TaharezLook/ComboDropList" />
+    <WindowAlias Alias="HUDWidgets/ComboEditbox"             Target="TaharezLook/ComboEditbox" />
+    <WindowAlias Alias="HUDWidgets/Editbox"                  Target="TaharezLook/Editbox" />
+    <WindowAlias Alias="HUDWidgets/FrameWindow"              Target="TaharezLook/FrameWindow" />
+    <WindowAlias Alias="HUDWidgets/GroupBox"                 Target="TaharezLook/GroupBox" />
+    <WindowAlias Alias="HUDWidgets/ItemListbox"              Target="TaharezLook/ItemListbox" />
+    <WindowAlias Alias="HUDWidgets/ListboxItem"              Target="TaharezLook/ListboxItem" />
+    <WindowAlias Alias="HUDWidgets/Listbox"                  Target="TaharezLook/Listbox" />
+    <WindowAlias Alias="HUDWidgets/ListHeader"               Target="TaharezLook/ListHeader" />
+    <WindowAlias Alias="HUDWidgets/ListHeaderSegment"        Target="TaharezLook/ListHeaderSegment" />
+    <WindowAlias Alias="HUDWidgets/MultiLineEditbox"         Target="TaharezLook/MultiLineEditbox" />
+    <WindowAlias Alias="HUDWidgets/Menubar"                  Target="TaharezLook/Menubar" />
+    <WindowAlias Alias="HUDWidgets/MenuItem"                 Target="TaharezLook/MenuItem" />
+    <WindowAlias Alias="HUDWidgets/MultiColumnList"          Target="TaharezLook/MultiColumnList" />
+    <WindowAlias Alias="HUDWidgets/PopupMenu"                Target="TaharezLook/PopupMenu" />
+    <WindowAlias Alias="HUDWidgets/ProgressBar"              Target="TaharezLook/ProgressBar" />
+    <WindowAlias Alias="HUDWidgets/Button"                   Target="TaharezLook/Button" />
+    <WindowAlias Alias="HUDWidgets/ImageButton"              Target="TaharezLook/ImageButton" />
+    <WindowAlias Alias="HUDWidgets/RadioButton"              Target="TaharezLook/RadioButton" />
+    <WindowAlias Alias="HUDWidgets/SystemButton"             Target="TaharezLook/SystemButton" />
+    <WindowAlias Alias="HUDWidgets/ScrollablePane"           Target="TaharezLook/ScrollablePane" />
+    <WindowAlias Alias="HUDWidgets/HorizontalScrollbar"      Target="TaharezLook/HorizontalScrollbar" />
+    <WindowAlias Alias="HUDWidgets/VerticalScrollbar"        Target="TaharezLook/VerticalScrollbar" />
+    <WindowAlias Alias="HUDWidgets/Slider"                   Target="TaharezLook/Slider" />
+    <WindowAlias Alias="HUDWidgets/Spinner"                  Target="TaharezLook/Spinner" />
+    <WindowAlias Alias="HUDWidgets/TabButton"                Target="TaharezLook/TabButton" />
+    <WindowAlias Alias="HUDWidgets/TabControl"               Target="TaharezLook/TabControl" />
+    <WindowAlias Alias="HUDWidgets/HorizontalScrollbarThumb" Target="TaharezLook/HorizontalScrollbarThumb" />
+    <WindowAlias Alias="HUDWidgets/SliderThumb"              Target="TaharezLook/SliderThumb" />
+    <WindowAlias Alias="HUDWidgets/VerticalScrollbarThumb"   Target="TaharezLook/VerticalScrollbarThumb" />
+    <WindowAlias Alias="HUDWidgets/Titlebar"                 Target="TaharezLook/Titlebar" />
+    <WindowAlias Alias="HUDWidgets/Tooltip"                  Target="TaharezLook/Tooltip" />
+    <WindowAlias Alias="HUDWidgets/Tree"                     Target="TaharezLook/Tree" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/TaharezLook.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/TaharezLook.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/TaharezLook.scheme	(revision 6952)
@@ -0,0 +1,53 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="TaharezLook">
+	<Imageset Name="TaharezLook" Filename="TaharezLook.imageset" />
+	<LookNFeel Filename="TaharezLook.looknfeel" />
+	<WindowRendererSet Filename="CEGUIFalagardWRBase" />
+
+    <!-- Standard widgets -->
+    <FalagardMapping WindowType="TaharezLook/StaticImage"              TargetType="DefaultWindow"           Renderer="Falagard/StaticImage"       LookNFeel="TaharezLook/StaticImage" />
+    <FalagardMapping WindowType="TaharezLook/StaticText"               TargetType="DefaultWindow"           Renderer="Falagard/StaticText"        LookNFeel="TaharezLook/StaticText" />
+    <FalagardMapping WindowType="TaharezLook/TabButtonPane"            TargetType="DefaultWindow"           Renderer="Falagard/Default"           LookNFeel="TaharezLook/TabButtonPane" />
+    <FalagardMapping WindowType="TaharezLook/TabContentPane"           TargetType="DefaultWindow"           Renderer="Falagard/Default"           LookNFeel="TaharezLook/TabContentPane" />
+    <FalagardMapping WindowType="TaharezLook/Checkbox"                 TargetType="CEGUI/Checkbox"          Renderer="Falagard/ToggleButton"      LookNFeel="TaharezLook/Checkbox" />
+    <FalagardMapping WindowType="TaharezLook/Combobox"                 TargetType="CEGUI/Combobox"          Renderer="Falagard/Default"           LookNFeel="TaharezLook/Combobox" />
+    <FalagardMapping WindowType="TaharezLook/ComboDropList"            TargetType="CEGUI/ComboDropList"     Renderer="Falagard/Listbox"           LookNFeel="TaharezLook/ComboDropList" />
+    <FalagardMapping WindowType="TaharezLook/ComboEditbox"             TargetType="CEGUI/Editbox"           Renderer="Falagard/Editbox"           LookNFeel="TaharezLook/ComboEditbox" />
+    <FalagardMapping WindowType="TaharezLook/Editbox"                  TargetType="CEGUI/Editbox"           Renderer="Falagard/Editbox"           LookNFeel="TaharezLook/Editbox" />
+    <FalagardMapping WindowType="TaharezLook/FrameWindow"              TargetType="CEGUI/FrameWindow"       Renderer="Falagard/FrameWindow"       LookNFeel="TaharezLook/FrameWindow" />
+    <FalagardMapping WindowType="TaharezLook/GroupBox"                 TargetType="CEGUI/GroupBox"          Renderer="Falagard/Default"           LookNFeel="TaharezLook/GroupBox" />
+    <FalagardMapping WindowType="TaharezLook/ItemListbox"              TargetType="CEGUI/ItemListbox"       Renderer="Falagard/ItemListbox"       LookNFeel="TaharezLook/ItemListbox" />
+    <FalagardMapping WindowType="TaharezLook/ListboxItem"              TargetType="CEGUI/ItemEntry"         Renderer="Falagard/ItemEntry"         LookNFeel="TaharezLook/ListboxItem" />
+    <FalagardMapping WindowType="TaharezLook/Listbox"                  TargetType="CEGUI/Listbox"           Renderer="Falagard/Listbox"           LookNFeel="TaharezLook/Listbox" />
+    <FalagardMapping WindowType="TaharezLook/ListHeader"               TargetType="CEGUI/ListHeader"        Renderer="Falagard/ListHeader"        LookNFeel="TaharezLook/ListHeader" />
+    <FalagardMapping WindowType="TaharezLook/ListHeaderSegment"        TargetType="CEGUI/ListHeaderSegment" Renderer="Falagard/ListHeaderSegment" LookNFeel="TaharezLook/ListHeaderSegment" />
+    <FalagardMapping WindowType="TaharezLook/MultiLineEditbox"         TargetType="CEGUI/MultiLineEditbox"  Renderer="Falagard/MultiLineEditbox"  LookNFeel="TaharezLook/MultiLineEditbox" />
+    <FalagardMapping WindowType="TaharezLook/Menubar"                  TargetType="CEGUI/Menubar"           Renderer="Falagard/Menubar"           LookNFeel="TaharezLook/Menubar" />
+    <FalagardMapping WindowType="TaharezLook/MenuItem"                 TargetType="CEGUI/MenuItem"          Renderer="Falagard/MenuItem"          LookNFeel="TaharezLook/MenuItem" />
+    <FalagardMapping WindowType="TaharezLook/MultiColumnList"          TargetType="CEGUI/MultiColumnList"   Renderer="Falagard/MultiColumnList"   LookNFeel="TaharezLook/MultiColumnList" />
+    <FalagardMapping WindowType="TaharezLook/PopupMenu"                TargetType="CEGUI/PopupMenu"         Renderer="Falagard/PopupMenu"         LookNFeel="TaharezLook/PopupMenu" />
+    <FalagardMapping WindowType="TaharezLook/ProgressBar"              TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="TaharezLook/ProgressBar" />
+    <FalagardMapping WindowType="TaharezLook/Button"                   TargetType="CEGUI/PushButton"        Renderer="Falagard/Button"            LookNFeel="TaharezLook/Button" />
+    <FalagardMapping WindowType="TaharezLook/ImageButton"              TargetType="CEGUI/PushButton"        Renderer="Falagard/Button"            LookNFeel="TaharezLook/ImageButton" />
+    <FalagardMapping WindowType="TaharezLook/RadioButton"              TargetType="CEGUI/RadioButton"       Renderer="Falagard/ToggleButton"      LookNFeel="TaharezLook/RadioButton" />
+    <FalagardMapping WindowType="TaharezLook/SystemButton"             TargetType="CEGUI/PushButton"        Renderer="Falagard/SystemButton"      LookNFeel="TaharezLook/Button" />
+    <FalagardMapping WindowType="TaharezLook/ScrollablePane"           TargetType="CEGUI/ScrollablePane"    Renderer="Falagard/ScrollablePane"    LookNFeel="TaharezLook/ScrollablePane" />
+    <FalagardMapping WindowType="TaharezLook/HorizontalScrollbar"      TargetType="CEGUI/Scrollbar"         Renderer="Falagard/Scrollbar"         LookNFeel="TaharezLook/HorizontalScrollbar" />
+    <FalagardMapping WindowType="TaharezLook/VerticalScrollbar"        TargetType="CEGUI/Scrollbar"         Renderer="Falagard/Scrollbar"         LookNFeel="TaharezLook/VerticalScrollbar" />
+    <FalagardMapping WindowType="TaharezLook/Slider"                   TargetType="CEGUI/Slider"            Renderer="Falagard/Slider"            LookNFeel="TaharezLook/Slider" />
+    <FalagardMapping WindowType="TaharezLook/Spinner"                  TargetType="CEGUI/Spinner"           Renderer="Falagard/Default"           LookNFeel="TaharezLook/Spinner" />
+    <FalagardMapping WindowType="TaharezLook/TabButton"                TargetType="CEGUI/TabButton"         Renderer="Falagard/TabButton"         LookNFeel="TaharezLook/TabButton" />
+    <FalagardMapping WindowType="TaharezLook/TabControl"               TargetType="CEGUI/TabControl"        Renderer="Falagard/TabControl"        LookNFeel="TaharezLook/TabControl" />
+    <FalagardMapping WindowType="TaharezLook/HorizontalScrollbarThumb" TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="TaharezLook/HorizontalScrollbarThumb" />
+    <FalagardMapping WindowType="TaharezLook/SliderThumb"              TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="TaharezLook/SliderThumb" />
+    <FalagardMapping WindowType="TaharezLook/VerticalScrollbarThumb"   TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="TaharezLook/VerticalScrollbarThumb" />
+    <FalagardMapping WindowType="TaharezLook/Titlebar"                 TargetType="CEGUI/Titlebar"          Renderer="Falagard/Titlebar"          LookNFeel="TaharezLook/Titlebar" />
+    <FalagardMapping WindowType="TaharezLook/Tooltip"                  TargetType="CEGUI/Tooltip"           Renderer="Falagard/Tooltip"           LookNFeel="TaharezLook/Tooltip" />
+    <FalagardMapping WindowType="TaharezLook/Tree"                     TargetType="CEGUI/Tree"              Renderer="Falagard/Tree"              LookNFeel="TaharezLook/Tree" />
+    
+    <!-- Additional widgets -->
+    <FalagardMapping WindowType="TaharezLook/AlternateProgressBar"        TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="TaharezLook/AltProgressBar" />
+    <FalagardMapping WindowType="TaharezLook/VUMeter"                     TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="TaharezLook/VUMeter" />
+    <FalagardMapping WindowType="TaharezLook/LargeVerticalScrollbar"      TargetType="CEGUI/Scrollbar"         Renderer="Falagard/Scrollbar"         LookNFeel="TaharezLook/LargeVerticalScrollbar" />
+    <FalagardMapping WindowType="TaharezLook/LargeVerticalScrollbarThumb" TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="TaharezLook/LargeVerticalScrollbarThumb" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/TaharezMenuWidgets.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/TaharezMenuWidgets.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/TaharezMenuWidgets.scheme	(revision 6952)
@@ -0,0 +1,42 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="TaharezMenuWidgets">
+    <WindowAlias Alias="MenuWidgets/StaticImage"              Target="TaharezLook/StaticImage" />
+    <WindowAlias Alias="MenuWidgets/StaticText"               Target="TaharezLook/StaticText" />
+    <WindowAlias Alias="MenuWidgets/TabButtonPane"            Target="TaharezLook/TabButtonPane" />
+    <WindowAlias Alias="MenuWidgets/TabContentPane"           Target="TaharezLook/TabContentPane" />
+    <WindowAlias Alias="MenuWidgets/Checkbox"                 Target="TaharezLook/Checkbox" />
+    <WindowAlias Alias="MenuWidgets/Combobox"                 Target="TaharezLook/Combobox" />
+    <WindowAlias Alias="MenuWidgets/ComboDropList"            Target="TaharezLook/ComboDropList" />
+    <WindowAlias Alias="MenuWidgets/ComboEditbox"             Target="TaharezLook/ComboEditbox" />
+    <WindowAlias Alias="MenuWidgets/Editbox"                  Target="TaharezLook/Editbox" />
+    <WindowAlias Alias="MenuWidgets/FrameWindow"              Target="TaharezLook/FrameWindow" />
+    <WindowAlias Alias="MenuWidgets/GroupBox"                 Target="TaharezLook/GroupBox" />
+    <WindowAlias Alias="MenuWidgets/ItemListbox"              Target="TaharezLook/ItemListbox" />
+    <WindowAlias Alias="MenuWidgets/ListboxItem"              Target="TaharezLook/ListboxItem" />
+    <WindowAlias Alias="MenuWidgets/Listbox"                  Target="TaharezLook/Listbox" />
+    <WindowAlias Alias="MenuWidgets/ListHeader"               Target="TaharezLook/ListHeader" />
+    <WindowAlias Alias="MenuWidgets/ListHeaderSegment"        Target="TaharezLook/ListHeaderSegment" />
+    <WindowAlias Alias="MenuWidgets/MultiLineEditbox"         Target="TaharezLook/MultiLineEditbox" />
+    <WindowAlias Alias="MenuWidgets/Menubar"                  Target="TaharezLook/Menubar" />
+    <WindowAlias Alias="MenuWidgets/MenuItem"                 Target="TaharezLook/MenuItem" />
+    <WindowAlias Alias="MenuWidgets/MultiColumnList"          Target="TaharezLook/MultiColumnList" />
+    <WindowAlias Alias="MenuWidgets/PopupMenu"                Target="TaharezLook/PopupMenu" />
+    <WindowAlias Alias="MenuWidgets/ProgressBar"              Target="TaharezLook/ProgressBar" />
+    <WindowAlias Alias="MenuWidgets/Button"                   Target="TaharezLook/Button" />
+    <WindowAlias Alias="MenuWidgets/ImageButton"              Target="TaharezLook/ImageButton" />
+    <WindowAlias Alias="MenuWidgets/RadioButton"              Target="TaharezLook/RadioButton" />
+    <WindowAlias Alias="MenuWidgets/SystemButton"             Target="TaharezLook/SystemButton" />
+    <WindowAlias Alias="MenuWidgets/ScrollablePane"           Target="TaharezLook/ScrollablePane" />
+    <WindowAlias Alias="MenuWidgets/HorizontalScrollbar"      Target="TaharezLook/HorizontalScrollbar" />
+    <WindowAlias Alias="MenuWidgets/VerticalScrollbar"        Target="TaharezLook/VerticalScrollbar" />
+    <WindowAlias Alias="MenuWidgets/Slider"                   Target="TaharezLook/Slider" />
+    <WindowAlias Alias="MenuWidgets/Spinner"                  Target="TaharezLook/Spinner" />
+    <WindowAlias Alias="MenuWidgets/TabButton"                Target="TaharezLook/TabButton" />
+    <WindowAlias Alias="MenuWidgets/TabControl"               Target="TaharezLook/TabControl" />
+    <WindowAlias Alias="MenuWidgets/HorizontalScrollbarThumb" Target="TaharezLook/HorizontalScrollbarThumb" />
+    <WindowAlias Alias="MenuWidgets/SliderThumb"              Target="TaharezLook/SliderThumb" />
+    <WindowAlias Alias="MenuWidgets/VerticalScrollbarThumb"   Target="TaharezLook/VerticalScrollbarThumb" />
+    <WindowAlias Alias="MenuWidgets/Titlebar"                 Target="TaharezLook/Titlebar" />
+    <WindowAlias Alias="MenuWidgets/Tooltip"                  Target="TaharezLook/Tooltip" />
+    <WindowAlias Alias="MenuWidgets/Tree"                     Target="TaharezLook/Tree" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/VanillaHUDWidgets.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/VanillaHUDWidgets.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/VanillaHUDWidgets.scheme	(revision 6952)
@@ -0,0 +1,42 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="VanillaHUDWidgets">
+    <WindowAlias Alias="HUDWidgets/StaticImage"              Target="Vanilla/StaticImage" />
+    <WindowAlias Alias="HUDWidgets/StaticText"               Target="Vanilla/StaticText" />
+    <WindowAlias Alias="HUDWidgets/TabButtonPane"            Target="Vanilla/TabButtonPane" />
+    <WindowAlias Alias="HUDWidgets/TabContentPane"           Target="Vanilla/TabContentPane" />
+    <WindowAlias Alias="HUDWidgets/Checkbox"                 Target="Vanilla/Checkbox" />
+    <WindowAlias Alias="HUDWidgets/Combobox"                 Target="Vanilla/Combobox" />
+    <WindowAlias Alias="HUDWidgets/ComboDropList"            Target="Vanilla/ComboDropList" />
+    <WindowAlias Alias="HUDWidgets/ComboEditbox"             Target="Vanilla/ComboEditbox" />
+    <WindowAlias Alias="HUDWidgets/Editbox"                  Target="Vanilla/Editbox" />
+    <WindowAlias Alias="HUDWidgets/FrameWindow"              Target="Vanilla/FrameWindow" />
+    <WindowAlias Alias="HUDWidgets/GroupBox"                 Target="Vanilla/GroupBox" />
+    <WindowAlias Alias="HUDWidgets/ItemListbox"              Target="Vanilla/ItemListbox" />
+    <WindowAlias Alias="HUDWidgets/ListboxItem"              Target="Vanilla/ListboxItem" />
+    <WindowAlias Alias="HUDWidgets/Listbox"                  Target="Vanilla/Listbox" />
+    <WindowAlias Alias="HUDWidgets/ListHeader"               Target="Vanilla/ListHeader" />
+    <WindowAlias Alias="HUDWidgets/ListHeaderSegment"        Target="Vanilla/ListHeaderSegment" />
+    <WindowAlias Alias="HUDWidgets/MultiLineEditbox"         Target="Vanilla/MultiLineEditbox" />
+    <WindowAlias Alias="HUDWidgets/Menubar"                  Target="Vanilla/Menubar" />
+    <WindowAlias Alias="HUDWidgets/MenuItem"                 Target="Vanilla/MenuItem" />
+    <WindowAlias Alias="HUDWidgets/MultiColumnList"          Target="Vanilla/MultiColumnList" />
+    <WindowAlias Alias="HUDWidgets/PopupMenu"                Target="Vanilla/PopupMenu" />
+    <WindowAlias Alias="HUDWidgets/ProgressBar"              Target="Vanilla/ProgressBar" />
+    <WindowAlias Alias="HUDWidgets/Button"                   Target="Vanilla/Button" />
+    <WindowAlias Alias="HUDWidgets/ImageButton"              Target="Vanilla/ImageButton" />
+    <WindowAlias Alias="HUDWidgets/RadioButton"              Target="Vanilla/RadioButton" />
+    <WindowAlias Alias="HUDWidgets/SystemButton"             Target="Vanilla/SystemButton" />
+    <WindowAlias Alias="HUDWidgets/ScrollablePane"           Target="Vanilla/ScrollablePane" />
+    <WindowAlias Alias="HUDWidgets/HorizontalScrollbar"      Target="Vanilla/HorizontalScrollbar" />
+    <WindowAlias Alias="HUDWidgets/VerticalScrollbar"        Target="Vanilla/VerticalScrollbar" />
+    <WindowAlias Alias="HUDWidgets/Slider"                   Target="Vanilla/Slider" />
+    <WindowAlias Alias="HUDWidgets/Spinner"                  Target="Vanilla/Spinner" />
+    <WindowAlias Alias="HUDWidgets/TabButton"                Target="Vanilla/TabButton" />
+    <WindowAlias Alias="HUDWidgets/TabControl"               Target="Vanilla/TabControl" />
+    <WindowAlias Alias="HUDWidgets/HorizontalScrollbarThumb" Target="Vanilla/HorizontalScrollbarThumb" />
+    <WindowAlias Alias="HUDWidgets/SliderThumb"              Target="Vanilla/SliderThumb" />
+    <WindowAlias Alias="HUDWidgets/VerticalScrollbarThumb"   Target="Vanilla/VerticalScrollbarThumb" />
+    <WindowAlias Alias="HUDWidgets/Titlebar"                 Target="Vanilla/Titlebar" />
+    <WindowAlias Alias="HUDWidgets/Tooltip"                  Target="Vanilla/Tooltip" />
+    <WindowAlias Alias="HUDWidgets/Tree"                     Target="Vanilla/Tree" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/VanillaLook.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/VanillaLook.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/VanillaLook.scheme	(revision 6952)
@@ -0,0 +1,53 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="VanillaLook">
+    <Imageset Name="Vanilla-Images" Filename="Vanilla.imageset" />
+    <Imageset Name="TaharezLook"    Filename="TaharezLook.imageset" />
+    <LookNFeel Filename="Vanilla.looknfeel" />
+    <LookNFeel Filename="TaharezLook.looknfeel" />
+    <WindowRendererSet Filename="CEGUIFalagardWRBase" />
+
+    <!-- Standard widgets -->
+    <FalagardMapping WindowType="Vanilla/StaticImage"              TargetType="DefaultWindow"           Renderer="Falagard/StaticImage"       LookNFeel="Vanilla/StaticImage" />
+    <FalagardMapping WindowType="Vanilla/StaticText"               TargetType="DefaultWindow"           Renderer="Falagard/StaticText"        LookNFeel="Vanilla/StaticText" />
+    <FalagardMapping WindowType="Vanilla/Editbox"                  TargetType="CEGUI/Editbox"           Renderer="Falagard/Editbox"           LookNFeel="Vanilla/Editbox" />
+    <FalagardMapping WindowType="Vanilla/FrameWindow"              TargetType="CEGUI/FrameWindow"       Renderer="Falagard/FrameWindow"       LookNFeel="Vanilla/FrameWindow" />
+    <FalagardMapping WindowType="Vanilla/Listbox"                  TargetType="CEGUI/Listbox"           Renderer="Falagard/Listbox"           LookNFeel="Vanilla/Listbox" />
+    <FalagardMapping WindowType="Vanilla/MultiLineEditbox"         TargetType="CEGUI/MultiLineEditbox"  Renderer="Falagard/MultiLineEditbox"  LookNFeel="Vanilla/MultiLineEditbox" />
+    <FalagardMapping WindowType="Vanilla/Button"                   TargetType="CEGUI/PushButton"        Renderer="Falagard/Button"            LookNFeel="Vanilla/Button" />
+    <FalagardMapping WindowType="Vanilla/HorizontalScrollbar"      TargetType="CEGUI/Scrollbar"         Renderer="Falagard/Scrollbar"         LookNFeel="Vanilla/HorizontalScrollbar" />
+    <FalagardMapping WindowType="Vanilla/VerticalScrollbar"        TargetType="CEGUI/Scrollbar"         Renderer="Falagard/Scrollbar"         LookNFeel="Vanilla/VerticalScrollbar" />
+    <FalagardMapping WindowType="Vanilla/HorizontalScrollbarThumb" TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="Vanilla/HorizontalScrollbarThumb" />
+    <FalagardMapping WindowType="Vanilla/VerticalScrollbarThumb"   TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="Vanilla/VerticalScrollbarThumb" />
+    <FalagardMapping WindowType="Vanilla/Titlebar"                 TargetType="CEGUI/Titlebar"          Renderer="Falagard/Titlebar"          LookNFeel="Vanilla/Titlebar" />
+
+    <!-- Missing widgets (using Taharez LookNFeel) -->
+    <FalagardMapping WindowType="Vanilla/TabButtonPane"            TargetType="DefaultWindow"           Renderer="Falagard/Default"           LookNFeel="TaharezLook/TabButtonPane" />
+    <FalagardMapping WindowType="Vanilla/TabContentPane"           TargetType="DefaultWindow"           Renderer="Falagard/Default"           LookNFeel="TaharezLook/TabContentPane" />
+    <FalagardMapping WindowType="Vanilla/Checkbox"                 TargetType="CEGUI/Checkbox"          Renderer="Falagard/ToggleButton"      LookNFeel="TaharezLook/Checkbox" />
+    <FalagardMapping WindowType="Vanilla/Combobox"                 TargetType="CEGUI/Combobox"          Renderer="Falagard/Default"           LookNFeel="TaharezLook/Combobox" />
+    <FalagardMapping WindowType="Vanilla/ComboDropList"            TargetType="CEGUI/ComboDropList"     Renderer="Falagard/Listbox"           LookNFeel="TaharezLook/ComboDropList" />
+    <FalagardMapping WindowType="Vanilla/ComboEditbox"             TargetType="CEGUI/Editbox"           Renderer="Falagard/Editbox"           LookNFeel="TaharezLook/ComboEditbox" />
+    <FalagardMapping WindowType="Vanilla/GroupBox"                 TargetType="CEGUI/GroupBox"          Renderer="Falagard/Default"           LookNFeel="TaharezLook/GroupBox" />
+    <FalagardMapping WindowType="Vanilla/ItemListbox"              TargetType="CEGUI/ItemListbox"       Renderer="Falagard/ItemListbox"       LookNFeel="TaharezLook/ItemListbox" />
+    <FalagardMapping WindowType="Vanilla/ListboxItem"              TargetType="CEGUI/ItemEntry"         Renderer="Falagard/ItemEntry"         LookNFeel="TaharezLook/ListboxItem" />
+    <FalagardMapping WindowType="Vanilla/ListHeader"               TargetType="CEGUI/ListHeader"        Renderer="Falagard/ListHeader"        LookNFeel="TaharezLook/ListHeader" />
+    <FalagardMapping WindowType="Vanilla/ListHeaderSegment"        TargetType="CEGUI/ListHeaderSegment" Renderer="Falagard/ListHeaderSegment" LookNFeel="TaharezLook/ListHeaderSegment" />
+    <FalagardMapping WindowType="Vanilla/Menubar"                  TargetType="CEGUI/Menubar"           Renderer="Falagard/Menubar"           LookNFeel="TaharezLook/Menubar" />
+    <FalagardMapping WindowType="Vanilla/MenuItem"                 TargetType="CEGUI/MenuItem"          Renderer="Falagard/MenuItem"          LookNFeel="TaharezLook/MenuItem" />
+    <FalagardMapping WindowType="Vanilla/MultiColumnList"          TargetType="CEGUI/MultiColumnList"   Renderer="Falagard/MultiColumnList"   LookNFeel="TaharezLook/MultiColumnList" />
+    <FalagardMapping WindowType="Vanilla/PopupMenu"                TargetType="CEGUI/PopupMenu"         Renderer="Falagard/PopupMenu"         LookNFeel="TaharezLook/PopupMenu" />
+    <FalagardMapping WindowType="Vanilla/ProgressBar"              TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="TaharezLook/ProgressBar" />
+    <FalagardMapping WindowType="Vanilla/ImageButton"              TargetType="CEGUI/PushButton"        Renderer="Falagard/Button"            LookNFeel="TaharezLook/ImageButton" />
+    <FalagardMapping WindowType="Vanilla/RadioButton"              TargetType="CEGUI/RadioButton"       Renderer="Falagard/ToggleButton"      LookNFeel="TaharezLook/RadioButton" />
+    <FalagardMapping WindowType="Vanilla/SystemButton"             TargetType="CEGUI/PushButton"        Renderer="Falagard/SystemButton"      LookNFeel="TaharezLook/Button" />
+    <FalagardMapping WindowType="Vanilla/ScrollablePane"           TargetType="CEGUI/ScrollablePane"    Renderer="Falagard/ScrollablePane"    LookNFeel="TaharezLook/ScrollablePane" />
+    <FalagardMapping WindowType="Vanilla/Slider"                   TargetType="CEGUI/Slider"            Renderer="Falagard/Slider"            LookNFeel="TaharezLook/Slider" />
+    <FalagardMapping WindowType="Vanilla/Spinner"                  TargetType="CEGUI/Spinner"           Renderer="Falagard/Default"           LookNFeel="TaharezLook/Spinner" />
+    <FalagardMapping WindowType="Vanilla/TabButton"                TargetType="CEGUI/TabButton"         Renderer="Falagard/TabButton"         LookNFeel="TaharezLook/TabButton" />
+    <FalagardMapping WindowType="Vanilla/TabControl"               TargetType="CEGUI/TabControl"        Renderer="Falagard/TabControl"        LookNFeel="TaharezLook/TabControl" />
+    <FalagardMapping WindowType="Vanilla/SliderThumb"              TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="TaharezLook/SliderThumb" />
+    <FalagardMapping WindowType="Vanilla/Tooltip"                  TargetType="CEGUI/Tooltip"           Renderer="Falagard/Tooltip"           LookNFeel="TaharezLook/Tooltip" />
+    <FalagardMapping WindowType="Vanilla/Tree"                     TargetType="CEGUI/Tree"              Renderer="Falagard/Tree"              LookNFeel="TaharezLook/Tree" />
+    
+    <!-- Additional widgets -->
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/VanillaMenuWidgets.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/VanillaMenuWidgets.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/VanillaMenuWidgets.scheme	(revision 6952)
@@ -0,0 +1,42 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="VanillaMenuWidgets">
+    <WindowAlias Alias="MenuWidgets/StaticImage"              Target="Vanilla/StaticImage" />
+    <WindowAlias Alias="MenuWidgets/StaticText"               Target="Vanilla/StaticText" />
+    <WindowAlias Alias="MenuWidgets/TabButtonPane"            Target="Vanilla/TabButtonPane" />
+    <WindowAlias Alias="MenuWidgets/TabContentPane"           Target="Vanilla/TabContentPane" />
+    <WindowAlias Alias="MenuWidgets/Checkbox"                 Target="Vanilla/Checkbox" />
+    <WindowAlias Alias="MenuWidgets/Combobox"                 Target="Vanilla/Combobox" />
+    <WindowAlias Alias="MenuWidgets/ComboDropList"            Target="Vanilla/ComboDropList" />
+    <WindowAlias Alias="MenuWidgets/ComboEditbox"             Target="Vanilla/ComboEditbox" />
+    <WindowAlias Alias="MenuWidgets/Editbox"                  Target="Vanilla/Editbox" />
+    <WindowAlias Alias="MenuWidgets/FrameWindow"              Target="Vanilla/FrameWindow" />
+    <WindowAlias Alias="MenuWidgets/GroupBox"                 Target="Vanilla/GroupBox" />
+    <WindowAlias Alias="MenuWidgets/ItemListbox"              Target="Vanilla/ItemListbox" />
+    <WindowAlias Alias="MenuWidgets/ListboxItem"              Target="Vanilla/ListboxItem" />
+    <WindowAlias Alias="MenuWidgets/Listbox"                  Target="Vanilla/Listbox" />
+    <WindowAlias Alias="MenuWidgets/ListHeader"               Target="Vanilla/ListHeader" />
+    <WindowAlias Alias="MenuWidgets/ListHeaderSegment"        Target="Vanilla/ListHeaderSegment" />
+    <WindowAlias Alias="MenuWidgets/MultiLineEditbox"         Target="Vanilla/MultiLineEditbox" />
+    <WindowAlias Alias="MenuWidgets/Menubar"                  Target="Vanilla/Menubar" />
+    <WindowAlias Alias="MenuWidgets/MenuItem"                 Target="Vanilla/MenuItem" />
+    <WindowAlias Alias="MenuWidgets/MultiColumnList"          Target="Vanilla/MultiColumnList" />
+    <WindowAlias Alias="MenuWidgets/PopupMenu"                Target="Vanilla/PopupMenu" />
+    <WindowAlias Alias="MenuWidgets/ProgressBar"              Target="Vanilla/ProgressBar" />
+    <WindowAlias Alias="MenuWidgets/Button"                   Target="Vanilla/Button" />
+    <WindowAlias Alias="MenuWidgets/ImageButton"              Target="Vanilla/ImageButton" />
+    <WindowAlias Alias="MenuWidgets/RadioButton"              Target="Vanilla/RadioButton" />
+    <WindowAlias Alias="MenuWidgets/SystemButton"             Target="Vanilla/SystemButton" />
+    <WindowAlias Alias="MenuWidgets/ScrollablePane"           Target="Vanilla/ScrollablePane" />
+    <WindowAlias Alias="MenuWidgets/HorizontalScrollbar"      Target="Vanilla/HorizontalScrollbar" />
+    <WindowAlias Alias="MenuWidgets/VerticalScrollbar"        Target="Vanilla/VerticalScrollbar" />
+    <WindowAlias Alias="MenuWidgets/Slider"                   Target="Vanilla/Slider" />
+    <WindowAlias Alias="MenuWidgets/Spinner"                  Target="Vanilla/Spinner" />
+    <WindowAlias Alias="MenuWidgets/TabButton"                Target="Vanilla/TabButton" />
+    <WindowAlias Alias="MenuWidgets/TabControl"               Target="Vanilla/TabControl" />
+    <WindowAlias Alias="MenuWidgets/HorizontalScrollbarThumb" Target="Vanilla/HorizontalScrollbarThumb" />
+    <WindowAlias Alias="MenuWidgets/SliderThumb"              Target="Vanilla/SliderThumb" />
+    <WindowAlias Alias="MenuWidgets/VerticalScrollbarThumb"   Target="Vanilla/VerticalScrollbarThumb" />
+    <WindowAlias Alias="MenuWidgets/Titlebar"                 Target="Vanilla/Titlebar" />
+    <WindowAlias Alias="MenuWidgets/Tooltip"                  Target="Vanilla/Tooltip" />
+    <WindowAlias Alias="MenuWidgets/Tree"                     Target="Vanilla/Tree" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/WindowsHUDWidgets.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/WindowsHUDWidgets.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/WindowsHUDWidgets.scheme	(revision 6952)
@@ -0,0 +1,42 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="WindowsHUDWidgets">
+    <WindowAlias Alias="HUDWidgets/StaticImage"              Target="WindowsLook/StaticImage" />
+    <WindowAlias Alias="HUDWidgets/StaticText"               Target="WindowsLook/StaticText" />
+    <WindowAlias Alias="HUDWidgets/TabButtonPane"            Target="WindowsLook/TabButtonPane" />
+    <WindowAlias Alias="HUDWidgets/TabContentPane"           Target="WindowsLook/TabContentPane" />
+    <WindowAlias Alias="HUDWidgets/Checkbox"                 Target="WindowsLook/Checkbox" />
+    <WindowAlias Alias="HUDWidgets/Combobox"                 Target="WindowsLook/Combobox" />
+    <WindowAlias Alias="HUDWidgets/ComboDropList"            Target="WindowsLook/ComboDropList" />
+    <WindowAlias Alias="HUDWidgets/ComboEditbox"             Target="WindowsLook/ComboEditbox" />
+    <WindowAlias Alias="HUDWidgets/Editbox"                  Target="WindowsLook/Editbox" />
+    <WindowAlias Alias="HUDWidgets/FrameWindow"              Target="WindowsLook/FrameWindow" />
+    <WindowAlias Alias="HUDWidgets/GroupBox"                 Target="WindowsLook/GroupBox" />
+    <WindowAlias Alias="HUDWidgets/ItemListbox"              Target="WindowsLook/ItemListbox" />
+    <WindowAlias Alias="HUDWidgets/ListboxItem"              Target="WindowsLook/ListboxItem" />
+    <WindowAlias Alias="HUDWidgets/Listbox"                  Target="WindowsLook/Listbox" />
+    <WindowAlias Alias="HUDWidgets/ListHeader"               Target="WindowsLook/ListHeader" />
+    <WindowAlias Alias="HUDWidgets/ListHeaderSegment"        Target="WindowsLook/ListHeaderSegment" />
+    <WindowAlias Alias="HUDWidgets/MultiLineEditbox"         Target="WindowsLook/MultiLineEditbox" />
+    <WindowAlias Alias="HUDWidgets/Menubar"                  Target="WindowsLook/Menubar" />
+    <WindowAlias Alias="HUDWidgets/MenuItem"                 Target="WindowsLook/MenuItem" />
+    <WindowAlias Alias="HUDWidgets/MultiColumnList"          Target="WindowsLook/MultiColumnList" />
+    <WindowAlias Alias="HUDWidgets/PopupMenu"                Target="WindowsLook/PopupMenu" />
+    <WindowAlias Alias="HUDWidgets/ProgressBar"              Target="WindowsLook/ProgressBar" />
+    <WindowAlias Alias="HUDWidgets/Button"                   Target="WindowsLook/Button" />
+    <WindowAlias Alias="HUDWidgets/ImageButton"              Target="WindowsLook/ImageButton" />
+    <WindowAlias Alias="HUDWidgets/RadioButton"              Target="WindowsLook/RadioButton" />
+    <WindowAlias Alias="HUDWidgets/SystemButton"             Target="WindowsLook/SystemButton" />
+    <WindowAlias Alias="HUDWidgets/ScrollablePane"           Target="WindowsLook/ScrollablePane" />
+    <WindowAlias Alias="HUDWidgets/HorizontalScrollbar"      Target="WindowsLook/HorizontalScrollbar" />
+    <WindowAlias Alias="HUDWidgets/VerticalScrollbar"        Target="WindowsLook/VerticalScrollbar" />
+    <WindowAlias Alias="HUDWidgets/Slider"                   Target="WindowsLook/Slider" />
+    <WindowAlias Alias="HUDWidgets/Spinner"                  Target="WindowsLook/Spinner" />
+    <WindowAlias Alias="HUDWidgets/TabButton"                Target="WindowsLook/TabButton" />
+    <WindowAlias Alias="HUDWidgets/TabControl"               Target="WindowsLook/TabControl" />
+    <WindowAlias Alias="HUDWidgets/HorizontalScrollbarThumb" Target="WindowsLook/HorizontalScrollbarThumb" />
+    <WindowAlias Alias="HUDWidgets/SliderThumb"              Target="WindowsLook/SliderThumb" />
+    <WindowAlias Alias="HUDWidgets/VerticalScrollbarThumb"   Target="WindowsLook/VerticalScrollbarThumb" />
+    <WindowAlias Alias="HUDWidgets/Titlebar"                 Target="WindowsLook/Titlebar" />
+    <WindowAlias Alias="HUDWidgets/Tooltip"                  Target="WindowsLook/Tooltip" />
+    <WindowAlias Alias="HUDWidgets/Tree"                     Target="WindowsLook/Tree" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/WindowsLook.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/WindowsLook.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/WindowsLook.scheme	(revision 6952)
@@ -0,0 +1,55 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="WindowsLook">
+    <Imageset Name="WindowsLook" Filename="WindowsLook.imageset" />
+    <Imageset Name="TaharezLook" Filename="TaharezLook.imageset" />
+    <LookNFeel Filename="WindowsLook.looknfeel" />
+    <LookNFeel Filename="TaharezLook.looknfeel" />
+    <WindowRendererSet Filename="CEGUIFalagardWRBase" />
+
+    <!-- Standard widgets -->
+    <FalagardMapping WindowType="WindowsLook/StaticImage"                 TargetType="DefaultWindow"           Renderer="Falagard/StaticImage"       LookNFeel="WindowsLook/StaticImage" />
+    <FalagardMapping WindowType="WindowsLook/StaticText"                  TargetType="DefaultWindow"           Renderer="Falagard/StaticText"        LookNFeel="WindowsLook/StaticText" />
+    <FalagardMapping WindowType="WindowsLook/TabButtonPane"               TargetType="DefaultWindow"           Renderer="Falagard/Default"           LookNFeel="WindowsLook/TabButtonPane" />
+    <FalagardMapping WindowType="WindowsLook/TabContentPane"              TargetType="DefaultWindow"           Renderer="Falagard/Default"           LookNFeel="WindowsLook/TabContentPane" />
+    <FalagardMapping WindowType="WindowsLook/Checkbox"                    TargetType="CEGUI/Checkbox"          Renderer="Falagard/ToggleButton"      LookNFeel="WindowsLook/Checkbox" />
+    <FalagardMapping WindowType="WindowsLook/Combobox"                    TargetType="CEGUI/Combobox"          Renderer="Falagard/Default"           LookNFeel="WindowsLook/Combobox" />
+    <FalagardMapping WindowType="WindowsLook/ComboDropList"               TargetType="CEGUI/ComboDropList"     Renderer="Falagard/Listbox"           LookNFeel="WindowsLook/ComboDropList" />
+    <FalagardMapping WindowType="WindowsLook/Editbox"                     TargetType="CEGUI/Editbox"           Renderer="Falagard/Editbox"           LookNFeel="WindowsLook/Editbox" />
+    <FalagardMapping WindowType="WindowsLook/FrameWindow"                 TargetType="CEGUI/FrameWindow"       Renderer="Falagard/FrameWindow"       LookNFeel="WindowsLook/FrameWindow" />
+    <FalagardMapping WindowType="WindowsLook/GroupBox"                    TargetType="CEGUI/GroupBox"          Renderer="Falagard/Default"           LookNFeel="WindowsLook/GroupBox" />
+    <FalagardMapping WindowType="WindowsLook/ItemListbox"                 TargetType="CEGUI/ItemListbox"       Renderer="Falagard/ItemListbox"       LookNFeel="WindowsLook/ItemListbox" />
+    <FalagardMapping WindowType="WindowsLook/ListboxItem"                 TargetType="CEGUI/ItemEntry"         Renderer="Falagard/ItemEntry"         LookNFeel="WindowsLook/ListboxItem" />
+    <FalagardMapping WindowType="WindowsLook/Listbox"                     TargetType="CEGUI/Listbox"           Renderer="Falagard/Listbox"           LookNFeel="WindowsLook/Listbox" />
+    <FalagardMapping WindowType="WindowsLook/ListHeader"                  TargetType="CEGUI/ListHeader"        Renderer="Falagard/ListHeader"        LookNFeel="WindowsLook/ListHeader" />
+    <FalagardMapping WindowType="WindowsLook/ListHeaderSegment"           TargetType="CEGUI/ListHeaderSegment" Renderer="Falagard/ListHeaderSegment" LookNFeel="WindowsLook/ListHeaderSegment" />
+    <FalagardMapping WindowType="WindowsLook/MultiLineEditbox"            TargetType="CEGUI/MultiLineEditbox"  Renderer="Falagard/MultiLineEditbox"  LookNFeel="WindowsLook/MultiLineEditbox" />
+    <FalagardMapping WindowType="WindowsLook/Menubar"                     TargetType="CEGUI/Menubar"           Renderer="Falagard/Menubar"           LookNFeel="WindowsLook/Menubar" />
+    <FalagardMapping WindowType="WindowsLook/MenuItem"                    TargetType="CEGUI/MenuItem"          Renderer="Falagard/MenuItem"          LookNFeel="WindowsLook/MenuItem" />
+    <FalagardMapping WindowType="WindowsLook/MultiColumnList"             TargetType="CEGUI/MultiColumnList"   Renderer="Falagard/MultiColumnList"   LookNFeel="WindowsLook/MultiColumnList" />
+    <FalagardMapping WindowType="WindowsLook/PopupMenu"                   TargetType="CEGUI/PopupMenu"         Renderer="Falagard/PopupMenu"         LookNFeel="WindowsLook/PopupMenu" />
+    <FalagardMapping WindowType="WindowsLook/ProgressBar"                 TargetType="CEGUI/ProgressBar"       Renderer="Falagard/ProgressBar"       LookNFeel="WindowsLook/ProgressBar" />
+    <FalagardMapping WindowType="WindowsLook/Button"                      TargetType="CEGUI/PushButton"        Renderer="Falagard/Button"            LookNFeel="WindowsLook/Button" />
+    <FalagardMapping WindowType="WindowsLook/RadioButton"                 TargetType="CEGUI/RadioButton"       Renderer="Falagard/ToggleButton"      LookNFeel="WindowsLook/RadioButton" />
+    <FalagardMapping WindowType="WindowsLook/SystemButton"                TargetType="CEGUI/PushButton"        Renderer="Falagard/SystemButton"      LookNFeel="WindowsLook/Button" />
+    <FalagardMapping WindowType="WindowsLook/ScrollablePane"              TargetType="CEGUI/ScrollablePane"    Renderer="Falagard/ScrollablePane"    LookNFeel="WindowsLook/ScrollablePane" />
+    <FalagardMapping WindowType="WindowsLook/HorizontalScrollbar"         TargetType="CEGUI/Scrollbar"         Renderer="Falagard/Scrollbar"         LookNFeel="WindowsLook/HorizontalScrollbar" />
+    <FalagardMapping WindowType="WindowsLook/VerticalScrollbar"           TargetType="CEGUI/Scrollbar"         Renderer="Falagard/Scrollbar"         LookNFeel="WindowsLook/VerticalScrollbar" />
+    <FalagardMapping WindowType="WindowsLook/Slider"                      TargetType="CEGUI/Slider"            Renderer="Falagard/Slider"            LookNFeel="WindowsLook/Slider" />
+    <FalagardMapping WindowType="WindowsLook/Spinner"                     TargetType="CEGUI/Spinner"           Renderer="Falagard/Default"           LookNFeel="WindowsLook/Spinner" />
+    <FalagardMapping WindowType="WindowsLook/TabButton"                   TargetType="CEGUI/TabButton"         Renderer="Falagard/TabButton"         LookNFeel="WindowsLook/TabButton" />
+    <FalagardMapping WindowType="WindowsLook/TabControl"                  TargetType="CEGUI/TabControl"        Renderer="Falagard/TabControl"        LookNFeel="WindowsLook/TabControl" />
+    <FalagardMapping WindowType="WindowsLook/HorizontalScrollbarThumb"    TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="WindowsLook/HorizontalScrollbarThumb" />
+    <FalagardMapping WindowType="WindowsLook/SliderThumb"                 TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="WindowsLook/SliderThumb" />
+    <FalagardMapping WindowType="WindowsLook/VerticalScrollbarThumb"      TargetType="CEGUI/Thumb"             Renderer="Falagard/Button"            LookNFeel="WindowsLook/VerticalScrollbarThumb" />
+    <FalagardMapping WindowType="WindowsLook/Titlebar"                    TargetType="CEGUI/Titlebar"          Renderer="Falagard/Titlebar"          LookNFeel="WindowsLook/Titlebar" />
+    <FalagardMapping WindowType="WindowsLook/Tooltip"                     TargetType="CEGUI/Tooltip"           Renderer="Falagard/Tooltip"           LookNFeel="WindowsLook/Tooltip" />
+    
+    <!-- Missing widgets (using Taharez LookNFeel) -->
+    <FalagardMapping WindowType="WindowsLook/ComboEditbox"                TargetType="CEGUI/Editbox"           Renderer="Falagard/Editbox"           LookNFeel="TaharezLook/ComboEditbox" />
+    <FalagardMapping WindowType="WindowsLook/ImageButton"                 TargetType="CEGUI/PushButton"        Renderer="Falagard/Button"            LookNFeel="TaharezLook/ImageButton" />
+    <FalagardMapping WindowType="WindowsLook/Tree"                        TargetType="CEGUI/Tree"              Renderer="Falagard/Tree"              LookNFeel="TaharezLook/Tree" />
+
+    <!-- Additional widgets -->
+    <FalagardMapping WindowType="WindowsLook/IconButton"                  TargetType="CEGUI/PushButton"        Renderer="Falagard/Button"            LookNFeel="WindowsLook/IconButton" />
+    <FalagardMapping WindowType="WindowsLook/Static"                      TargetType="DefaultWindow"           Renderer="Falagard/Static"            LookNFeel="WindowsLook/Static" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/schemes/WindowsMenuWidgets.scheme
===================================================================
--- /code/branches/rocket2/data/gui/schemes/WindowsMenuWidgets.scheme	(revision 6952)
+++ /code/branches/rocket2/data/gui/schemes/WindowsMenuWidgets.scheme	(revision 6952)
@@ -0,0 +1,42 @@
+<?xml version="1.0" ?>
+<GUIScheme Name="WindowsMenuWidgets">
+    <WindowAlias Alias="MenuWidgets/StaticImage"              Target="WindowsLook/StaticImage" />
+    <WindowAlias Alias="MenuWidgets/StaticText"               Target="WindowsLook/StaticText" />
+    <WindowAlias Alias="MenuWidgets/TabButtonPane"            Target="WindowsLook/TabButtonPane" />
+    <WindowAlias Alias="MenuWidgets/TabContentPane"           Target="WindowsLook/TabContentPane" />
+    <WindowAlias Alias="MenuWidgets/Checkbox"                 Target="WindowsLook/Checkbox" />
+    <WindowAlias Alias="MenuWidgets/Combobox"                 Target="WindowsLook/Combobox" />
+    <WindowAlias Alias="MenuWidgets/ComboDropList"            Target="WindowsLook/ComboDropList" />
+    <WindowAlias Alias="MenuWidgets/ComboEditbox"             Target="WindowsLook/ComboEditbox" />
+    <WindowAlias Alias="MenuWidgets/Editbox"                  Target="WindowsLook/Editbox" />
+    <WindowAlias Alias="MenuWidgets/FrameWindow"              Target="WindowsLook/FrameWindow" />
+    <WindowAlias Alias="MenuWidgets/GroupBox"                 Target="WindowsLook/GroupBox" />
+    <WindowAlias Alias="MenuWidgets/ItemListbox"              Target="WindowsLook/ItemListbox" />
+    <WindowAlias Alias="MenuWidgets/ListboxItem"              Target="WindowsLook/ListboxItem" />
+    <WindowAlias Alias="MenuWidgets/Listbox"                  Target="WindowsLook/Listbox" />
+    <WindowAlias Alias="MenuWidgets/ListHeader"               Target="WindowsLook/ListHeader" />
+    <WindowAlias Alias="MenuWidgets/ListHeaderSegment"        Target="WindowsLook/ListHeaderSegment" />
+    <WindowAlias Alias="MenuWidgets/MultiLineEditbox"         Target="WindowsLook/MultiLineEditbox" />
+    <WindowAlias Alias="MenuWidgets/Menubar"                  Target="WindowsLook/Menubar" />
+    <WindowAlias Alias="MenuWidgets/MenuItem"                 Target="WindowsLook/MenuItem" />
+    <WindowAlias Alias="MenuWidgets/MultiColumnList"          Target="WindowsLook/MultiColumnList" />
+    <WindowAlias Alias="MenuWidgets/PopupMenu"                Target="WindowsLook/PopupMenu" />
+    <WindowAlias Alias="MenuWidgets/ProgressBar"              Target="WindowsLook/ProgressBar" />
+    <WindowAlias Alias="MenuWidgets/Button"                   Target="WindowsLook/Button" />
+    <WindowAlias Alias="MenuWidgets/ImageButton"              Target="WindowsLook/ImageButton" />
+    <WindowAlias Alias="MenuWidgets/RadioButton"              Target="WindowsLook/RadioButton" />
+    <WindowAlias Alias="MenuWidgets/SystemButton"             Target="WindowsLook/SystemButton" />
+    <WindowAlias Alias="MenuWidgets/ScrollablePane"           Target="WindowsLook/ScrollablePane" />
+    <WindowAlias Alias="MenuWidgets/HorizontalScrollbar"      Target="WindowsLook/HorizontalScrollbar" />
+    <WindowAlias Alias="MenuWidgets/VerticalScrollbar"        Target="WindowsLook/VerticalScrollbar" />
+    <WindowAlias Alias="MenuWidgets/Slider"                   Target="WindowsLook/Slider" />
+    <WindowAlias Alias="MenuWidgets/Spinner"                  Target="WindowsLook/Spinner" />
+    <WindowAlias Alias="MenuWidgets/TabButton"                Target="WindowsLook/TabButton" />
+    <WindowAlias Alias="MenuWidgets/TabControl"               Target="WindowsLook/TabControl" />
+    <WindowAlias Alias="MenuWidgets/HorizontalScrollbarThumb" Target="WindowsLook/HorizontalScrollbarThumb" />
+    <WindowAlias Alias="MenuWidgets/SliderThumb"              Target="WindowsLook/SliderThumb" />
+    <WindowAlias Alias="MenuWidgets/VerticalScrollbarThumb"   Target="WindowsLook/VerticalScrollbarThumb" />
+    <WindowAlias Alias="MenuWidgets/Titlebar"                 Target="WindowsLook/Titlebar" />
+    <WindowAlias Alias="MenuWidgets/Tooltip"                  Target="WindowsLook/Tooltip" />
+    <WindowAlias Alias="MenuWidgets/Tree"                     Target="WindowsLook/Tree" />
+</GUIScheme>
Index: /code/branches/rocket2/data/gui/scripts/AudioMenu.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/AudioMenu.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/AudioMenu.lua	(revision 6952)
@@ -0,0 +1,175 @@
+-- AudioMenu.lua
+
+local P = createMenuSheet("AudioMenu")
+
+function P.onLoad()
+    soundMgr = orxonox.SoundManager:getInstance()
+    block = false
+    masterscrollbar_active = false
+    musicscrollbar_active = false
+    effectsscrollbar_active = false
+    mastervolume = soundMgr:getVolume(orxonox.SoundType.All)
+    musicvolume = soundMgr:getVolume(orxonox.SoundType.Music)
+    effectsvolume = soundMgr:getVolume(orxonox.SoundType.Effects)
+    mastermute = soundMgr:getMute(orxonox.SoundType.All)
+    musicmute = soundMgr:getMute(orxonox.SoundType.Music)
+    effectsmute = soundMgr:getMute(orxonox.SoundType.Effects)
+    masterscrollbarwindow = tolua.cast(winMgr:getWindow("orxonox/MasterScrollbar"),"CEGUI::Scrollbar")
+    musicscrollbarwindow = tolua.cast(winMgr:getWindow("orxonox/MusicScrollbar"),"CEGUI::Scrollbar")
+    effectsscrollbarwindow = tolua.cast(winMgr:getWindow("orxonox/EffectsScrollbar"),"CEGUI::Scrollbar")
+    mastermutewindow = tolua.cast(winMgr:getWindow("orxonox/MasterCheckbox"),"CEGUI::Checkbox")
+    musicmutewindow = tolua.cast(winMgr:getWindow("orxonox/MusicCheckbox"),"CEGUI::Checkbox")
+    effectsmutewindow = tolua.cast(winMgr:getWindow("orxonox/EffectsCheckbox"),"CEGUI::Checkbox")
+    masterscrollbarwindow:setScrollPosition(mastervolume)
+    musicscrollbarwindow:setScrollPosition(musicvolume)
+    effectsscrollbarwindow:setScrollPosition(effectsvolume)
+    mastermutewindow:setSelected(mastermute)
+    musicmutewindow:setSelected(musicmute)
+    effectsmutewindow:setSelected(effectsmute)
+    choice = "Default"
+    listboxwindow = winMgr:getWindow("orxonox/AudioThemeListbox")
+    local themeList = {}
+    table.insert(themeList, "Default")
+    table.insert(themeList, "Drum n' Bass")
+    for k,v in pairs(themeList) do
+        item = CEGUI.createListboxTextItem(v)
+        item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+        CEGUI.toListbox(listboxwindow):addItem(item)
+    end
+    if orxonox.getConfig("MoodManager", "mood_") == "dnb" then
+        listboxwindow:setItemSelectState(1,true)
+    else
+        listboxwindow:setItemSelectState(0,true)
+    end
+end
+
+function P.AudioMasterScrollbar_changed(e)
+    if mastermute then
+        block = true
+        mastermutewindow:setSelected(false)
+        block = false
+        mastermute = false
+    end
+    if masterscrollbar_active == false then
+        mastervolume = masterscrollbarwindow:getScrollPosition()
+        orxonox.config("SoundManager", "soundVolume_", mastervolume)
+    end
+end
+
+function P.AudioMasterScrollbar_started(e)
+    masterscrollbar_active = true
+end
+
+function P.AudioMasterScrollbar_ended(e)
+    mastervolume = masterscrollbarwindow:getScrollPosition()
+    orxonox.config("SoundManager", "soundVolume_", mastervolume)
+    masterscrollbar_active = false
+end
+
+function P.AudioMusicScrollbar_changed(e)
+    if musicmute then
+        block = true
+        musicmutewindow:setSelected(false)
+        block = false
+        musicmute = false
+    end
+    if musicscrollbar_active == false then
+        musicvolume = musicscrollbarwindow:getScrollPosition()
+        orxonox.config("SoundManager", "ambientVolume_", musicvolume)
+    end
+end
+
+function P.AudioMusicScrollbar_started(e)
+    musicscrollbar_active = true
+end
+
+function P.AudioMusicScrollbar_ended(e)
+    musicmutewindow:setSelected(false)
+    musicvolume = musicscrollbarwindow:getScrollPosition()
+    orxonox.config("SoundManager", "ambientVolume_", musicvolume)
+    musicscrollbar_active = false
+end
+
+function P.AudioEffectsScrollbar_changed(e)
+    if effectsmute then
+        block = true
+        effectsmutewindow:setSelected(false)
+        block = false
+        effectsmute = false
+    end
+    if effectsscrollbar_active == false then
+        effectsvolume = effectsscrollbarwindow:getScrollPosition()
+        orxonox.config("SoundManager", "effectsVolume_", effectsvolume)
+    end
+end
+
+function P.AudioEffectsScrollbar_started(e)
+    effectsscrollbar_active = true
+end
+
+function P.AudioEffectsScrollbar_ended(e)
+    effectsmutewindow:setSelected(false)
+    effectsvolume = effectsscrollbarwindow:getScrollPosition()
+    orxonox.config("SoundManager", "effectsVolume_", effectsvolume)
+    effectsscrollbar_active = false
+end
+
+function P.AudioMuteMasterCheckbox_clicked(e)
+    if block == false then
+        if mastermute then
+            masterscrollbarwindow:setScrollPosition(mastervolume)
+            mastermute = false
+        else
+            temp = masterscrollbarwindow:getScrollPosition()
+            masterscrollbarwindow:setScrollPosition(0)
+            mastervolume = temp
+            mastermute = true
+        end
+    end
+    soundMgr:toggleMute(orxonox.SoundType.All)
+end
+
+function P.AudioMuteMusicCheckbox_clicked(e)
+    if block == false then
+        if musicmute then
+            musicscrollbarwindow:setScrollPosition(musicvolume)
+            musicmute = false
+        else
+            temp = musicscrollbarwindow:getScrollPosition()
+            musicscrollbarwindow:setScrollPosition(0)
+            musicvolume = temp
+            musicmute = true
+        end
+    end
+    soundMgr:toggleMute(orxonox.SoundType.Music)
+end
+
+function P.AudioMuteEffectsCheckbox_clicked(e)
+    if block == false then
+        if effectsmute then
+            effectsscrollbarwindow:setScrollPosition(effectsvolume)
+            effectsmute = false
+        else
+            temp = effectsscrollbarwindow:getScrollPosition()
+            effectsscrollbarwindow:setScrollPosition(0)
+            effectsvolume = temp
+            effectsmute = true
+        end
+    end
+    soundMgr:toggleMute(orxonox.SoundType.Effects)
+end
+
+function P.AudioThemeListbox_changed(e)
+    if listboxwindow:isItemSelected(1) then
+        orxonox.config("MoodManager", "mood_", "dnb")
+    else
+        orxonox.config("MoodManager", "mood_", "default")
+    end
+end
+
+function P.AudioBackButton_clicked(e)
+    hideMenuSheet(P.name)
+end
+
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/ChatBox-inputonly.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/ChatBox-inputonly.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/ChatBox-inputonly.lua	(revision 6952)
@@ -0,0 +1,5 @@
+-- ChatBox-inputonly.lua
+
+local P = createMenuSheet("ChatBox-inputonly")
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/ChatBox.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/ChatBox.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/ChatBox.lua	(revision 6952)
@@ -0,0 +1,5 @@
+-- ChatBox.lua
+
+local P = createMenuSheet("ChatBox")
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/ControlsMenu.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/ControlsMenu.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/ControlsMenu.lua	(revision 6952)
@@ -0,0 +1,19 @@
+-- ControlsMenu.lua
+
+local P = createMenuSheet("ControlsMenu")
+P.loadAlong = { "MouseControlsMenu", "KeyBindMenu" }
+
+function P.ControlsMouseControlsButton_clicked(e)
+    showMenuSheet("MouseControlsMenu", true)
+end
+
+function P.ControlsKeyboardControlsButton_clicked(e)
+    showMenuSheet("KeyBindMenu", true)
+end
+
+function P.ControlsBackButton_clicked(e)
+    hideMenuSheet(P.name)
+end
+
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/CreditsMenu.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/CreditsMenu.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/CreditsMenu.lua	(revision 6952)
@@ -0,0 +1,10 @@
+-- CreditsMenu.lua
+
+local P = createMenuSheet("CreditsMenu")
+
+function P.CreditsBackButton_clicked(e)
+    hideMenuSheet(P.name)
+end
+
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/DecisionPopup.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/DecisionPopup.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/DecisionPopup.lua	(revision 6952)
@@ -0,0 +1,29 @@
+-- DecisionPopup.lua
+
+local P = createMenuSheet("DecisionPopup")
+
+function P.setCallback(functionPtr)
+    P.functionPtr = functionPtr
+end
+
+function P.setText( text )
+    winMgr:getWindow("orxonox/DecisionPopup_text"):setText( text )
+end
+
+-- events for ingamemenu
+function P.button_yes(e)
+    if P.functionPtr ~= nil then
+        P.functionPtr(true)
+    end
+    hideMenuSheet("DecisionPopup")
+end
+
+function P.button_no(e)
+    if P.functionPtr ~= nil then
+        P.functionPtr(false)
+    end
+    hideMenuSheet("DecisionPopup")
+end
+
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/GUISheet.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/GUISheet.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/GUISheet.lua	(revision 6952)
@@ -0,0 +1,62 @@
+-- GUISheet.lua
+
+local P = {}
+_G[_REQUIREDNAME or "GUISheet"] = P
+P.__index = P
+
+-- Don't use directly --> use HUDSheet.new or MenuSheet.new
+function P.new(_name)
+    local newSheet = { name = _name }
+    setmetatable(newSheet, P)
+    return newSheet
+end
+
+-- Override this function if you need to do work on load
+function P:onLoad()
+end
+
+-- show function for the GUI
+function P:show()
+    self.window:show()
+    self.bVisible = true
+
+    self:onShow()
+end
+
+-- Override this function if you need to do work on show
+function P:onShow()
+end
+
+-- hide function for the GUI
+function P:hide()
+    self.window:hide()
+    self.bVisible = false
+
+    self:onHide()
+end
+
+-- Override this function if you need to do work on hide
+function P:onHide()
+end
+
+function P:load()
+    -- Load the layout that describes the sheet
+    self.window = winMgr:loadWindowLayout(self.name .. ".layout")
+    if self.window == nil then
+        error("Could not load layout file for GUI sheet '"..self.name.."'")
+    end
+    -- Hide it at first
+    self:hide()
+    -- Allow sheets to do some work upon loading
+    self:onLoad()
+
+    -- Also load additional sheets to avoid display lags
+    if self.loadAlong then
+        for k, sheet in pairs(self.loadAlong) do
+            loadSheet(sheet)
+        end
+    end
+    return self
+end
+
+return P
Index: /code/branches/rocket2/data/gui/scripts/GUITools.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/GUITools.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/GUITools.lua	(revision 6952)
@@ -0,0 +1,46 @@
+-- Returns a new menu sheet
+-- See MenuSheet.new for details about the parameters
+function createMenuSheet(name, bHidePrevious, tShowCursor, tUseKeyboard, bBlockJoyStick)
+    local sheet = require("MenuSheet").new(name, bHidePrevious, tShowCursor, tUseKeyboard, bBlockJoyStick)
+    _G[sheet.name] = sheet -- Global access required because of the event handlers
+    return sheet
+end
+
+-- Returns a new HUD sheet
+function createHUDSheet(name)
+    local sheet = require("HUDSheet").new(name)
+    _G[sheet.name] = sheet -- Global access required because of the event handlers
+    return sheet
+end
+
+function openDecisionPopup( text, callbackPtr )
+    showMenuSheet("DecisionPopup", false, true)
+    DecisionPopup.setCallback(callbackPtr)
+    DecisionPopup.setText(text)
+end
+
+function openInfoPopup(text, functionPtr, closeButton, arguments)
+    showMenuSheet("InfoPopup", false, true)
+    InfoPopup.execute(functionPtr, arguments)
+    InfoPopup.setText(text)
+    InfoPopup.setCloseButton(closeButton)
+end
+
+function getMinTextSize(window)
+    local size = {}
+
+    local lookAndFeel = CEGUI.WidgetLookManager:getSingleton():getWidgetLook(window:getLookNFeel())
+    local height = window:getFont():getLineSpacing() + window:getUnclippedPixelRect():getHeight() - lookAndFeel:getNamedArea("WithFrameTextRenderArea"):getArea():getPixelRect(window):getHeight()
+    local width =  window:getFont():getTextExtent(window:getText()) + window:getUnclippedPixelRect():getWidth() - lookAndFeel:getNamedArea("WithFrameTextRenderArea"):getArea():getPixelRect(window):getWidth()
+
+    table.insert(size, height)
+    table.insert(size, width)
+    return size
+end
+
+function getScrollingStepSize(window)
+    local height = window:getUnclippedPixelRect():getHeight()
+    local maxHeight = CEGUI.System:getSingleton():getGUISheet():getUnclippedPixelRect():getHeight()
+    local ratio = height/maxHeight
+    return 0.008*ratio/0.3204
+end
Index: /code/branches/rocket2/data/gui/scripts/GameplayMenu.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/GameplayMenu.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/GameplayMenu.lua	(revision 6952)
@@ -0,0 +1,43 @@
+-- GameplayMenu.lua
+
+local P = createMenuSheet("GameplayMenu")
+
+function P.onLoad()
+    dropdown = winMgr:getWindow("orxonox/ThemeCombobox")
+    local themeList = {}
+    table.insert(themeList, "Theme 1")
+    table.insert(themeList, "Theme 2")
+    table.insert(themeList, "Theme 3")
+    for k,v in pairs(themeList) do
+        item = CEGUI.createListboxTextItem(v)
+        item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+        CEGUI.toCombobox(dropdown):addItem(item)
+    end
+end
+
+function P.GameplayThemeCombobox_changed(e)
+    -- theme
+    logMessage(0, "event: theme")
+end
+
+function P.GameplayDifficultyEasyButton_clicked(e)
+    -- difficulty easy
+    logMessage(0, "event: easy")
+end
+
+function P.GameplayDifficultyNormalButton_clicked(e)
+    -- difficulty normal
+    logMessage(0, "event: normal")
+end
+
+function P.GameplayDifficultyHardButton_clicked(e)
+    -- difficulty hard
+    logMessage(0, "event: hard")
+end
+
+function P.GameplayBackButton_clicked(e)
+    hideMenuSheet(P.name)
+end
+
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/GraphicsMenu.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/GraphicsMenu.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/GraphicsMenu.lua	(revision 6952)
@@ -0,0 +1,198 @@
+-- GraphicsMenu.lua
+
+local P = createMenuSheet("GraphicsMenu")
+
+function P.onLoad()
+    block = true
+    file = orxonox.PathConfig:getConfigPathString() .. orxonox.getConfig("GraphicsManager", "ogreConfigFile_")
+    search_mode = 0
+    f = io.open(file, "r")
+    firstline = f:read("*line")
+    rendersystem = string.sub(firstline, 15)
+    for line in f:lines() do
+        if search_mode == 0 then
+            if string.find(line, rendersystem) ~= nil then
+                search_mode = 1
+            end
+        end
+        if search_mode == 1 then
+            if string.sub(line, 1, 11) == "Full Screen" then
+                if string.sub(line, 13) == "Yes" then
+                    fullscreen = true
+                else
+                    fullscreen = false
+                end
+            end
+            if string.sub(line, 1, 10) == "Video Mode" then
+                if string.match(line, "@") == "@" then
+                    resolution = string.sub(line, 12, string.find(line, "@")-2)
+                else
+                    resolution = string.sub(line, 12)
+                end
+                break
+            end
+        end
+    end
+    f:close()
+    local fullscreenwindow = tolua.cast(winMgr:getWindow("orxonox/FullscreenCheckbox"),"CEGUI::Checkbox")
+    fullscreenwindow:setSelected(fullscreen)
+    listboxwindow = winMgr:getWindow("orxonox/ResolutionListbox")
+    local resolutionList = {}
+    table.insert(resolutionList, "640 x 480")
+    table.insert(resolutionList, "720 x 480")
+    table.insert(resolutionList, "720 x 576")
+    table.insert(resolutionList, "800 x 480")
+    table.insert(resolutionList, "800 x 600")
+    table.insert(resolutionList, "1024 x 480")
+    table.insert(resolutionList, "1024 x 600")
+    table.insert(resolutionList, "1024 x 768")
+    table.insert(resolutionList, "1152 x 864")
+    table.insert(resolutionList, "1280 x 720")
+    table.insert(resolutionList, "1280 x 768")
+    table.insert(resolutionList, "1440 x 900")
+    for k,v in pairs(resolutionList) do
+        item = CEGUI.createListboxTextItem(v)
+        item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+        CEGUI.toListbox(listboxwindow):addItem(item)
+    end
+    if resolution == "640 x 480" then
+        listboxwindow:setItemSelectState(0,true)
+    elseif resolution == "720 x 480" then
+        listboxwindow:setItemSelectState(1,true)
+    elseif resolution == "720 x 576" then
+        listboxwindow:setItemSelectState(2,true)
+    elseif resolution == "800 x 480" then
+        listboxwindow:setItemSelectState(3,true)
+    elseif resolution == "800 x 600" then
+        listboxwindow:setItemSelectState(4,true)
+    elseif resolution == "1024 x 480" then
+        listboxwindow:setItemSelectState(5,true)
+    elseif resolution == "1024 x 600" then
+        listboxwindow:setItemSelectState(6,true)
+    elseif resolution == "1024 x 768" then
+        listboxwindow:setItemSelectState(7,true)
+    elseif resolution == "1152 x 864" then
+        listboxwindow:setItemSelectState(8,true)
+    elseif resolution == "1280 x 720" then
+        listboxwindow:setItemSelectState(9,true)
+    elseif resolution == "1280 x 768" then
+        listboxwindow:setItemSelectState(10,true)
+    elseif resolution == "1440 x 900" then
+        listboxwindow:setItemSelectState(11,true)
+    end
+    scrollbar_active = false
+    block = false
+end
+
+function P.GraphicsResolutionListbox_changed(e)
+    if listboxwindow:isItemSelected(0) then
+        resolution = "640 x 480"
+    elseif listboxwindow:isItemSelected(1) then
+        resolution = "720 x 480"
+    elseif listboxwindow:isItemSelected(2) then
+        resolution = "720 x 576"
+    elseif listboxwindow:isItemSelected(3) then
+        resolution = "800 x 480"
+    elseif listboxwindow:isItemSelected(4) then
+        resolution = "800 x 600"
+    elseif listboxwindow:isItemSelected(5) then
+        resolution = "1024 x 480"
+    elseif listboxwindow:isItemSelected(6) then
+        resolution = "1024 x 600"
+    elseif listboxwindow:isItemSelected(7) then
+        resolution = "1024 x 768"
+    elseif listboxwindow:isItemSelected(8) then
+        resolution = "1152 x 864"
+    elseif listboxwindow:isItemSelected(9) then
+        resolution = "1280 x 720"
+    elseif listboxwindow:isItemSelected(10) then
+        resolution = "1280 x 768"
+    elseif listboxwindow:isItemSelected(11) then
+        resolution = "1440 x 900"
+    end
+    search_mode = 0
+    f = io.open(file, "r")
+    firstline = f:read("*line")
+    text = firstline .. "\n"
+    rendersystem = string.sub(firstline, 15)
+    for line in f:lines() do
+        if search_mode == 0 then
+            if string.find(line, rendersystem) ~= nil then
+                search_mode = 1
+            end
+        end
+        if search_mode == 1 then
+            if string.sub(line, 1, 10) == "Video Mode" then
+                if string.match(line, "@") == "@" then
+                    line = "Video Mode=" .. resolution .. string.sub(line, string.find(line, "@")-1)
+                else
+                    line = "Video Mode=" .. resolution
+                end
+                search_mode = 2
+            end
+        end
+        text = text .. line .. "\n"
+    end
+    f:close()
+    f = io.open(file, "w")
+    f:write(text)
+    f:close()
+end
+
+function P.GraphicsBrightnessScrollbar_changed(e)
+    if scrollbar_active == false then
+        -- brightness
+        logMessage(0, "event: brightness")
+    end
+end
+
+function P.GraphicsBrightnessScrollbar_started(e)
+    scrollbar_active = true
+end
+
+function P.GraphicsBrightnessScrollbar_ended(e)
+    -- brightness
+    logMessage(0, "event: brightness")
+    scrollbar_active = false
+end
+
+function P.GraphicsFullscreenCheckbox_clicked(e)
+    if block == false then
+        search_mode = 0
+        f = io.open(file, "r")
+        firstline = f:read("*line")
+        text = firstline .. "\n"
+        rendersystem = string.sub(firstline, 15)
+        for line in f:lines() do
+            if search_mode == 0 then
+                if string.find(line, rendersystem) ~= nil then
+                    search_mode = 1
+                end
+            end
+            if search_mode == 1 then
+                if string.sub(line, 1, 11) == "Full Screen" then
+                    if fullscreen == true then
+                        line = "Full Screen=No"
+                        fullscreen = false
+                    else
+                        line = "Full Screen=Yes"
+                        fullscreen = true
+                    end
+                    search_mode = 2
+                end
+            end
+            text = text .. line .. "\n"
+        end
+        f:close()
+        f = io.open(file, "w")
+        f:write(text)
+        f:close()
+    end
+end
+
+function P.GraphicsBackButton_clicked(e)
+    hideMenuSheet(P.name)
+end
+
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/HUDSheet.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/HUDSheet.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/HUDSheet.lua	(revision 6952)
@@ -0,0 +1,15 @@
+-- HUDSheet.lua
+
+local P = {} -- Local alias, always use it in this file
+HUDSheet = P -- Global name
+setmetatable(P, require("GUISheet")) -- Inherit from GUISheet
+P.__index = P -- Provide class character
+
+-- Use this function to construct a new HUDSheet
+function P.new(name)
+    local newSheet = GUISheet.new(name)
+    setmetatable(newSheet, P)
+    return newSheet
+end
+
+return P
Index: /code/branches/rocket2/data/gui/scripts/InGameMenu.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/InGameMenu.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/InGameMenu.lua	(revision 6952)
@@ -0,0 +1,34 @@
+-- InGameMenu.lua
+
+local P = createMenuSheet("InGameMenu")
+P.loadAlong = { "DecisionPopup" }
+
+-- events for ingamemenu
+function P.button_quit_clicked(e)
+    openDecisionPopup( "Do you really want to quit the game?", InGameMenu.callback )
+end
+
+function P.button_mainmenu_clicked(e)
+    orxonox.Game:getInstance():popState()
+    orxonox.Game:getInstance():popState()
+    orxonox.Game:getInstance():requestState("mainmenu")
+    hideMenuSheet("InGameMenu")
+end
+
+function P.button_settings_clicked(e)
+    showMenuSheet("SettingsMenu", true)
+end
+
+function P.button_return_clicked(e)
+    hideMenuSheet("InGameMenu")
+end
+
+function P.callback(doExit)
+    if doExit then
+        hideMenuSheet("InGameMenu")
+        orxonox.execute("exit")
+    end
+end
+
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/InGamePickupHUD.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/InGamePickupHUD.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/InGamePickupHUD.lua	(revision 6952)
@@ -0,0 +1,33 @@
+-- InGamePickupHUD.lua
+
+BasicGUI = require("BasicGUI")
+local P = BasicGUI:new() --inherit everything from the gui package
+if _REQUIREDNAME == nil then
+    InGamePickupHUD = P
+else
+    _G[_REQUIREDNAME] = P
+end
+
+P.filename = "InGamePickupHUD"
+P.layoutString = "InGamePickupHUD.layout"
+
+function P:init()
+end
+
+
+-- events for ingamemenu
+
+
+function P.button_Pickup_clicked(e)
+    orxonox.Game:getInstance():popState()
+    orxonox.Game:getInstance():popState()
+    orxonox.Game:getInstance():requestState("mainmenu")
+    hideGUI("InGameMenu")
+end
+
+function P.close_button_clicked()
+    hideGUI("InGamePickupHUD")
+end
+
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/InfoPopup.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/InfoPopup.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/InfoPopup.lua	(revision 6952)
@@ -0,0 +1,34 @@
+-- InfoPopup.lua
+
+local P = createMenuSheet("InfoPopup")
+
+function P.execute(functionPtr, arguments)
+    if functionPtr ~= nil then
+        if arguments ~= nil then
+            functionPtr(arguments)
+        else
+            functionPtr()
+        end
+    end
+end
+
+function P.setText(text)
+    winMgr:getWindow("orxonox/InfoPopup_text"):setText( text )
+end
+
+function P.setCloseButton(closeButton)
+    close = winMgr:getWindow("orxonox/InfoPopup_close")
+    close:setVisible(closeButton)
+    if(not closeButton) then
+        close:deactivate();
+    else
+        close:activate();
+    end
+end
+
+-- events for ingamemenu
+function P.close(e)
+    hideMenuSheet(P.name)
+end
+
+return P
Index: /code/branches/rocket2/data/gui/scripts/InitialiseGUI.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/InitialiseGUI.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/InitialiseGUI.lua	(revision 6952)
@@ -0,0 +1,31 @@
+-- Define some global shortcuts for common Managers
+guiMgr    = orxonox.GUIManager:getInstance()
+inputMgr  = orxonox.InputManager:getInstance()
+schemeMgr = CEGUI.SchemeManager:getSingleton()
+winMgr    = CEGUI.WindowManager:getSingleton()
+
+-- Load all required skins
+schemeMgr:loadScheme("TaharezGreenLook.scheme")
+--schemeMgr:loadScheme("TaharezLook.scheme")
+--schemeMgr:loadScheme("WindowsLook.scheme")
+--schemeMgr:loadScheme("VanillaLook.scheme")
+--schemeMgr:loadScheme("SleekSpaceLook.scheme")
+
+-- Connect skin specific window types with our own window types
+-- By loading a different file (if there is) you can change the skin
+-- of the menus or the HUD independently
+schemeMgr:loadScheme("TaharezGreenMenuWidgets.scheme")
+menuImageSet = "TaharezGreenLook"
+schemeMgr:loadScheme("TaharezGreenHUDWidgets.scheme")
+hudImageSet = "TaharezGreenLook"
+
+-- Just a remaining test hack
+schemeMgr:loadScheme("OrxonoxGUIScheme.scheme")
+
+local system = CEGUI.System:getSingleton()
+system:setDefaultMouseCursor(menuImageSet, "MouseArrow")
+system:setDefaultFont("BlueHighway-12")
+system:setDefaultTooltip("MenuWidgets/Tooltip")
+
+-- Convenience function and additional tools
+require("GUITools")
Index: /code/branches/rocket2/data/gui/scripts/KeyBindMenu.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/KeyBindMenu.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/KeyBindMenu.lua	(revision 6952)
@@ -0,0 +1,250 @@
+-- KeyBindMenu.lua
+
+local P = createMenuSheet("KeyBindMenu")
+P.loadAlong = { "InfoPopup" }
+
+function P.onLoad()
+
+    commandList = {}
+    table.insert(commandList, "fire 0")
+    table.insert(commandList, "fire 1 | unfire")
+    table.insert(commandList, "onpress fire 2")
+    table.insert(commandList, "scale 1 moveFrontBack")
+    table.insert(commandList, "scale -1 moveFrontBack")
+    table.insert(commandList, "boost")
+    table.insert(commandList, "scale 1 moveRightLeft")
+    table.insert(commandList, "scale -1 moveRightLeft")
+    table.insert(commandList, "scale 1 moveUpDown")
+    table.insert(commandList, "scale -1 moveUpDown")
+    table.insert(commandList, "scale -1 rotateRoll")
+    table.insert(commandList, "scale 1 rotateRoll")
+    table.insert(commandList, "scale 1 rotateYaw")
+    table.insert(commandList, "scale -1 rotateYaw")
+    table.insert(commandList, "scale 1 rotatePitch")
+    table.insert(commandList, "scale -1 rotatePitch")
+    table.insert(commandList, "NewHumanController changeMode")
+    table.insert(commandList, "switchCamera")
+    table.insert(commandList, "openConsole")
+    table.insert(commandList, "OverlayGroup toggleVisibility Debug")
+    table.insert(commandList, "OverlayGroup toggleVisibility Stats")
+    table.insert(commandList, "mouseLook")
+    table.insert(commandList, "pause")
+
+    nameList = {}
+    table.insert(nameList, "Primary Fire")
+    table.insert(nameList, "Secondary Fire")
+    table.insert(nameList, "Fire Rocket")
+    table.insert(nameList, "Accelerate")
+    table.insert(nameList, "Break")
+    table.insert(nameList, "Boost")
+    table.insert(nameList, "Move Right")
+    table.insert(nameList, "Move Left")
+    table.insert(nameList, "Move Up")
+    table.insert(nameList, "Move Down")
+    table.insert(nameList, "Roll Right")
+    table.insert(nameList, "Roll Left")
+    table.insert(nameList, "Yaw Left")
+    table.insert(nameList, "Yaw Right")
+    table.insert(nameList, "Pitch Up")
+    table.insert(nameList, "Pitch Down")
+    table.insert(nameList, "Switch Input Mode")
+    table.insert(nameList, "Switch Camera")
+    table.insert(nameList, "Open Console")
+    table.insert(nameList, "Show Debug")
+    table.insert(nameList, "Show Stats")
+    table.insert(nameList, "Look Around")
+    table.insert(nameList, "Pause")
+
+    linesList = {}
+
+    --Calculate design parameters:
+    sampleWindow = winMgr:createWindow("MenuWidgets/StaticText", "orxonox/KeyBindPane/SampleWindow")
+    sampleWindow:setText("SampleText")
+
+    local size = getMinTextSize(sampleWindow)
+    lineHeight = size[1]
+
+    commandWidth = 0
+    for k,v in pairs(commandList) do
+        sampleWindow:setText(nameList[k])
+        size = getMinTextSize(sampleWindow)
+        if size[2] > commandWidth then
+            commandWidth = size[2]
+        end
+    end
+
+    sampleWindow:setText("add")
+    size = getMinTextSize(sampleWindow)
+    addWidth = size[2]
+
+    sampleWindow:setText("X")
+    size = getMinTextSize(sampleWindow)
+    clearWidth = size[2]
+
+    spaceWidth = math.floor(1/14*commandWidth)
+
+    buttonWidth = 145
+
+    P.createLines()
+
+    local funct = luaState:createLuaFunctor("KeyBindMenu.callback()")
+    orxonox.KeyBinderManager:getInstance():registerKeybindCallback(funct)
+end
+
+function P.KeyNameNiceifier(key)
+    local name = string.sub(key, string.find(key, '%.(.*)')+1)
+    local group = string.sub(key, string.find(key, '(.*)%.'))
+    group = string.sub(group,1,string.len(group)-1)
+    if( group == "Keys") then
+        return "Key " .. string.sub(name, string.find(name, 'Key(.*)')+3)
+    elseif( group == "MouseButtons") then
+        return "Mouse " .. name
+    elseif( string.find(group, "JoyStickButtons") ~= nil ) then
+        return "Joystick " .. name
+    elseif( string.find(group, "JoyStickAxes") ~= nil ) then
+        return "Joystick Axis" .. string.sub(name, 5, 6) .. string.sub(name, string.find(name, 'Axis%d%d(.*)')+6)
+    elseif( group == "MouseAxes" ) then
+        return "Mouse " .. string.sub(name, string.find(name, '.(.*)')+1) .. " " .. string.sub(name, 1, 1) .. "-Axis"
+    end
+    return key
+end
+
+function P.createLine(k)
+    local offset = 0
+    local line = winMgr:createWindow("DefaultWindow", "orxonox/KeyBindPane/Binding" .. k)
+    line:setHeight(CEGUI.UDim(0, lineHeight))
+    line:setPosition(CEGUI.UVector2(CEGUI.UDim(0, 0), CEGUI.UDim(0, lineHeight*(k-1))))
+
+    local command = winMgr:createWindow("MenuWidgets/StaticText", "orxonox/KeyBindPane/Binding" .. k .. "/Command")
+    command:setText(nameList[k])
+    command:setSize(CEGUI.UVector2(CEGUI.UDim(0, commandWidth), CEGUI.UDim(1, 0)))
+    command:setPosition(CEGUI.UVector2(CEGUI.UDim(0, offset), CEGUI.UDim(0, 0)))
+    line:addChildWindow(command)
+    offset = offset + commandWidth + spaceWidth
+
+    local plus = winMgr:createWindow("MenuWidgets/TabButton", "orxonox/KeyBindPane/Binding" .. k .. "/Plus")
+    plus:setSize(CEGUI.UVector2(CEGUI.UDim(0, addWidth), CEGUI.UDim(0.7, 0)))
+    plus:setPosition(CEGUI.UVector2(CEGUI.UDim(0, offset), CEGUI.UDim(0.15, 0)))
+    plus:setText("add")
+    orxonox.GUIManager:subscribeEventHelper(plus, "Clicked", P.name .. ".KeyBindPlus_clicked")
+    line:addChildWindow(plus)
+    offset = offset + addWidth + spaceWidth
+
+    local numButtons = orxonox.KeyBinderManager:getInstance():getCurrent():getNumberOfBindings(commandList[k]);
+    for i=0,(numButtons-1) do
+        local button = winMgr:createWindow("MenuWidgets/TabButton", "orxonox/KeyBindPane/Binding" .. k .. "/Button" .. i)
+        local name = orxonox.KeyBinderManager:getInstance():getCurrent():getBinding(commandList[k],i)
+        name = P.KeyNameNiceifier(name)
+        button:setText(name)
+        sampleWindow:setText(name)
+        local size = getMinTextSize(sampleWindow)
+        local buttonWidth = size[2]
+        button:setSize(CEGUI.UVector2(CEGUI.UDim(0, buttonWidth), CEGUI.UDim(0.7, 0)))
+        button:setPosition(CEGUI.UVector2(CEGUI.UDim(0, offset), CEGUI.UDim(0.15, 0)))
+        orxonox.GUIManager:subscribeEventHelper(button, "Clicked", P.name .. ".KeyBindButton_clicked")
+        --button:subscribeScriptedEvent("EventClicked", P.name .. ".KeyBindButton_clicked")
+        line:addChildWindow(button)
+        offset = offset + buttonWidth
+
+        local clear = winMgr:createWindow("MenuWidgets/TabButton", "orxonox/KeyBindPane/Binding" .. k .. "/Clear" .. i)
+        clear:setSize(CEGUI.UVector2(CEGUI.UDim(0, clearWidth), CEGUI.UDim(0.7, 0)))
+        clear:setPosition(CEGUI.UVector2(CEGUI.UDim(0, offset), CEGUI.UDim(0.15, 0)))
+        clear:setText("X")
+        orxonox.GUIManager:subscribeEventHelper(clear, "Clicked", P.name .. ".KeyBindClear_clicked")
+        line:addChildWindow(clear)
+        offset = offset + clearWidth + spaceWidth
+    end
+
+    line:setWidth(CEGUI.UDim(0, offset+clearWidth))
+
+    return line
+end
+
+function P.createLines()
+    local window = winMgr:getWindow("orxonox/KeyBindPane")
+
+    for k,v in pairs(commandList) do
+        local line = P.createLine(k)
+        table.insert(linesList, line)
+        window:addChildWindow(line)
+    end
+
+    pane = tolua.cast(window, "CEGUI::ScrollablePane")
+    pane:setVerticalStepSize(getScrollingStepSize(window))
+end
+
+function P.KeyBindButton_clicked(e)
+    local we = CEGUI.toWindowEventArgs(e)
+    local name = we.window:getName()
+
+    local match = string.gmatch(name, "%d+")
+    local commandNr = tonumber(match())
+    local buttonNr = tonumber(match())
+
+    local arguments = {}
+    arguments[1] = commandNr
+    arguments[2] = buttonNr
+    openInfoPopup("Press any button/key or move a mouse/joystick axis.", KeyBindMenu.keybind, false, arguments)
+end
+
+function P.KeyBindPlus_clicked(e)
+    local we = CEGUI.toWindowEventArgs(e)
+    local name = we.window:getName()
+
+    local match = string.gmatch(name, "%d+")
+    local commandNr = tonumber(match())
+
+    local arguments = {}
+    arguments[1] = commandNr
+    openInfoPopup("Press any button/key or move a mouse/joystick axis.", KeyBindMenu.keybind, false, arguments)
+end
+
+function P.KeyBindClear_clicked(e)
+    local we = CEGUI.toWindowEventArgs(e)
+    local name = we.window:getName()
+
+    local match = string.gmatch(name, "%d+")
+    local commandNr = tonumber(match())
+    local buttonNr = tonumber(match())
+
+    local str = orxonox.KeyBinderManager:getInstance():getCurrent():getBinding(commandList[commandNr], buttonNr)
+    orxonox.KeyBinderManager:getInstance():unbind(str)
+
+    P.callback()
+end
+
+function P.keybind(arguments)
+    local commandNr = arguments[1]
+    local buttonNr = arguments[2]
+    if buttonNr ~= nil then
+        local str = orxonox.KeyBinderManager:getInstance():getCurrent():getBinding(commandList[commandNr], buttonNr)
+        orxonox.KeyBinderManager:getInstance():unbind(str)
+    end
+
+    orxonox.KeyBinderManager:getInstance():keybind(commandList[commandNr])
+end
+
+function P.callback()
+    local pane = tolua.cast(winMgr:getWindow("orxonox/KeyBindPane"), "CEGUI::ScrollablePane")
+    local position = pane:getVerticalScrollPosition()
+    while table.getn(linesList) ~= 0 do
+        if linesList[1] ~= nil then
+            winMgr:destroyWindow(linesList[1]:getName())
+        end
+        table.remove(linesList, 1)
+    end
+
+    linesList = {}
+
+    P.createLines()
+    if(InfoPopup ~= nil) then
+        InfoPopup.close()
+    end
+    pane:setVerticalScrollPosition( position )
+end
+
+function P.KeyBindBackButton_clicked(e)
+    hideMenuSheet("KeyBindMenu")
+end
+
+return P
Index: /code/branches/rocket2/data/gui/scripts/MainMenu.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/MainMenu.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/MainMenu.lua	(revision 6952)
@@ -0,0 +1,32 @@
+-- MainMenu.lua
+
+local P = createMenuSheet("MainMenu")
+P.loadAlong = { "SingleplayerMenu", "MultiplayerMenu", "SettingsMenu", "CreditsMenu" }
+
+-- events for MainMenu
+function P.QuickGameTestButton_clicked(e)
+    orxonox.execute("startGame")
+end
+
+function P.SingleplayerButton_clicked(e)
+    showMenuSheet("SingleplayerMenu", true)
+end
+
+function P.MultiplayerButton_clicked(e)
+    showMenuSheet("MultiplayerMenu", true)
+end
+
+function P.SettingsButton_clicked(e)
+    showMenuSheet("SettingsMenu", true)
+end
+
+function P.CreditsButton_clicked(e)
+    showMenuSheet("CreditsMenu", true)
+end
+
+function P.ExitButton_clicked(e)
+    orxonox.execute("exit")
+end
+
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/MenuSheet.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/MenuSheet.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/MenuSheet.lua	(revision 6952)
@@ -0,0 +1,36 @@
+-- MenuSheet.lua
+-- Base class for all GUI sheets that represent a menu.
+-- Inherits itself from GUISheet
+
+local P = {}  -- Local alias, always use it in this file
+MenuSheet = P -- Global name
+setmetatable(P, require("GUISheet")) -- Inherit from GUISheet
+P.__index = P -- Provide class character
+
+-- Use this function to construct a new MenuSheet.
+-- Parameters:
+-- Except for _name, you can provide nil. Then the default value will be used.
+-- For _tShowCusor and _tUseKeyboard you can specify TriBool.Dontcare if the value doesn't matter at all. Then the value of the underlaying sheet will be used.
+function P.new(_name, _bHidePrevious, _tShowCursor, _tUseKeyboard, _bBlockJoyStick)
+    local newSheet = GUISheet.new(_name)
+    newSheet.bHidePrevious  = handleDefArg(_bHidePrevious,  true)
+    newSheet.tShowCursor    = handleDefArg(_tShowCusor,     TriBool.True)
+    newSheet.tUseKeyboard   = handleDefArg(_tUseKeyboard,   TriBool.Dontcare)
+    newSheet.bBlockJoyStick = handleDefArg(_bBlockJoyStick, false)
+
+    setmetatable(newSheet, P)
+    return newSheet
+end
+
+function P:load()
+    -- Create the input state
+    self.inputState = guiMgr:createInputState("GUI_" .. self.name,
+        self.tShowCursor, self.tUseKeyboard, self.bBlockJoyStick)
+
+    -- load() of base 'class'
+    GUISheet.load(self)
+
+    return self
+end
+
+return P
Index: /code/branches/rocket2/data/gui/scripts/MouseControlsMenu.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/MouseControlsMenu.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/MouseControlsMenu.lua	(revision 6952)
@@ -0,0 +1,101 @@
+-- MouseControlsMenu.lua
+
+local P = createMenuSheet("MouseControlsMenu")
+
+function P.onLoad()
+    block = false
+    mousenormalscrollbarwindow = tolua.cast(winMgr:getWindow("orxonox/MouseNormalScrollbar"),"CEGUI::Scrollbar")
+    mousederivescrollbarwindow = tolua.cast(winMgr:getWindow("orxonox/MouseDeriveScrollbar"),"CEGUI::Scrollbar")
+    normalwindow = tolua.cast(winMgr:getWindow("orxonox/MouseNormalButton"),"CEGUI::RadioButton")
+    derivewindow = tolua.cast(winMgr:getWindow("orxonox/MouseDeriveButton"),"CEGUI::RadioButton")
+    invertwindow = tolua.cast(winMgr:getWindow("orxonox/MouseInvertCheckbox"),"CEGUI::Checkbox")
+    mousenormalscrollbar_active = false
+    mousederivescrollbar_active = false
+    derive_active = orxonox.getConfig("KeyBinder","bDeriveMouseInput_")
+    invert_active = false
+    mousenormalsensitivity = orxonox.getConfig("KeyBinder","mouseSensitivity_")
+    mousederivesensitivity = orxonox.getConfig("KeyBinder","mouseSensitivityDerived_")
+    mousenormalscrollbarwindow:setScrollPosition((math.log(14*mousenormalsensitivity-6))/(6*math.log(2)))
+    mousederivescrollbarwindow:setScrollPosition((math.log(14*mousederivesensitivity-6))/(6*math.log(2)))
+    if derive_active == "true" then
+        normal_active = false
+        derive_active = true
+        derivewindow:setSelected(derive_active)
+    else
+        normal_active = true
+        derive_active = false
+        normalwindow:setSelected(normal_active)
+    end
+    if invert_active == "true" then
+        invert_active = true
+    else
+        invert_active = false
+    end
+end
+
+function P.MouseControlsMouseNormalScrollbar_changed(e)
+    if mousenormalscrollbar_active == false then
+        scrollposition = mousenormalscrollbarwindow:getScrollPosition()
+        mousenormalsensitivity = (math.pow(64,scrollposition)+6)/14
+        orxonox.config("KeyBinder", "mouseSensitivity_", mousenormalsensitivity)
+    end
+end
+
+function P.MouseControlsMouseNormalScrollbar_started(e)
+    mousenormalscrollbar_active = true
+end
+
+function P.MouseControlsMouseNormalScrollbar_ended(e)
+    scrollposition = mousenormalscrollbarwindow:getScrollPosition()
+    mousenormalsensitivity = (math.pow(64,scrollposition)+6)/14
+    orxonox.config("KeyBinder", "mouseSensitivity_", mousenormalsensitivity)
+    mousenormalscrollbar_active = false
+end
+
+function P.MouseControlsMouseDeriveScrollbar_changed(e)
+    if mousederivescrollbar_active == false then
+        scrollposition = mousederivescrollbarwindow:getScrollPosition()
+        mousederivesensitivity = (math.pow(64,scrollposition)+6)/14
+        orxonox.config("KeyBinder", "mouseSensitivityDerived_", mousederivesensitivity)
+    end
+end
+
+function P.MouseControlsMouseDeriveScrollbar_started(e)
+    mousederivescrollbar_active = true
+end
+
+function P.MouseControlsMouseDeriveScrollbar_ended(e)
+    scrollposition = mousederivescrollbarwindow:getScrollPosition()
+    mousederivesensitivity = (math.pow(64,scrollposition)+6)/14
+    orxonox.config("KeyBinder", "mouseSensitivityDerived_", mousederivesensitivity)
+    mousederivescrollbar_active = false
+end
+
+function P.MouseNormalButton_clicked(e)
+    if block == false then
+        block = true
+        derivewindow:setSelected(false)
+        block = false
+        orxonox.config("KeyBinder", "bDeriveMouseInput_", 0)
+    end
+end
+
+function P.MouseDeriveButton_clicked(e)
+    if block == false then
+        block = true
+        normalwindow:setSelected(false)
+        block = false
+        orxonox.config("KeyBinder", "bDeriveMouseInput_", 1)
+    end
+end
+
+function P.MouseInvertCheckbox_clicked(e)
+    -- invert mouse
+end
+
+function P.MouseControlsBackButton_clicked(e)
+    hideMenuSheet(P.name)
+end
+
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/MultiplayerMenu.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/MultiplayerMenu.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/MultiplayerMenu.lua	(revision 6952)
@@ -0,0 +1,73 @@
+-- MultiplayerMenu.lua
+
+local P = createMenuSheet("MultiplayerMenu")
+
+function P.onLoad()
+    listbox = winMgr:getWindow("orxonox/MultiplayerLevelListbox")
+    preselect = orxonox.LevelManager:getInstance():getDefaultLevel()
+    orxonox.LevelManager:getInstance():compileAvailableLevelList()
+    local levelList = {}
+    local index = 0
+    local level = ""
+    while true do
+        level = orxonox.LevelManager:getInstance():getAvailableLevelListItem(index)
+        if level == "" then
+            break
+        end
+        table.insert(levelList, level)
+        index = index + 1
+    end
+    table.sort(levelList)
+    for k,v in pairs(levelList) do
+        item = CEGUI.createListboxTextItem(v)
+        item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+        CEGUI.toListbox(listbox):addItem(item)
+        if v .. ".oxw" == preselect then
+            listbox:setItemSelectState(item, true)
+        end
+    end
+    local multiplayerMode = "startClient"
+    if multiplayerMode == "startClient" then
+        window = winMgr:getWindow("orxonox/MultiplayerJoinButton")
+        button = tolua.cast(window,"CEGUI::RadioButton")
+        button:setSelected(true)
+    end
+    if multiplayerMode == "startServer" then
+        window = winMgr:getWindow("orxonox/MultiplayerHostButton")
+        button = tolua.cast(window,"CEGUI::RadioButton")
+        button:setSelected(true)
+    end
+    if multiplayerMode == "startDedicated" then
+        window = winMgr:getWindow("orxonox/MultiplayerDedicatedButton")
+        button = tolua.cast(window,"CEGUI::RadioButton")
+        button:setSelected(true)
+    end
+end
+
+function P.MultiplayerJoinButton_clicked(e)
+    multiplayerMode = "startClient"
+end
+
+function P.MultiplayerHostButton_clicked(e)
+    multiplayerMode = "startServer"
+end
+
+function P.MultiplayerDedicatedButton_clicked(e)
+    multiplayerMode = "startDedicated"
+end
+
+function P.MultiplayerStartButton_clicked(e)
+    local choice = winMgr:getWindow("orxonox/MultiplayerLevelListbox"):getFirstSelectedItem()
+    if choice then
+        orxonox.LevelManager:getInstance():setDefaultLevel(choice:getText() .. ".oxw")
+        orxonox.execute(multiplayerMode)
+        hideAllMenuSheets()
+    end
+end
+
+function P.MultiplayerBackButton_clicked(e)
+    hideMenuSheet(P.name)
+end
+
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/MultiplayerOptionsMenu.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/MultiplayerOptionsMenu.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/MultiplayerOptionsMenu.lua	(revision 6952)
@@ -0,0 +1,9 @@
+-- MultiplayerOptionsMenu.lua
+
+local P = createMenuSheet("MultiplayerOptionsMenu")
+
+function P.MultiplayerOptionsBackButton_clicked(e)
+    hideMenuSheet(P.name)
+end
+
+return P
Index: /code/branches/rocket2/data/gui/scripts/PickupInventory.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/PickupInventory.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/PickupInventory.lua	(revision 6952)
@@ -0,0 +1,277 @@
+-- PickupInventory.lua
+
+local P = createMenuSheet("PickupInventory")
+
+P.carrierList = {}
+P.wrapper = nil
+P.detailsWindows = {}
+
+function P.onLoad()
+    carrierList = {}
+end
+
+function P.onShow()
+    P.createInventory()
+end
+
+function P.onHide()
+    P.cleanup()
+end
+
+function P.update()
+    P.cleanup()
+    
+    P.createInventory()
+end
+
+function P.createInventory()
+    local pickupManager = orxonox.PickupManager:getInstance()
+    local carrier = pickupManager:getPawn()
+    
+    local root = winMgr:getWindow("orxonox/PickupInventory/Inventory")
+    P.wrapper = winMgr:createWindow("MenuWidgets/ScrollablePane", "orxonox/PickupInventory/Inventory/Wrapper")
+    P.wrapper:setSize(CEGUI.UVector2(CEGUI.UDim(1,0),CEGUI.UDim(1,0)))
+    root:addChildWindow(P.wrapper)
+    
+    P.carrierList = {}
+    
+    --Design parameters:
+    local space = 15
+    
+    P.getCarrierList(carrier)
+    local offset = 0
+    for k,v in pairs(P.carrierList) do
+        local window = P.createCarrierBox(v,k)
+        window:setYPosition(CEGUI.UDim(0,offset))
+        offset = offset + window:getHeight():asAbsolute(1) + space
+        P.wrapper:addChildWindow(window)
+    end
+end
+
+function P.getCarrierList(carrier)
+
+    -- TODO: Test for nil or 0?
+    if carrier == nil then
+        return
+    end
+    
+    table.insert(P.carrierList, carrier)
+    
+    local numCarriers = orxonox.PickupManager:getInstance():getNumCarrierChildren(carrier)
+    if numCarriers == 0 then
+        return
+    end
+    
+    for i=0,numCarriers-1,1 do
+        local child = orxonox.PickupManager:getInstance():getCarrierChild(i, carrier)
+        if child ~= nil then
+            P.getCarrierList(child)
+        end
+    end
+end
+
+function P.createCarrierBox(carrier, index)
+
+    local name = "orxonox/PickupInventory/Carrier" .. index
+    
+    --Design parameters:
+    local imageHeight = 50
+    local textHeight = 30
+    local horizontalOffset = 20
+    local buttonWidth = 85
+    
+    local offset = 0
+
+    local box = winMgr:createWindow("MenuWidgets/ScrollablePane", name .. "/Box")
+    box:setPosition(CEGUI.UVector2(CEGUI.UDim(0, horizontalOffset), CEGUI.UDim(0, 0)))
+    box:setSize(CEGUI.UVector2(CEGUI.UDim(1.0, -horizontalOffset), CEGUI.UDim(1, 0)))
+    
+    local numPickups = orxonox.PickupManager:getInstance():getNumPickups(carrier)
+    for i=0,numPickups-1,1 do
+        local pickup = orxonox.PickupManager:getInstance():getPickupRepresentation(i, carrier)
+        
+        local item = winMgr:createWindow("MenuWidgets/StaticText", name .. "/Box/Pickup" .. i)
+        item:setSize(CEGUI.UVector2(CEGUI.UDim(1, -horizontalOffset), CEGUI.UDim(0, imageHeight)))
+        item:setPosition(CEGUI.UVector2(CEGUI.UDim(0, horizontalOffset), CEGUI.UDim(0, offset)))
+        box:addChildWindow(item)
+        offset = offset + imageHeight+5
+        
+        local image = winMgr:createWindow("MenuWidgets/StaticImage", name .. "/Box/Pickup" .. i .. "/Image")
+        image:setProperty("Image", "set:PickupInventory image:" .. pickup:getInventoryRepresentation())
+        image:setProperty("BackgroundEnabled", "set:False")
+        image:setProperty("FrameEnabled", "set:True")
+        image:setSize(CEGUI.UVector2(CEGUI.UDim(0, imageHeight), CEGUI.UDim(0, imageHeight)))
+        item:addChildWindow(image)
+        
+        local title = winMgr:createWindow("MenuWidgets/StaticText", name .. "/Box/Pickup" .. i .. "/Title")
+        title:setPosition(CEGUI.UVector2(CEGUI.UDim(0, imageHeight+5), CEGUI.UDim(0, (imageHeight-textHeight)/2)))
+        title:setSize(CEGUI.UVector2(CEGUI.UDim(0.4, 0), CEGUI.UDim(0, textHeight)))
+        title:setText(pickup:getPickupName())
+        title:setProperty("FrameEnabled", "set:False")
+        item:addChildWindow(title)
+        
+        local useButton = winMgr:createWindow("MenuWidgets/Button", name .. "/Box/Pickup" .. i .. "/UseButton")
+        useButton:setPosition(CEGUI.UVector2(CEGUI.UDim(0.4, imageHeight+10),CEGUI.UDim(0, (imageHeight-textHeight)/2)))
+        useButton:setSize(CEGUI.UVector2(CEGUI.UDim(0, buttonWidth), CEGUI.UDim(0, textHeight)))
+        useButton:setText("use")
+        orxonox.GUIManager:subscribeEventHelper(useButton, "Clicked", P.name .. ".InventoryUseButton_clicked")
+        item:addChildWindow(useButton)
+        
+        local dropButton = winMgr:createWindow("MenuWidgets/Button", name .. "/Box/Pickup" .. i .. "/DropButton")
+        dropButton:setPosition(CEGUI.UVector2(CEGUI.UDim(0.4, imageHeight+15+buttonWidth),CEGUI.UDim(0, (imageHeight-textHeight)/2)))
+        dropButton:setSize(CEGUI.UVector2(CEGUI.UDim(0, buttonWidth), CEGUI.UDim(0, textHeight)))
+        dropButton:setText("drop")
+        orxonox.GUIManager:subscribeEventHelper(dropButton, "Clicked", P.name .. ".InventoryDropButton_clicked")
+        item:addChildWindow(dropButton)
+        
+        local detailsButton = winMgr:createWindow("MenuWidgets/Button", name .. "/Box/Pickup" .. i .. "/DetailsButton")
+        detailsButton:setPosition(CEGUI.UVector2(CEGUI.UDim(0.4, imageHeight+20+2*buttonWidth),CEGUI.UDim(0, (imageHeight-textHeight)/2)))
+        detailsButton:setSize(CEGUI.UVector2(CEGUI.UDim(0, buttonWidth), CEGUI.UDim(0, textHeight)))
+        detailsButton:setText("details")
+        orxonox.GUIManager:subscribeEventHelper(detailsButton, "Clicked", P.name .. ".InventoryDetailsButton_clicked")
+        item:addChildWindow(detailsButton)
+    end
+    
+    box:setHeight(CEGUI.UDim(0,offset))
+    
+    return box
+end
+
+function P.cleanup()
+    if P.wrapper ~= nil then
+        winMgr:destroyWindow(P.wrapper)
+    end
+    
+    --Destroy details windows.
+    for k,v in pairs(P.detailsWindows) do
+        if v ~= nil then
+            winMgr:destroyWindow(v)
+        end
+    end
+end
+
+function P.windowToCarrierHelper(e)
+    local we = CEGUI.toWindowEventArgs(e)
+    local name = we.window:getName()
+
+    local match = string.gmatch(name, "%d+")
+    local carrierNr = tonumber(match())
+    local pickupNr = tonumber(match())
+
+    local arguments = {}
+    arguments[1] = carrierNr
+    arguments[2] = pickupNr
+    return arguments
+end
+
+function P.createDetailsWindow(pickupIndex, carrierIndex)
+    local carrier = P.carrierList[carrierIndex]
+    local pickup = orxonox.PickupManager:getInstance():getPickupRepresentation(pickupIndex, carrier)
+    
+    local headerOffset = 35
+    --Design parameters
+    local titleHeight = 30
+    local imageSize = 100
+    local buttonWidth = 85
+    
+    local name = "orxonox/PickupInventory/Carrier" .. carrierIndex .. "/Pickup" .. pickupIndex .. "/Details" .. P.getNewDetailNumber()
+    
+    local window = winMgr:createWindow("MenuWidgets/FrameWindow", name)
+    window:setSize(CEGUI.UVector2(CEGUI.UDim(0.5,0),CEGUI.UDim(0.4,0)))
+    orxonox.GUIManager:subscribeEventHelper(window, "CloseClicked", P.name .. ".closeDetailWindow")
+    
+    local root = winMgr:getWindow("orxonox/PickupInventory/Background")
+    root:addChildWindow(window)
+    
+    local wrapper = winMgr:createWindow("DefaultWindow", name .. "/Wrapper")
+    wrapper:setSize(CEGUI.UVector2(CEGUI.UDim(1, -20),CEGUI.UDim(1, -50)))
+    wrapper:setPosition(CEGUI.UVector2(CEGUI.UDim(0, 10),CEGUI.UDim(0, 40)))
+    window:addChildWindow(wrapper)
+    
+    local title = winMgr:createWindow("MenuWidgets/StaticText", name .. "/Title")
+    title:setText(pickup:getPickupName())
+    title:setHeight(CEGUI.UDim(0, titleHeight))
+    title:setProperty("FrameEnabled", "set:False")
+    title:setProperty("BackgroundEnabled", "set:False")
+    wrapper:addChildWindow(title)
+    
+    local image = winMgr:createWindow("MenuWidgets/StaticImage", name .. "/Image")
+    image:setProperty("Image", "set:PickupInventory image:" .. pickup:getInventoryRepresentation())
+    image:setProperty("BackgroundEnabled", "set:False")
+    image:setProperty("FrameEnabled", "set:True")
+    image:setSize(CEGUI.UVector2(CEGUI.UDim(0, imageSize), CEGUI.UDim(0, imageSize)))
+    image:setYPosition(CEGUI.UDim(0, titleHeight + 5))
+    wrapper:addChildWindow(image)
+    
+    local box = winMgr:createWindow("MenuWidgets/ScrollablePane", name .. "/Description")
+    box:setSize(CEGUI.UVector2(CEGUI.UDim(1.0, -1*(imageSize + 10)),CEGUI.UDim(1, -(titleHeight + 5 + titleHeight + 20))))
+    box:setPosition(CEGUI.UVector2(CEGUI.UDim(0, imageSize + 10),CEGUI.UDim(0, titleHeight + 5)))
+    local description = winMgr:createWindow("TaharezLook/StaticText", name .. "/Description/Text")
+    description:setText(pickup:getPickupDescription())
+    description:setProperty("HorzFormatting", "WordWrapLeftAligned")
+    description:setProperty("VertFormatting", "TopAligned")
+    box:addChildWindow(description)
+    wrapper:addChildWindow(box)
+    
+    local useButton = winMgr:createWindow("MenuWidgets/Button", name .. "/UseButton")
+    useButton:setPosition(CEGUI.UVector2(CEGUI.UDim(0, imageSize+10),CEGUI.UDim(1, -40)))
+    useButton:setSize(CEGUI.UVector2(CEGUI.UDim(0, buttonWidth), CEGUI.UDim(0, titleHeight)))
+    useButton:setText("use")
+    orxonox.GUIManager:subscribeEventHelper(useButton, "Clicked", P.name .. ".InventoryUseButton_clicked")
+    wrapper:addChildWindow(useButton)
+    
+    local dropButton = winMgr:createWindow("MenuWidgets/Button", name .. "/DropButton")
+    dropButton:setPosition(CEGUI.UVector2(CEGUI.UDim(0, imageSize+10+buttonWidth+10),CEGUI.UDim(1, -40)))
+    dropButton:setSize(CEGUI.UVector2(CEGUI.UDim(0, buttonWidth), CEGUI.UDim(0, titleHeight)))
+    dropButton:setText("drop")
+    orxonox.GUIManager:subscribeEventHelper(dropButton, "Clicked", P.name .. ".InventoryDropButton_clicked")
+    wrapper:addChildWindow(dropButton)
+    
+    table.insert(P.detailsWindows, window)
+    
+end
+
+function P.getNewDetailNumber()
+    local number = table.getn(P.detailsWindows)
+    for k,v in pairs(P.detailsWindows) do
+        if v == nil then
+            number = k-1
+        end
+    end
+    return number
+end
+
+function P.InventoryUseButton_clicked(e)
+    local arguments = P.windowToCarrierHelper(e)
+    orxonox.PickupManager:getInstance():usePickup(arguments[2], P.carrierList[arguments[1]], true)
+end
+
+function P.InventoryDropButton_clicked(e)
+    local arguments = P.windowToCarrierHelper(e)
+    orxonox.PickupManager:getInstance():dropPickup(arguments[2], P.carrierList[arguments[1]])
+end
+
+function P.InventoryDetailsButton_clicked(e)
+    local arguments = P.windowToCarrierHelper(e)
+    P.createDetailsWindow(arguments[2], arguments[1])
+end
+
+function P.closeDetailWindow(e)
+    --Get some numbers from the window
+    local we = CEGUI.toWindowEventArgs(e)
+    local name = we.window:getName()
+    local match = string.gmatch(name, "%d+")
+    local carrierNr = tonumber(match())
+    local pickupNr = tonumber(match())
+    local detailNr = tonumber(match())
+    
+    local window = P.detailsWindows[detailNr+1]
+    winMgr:destroyWindow(window)
+    P.detailsWindows[detailNr+1] = nil
+end
+
+function P.InventoryBackButton_clicked(e)
+    orxonox.CommandExecutor:execute("OrxonoxOverlay toggleVisibility PickupInventory")
+end
+
+return P
Index: /code/branches/rocket2/data/gui/scripts/QuestGUI.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/QuestGUI.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/QuestGUI.lua	(revision 6952)
@@ -0,0 +1,20 @@
+-- QuestGUI.lua
+
+local P = createMenuSheet("QuestGUI")
+
+function P.show()
+    P.window:show() -- TODO: Do this through parent...
+    P.visible = true
+
+    local questManager = orxonox.QuestManager:getInstance()
+
+    local questsList = winMgr:getWindow("orxonox/QuestGUI/QuestsList")
+
+    local window = questManager:getQuestGUI(P.name)
+
+    questsList:addChildWindow(window)
+
+end
+
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/SettingsMenu.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/SettingsMenu.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/SettingsMenu.lua	(revision 6952)
@@ -0,0 +1,36 @@
+-- SettingsMenu.lua
+
+local P = createMenuSheet("SettingsMenu")
+P.loadAlong = { "ControlsMenu", "AudioMenu", "GraphicsMenu" }
+
+function P.SettingsGameplayButton_clicked(e)
+    showMenuSheet("GameplayMenu", true)
+end
+
+function P.SettingsMultiplayerOptionsButton_clicked(e)
+    showMenuSheet("MultiplayerOptionsMenu", true)
+end
+
+function P.SettingsControlsButton_clicked(e)
+    showMenuSheet("ControlsMenu", true)
+end
+
+function P.SettingsGraphicsButton_clicked(e)
+    showMenuSheet("GraphicsMenu", true)
+end
+
+function P.SettingsAudioButton_clicked(e)
+    showMenuSheet("AudioMenu", true)
+end
+
+function P.SettingsResetSettingsButton_clicked(e)
+    -- reset settings
+    logMessage(0, "event: reset settings")
+end
+
+function P.SettingsBackButton_clicked(e)
+    hideMenuSheet(P.name)
+end
+
+return P
+
Index: /code/branches/rocket2/data/gui/scripts/SheetManager.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/SheetManager.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/SheetManager.lua	(revision 6952)
@@ -0,0 +1,197 @@
+-- SheetManager.lua
+
+local cursor = CEGUI.MouseCursor:getSingleton()
+local loadedSheets = {}
+local activeMenuSheets = {size = 0, topSheetTuple = nil}
+local menuSheetsRoot = guiMgr:getMenuRootWindow()
+
+-----------------------
+--- Local functions ---
+-----------------------
+
+local function hideCursor()
+    if cursor:isVisible() then
+        cursor:hide()
+    end
+end
+
+local function showCursor()
+    if not cursor:isVisible() and inputMgr:isMouseExclusive() then
+        cursor:show()
+    end
+end
+
+
+------------------------
+--- Global functions ---
+------------------------
+
+-- Loads the GUI with the specified name
+-- The name corresponds to the filename of the *.lua and *.layout files
+-- but without the extension
+function loadSheet(name)
+    -- Check if it has already been loaded
+    local sheet = loadedSheets[name]
+    if sheet == nil then
+        -- Load the sheet
+        sheet = require(name)
+        sheet:load()
+        loadedSheets[name] = sheet
+    end
+    return sheet
+end
+
+-- ?
+function showMenuSheet(name, bHidePrevious, ptr)
+    local sheet = showMenuSheet(name, bHidePrevious)
+    sheet.overlay = ptr
+    return sheet
+end
+
+-- Shows the specified menu sheet and loads it if neccessary
+function showMenuSheet(name, bHidePrevious)
+    if name == "" then
+        return nil
+    end
+    -- Get sheet (or load it)
+    local menuSheet = loadSheet(name)
+
+    -- Use sheet's value if nil was provided
+    if bHidePrevious == nil then
+        bHidePrevious = menuSheet.bHidePrevious
+        assert(bHidePrevious ~= nil)
+    end
+
+    -- Pause game control if this is the first menu to be displayed
+    -- HUGE HACK?
+    if activeMenuSheets.size == 0 then
+        orxonox.HumanController:pauseControl()
+    end
+
+    -- Hide if already displayed (to make sure it is up front in the end)
+    if activeMenuSheets[name] ~= nil then
+        hideMenuSheet(name)
+    end
+
+    -- Add the sheet in a tuple of additional information
+    local sheetTuple =
+    {
+        ["sheet"]          = menuSheet,
+        ["bHidePrevious"]  = bHidePrevious
+    }
+    table.insert(activeMenuSheets, sheetTuple) -- indexed array access
+    activeMenuSheets[name] = sheetTuple -- name access
+    activeMenuSheets.size = activeMenuSheets.size + 1
+    activeMenuSheets.topSheetTuple = sheetTuple
+
+    -- Add sheet to the root window
+    menuSheetsRoot:addChildWindow(menuSheet.window)
+
+    -- Handle input distribution
+    inputMgr:enterState(menuSheet.inputState)
+
+    -- Only change cursor situation if menuSheet.tShowCursor ~= TriBool.Dontcare
+    if menuSheet.tShowCursor == TriBool.True then
+        showCursor()
+    elseif menuSheet.tShowCursor == TriBool.False then
+        hideCursor()
+    end
+
+    -- Hide all previous sheets if necessary
+    if bHidePrevious then
+        for i = 1, activeMenuSheets.size - 1 do
+            activeMenuSheets[i].sheet:hide()
+        end
+    end
+
+    menuSheet:show()
+
+    return menuSheet
+end
+
+function hideMenuSheet(name)
+    local sheetTuple = activeMenuSheets[name]
+    if sheetTuple == nil then
+        return
+    end
+
+    -- Hide the sheet
+    sheetTuple.sheet:hide()
+
+    -- Show sheets that were hidden by the sheet to be removed
+    local i = activeMenuSheets.size
+    -- Only do something if all sheets on top of sheetTuple
+    -- have bHidePrevious == true and sheetTuple.bHidePrevious == true
+    while i > 0 do
+        if activeMenuSheets[i].bHidePrevious then
+            if activeMenuSheets[i] == sheetTuple then
+                i = i - 1
+                while i > 0 do
+                    activeMenuSheets[i].sheet:show()
+                    if activeMenuSheets[i].bHidePrevious then
+                        break
+                    end
+                    i = i - 1
+                end
+            end
+            break
+        end
+        i = i - 1
+    end
+
+    -- Remove sheet with its tuple from the table
+    menuSheetsRoot:removeChildWindow(sheetTuple.sheet.window)
+    table.remove(activeMenuSheets, table.findIndex(activeMenuSheets, sheetTuple))
+    activeMenuSheets[name] = nil
+    activeMenuSheets.size = activeMenuSheets.size - 1
+    activeMenuSheets.topSheetTuple = activeMenuSheets[activeMenuSheets.size]
+
+    -- Leave the input state
+    inputMgr:leaveState(sheetTuple.sheet.inputState)
+    
+    -- CURSOR SHOWING
+    local i = activeMenuSheets.size
+    -- Find top most sheet that doesn't have tShowCusor == TriBool.Dontcare
+    while i > 0 and activeMenuSheets[i].sheet.tShowCursor == TriBool.Dontcare do
+        i = i - 1
+    end
+    if i > 0 and activeMenuSheets[i].sheet.tShowCursor == TriBool.True then
+        showCursor()
+    else
+        hideCursor()
+    end
+
+    -- Resume control if the last menu is hidden
+    if activeMenuSheets.size == 0 then
+        orxonox.HumanController:resumeControl()
+        hideCursor()
+    end
+end
+
+-- Hides all menu GUI sheets
+function hideAllMenuSheets()
+    while activeMenuSheets.size ~= 0 do
+        hideMenuSheet(activeMenuSheets.topSheetTuple.sheet.name)
+    end
+end
+
+function keyESC()
+    -- HUGE, very HUGE hacks!
+    if activeMenuSheets.size == 1 and activeMenuSheets[1].sheet.name == "MainMenu" then
+        orxonox.execute("exit")
+    elseif activeMenuSheets.size > 0 then
+        orxonox.execute("hideGUI "..activeMenuSheets.topSheetTuple.sheet.name)
+    else
+        showMenuSheet("InGameMenu")
+    end
+end
+
+function setBackgroundImage(imageSet, imageName)
+    guiMgr:setBackgroundImage(imageSet, imageName)
+end
+
+----------------------
+--- Initialisation ---
+----------------------
+
+hideCursor()
Index: /code/branches/rocket2/data/gui/scripts/SingleplayerMenu.lua
===================================================================
--- /code/branches/rocket2/data/gui/scripts/SingleplayerMenu.lua	(revision 6952)
+++ /code/branches/rocket2/data/gui/scripts/SingleplayerMenu.lua	(revision 6952)
@@ -0,0 +1,45 @@
+-- SingleplayerMenu.lua
+
+local P = createMenuSheet("SingleplayerMenu")
+
+function P.onLoad()
+    listbox = winMgr:getWindow("orxonox/SingleplayerLevelListbox")
+    preselect = orxonox.LevelManager:getInstance():getDefaultLevel()
+    orxonox.LevelManager:getInstance():compileAvailableLevelList()
+    local levelList = {}
+    local index = 0
+    local level = ""
+    while true do
+      level = orxonox.LevelManager:getInstance():getAvailableLevelListItem(index)
+      if level == "" then
+        break
+      end
+      table.insert(levelList, level)
+      index = index + 1
+    end
+    table.sort(levelList)
+    for k,v in pairs(levelList) do
+        item = CEGUI.createListboxTextItem(v)
+        item:setSelectionBrushImage(menuImageSet, "MultiListSelectionBrush")
+        CEGUI.toListbox(listbox):addItem(item)
+        if v .. ".oxw" == preselect then
+            listbox:setItemSelectState(item, true)
+        end
+    end
+end
+
+function P.SingleplayerStartButton_clicked(e)
+    local choice = CEGUI.toListbox(winMgr:getWindow("orxonox/SingleplayerLevelListbox")):getFirstSelectedItem()
+    if choice then
+        orxonox.LevelManager:getInstance():setDefaultLevel(choice:getText() .. ".oxw")
+        orxonox.execute("startGame")
+        hideAllMenuSheets()
+    end
+end
+
+function P.SingleplayerBackButton_clicked(e)
+    hideMenuSheet(P.name)
+end
+
+return P
+
Index: /code/branches/rocket2/data/levels/Level(Deathmatch).oxw
===================================================================
--- /code/branches/rocket2/data/levels/Level(Deathmatch).oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/Level(Deathmatch).oxw	(revision 6952)
@@ -0,0 +1,429 @@
+<?lua
+	include("stats.oxo")
+	include("hudtemplates3.oxo")
+	include("underattackhud.oxo")
+	include("templates/spaceship_assff.oxt")
+	include("templates/spaceship_pirate.oxt")
+	include("templates/spaceship_Transporter.oxt")
+?>
+
+<!--*****************************************************************************************************************************************************************************************-->
+<!--Including Template for triggering on player-->
+
+<Template name=spaceshipassffplayer>
+  <SpaceShip
+   hudtemplate            = spaceshiphud
+   camerapositiontemplate = spaceshipassffcameras
+   engine                 = spaceshipassffengine
+   spawnparticlesource    = "Orxonox/fairytwirl"
+   spawnparticleduration  = 3
+   explosionchunks        = 6
+
+   health            = 100
+   maxhealth         = 200
+   initialhealth     = 100
+
+   primaryThrust     = 100;
+   auxilaryThrust    = 30;
+   rotationThrust    = 25;
+
+   collisionType     = "dynamic"
+   mass              = 100
+   linearDamping     = 0.7
+   angularDamping    = 0.9999999
+  >
+    <attached>
+      <Model position="0,0,0" yaw=90 pitch=-90 roll=0 scale=4 mesh="assff.mesh" />
+      <BlinkingBillboard position="17,-1.5,0" material="Examples/Flare" colour="1.0, 0.5, 0.3" amplitude=0.1 frequency=0.5 quadratic=1 />
+      <BlinkingBillboard position="-17,-1.5,0" material="Examples/Flare" colour="0.5, 1.0, 0.3" amplitude=0.1 frequency=0.5 phase=180 quadratic=1 />
+      <DistanceTriggerBeacon name="PlayerDistanceTrigger" /> <!--added DistanceTrigger-->
+    </attached>
+    <collisionShapes>
+      <BoxCollisionShape position="0,0,0"      halfExtents="10, 3, 5" />
+      <BoxCollisionShape position="13,-1.3,0"  halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="-13,-1.3,0" halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="0,0,7"      halfExtents="3, 2, 2" />
+      <BoxCollisionShape position="0,0.1,-11"  halfExtents="2.2, 1.8, 6" />
+      <BoxCollisionShape position="0,0.1,-19"  halfExtents="1.4, 1, 2" />
+    </collisionShapes>
+<?lua
+  include("includes/weaponsettings3.oxi")
+?>
+  </SpaceShip>
+</Template>
+
+<!--*****************************************************************************************************************************************************************************************-->
+<!-- Ausgang: Level ===> name/description -->
+<Level
+  name="Level"
+  description="Level zerstoeren von Transportern"
+  gametype=TeamDeathmatch
+>
+    <lodinformation>
+	    <MeshLodInformation mesh=Transporter.mesh lodQuality=10 />
+    </lodinformation>
+
+	<!-- Ausgang: Szene ===> ambientlight/skybox -->
+	<Scene
+	  ambientlight="0.8,0.8,0.8"
+	  skybox="Orxonox/skypanoramagen1"
+	>
+		
+		<!--Light: noch zu aendern -->
+		<Light type=directional position="0,0,0" direction="0, 0, 0" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 1.0, 0.9" />
+
+
+<!--*****************************************************************************************************************************************************************************************-->
+<!--Quests ==> id/title/description/failMessage/completeMessage-->
+	<GlobalQuest id="Levelname.nameofQuest1.testsasimplequesttoseehowitworks">    <!--QUESTIDS MUST HAVE AT LEAST 32 CHARACTERS-->
+		<QuestDescription title="ErkundungsFlug" description="Ein Erkundungsflug durch die Skybox!" failMessage="You failed!" completeMessage="You win!" />
+	</GlobalQuest>
+
+
+<!--QuestEnd-->
+<!--*****************************************************************************************************************************************************************************************-->
+
+		<!--Spieler Spawnpoint ===> position/direction-->
+		<SpawnPoint position="150,0,-50" direction="2000,0,-1000" spawnclass=SpaceShip pawndesign=spaceshipassffplayer team=0 active="true" name=spawn1> 
+			<events>
+				<activity>
+					<EventListener event="activateFirstSpawnpoint" />
+				</activity>
+			</events>
+			<attached>
+			    <Billboard position="0,0,0" colour="0,1.0,0" material="Examples/Flare"/>
+			</attached>
+		</SpawnPoint>
+
+		<SpawnPoint position="10000,0,3000" direction="2000,0,-1000" spawnclass=SpaceShip pawndesign=spaceshipassffplayer team=0 active="false" name=spawn2> 
+			<events>
+				<activity>
+					<EventListener event="activateSecondSpawnpoint" />
+				</activity>
+			</events>
+			<attached>
+			    <Billboard position="0,0,0" colour="1.0,0,0" material="Examples/Flare"/>
+			</attached>
+		</SpawnPoint>
+
+
+<!--Auslosen der 1 testQuest-->
+<!-- Funktioniert noch nicht (Fehler beim mehrfachen Ausfuehren)-->
+<!--		<QuestEffectBeacon position="1000,0,0" times="1">
+			<effects>
+				<AddQuest questId="Levelname.nameofQuest1.testsasimplequesttoseehowitworks"/>
+			</effects>
+			<events>
+				<execute>
+					<EventListener event="Levelnamequest1"/>
+				</execute>
+			</events>
+			<attached>
+				<Billboard position="0,0,0" colour="1.0,1.0,1.0" material="Examples/Flare"/>
+				<DistanceTrigger name="Levelnamequest1" position="0,0,0" distance="50" target="ControllableEntity"/>
+			</attached>
+		</QuestEffectBeacon><!---->
+
+<!--Erstellen der Transporter________nur noch zwei_________________________________________________________________________________________________________________________________________OK-->
+
+
+<?lua for i=0,0,1 do
+x=800
+health=1600
+?>
+		<!--Transporter 1 ++ FUNKTIONIERT-->
+	<EventTrigger name="activateTeam1No1" acitvations=1 stayactive="true">
+	<events>
+	<trigger>
+		<SpaceShip position="<?lua print(3800-i*x) ?>,0,3000" lookat="<?lua print(4800-i*x) ?>,0,4000" health=<?lua print(health) ?> maxhealth=<?lua print(health) ?> initialhealth=<?lua print(health) ?> >
+			<templates>
+	    			<Template link=spaceshipTransporter />
+	  		</templates>
+	  		<controller>
+				<WaypointPatrolController alertnessradius=1000 team=1>
+					<waypoints>
+						<Model mesh="cube.mesh" scale=0 position="<?lua print(14800-i*x) ?>,0,3000"/>
+					</waypoints>
+				</WaypointPatrolController>
+	  		</controller>
+		</SpaceShip><!---->
+	</trigger>
+	</events>
+	</EventTrigger>
+<?lua end ?>
+
+
+<?lua for j=0,1,1 do 
+health=1600
+x=800
+z=j*300
+?>
+		<!--Transporter 2,3 ++ FUNKTIONIERT-->
+	<EventTrigger name="activateTeam1No1" acitvations=1 stayactive="true">
+	<events>
+	<trigger>
+		<SpaceShip position="<?lua print(2600+x) ?>,0,<?lua print(3150-z) ?>" lookat="<?lua print(3500+x) ?>,0,<?lua print(4150-z) ?>" health=<?lua print(health) ?> maxhealth=<?lua print(health) ?> initialhealth=<?lua print(health) ?> >
+			<templates>
+	    			<Template link=spaceshipTransporter />
+	  		</templates>
+	  		<controller>
+				<WaypointPatrolController alertnessradius=1000 team=1>
+					<waypoints>
+						<Model mesh="cube.mesh" scale=0 position="<?lua print(13500+x) ?>,0,<?lua print(3150-z) ?>"/>
+					</waypoints>
+				</WaypointPatrolController>
+	  		</controller>
+		</SpaceShip><!---->
+	</trigger>
+	</events>
+	</EventTrigger>
+<?lua end ?>
+
+
+<!--Erstellen der Transporter______ENDE______________________________________________________________________________________________________________________________________________________-->
+
+<!--Erstellen der Schiffe des ErkundungsTrupps_____________________________________________________________________________________________________________________________________________OK-->
+		<!--Spaceships team 0 (player:team=0)FUNKTIONIERT-->
+		<SpaceShip position="50,0,0" lookat="2050,0,-1000" health="500" maxhealth="500" initialhealth="500" >
+	  		<templates>
+	   			<Template link=spaceshipassff />
+	 		</templates>
+	  		<controller>
+				<WaypointPatrolController alertnessradius=2000 team=0 >
+					<waypoints>
+						<Model mesh="cube.mesh" scale=0 position="2050,0,-1000" />
+						<Model mesh="cube.mesh" scale=0 position="6050,0,0" />
+            					<Model mesh="cube.mesh" scale=0 position="10050,0,3000" />
+            					<Model mesh="cube.mesh" scale=0 position="3050,0,3000" />
+						<Model mesh="cube.mesh" scale=0 position="-4050,0,3000" />
+					</waypoints>
+				</WaypointPatrolController>
+	  		</controller>
+		</SpaceShip>
+		<!--Second Spaceship team 0 (player: team 0)FUNKTIONIERT-->
+		<SpaceShip position="0,0,100" lookat="2000,0,-950" health="400" maxhealth="400" initialhealth="400" >
+	  		<templates>
+	   			<Template link=spaceshipassff />
+	 		</templates>
+	  		<controller>
+				<WaypointPatrolController alertnessradius=2000 team=0 >
+					<waypoints>
+						<Model mesh="cube.mesh" scale=0 position="2000,0,-900" />
+						<Model mesh="cube.mesh" scale=0 position="6000,0,0" />
+            					<Model mesh="cube.mesh" scale=0 position="10000,0,3100" />
+            					<Model mesh="cube.mesh" scale=0 position="3000,0,3100" />
+						<Model mesh="cube.mesh" scale=0 position="-4000,0,3100"/>
+					</waypoints>
+				</WaypointPatrolController>
+	  		</controller>
+		</SpaceShip>
+		<!--third Spaceship team 0 (player: team 0)FUNKTIONIERT-->
+		<SpaceShip position="0,0,-100" lookat="2000,0,-1050" health="400" maxhealth="400" initialhealth="400" >
+	  		<templates>
+	   			<Template link=spaceshipassff />
+	 		</templates>
+	  		<controller>
+				<WaypointPatrolController alertnessradius=2000 team=0 >
+					<waypoints>
+						<Model mesh="cube.mesh" scale=0 position="2000,0,-1100" />
+						<Model mesh="cube.mesh" scale=0 position="6000,0,-100" />
+            					<Model mesh="cube.mesh" scale=0 position="10000,0,2900" />
+            					<Model mesh="cube.mesh" scale=0 position="3000,0,2900" />
+						<Model mesh="cube.mesh" scale=0 position="-4000,0,2900" />
+					</waypoints>
+				</WaypointPatrolController>
+	  		</controller>
+		</SpaceShip>
+<!--Erstellen der Schiffe des ErkundungsTrupps ______ENDE ___________________________________________________________________________________________________________________________________-->
+
+
+<!--Erstellen des Asteroidenfeldes___FUNKTIONIERT_________________________________________________________________________________________________________________________________________OK--> 
+
+		<?lua for i=0,100,1 do 
+		x=math.random(250,4000)
+		y=math.random(-500,500)
+		z=math.random(1000,2000)
+		scale=math.random(20,70)
+		?>
+		<MovableEntity collisionType=kinematic linearDamping=0.8 angularDamping=0 mass="<?lua print(scale * 5) ?>" position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" rotationaxis="<?lua print(math.random()) ?>,<?lua print(math.random()) ?>,<?lua print(math.random()) ?>" rotationrate="<?lua print(math.random()*15) ?>">
+			<attached>
+				<Model scale=<?lua print(scale) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false/>
+			</attached>
+			<collisionShapes>
+				<SphereCollisionShape radius="<?lua print(scale * 3) ?>" />
+				</collisionShapes> 
+		</MovableEntity>
+		<?lua end ?>
+
+<!--Erstellen des Ateroidenfeldes______ENDE__________________________________________________________________________________________________________________________________________________-->
+
+<!--Erstellen von Asteroiden die zufaellig plaziert sind___________________________________________________________________________________________________________________________________OK-->
+
+	<?lua for i=0,150,1 do 
+	x=math.random(-8000,8000)
+	y=math.random(-8000,8000)
+	z=math.random(-8000,8000)
+	?>
+	<MovableEntity collisionType=kinematic linearDamping=0.8 angularDamping=0 mass="<?lua print(scale * 5) ?>" position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" rotationaxis="<?lua print(math.random()) ?>,<?lua print(math.random()) ?>,<?lua print(math.random()) ?>" rotationrate="<?lua print(math.random()*15) ?>" >
+		<attached>
+			<Model scale=<?lua print(math.random(20,70)) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false/>
+		</attached>
+		<collisionShapes>
+			<SphereCollisionShape radius="<?lua print(scale * 3) ?>" />
+		</collisionShapes> 
+	</MovableEntity>
+	<?lua end ?>
+
+<!--Erstellen von Asteroiden die zufaellig plaziert sind______ENDE___________________________________________________________________________________________________________________________-->
+
+<!--Erstellen der Hilfsschiffe_____________________________________________________________________________________________________________________________________________________________OK-->
+<!---->
+		<!--Trigger to activate this Team (TEAM NO 1)-->
+	<DistanceTrigger name="activateTeam0No1" position="8000,0,3100" distance="1000" target="DistanceTriggerBeacon" targetname="PlayerDistanceTrigger" activations="1" stayactive="true" />
+
+<!--TEAM NO 1 (activationType : distance || killing a spaceship what belongs to TEAM 0 NO 0)-->
+<?lua for i=0,9,1 do
+x=math.random(-500,500)
+y=math.random(-300,300)
+z=math.random(-300,300)
+?>
+	<EventTrigger name="activateTeam0No1" activations=1 stayactive="true">
+		<events>
+			<trigger>
+				<SpaceShip position="<?lua print(x+4500) ?>,<?lua print(y) ?>,<?lua print(z+6000) ?>" lookat="<?lua print(4000+x) ?>,<?lua print(y) ?>,<?lua print(z+3000) ?>">
+					<templates>
+						<Template link=spaceshipassff />
+					</templates>
+					<controller>
+						<WaypointPatrolController alertnessradius=2000 team=0 active=false>
+							<waypoints>
+								<Model mesh="cube.mesh" scale=0 position="<?lua print(4500+x) ?>,<?lua print(y) ?>,<?lua print(z+3000) ?>" />
+								<Model mesh="cube.mesh" scale=0 position="<?lua print(x-4000) ?>,<?lua print(y) ?>,<?lua print(z+3000) ?>" />
+							</waypoints>
+							<events>
+								<activity>
+									<EventListener event="activateTeam0No1" />
+								</activity>
+							</events>
+						</WaypointPatrolController>
+					</controller>
+				</SpaceShip>
+			</trigger>
+		</events>
+	</EventTrigger>
+
+
+<?lua end ?>
+
+<!---->
+<!--Erstellen der Hilfsschiffe______ENDE_____________________________________________________________________________________________________________________________________________________-->
+
+<!--Erstellen von Feinden die den Transportern zu Hilfe eilen_______________________________________________________________________________________________________________________________OK-->
+<!---->
+<!--TEAM 1 NO 1 (activationType : killing a Transporter || killing a spaceship what belongs to TEAM 1 NO 1)-->
+<?lua for i=0,11,1 do
+x=math.random(-500,500)
+y=math.random(-300,300)
+z=math.random(-300,300)
+?>
+	<EventTrigger name="activateTeam1No1" activations=1 stayactive="true" >
+		<events>
+			<trigger>
+				<SpaceShip position="<?lua print(x-4000) ?>,<?lua print(y) ?>,<?lua print(z+3000) ?>" lookat="<?lua print(4000+x) ?>,<?lua print(y) ?>,<?lua print(z+3000) ?>">
+					<templates>
+						<Template link=spaceshippirate />
+					</templates>
+					<controller>
+						<WaypointPatrolController alertnessradius=5000 team=1 active=false>
+							<waypoints>
+								<Model mesh="cube.mesh" scale=0 position="<?lua print(4000+x) ?>,<?lua print(y) ?>,<?lua print(z+3000) ?>" />
+							</waypoints>
+							<events>
+								<activity>
+									<EventListener event="activateTeam1No1" />
+								</activity>
+							</events>
+						</WaypointPatrolController>
+					</controller>
+				</SpaceShip>
+			</trigger>
+		</events>
+	</EventTrigger>
+
+<?lua end ?>
+<!---->
+<!--Erstellen von Feinden die dem Transporter zu Hilfe eilen_________________________________________________________________________________________________________________________________-->
+
+<!--Erstellen von Feinden auf dem Weg zu den Transportern___________________________________________________________________________________(noch besser machen [mehr Feinde/ Koordinierung])-->
+<?lua for i=0,1,1 do 
+z=math.random(-300,300)
+?>
+		<SpaceShip position="<?lua print(5900+i*100) ?>,0,-3000" lookat="2500,0,-1000">
+			<templates>
+				<Template link=spaceshippirate/>
+			</templates>
+			<controller>
+				<WaypointPatrolController alertnessRadius=1500 team=1>
+					<waypoints>
+						<Model mesh="cube.mesh" scale=0 position="<?lua print(2500+100*i) ?>,0,-1000" />
+					</waypoints>
+				</WaypointPatrolController>
+			</controller>
+		</SpaceShip>
+
+
+		<SpaceShip position="<?lua print(9000) ?>,13000,<?lua print(z*i+3000) ?>" lookat="1000,0,3000">
+			<templates>
+				<Template link=spaceshippirate/>
+			</templates>
+			<controller>
+				<WaypointPatrolController alertnessRadius=1500 team=1>
+					<waypoints>
+						<Model mesh="cube.mesh" scale=0 position="<?lua print(10000) ?>,0,<?lua print(3000+z*i) ?>" />
+					</waypoints>
+				</WaypointPatrolController>
+			</controller>
+		</SpaceShip>
+
+<?lua end ?>
+
+<?lua for i=0,3,1 do ?>
+		<SpaceShip position="<?lua print(math.random(5500,6500)+2000) ?>,0,1000" lookat="2500,0,-1000">
+			<templates>
+				<Template link=spaceshippirate/>
+			</templates>
+			<controller>
+				<WaypointPatrolController alertnessRadius=1500 team=1>
+					<waypoints>
+						<Model mesh="cube.mesh" scale=0 position="<?lua print(math.random(5750,6250)+2000) ?>,0,1250" />
+						<Model mesh="cube.mesh" scale=0 position="<?lua print(math.random(5750,6250)+2000) ?>,250,1000" />
+						<Model mesh="cube.mesh" scale=0 position="<?lua print(math.random(5750,6250)+2000) ?>,0,1000" />
+					</waypoints>
+				</WaypointPatrolController>
+			</controller>
+		</SpaceShip>
+<?lua end ?>
+<!--Erstellen von Feinden auf dem Weg zu den Transportern______ENDE__________________________________________________________________________________________________________________________-->
+
+<Trigger name=activateFirstSpawnpoint invert=true >
+    <DistanceTrigger name="activateSecondSpawnpoint" position="150,0,-300" distance="10" target="DistanceTriggerBeacon" targetname="PlayerDistanceTrigger" activations="1" stayactive="true">
+        <attached>
+                <Billboard position="0,0,0" colour="0,0,1.0" material="Examples/Flare" />
+        </attached>
+    </DistanceTrigger>
+</Trigger>
+
+	</Scene>
+</Level>
+
+
+
+
+
+
+
+
+
+
+
+
Index: /code/branches/rocket2/data/levels/Level(UnderAttack).oxw
===================================================================
--- /code/branches/rocket2/data/levels/Level(UnderAttack).oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/Level(UnderAttack).oxw	(revision 6952)
@@ -0,0 +1,118 @@
+<?lua
+	include("stats.oxo")
+	include("hudtemplates3.oxo")
+	include("underattackhud.oxo")
+	include("templates/spaceship_assff.oxt")
+	include("templates/spaceship_pirate.oxt")
+	include("templates/spaceship_destroyer.oxt")
+?>
+
+<!-- Ausgang: Level ===> name/description -->
+<Level
+  name="Level"
+  description="Level zerstoeren von Transportern"
+  gametype=UnderAttack
+>
+
+	<!-- Ausgang: Szene ===> ambientlight/skybox -->
+	<Scene
+	  ambientlight="0.8,0.8,0.8"
+	  skybox="Orxonox/skypanoramagen1"
+	>
+		
+		<!--Light: noch zu aendern -->
+		<Light type=directional position="0,0,0" direction="0, 0, 0" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 1.0, 0.9" />
+
+<!--******************************************************************************************************************************************************************************************-->
+<!--Quests ==> id/title/description/failMessage/completeMessage-->
+	<GlobalQuest id="Levelname.nameofQuest1.testsasimplequesttoseehowitworks">    <!--QUESTIDS MUST HAVE AT LEAST 32 CHARACTERS-->
+		<QuestDescription title="ErkundungsFlug" description="Ein Erkundungsflug durch die Skybox!" failMessage="You failed!" completeMessage="You win!" />
+	</GlobalQuest>
+
+
+<!--QuestEnd-->
+<!--******************************************************************************************************************************************************************************************-->
+
+		<!--Spieler Spawnpoint ===> position/direction-->
+		<SpawnPoint position="-100,50,0" direction="1000,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff team=0 />
+
+
+		<!--Auslosen der 1 testQuest-->
+<!-- Funktioniert noch nicht Fehler mit einem Argument in Quest-->
+		<QuestEffectBeacon position="1000,0,0" times="1">
+			<effects>
+				<AddQuest questId="Levelname.nameofQuest1.testsasimplequesttoseehowitworks"/>
+			</effects>
+			<events>
+				<execute>
+					<EventListener event="Levelnamequest1"/>
+				</execute>
+			</events>
+			<attached>
+				<Billboard position="0,0,0" colour="1.0,1.0,1.0" material="Examples/Flare"/>
+				<DistanceTrigger name="Levelnamequest1" position="0,0,0" distance="50" target="ControllableEntity"/>
+			</attached>
+		</QuestEffectBeacon>
+
+		<!--Destroyer 1 ++ Benutzen des spaceship_destroyer template (Fehler mit dem Ziel ==> muss nur den letzten transporter zerstoeren) ==> health/maxHealth/initialHealth-->
+		<Destroyer
+			position="3000,0,3000"
+			velocity="-25,0,0"
+			template=spaceshipDestroyer
+			health=1000
+			maxHealth = 1000
+			initialHealth = 1000
+		>
+		</Destroyer>
+
+<!--Erstellen der Schiffe des ErkundungsTrupps__________________________________________________________________-->
+		<!--Spaceships team 0 (player:team=0)-->
+		<SpaceShip position="75,0,0" lookat="1000,0,0" >
+	  		<templates>
+	   			<Template link=spaceshipassff />
+	 		</templates>
+	  		<controller>
+				<WaypointPatrolController alertnessradius=1000 team=0>
+					<waypoints>
+						<Model mesh="cube.mesh" scale=0 position="3025,0,0" />
+            					<Model mesh="cube.mesh" scale=0 position="4025,0,1000" />
+            					<Model mesh="cube.mesh" scale=0 position="3025,0,3000" />
+					</waypoints>
+				</WaypointPatrolController>
+	  		</controller>
+		</SpaceShip>
+		<!--Second Spaceship team 0 (player: team 0)-->
+		<SpaceShip position="0,0,75" lookat="1000,0,75" >
+	  		<templates>
+	   			<Template link=spaceshipassff />
+	 		</templates>
+	  		<controller>
+				<WaypointPatrolController alertnessradius=1000 team=0>
+					<waypoints>
+						<Model mesh="cube.mesh" scale=0 position="3000,0,25" />
+            					<Model mesh="cube.mesh" scale=0 position="4000,0,1025" />
+            					<Model mesh="cube.mesh" scale=0 position="3000,0,3025" />
+					</waypoints>
+				</WaypointPatrolController>
+	  		</controller>
+		</SpaceShip>
+		<!--third Spaceship team 0 (player: team 0)-->
+		<SpaceShip position="0,0,-75" lookat="1000,0,-75" >
+	  		<templates>
+	   			<Template link=spaceshipassff />
+	 		</templates>
+	  		<controller>
+				<WaypointPatrolController alertnessradius=1000 team=0>
+					<waypoints>
+						<Model mesh="cube.mesh" scale=0 position="3000,0,-25" />
+            					<Model mesh="cube.mesh" scale=0 position="4000,0,975" />
+            					<Model mesh="cube.mesh" scale=0 position="3000,0,2975" />
+					</waypoints>
+				</WaypointPatrolController>
+	  		</controller>
+		</SpaceShip>
+<!--Erstellen der Schiffe des ErkundungsTrupps ______ENDE ______________________________________________-->
+
+
+	</Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/empty_level.oxw
===================================================================
--- /code/branches/rocket2/data/levels/empty_level.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/empty_level.oxw	(revision 6952)
@@ -0,0 +1,28 @@
+<?lua
+  include("stats.oxo")
+  include("hudtemplates3.oxo")
+  include("templates/lodinformation.oxt")
+?>
+
+<?lua
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_pirate.oxt")
+?>
+
+<Level
+ name         = "Sample"
+ description  = "Just a few tests"
+>
+  <templates>
+    <Template link=lodtemplate_default />
+  </templates>
+
+  <Scene
+    ambientlight = "0.8, 0.8, 0.8"
+    skybox       = "Orxonox/Starbox"
+  >
+    
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+    <SpawnPoint position="0,0,100" spawnclass=SpaceShip pawndesign=spaceshipassff />
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/events.oxw
===================================================================
--- /code/branches/rocket2/data/levels/events.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/events.oxw	(revision 6952)
@@ -0,0 +1,223 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_H2.oxt")
+?>
+
+<Level
+ name         = "Event testing"
+ description  = "A simple level to test the event-system (with comments)"
+>
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/skypanoramagen1"
+  >
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+    <SpawnPoint position="0,-100,0" lookat="0,0,0" roll=180 spawnclass=SpaceShip pawndesign=spaceshipassff />
+
+    <Billboard position=" 300,100,  0" material="Examples/Flare" colour="1.0, 0.0, 0.0" />
+    <Billboard position=" 200,100,  0" material="Examples/Flare" colour="1.0, 0.5, 0.0" />
+    <Billboard position=" 200,100,100" material="Examples/Flare" colour="1.0, 0.5, 0.0" />
+    <Billboard position=" 100,100,  0" material="Examples/Flare" colour="1.0, 1.0, 0.0" />
+    <Billboard position="   0,100,  0" material="Examples/Flare" colour="0.0, 1.0, 0.0" />
+    <Billboard position="-100,100,  0" material="Examples/Flare" colour="0.0, 1.0, 1.0" />
+    <Billboard position="-100,100,100" material="Examples/Flare" colour="0.0, 1.0, 1.0" />
+    <Billboard position="-200,100,  0" material="Examples/Flare" colour="0.0, 0.0, 1.0" />
+    <Billboard position="-300,100,  0" material="Examples/Flare" colour="1.0, 0.0, 1.0" />
+
+
+
+    <!--
+      Begin of the tutorial section.
+    -->
+
+
+
+    <!--
+      Note:
+      All following examples use only one subobject (in nested layouts). But of course you can add more
+      objects. They will all follow the same rules (depending on the example receive, send or pipe events).
+
+      Some examples address objects by name. Those methods always address ALL objects with this name, no
+      matter where they are in the XML-file (before or after the addressing object). Of course this also
+      works with all amounts of objects from zero to infinity. In the examples I used two objects each.
+    -->
+
+
+    <!-- red -->
+    <!--
+      Standard:
+      Direct event-connection between an event-listener (Billboard) and an event source (DistanceTrigger).
+      Every fired event of the source is mapped to the "visibility" state of the listener.
+
+      This is a 1:1 mapping between event-listener and event-source.
+    -->
+    <Billboard position="300,150,0" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0>
+      <events>
+        <visibility>
+          <DistanceTrigger position="300,100,0" distance=25 target="ControllableEntity" />
+        </visibility>
+      </events>
+    </Billboard>
+
+
+    <!-- orange -->
+    <!--
+      EventListener:
+      The EventListener object forwards all events from objects, whose names equal the "event" attribute
+      of the EventListener, to the enclosing object (Billboard).
+      In this case, both triggers have the name "trigger2" and thus both triggers send events to the Billboard.
+
+      The EventListener provides an 1:n mapping between one listener and multiple event-sources.
+    -->
+    <Billboard position="200,150,0" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0>
+      <events>
+        <visibility>
+          <EventListener event="trigger2" />
+        </visibility>
+      </events>
+    </Billboard>
+    <DistanceTrigger name="trigger2" position="200,100,0" distance=25 target="ControllableEntity" />
+    <DistanceTrigger name="trigger2" position="200,100,100" distance=25 target="ControllableEntity" />
+
+
+    <!-- yellow -->
+    <!--
+      EventTarget:
+      The EventTarget object forwards the events, received from objects whithin the "events" subsection,
+      to all  objects whose names equal the "name" attribute.
+      In this case, the EventTarget forwards the event from the DistanceTrigger to all listeners with
+      name "bb3".
+
+      The EventTarget provides an n:1 mapping between several listeners and one event-source.
+    -->
+    <Billboard name="bb3" position="100,150,0" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0 />
+    <Billboard name="bb3" position="100,150,100" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0 />
+    <EventTarget target="bb3">
+      <events>
+        <visibility>
+          <DistanceTrigger position="100,100,0" distance=25 target="ControllableEntity" />
+        </visibility>
+      </events>
+    </EventTarget>
+
+
+    <!-- green -->
+    <!--
+      EventDispatcher:
+      The EventDispatcher catches events from objects in its "events" subsection. Those events are forwared
+      to all objects in the "targets" subsection. The EventDispatcher resembles the EventTarget, but
+      doesn't address objects with the "name" attribute. It rather places them directly inside the "targets"
+      subsection.
+      In this case, the EventDispatcher receives events from the DistanceTrigger and forwards those events
+      to the Billboard object.
+
+      The EventDispatcher provides an n:1 mapping between several targets (listeners) and one event source.
+    -->
+    <EventDispatcher>
+      <targets>
+        <Billboard position="0,150,0" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0 />
+      </targets>
+      <events>
+        <visibility>
+          <DistanceTrigger position="0,100,0" distance=25 target="ControllableEntity" />
+        </visibility>
+      </events>
+    </EventDispatcher>
+
+
+    <!-- turquoise -->
+    <!--
+      Combination:
+      By combinding the above three classes, namely EventDispatcher, EventTarget and EventListener, you can
+      extract the event logic completely from the actual objects (Billboards and DistanceTriggers).
+      In this case, both triggers (whith names "trigger5") send events to both Billboards (with names "bb5").
+
+      This combination allows an n:n mapping between event-listeners and event-sources.
+    -->
+    <Billboard name="bb5" position="-100,150,0" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0 />
+    <Billboard name="bb5" position="-100,150,100" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0 />
+    <DistanceTrigger name="trigger5" position="-100,100,0" distance=25 target="ControllableEntity" />
+    <DistanceTrigger name="trigger5" position="-100,100,100" distance=25 target="ControllableEntity" />
+    <EventDispatcher>
+      <targets>
+        <EventTarget target="bb5" />
+      </targets>
+      <events>
+        <visibility>
+          <EventListener event="trigger5" />
+        </visibility>
+      </events>
+    </EventDispatcher>
+
+
+    <!-- blue -->
+    <!--
+      Mainstate:
+      Apart from the standard states (like activity and visibility), each object can have a mainstate.
+      You can define the mainstate with an xml-attribute: mainstate="state". "state" must be one of the
+      supported states of the object (except states which need the originator as a second argument). If
+      the mainstate is set (by default that's not the case), you can send events to the "mainstate" state.
+      This allows you to hide the actually affected state in the event-listener, while the event-source
+      just sends events.
+      Note that this example is exactly like the standard case, but the event is sent to the main-state,
+      which in turn is set to "visibility".
+    -->
+    <Billboard position="-200,150,0" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0 mainstate="visibility">
+      <events>
+        <mainstate>
+          <DistanceTrigger position="-200,100,0" distance=25 target="ControllableEntity" />
+        </mainstate>
+      </events>
+    </Billboard>
+
+
+    <!-- violet -->
+    <!--
+      Event forwarding:
+      As a consequence of the mainstate, events can also be sent without any explicit declaration of
+      the targets state. This allows us to forward events from an event-source directly to a bunch of
+      event-listeners. The events are automatically piped into the mainstate. Therefore the listeners
+      have to declare their main-state.
+      In this example, the DistanceTrigger forwards the events to the Billboards main-state (visibility).
+      This does the same like the example above, but instead of piping events backwards from the source
+      into the mainstate of the listener, we're forwarding the event implicitly to the mainstate.
+    -->
+    <DistanceTrigger position="-300,100,0" distance=25 target="ControllableEntity">
+      <eventlisteners>
+        <Billboard position="-300,150,0" material="Examples/Flare" colour="1.0, 1.0, 1.0" visible=0 mainstate="visibility" />
+      </eventlisteners>
+    </DistanceTrigger>
+
+
+
+    <!--
+      End of the tutorial section.
+    -->
+
+
+
+    <!--
+      The following example shows again the red (standard layout) and the violet (event forwarding) example,
+      but this time with a memoryless state (spawn) from the ParticleSpawner instead of the boolean state
+      (visibility) in the other examples.
+    -->
+    <Billboard position=" 300,100,300" material="Examples/Flare" colour="1.0, 0.0, 0.0" />
+    <Billboard position="-300,100,300" material="Examples/Flare" colour="1.0, 0.0, 1.0" />
+    <ParticleSpawner position="300,150,300" source="Orxonox/BigExplosion1part1" lifetime=3.0 autostart=0>
+      <events>
+        <spawn>
+          <DistanceTrigger position="300,100,300" distance=25 target="ControllableEntity" />
+        </spawn>
+      </events>
+    </ParticleSpawner>
+    <DistanceTrigger position="-300,100,300" distance=25 target="ControllableEntity">
+      <eventlisteners>
+        <ParticleSpawner position="-300,150,300" source="Orxonox/BigExplosion1part1" lifetime=3.0 autostart=0 mainstate="spawn" />
+      </eventlisteners>
+    </DistanceTrigger>
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/gametype_asteroids.oxw
===================================================================
--- /code/branches/rocket2/data/levels/gametype_asteroids.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/gametype_asteroids.oxw	(revision 6952)
@@ -0,0 +1,458 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+  include("templates/lodinformation.oxt")
+?>
+
+<Level
+ name         = "Asteroids Race"
+ description  = "testmap for gametype asteroid race"
+ gametype     =  Asteroids
+>
+  <templates>
+    <Template link=lodtemplate_default />
+  </templates>
+
+<Scene
+ ambientlight = "0.5, 0.5, 0.5"
+ skybox       = "Orxonox/Starbox"
+>
+
+<Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+
+
+<SpawnPoint position="-300,300,0" name="playerstart" direction="1,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+
+
+<?lua
+for i = 1, 250, 1
+do
+j = math.random()
+?>
+
+    <MovableEntity
+     position="<?lua print(math.random()* 15000 - 1000) ?>,<?lua print(math.random() * 12000 - 4000) ?>,<?lua print(math.random() * 12000 - 4000) ?>"        collisionType=dynamic
+     linearDamping=0.8
+     angularDamping=0
+     scale=<?lua print(j * 150)?>
+     collisiondamage=1
+     enablecollisiondamage=true>
+      <attached>
+        <Model mass=<?lua print(j * 1000) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+      </attached>
+      <collisionShapes>
+        <SphereCollisionShape radius="<?lua print(j * 350) ?>" />
+      </collisionShapes>
+    </MovableEntity>
+<?lua
+end
+?>
+
+<!--
+<MovableEntity position="0,0,0" collisionType=dynamic scale=5 linearDamping=0.8 angularDamping=0  collisiondamage=0.005 enablecollisiondamage=true>
+  <attached>
+    <Model mass=100 mesh="ast1.mesh" />
+  </attached>
+    <collisionShapes>
+      <SphereCollisionShape radius=11.75 />
+    </collisionShapes>
+</MovableEntity>
+
+
+<MovableEntity position="0,300,0" scale=10 collisionType=dynamic linearDamping=0.8 angularDamping=0  collisiondamage=0.005 enablecollisiondamage=true>
+  <attached>
+    <Model mass=100 mesh="ast1.mesh" />
+  </attached>
+    <collisionShapes>
+      <SphereCollisionShape radius=22.5 />
+    </collisionShapes>
+</MovableEntity>
+
+
+<MovableEntity position="0,600,0"  scale=34  collisionType=dynamic linearDamping=0.8 angularDamping=0 collisiondamage=0.005 enablecollisiondamage=true>
+  <attached>
+    <Model mass=100 mesh="ast1.mesh" />
+  </attached>
+    <collisionShapes>
+      <SphereCollisionShape radius=76.5 />
+    </collisionShapes>
+</MovableEntity>
+
+<MovableEntity position="0,1200,0" scale=80 collisionType=dynamic linearDamping=0.8 angularDamping=0  collisiondamage=0.005 enablecollisiondamage=true>
+  <attached>
+    <Model mass=100 mesh="ast1.mesh" />
+  </attached>
+    <collisionShapes>
+      <SphereCollisionShape radius=200 />
+    </collisionShapes>
+</MovableEntity>
+-->
+
+<SpaceShip position="2000,200,0" lookat="0,0,0" >
+  <templates>
+    <Template link=spaceshipassff />
+  </templates>
+  <controller>
+    <AIController />
+  </controller>
+</SpaceShip>
+
+<SpaceShip position="8000,300,700" lookat="0,0,0" >
+  <templates>
+    <Template link=spaceshipassff />
+  </templates>
+  <controller>
+    <AIController />
+  </controller>
+</SpaceShip>
+
+<SpaceShip position="10200,400,-600" lookat="0,0,0" >
+  <templates>
+    <Template link=spaceshipassff />
+  </templates>
+  <controller>
+    <AIController />
+  </controller>
+</SpaceShip>
+
+<ForceField position="200,300,-500" direction="0,0,1" diameter=500 velocity=120>
+  <attached>
+    <ParticleEmitter source="Orxonox/ForceFieldPurpleSmall" startdelay=0 />
+  </attached>
+</ForceField>
+
+ <ForceField position="2200,-300,1200" direction="1,0.3,-0.7" diameter=800 velocity=200>
+  <attached>
+    <ParticleEmitter source="Orxonox/ForceFieldBlueBig" startdelay=0 />
+  </attached>
+</ForceField>
+
+ <ForceField position="8600,1400,500" direction="-1,-1,-1" diameter=500 velocity=400>
+  <attached>
+    <ParticleEmitter source="Orxonox/ForceFieldGreenSmall" startdelay=0 />
+  </attached>
+</ForceField>
+
+  <ForceField position="11800,500,-2600" direction="-1,0,1" diameter=900 velocity=300>
+  <attached>
+    <ParticleEmitter source="Orxonox/ForceFieldPurpleBig" startdelay=0 />
+  </attached>
+</ForceField>
+
+
+<CheckPoint name=trigger1 position="-300,300,0" scale=1 isdestination=false isfirst=true stayactive=true distance=10 addtime=13 />
+
+
+<CheckPoint name=trigger2 position="2200,600,0" scale=3 isdestination=false stayactive=true distance=100 addtime=10>
+  <events>
+    <activity>
+      <EventListener event=trigger1 />
+    </activity>
+  </events>
+  <attached>
+    <Billboard material="Flares/lensflare" colour="1,0,0">
+      <events>
+        <visibility>
+          <EventTrigger invert=true>
+            <events>
+              <trigger>
+                <EventListener event=trigger1 />
+              </trigger>
+            </events>
+          </EventTrigger>
+        </visibility>
+      </events>
+    </Billboard>
+    <BlinkingBillboard frequency=0.2 amplitude=1 material="Flares/lensflare" colour="1,1,0">
+      <events>
+        <visibility>
+          <EventTrigger>
+            <events>
+              <trigger>
+                <EventListener event=trigger1 />
+              </trigger>
+            </events>
+            <EventTrigger invert=true>
+              <events>
+                <trigger>
+                  <EventListener event=trigger2 />
+                </trigger>
+              </events>
+            </EventTrigger>
+          </EventTrigger>
+        </visibility>
+      </events>
+    </BlinkingBillboard>
+    <Billboard material="Flares/lensflare" colour="0,1,0">
+      <events>
+        <visibility>
+          <EventListener event=trigger2 />
+        </visibility>
+      </events>
+    </Billboard>
+  </attached>
+</CheckPoint>
+
+
+<CheckPoint name=trigger3 position="4100,0,400" scale=3 isdestination=false stayactive=true distance=100 addtime=9>
+  <events>
+    <activity>
+      <EventListener event=trigger2 />
+    </activity>
+  </events>
+  <attached>
+    <Billboard material="Flares/lensflare" colour="1,0,0">
+      <events>
+        <visibility>
+          <EventTrigger invert=true>
+            <events>
+              <trigger>
+                <EventListener event=trigger2 />
+              </trigger>
+            </events>
+          </EventTrigger>
+        </visibility>
+      </events>
+    </Billboard>
+    <BlinkingBillboard frequency=0.2 amplitude=1 material="Flares/lensflare" colour="1,1,0">
+      <events>
+        <visibility>
+          <EventTrigger>
+            <events>
+              <trigger>
+                <EventListener event=trigger2 />
+              </trigger>
+            </events>
+            <EventTrigger invert=true>
+              <events>
+                <trigger>
+                  <EventListener event=trigger3 />
+                </trigger>
+              </events>
+            </EventTrigger>
+          </EventTrigger>
+        </visibility>
+      </events>
+    </BlinkingBillboard>
+    <Billboard material="Flares/lensflare" colour="0,1,0">
+      <events>
+        <visibility>
+          <EventListener event=trigger3 />
+        </visibility>
+      </events>
+    </Billboard>
+  </attached>
+</CheckPoint>
+
+
+<CheckPoint name=trigger4 position="5600,400,0" scale=3 isdestination=false stayactive=true distance=100 addtime=9>
+  <events>
+    <activity>
+      <EventListener event=trigger3 />
+    </activity>
+  </events>
+  <attached>
+    <Billboard material="Flares/lensflare" colour="1,0,0">
+      <events>
+        <visibility>
+          <EventTrigger invert=true>
+            <events>
+              <trigger>
+                <EventListener event=trigger3 />
+              </trigger>
+            </events>
+          </EventTrigger>
+        </visibility>
+      </events>
+    </Billboard>
+    <BlinkingBillboard frequency=0.2 amplitude=1 material="Flares/lensflare" colour="1,1,0">
+      <events>
+        <visibility>
+          <EventTrigger>
+            <events>
+              <trigger>
+                <EventListener event=trigger3 />
+              </trigger>
+            </events>
+            <EventTrigger invert=true>
+              <events>
+                <trigger>
+                  <EventListener event=trigger4 />
+                </trigger>
+              </events>
+            </EventTrigger>
+          </EventTrigger>
+        </visibility>
+      </events>
+    </BlinkingBillboard>
+    <Billboard material="Flares/lensflare" colour="0,1,0">
+      <events>
+        <visibility>
+          <EventListener event=trigger4 />
+        </visibility>
+      </events>
+    </Billboard>
+  </attached>
+</CheckPoint>
+
+
+<CheckPoint name=trigger5 position="7200,600,-200" scale=3 isdestination=false stayactive=true distance=100 addtime=8>
+  <events>
+    <activity>
+      <EventListener event=trigger4 />
+    </activity>
+  </events>
+  <attached>
+    <Billboard material="Flares/lensflare" colour="1,0,0">
+      <events>
+        <visibility>
+          <EventTrigger invert=true>
+            <events>
+              <trigger>
+                <EventListener event=trigger4 />
+              </trigger>
+            </events>
+          </EventTrigger>
+        </visibility>
+      </events>
+    </Billboard>
+    <BlinkingBillboard frequency=0.2 amplitude=1 material="Flares/lensflare" colour="1,1,0">
+      <events>
+        <visibility>
+          <EventTrigger>
+            <events>
+              <trigger>
+                <EventListener event=trigger4 />
+              </trigger>
+            </events>
+            <EventTrigger invert=true>
+              <events>
+                <trigger>
+                  <EventListener event=trigger5 />
+                </trigger>
+              </events>
+            </EventTrigger>
+          </EventTrigger>
+        </visibility>
+      </events>
+    </BlinkingBillboard>
+    <Billboard material="Flares/lensflare" colour="0,1,0">
+      <events>
+        <visibility>
+          <EventListener event=trigger5 />
+        </visibility>
+      </events>
+    </Billboard>
+  </attached>
+</CheckPoint>
+
+
+<CheckPoint name=trigger6 position="9200, 800,-800" scale=3 isdestination=false stayactive=true distance=100 addtime=10>
+  <events>
+    <activity>
+      <EventListener event=trigger5 />
+    </activity>
+  </events>
+  <attached>
+    <Billboard material="Flares/lensflare" colour="1,0,0">
+      <events>
+        <visibility>
+          <EventTrigger invert=true>
+            <events>
+              <trigger>
+                <EventListener event=trigger5 />
+              </trigger>
+            </events>
+          </EventTrigger>
+        </visibility>
+      </events>
+    </Billboard>
+    <BlinkingBillboard frequency=0.2 amplitude=1 material="Flares/lensflare" colour="1,1,0">
+      <events>
+        <visibility>
+          <EventTrigger>
+            <events>
+              <trigger>
+                <EventListener event=trigger5 />
+              </trigger>
+            </events>
+            <EventTrigger invert=true>
+              <events>
+                <trigger>
+                  <EventListener event=trigger6 />
+                </trigger>
+              </events>
+            </EventTrigger>
+          </EventTrigger>
+        </visibility>
+      </events>
+    </BlinkingBillboard>
+    <Billboard material="Flares/lensflare" colour="0,1,0">
+      <events>
+        <visibility>
+          <EventListener event=trigger6 />
+        </visibility>
+      </events>
+    </Billboard>
+  </attached>
+</CheckPoint>
+
+
+<Model position="11200,400,-1800" scale=10 pitch=-90  mesh="Carrier.mesh">
+  <attached>
+    <CheckPoint position="-10,0,0" name=trigger7 scale=0.6 isdestination=true stayactive=true distance=100>
+  <events>
+    <activity>
+      <EventListener event=trigger6 />
+    </activity>
+  </events>
+  <attached>
+    <Billboard material="Flares/lensflare" colour="1,0,0">
+      <events>
+        <visibility>
+          <EventTrigger invert=true>
+            <events>
+              <trigger>
+                <EventListener event=trigger6 />
+              </trigger>
+            </events>
+          </EventTrigger>
+        </visibility>
+      </events>
+    </Billboard>
+    <BlinkingBillboard frequency=0.2 amplitude=1 material="Flares/lensflare" colour="1,1,0">
+      <events>
+        <visibility>
+          <EventTrigger>
+            <events>
+              <trigger>
+                <EventListener event=trigger6 />
+              </trigger>
+            </events>
+            <EventTrigger invert=true>
+              <events>
+                <trigger>
+                  <EventListener event=trigger7 />
+                </trigger>
+              </events>
+            </EventTrigger>
+          </EventTrigger>
+        </visibility>
+      </events>
+    </BlinkingBillboard>
+    <Billboard material="Flares/lensflare" colour="0,1,0">
+      <events>
+        <visibility>
+          <EventListener event=trigger7 />
+        </visibility>
+      </events>
+    </Billboard>
+  </attached>
+</CheckPoint>
+  </attached>
+</Model>
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/gametype_underattack.oxw
===================================================================
--- /code/branches/rocket2/data/levels/gametype_underattack.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/gametype_underattack.oxw	(revision 6952)
@@ -0,0 +1,166 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("underattackhud.oxo")
+  include("templates/spaceship_assff.oxt")
+  include("templates/lodinformation.oxt")
+?>
+
+<Level
+ name         = "UnderAttack testing"
+ description  = "A simple testlevel"
+ gametype     = UnderAttack
+>
+  <templates>
+    <Template link=lodtemplate_default />
+  </templates>
+
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/skypanoramagen1"
+  >
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+    <?lua for i = 1, 30, 1 do ?>
+        <MovableEntity
+            position="<?lua print(math.random() * 10000 - 5000) ?>, <?lua print(math.random() * 10000 - 5000) ?>, <?lua print(math.random() * 10000 - 5000) ?>"
+            velocity="<?lua print(math.random() * 500 - 250) ?>, <?lua print(math.random() * 500 - 250) ?>, <?lua print(math.random() * 500 - 250) ?>"
+        >
+            <attached>
+                <Model
+                    <?lua x = math.random() * 150 + 30 ?>
+                    scale="<?lua print(x) ?>"
+                    mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh"
+                    position="0,0,0"
+                />
+            </attached>
+            <collisionShapes>
+                <SphereCollisionShape radius=<?lua print(x) ?> position="0,0,0" />
+            </collisionShapes>
+        </MovableEntity>
+    <?lua end ?>
+
+    <Destroyer
+        position          = "100,150,0"
+        collisionType     = dynamic
+        mass              = 100000
+        velocity          = "-35,0,0"
+        angularDamping    = 0.9999999
+        health            = 10000
+        maxhealth         = 10000
+        initialhealth     = 10000
+    >
+
+        <attached>
+            <TeamSpawnPoint team=1 position="150,0,7" direction="-1,0,0" roll=90 yaw=0 spawnclass=SpaceShip pawndesign=spaceshipassff />
+            <TeamSpawnPoint team=1 position="0,0,7" lookat="-1,0,0" roll="90"  yaw=0 spawnclass=SpaceShip pawndesign=spaceshipassff />
+            <TeamSpawnPoint team=1 position="-50,0,7" lookat="-1,0,0" roll="90" yaw=0 spawnclass=SpaceShip pawndesign=spaceshipassff />
+            <TeamSpawnPoint team=1 position="100,0,7" lookat="-1,0,0" roll="90" yaw=0 spawnclass=SpaceShip pawndesign=spaceshipassff />
+            <TeamSpawnPoint team=1 position="50,0,7" lookat="-1,0,0" roll="90" yaw=0 spawnclass=SpaceShip pawndesign=spaceshipassff />
+            <?lua for i = 1, 100, 1 do ?>
+                <TeamSpawnPoint
+                    team=0
+                    position="<?lua print((math.random() * 500 + 500) * (math.floor(math.random() + 0.5) * 2 - 1)) ?>,<?lua print((math.random() * 500 + 500) * (math.floor(math.random() + 0.5) * 2 - 1)) ?>,<?lua print((math.random() * 500 + 500) * (math.floor(math.random() + 0.5) * 2 - 1)) ?>"
+                    lookat="0,0,0"
+                    spawnclass=SpaceShip
+                    pawndesign=spaceshipassff
+                />
+
+                <!--more spawnpoints for team1-->
+                <!--
+                <TeamSpawnPoint
+                    team=1 position="<?lua print((math.random() * 500 + 500)) ?>,<?lua print((math.random() * 500 + 500) ) ?>,<?lua print((math.random() * 500 + 500)) ?>"
+                    lookat="0,0,0"
+                    spawnclass=SpaceShip
+                    pawndesign=spaceshipassff
+                />-->
+            <?lua end ?>
+
+            <Model mesh="Carrier.mesh" scale="5" />
+            <Backlight
+                mainstate=activity
+                active=false
+                scale=0.4
+                name=bltest
+                position=" 7.6, 0, 6"
+                colour="0.2, 0.65, 1.0, 1.0"
+                width=15
+                length=1500
+                lifetime=2
+                elements=50
+                trailmaterial="Trail/backlighttrail"
+                turnontime=1
+                turnofftime=1
+                material="Flares/ThrusterFlare1"
+            />
+            <?lua for i=0,8,1 do ?>
+                <BlinkingBillboard
+                    position="<?lua print(200-270/8*i)?> ,15,2"
+                    material="Examples/Flare"
+                    colour="1.0, 0.5, 0.3"
+                    phase=<?lua print(-360/8*i)?>
+                    amplitude=0.1
+                    frequency=0.5
+                    quadratic=1
+                />
+
+                <BlinkingBillboard
+                    position="<?lua print(200-270/8*i)?>,-15,2"
+                    material="Examples/Flare"
+                    colour="1.0, 0.5, 0.3"
+                    phase=<?lua print(-360/8*i)?>
+                    amplitude=0.1
+                    frequency=0.5
+                    quadratic=1
+                />
+            <?lua end ?>
+
+            <Backlight
+                scale=1
+                position=" 169, 75, -15"
+                colour="1, 0.85, 0.5, 0.5"
+                width=40
+                length=1000
+                lifetime=5
+                elements=15
+                trailmaterial="Trail/backlighttrail"
+                material="Examples/Flare"
+            />
+            <Backlight
+                scale=1
+                position=" 169, -75, -15"
+                colour="1, 0.85, 0.5, 0.5"
+                width=40
+                length=1000
+                lifetime=5
+                elements=15
+                trailmaterial="Trail/backlighttrail"
+                material="Examples/Flare" />
+        </attached>
+        <collisionShapes>
+            <BoxCollisionShape position="70,0,-25"      halfExtents="150, 50, 25" />
+            <BoxCollisionShape position="95,75,-16"     halfExtents="70, 10, 12" />
+            <BoxCollisionShape position="95,-75,-16"    halfExtents="70, 10, 12" />
+            <BoxCollisionShape position="77,47,30"      halfExtents="110, 2, 30" />
+            <BoxCollisionShape position="77,-47,30"     halfExtents="110, 2, 30" />
+            <BoxCollisionShape position="77,0,50"       halfExtents="110, 45, 6" />
+            <BoxCollisionShape position="167,0,70"      halfExtents="17, 20, 20" />
+        </collisionShapes>
+    </Destroyer>
+
+    <GlobalShader compositor="Bloom" visible=false>
+      <events>
+        <visibility>
+          <DistanceTrigger position="0,0,0" distance=30 target="Spectator" switch=true />
+        </visibility>
+      </events>
+    </GlobalShader>
+
+    <Model position="0,0,0" scale=8 mesh="ast1.mesh" />
+    <StaticEntity position="0,0,0" collisionType=static>
+      <collisionShapes>
+        <SphereCollisionShape radius="20" />
+      </collisionShapes>
+    </StaticEntity>
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/includes/CuboidSpaceStation.lua
===================================================================
--- /code/branches/rocket2/data/levels/includes/CuboidSpaceStation.lua	(revision 6952)
+++ /code/branches/rocket2/data/levels/includes/CuboidSpaceStation.lua	(revision 6952)
@@ -0,0 +1,678 @@
+----------------------------------------------------------------------------------------------------
+-- This lua script creates a totally random generated space station for the orxonox computer game!--
+-- (c) Wallah 2008, published under GPL licence!												  --
+----------------------------------------------------------------------------------------------------
+
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- IMPORTANT: If you need more parameters, do the following: copy the actual function (just the headline and the end statement) to the end of the file,			  --
+-- like I did with createSpaceStation() and let that function call the new function where you can modify the parameters. For all parameters which the old function--
+-- doesn't have you just give the standard default values, which I have defined. This is to make sure, that anyone else who uses the old function can still use it--
+-- the same way he/she always did. If you want a function with less parameters, just create a new one at the end of the file and call this function with some	  --
+-- default values. REMEMBER: Function overloading is not possible, be sure to call your function differently from others already existing ones.					  --
+--------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+-- This function creates a randomly generated space station.
+-- The first argument ranSeed, must be 0, or a positive Integer, if it is 0 your space station is always chosen randomly, if you give an integer,
+--	your space station will be generated randomly, but once you have the space station it will always be the same.
+-- The argument xLength defines how large the space station will be into the x-direction.
+-- The argument xVar defines how much the space station will vary at the ends in x-direction, this is so that the station is no cube.
+-- The argument yLength is the same as xLength, but for the y-direction.
+-- The argument yVar is the same as xLength, but for the y-direction.
+-- The argument zLength is the same as xLength, but for the z-direction.
+-- The argument zVar is the same as xLength, but for the z-direction.
+-- The argument sSScale scales the station proportionally in all directions.
+function createSpaceStationPar(ranSeed, xLength, xVar, yLength, yVar, zLength, zVar, sSScale)
+
+
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- This prints xml code, which creates a MovableEntity, which I need to attach all the parts of the space station.
+print("<MovableEntity scale=1 position=\"0,0,0\" >")
+-- End create Movable Entity.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Create a randomseed, so that the math.random() function is actually random.
+if ranSeed == 0 then
+	math.randomseed(os.time())
+else
+	math.randomseed(ranSeed)
+end
+-- End create randomseed.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Here you can define some global variables, with which you can modify the space station.
+
+-- Define the maximal size of the grid, this value is based on how large you define the area of bodyparts plus 20 gridpoints for attachparts.
+sSSize=30
+if xLength>=yLength and xLength>=zLength then
+	sSSize=xLength+20
+elseif yLength>=xLength and yLength>=zLength then
+	sSSize=yLength+20
+elseif zLength>=xLength and zLength>=yLength then
+	sSSize=zLength+20
+end
+-- Define how many parts the space station has, this value has to be exact, so be sure to increment it if you're adding a new part.
+sSParts=9
+-- Define how many body parts the space station has, this value has to be exact. Body part means a part, which has connections at least in two directions.
+sSBodyParts=3
+-- Define how many frontParts you have.
+frontParts=1
+-- Define how many backParts you have.
+backParts=1
+-- Define how many side parts for the left side you have.
+leftSideParts=1
+-- Define how many side parts for the right side you have.
+rightSideParts=1
+-- Define how many top parts you have.
+topParts=2
+-- Define how many connection parts you have.
+connParts=1
+-- Define the maximal dimension of a single part, be sure this value is big enough, better it's too big, it's only a matter of efficiency.
+-- It should be at least 1 bigger than the biggest part needs, because I guarantee that it works with odd numbers, to do so I use the math.floor function.
+pDim=6
+-- Define the griddimension, be sure this value matches the size of a single space station part plus the size of a connection part, which means your parts must be:
+--	integer*(gridDim-connectionSize), then integer tells you how many griddimensions your part is.
+gridDim=2.25
+-- End define global parameters.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- This creates a 4-dimensional grid, which tells us if there is a part or not, and in which direction it has connections.
+-- The parameters x,y,z are the axis of the space station, which iterate to sSSize, the maximal size of the space station.
+-- The griddimension, this word I will use later, means that the distance of a point to the next point is gridDim in the game, so the absolute x-axis is x*gridDim*sSScale,
+--	and so on for the other dimensions y and z.
+-- grid[x][y][z][0] contains 0 if there is no part at the position (x,y,z), otherwise 1.
+-- grid[x][y][z][1] contains 0 if there is no connection from (x,y,z) in x-direction, "+" if there is one in the positive x-direction,
+--	"-" if there is one in the negative x-direction, "+-" if there are in both x-directions.
+-- grid[x][y][z][2] contains 0 if there is no connection from (x,y,z) in y-direction, "+" if there is one in the positive y-direction,
+--	"-" if there is one in the negative y-direction, "+-" if there are in both y-directions.
+-- grid[x][y][z][3] contains 0 if there is no connection from (x,y,z) in z-direction, "+" if there is one in the positive z-direction,
+--	"-" if there is one in the negative z-direction, "+-" if there are in both z-directions.
+grid = {}
+for x=-math.floor(sSSize/2),math.floor(sSSize/2) do
+	grid[x] = {}
+	for y=-math.floor(sSSize/2),math.floor(sSSize/2) do
+		grid[x][y]= {}
+		for z=-math.floor(sSSize/2),math.floor(sSSize/2) do
+			grid[x][y][z]={}
+			for i=0,3 do
+				grid[x][y][z][i]=0
+			end
+		end
+	end
+end
+-- End create 4-dim grid.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- This creates an array which stores all the parts, it's size is depending on the global values pDim and sSParts.
+-- The first parameter i, tells us how many parts fit into the array, so it iterates from 1 to sSParts, each part has his own value i.
+-- The second, third and fourth parameters are the relative coordinates of the part, you have to start at (0,0,0) and be sure you fill the array into the right direction.
+--	A short example: your part is 2 griddimensions long and you place it in the game, that the relative coordinate point is at (0,0,0) and the part lies in the positive
+--	z-axis, then you have to use the coordinate point (0,0,1).
+-- The fifth parameter is an array with size 4, at index=0, you have to set 1 if your part covers the gridpoint at (x,y,z), otherwise 0.
+--	At index=1,2,3 you define the possible connection directions (1 for x, 2 for y and 3 for z), be sure to use the notation from above (0, "+-", "+", "-").
+bodyParts={}
+for i=1,sSParts do
+	bodyParts[i]={}
+	for x=-math.floor(pDim/2),math.floor(pDim/2) do
+		bodyParts[i][x]={}
+		for y=-math.floor(pDim/2),math.floor(pDim/2) do
+			bodyParts[i][x][y]={}
+			for z=-math.floor(pDim/2),math.floor(pDim/2) do
+				bodyParts[i][x][y][z]={}
+				for k=0,3 do
+					bodyParts[i][x][y][z][k]=0
+				end
+			end
+		end
+	end
+	-- This contains the name of the mesh file.
+	bodyParts[i][0][0][0][4]=""
+	-- This contains the first possible rotation of your part, pitch=... yaw=... roll=... .
+	bodyParts[i][0][0][0][5]=""
+	-- This contains the second possible rotation of your part, pitch=... yaw=... roll=... .
+	bodyParts[i][0][0][0][6]=""
+	-- This contains the third possible rotation of your part, pitch=... yaw=... roll=... .
+	bodyParts[i][0][0][0][7]=""
+	-- Contains the movement rotation, rotationaxis=... rotationrate=... .
+	bodyParts[i][0][0][0][8]=""
+	-- Contains the attachment, if your part has an attachment, e.g. <ParticleEmitter .../>.
+	bodyParts[i][0][0][0][9]=""
+	-- Contains how many of this part you want to attach to your space station.
+	bodyParts[i][0][0][0][10]=1
+end
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Here you can add a part to the space station, there are some examples here and how to describe your part is written above in the commentary.
+
+-- The part must be inserted so, that the center of reference is at position (0,0,0).
+-- At position bodyParts[i][0][0][0][4] you have to put the mesh name of your part.
+-- At bodyParts[i][0][0][0][5] you can rotate your part, with pitch=angle, yaw=angle or roll=angle (x,y or z). Positive angle means in screw direction.
+-- At bodyParts[i][0][0][0][6] you have another possibility to rotate your part in a different way, e.g. for left and right side parts.
+-- At bodyParts[i][0][0][0][7] you have a third possibility to rotate your part, e.g. connection parts must be rotated into 3 different ways.
+-- At bodyParts[i][0][0][0][8] you can rotate your part around his own axis, with rotationaxis="x,y,z" rotationrate=number.
+-- At bodyParts[i][0][0][0][9] you can attach something to your model, e.g. <ParticleEmitter .../>.
+
+-- Insert the CuboidBody, which is only one griddimension and can have connections in every direction.
+bodyParts[1][0][0][0][4]="CuboidBody.mesh"
+
+bodyParts[1][0][0][0][0]=1
+bodyParts[1][0][0][0][1]="+-"
+bodyParts[1][0][0][0][2]="+-"
+bodyParts[1][0][0][0][3]="+-"
+-- End insert CuboidBody.
+
+-- Insert the DoubleCuboidBody, which is two griddimensions long, and one wide and high and can have connections in every direction except in the middle.
+bodyParts[2][0][0][0][4]="DoubleCuboidBody.mesh"
+bodyParts[2][0][0][0][5]="pitch=-90"
+
+bodyParts[2][0][0][0][0]=1
+bodyParts[2][0][0][0][1]="+-"
+bodyParts[2][0][0][0][2]="+-"
+bodyParts[2][0][0][0][3]="-"
+
+bodyParts[2][0][0][1][0]=1
+bodyParts[2][0][0][1][1]="+-"
+bodyParts[2][0][0][1][2]="+-"
+bodyParts[2][0][0][1][3]="+"
+-- End insert DoubleCuboidBody.
+
+-- Insert the CuboidConnectionBody, it is three griddimensions long and one wide and high and can have only connections at griddimension 1
+--	(except the side in direction of griddimension 2) and griddimension 3 (except the side in direction of griddimension 2).
+bodyParts[3][0][0][0][4]="CuboidConnBody.mesh"
+bodyParts[3][0][0][0][5]="pitch=-90"
+
+bodyParts[3][0][0][0][0]=1
+bodyParts[3][0][0][0][1]="+-"
+bodyParts[3][0][0][0][2]="+-"
+bodyParts[3][0][0][0][3]="-"
+
+bodyParts[3][0][0][1][0]=1
+
+bodyParts[3][0][0][2][0]=1
+bodyParts[3][0][0][2][1]="+-"
+bodyParts[3][0][0][2][2]="+-"
+bodyParts[3][0][0][2][3]="+"
+-- End insert CuboidConnectionBody.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Insert the back parts.
+-- If you're space station has no back parts, be sure to set backPartsIndex[0]=false.
+backPartsIndex={}
+backPartsIndex[0]=""
+
+-- Insert the thruster, which is one griddimension long, two wide and high, it can only have a connection into the negative z-direction.
+backPartsIndex[1]=4
+bodyParts[backPartsIndex[1]][0][0][0][4]="Thruster.mesh"
+bodyParts[backPartsIndex[1]][0][0][0][5]="pitch=-90"
+bodyParts[backPartsIndex[1]][0][0][0][9]="<ParticleEmitter position=\"0,-0.5,0\" source=\"Orxonox/ThrusterFire\" />"
+bodyParts[backPartsIndex[1]][0][0][0][10]=5
+
+bodyParts[backPartsIndex[1]][0][0][0][0]=1
+bodyParts[backPartsIndex[1]][0][0][0][3]="-"
+bodyParts[backPartsIndex[1]][1][0][0][0]=1
+bodyParts[backPartsIndex[1]][-1][0][0][0]=1
+bodyParts[backPartsIndex[1]][0][1][0][0]=1
+bodyParts[backPartsIndex[1]][0][-1][0][0]=1
+-- End insert the thruster.
+
+-- End insert the back parts.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Insert the front parts. If your space station has no front parts, be sure to set frontPartsIndex[0]=false.
+frontPartsIndex={}
+frontPartsIndex[0]=""
+
+-- The SemiCircleCockpit is 3 x-griddimensions long, 3 y-griddimensions and 2 z-griddimensions, it can only have a connection in the positive z-direction.
+frontPartsIndex[1]=5
+bodyParts[frontPartsIndex[1]][0][0][0][4]="SemiCircleCockpit.mesh"
+bodyParts[frontPartsIndex[1]][0][0][0][5]="pitch=-90 yaw=180"
+bodyParts[frontPartsIndex[1]][0][0][0][9]="<Billboard scale=0.01 position=\"0,-0.1,2.2\" colour=\"1.0,1.0,1.0\" material=\"Examples/Flare\" /> <Billboard scale=0.01 position=\"0.5,-0.1,2.2\" colour=\"1.0,1.0,1.0\" material=\"Examples/Flare\" /> <Billboard scale=0.01 position=\"-0.5,-0.1,2.2\" colour=\"1.0,1.0,1.0\" material=\"Examples/Flare\" />"
+
+bodyParts[frontPartsIndex[1]][0][0][0][0]=1
+bodyParts[frontPartsIndex[1]][0][0][0][3]="+"
+
+bodyParts[frontPartsIndex[1]][-1][0][0][0]=1
+bodyParts[frontPartsIndex[1]][1][0][0][0]=1
+bodyParts[frontPartsIndex[1]][0][-1][0][0]=1
+bodyParts[frontPartsIndex[1]][0][1][0][0]=1
+bodyParts[frontPartsIndex[1]][-1][-1][0][0]=1
+bodyParts[frontPartsIndex[1]][1][-1][0][0]=1
+bodyParts[frontPartsIndex[1]][-1][1][0][0]=1
+bodyParts[frontPartsIndex[1]][1][1][0][0]=1
+bodyParts[frontPartsIndex[1]][0][0][-1][0]=1
+bodyParts[frontPartsIndex[1]][-1][0][-1][0]=1
+bodyParts[frontPartsIndex[1]][1][0][-1][0]=1
+bodyParts[frontPartsIndex[1]][0][-1][-1][0]=1
+bodyParts[frontPartsIndex[1]][0][1][-1][0]=1
+bodyParts[frontPartsIndex[1]][-1][-1][-1][0]=1
+bodyParts[frontPartsIndex[1]][1][-1][-1][0]=1
+bodyParts[frontPartsIndex[1]][-1][1][-1][0]=1
+bodyParts[frontPartsIndex[1]][1][1][-1][0]=1
+-- End insert SemiCircleCockpit.
+
+-- End insert the front parts.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Insert the side parts.
+-- If your space station has no left side parts, be sure to set leftsidePartsIndex[0]=false.
+-- If your space station has no right side parts, be sure to set rightsidePartsIndex[0]=false.
+leftSidePartsIndex={}
+leftSidePartsIndex[0]=""
+rightSidePartsIndex={}
+rightSidePartsIndex[0]=""
+
+-- Insert the solar panel, which i wanna use as left and right side part.
+leftSidePartsIndex[1]=6
+rightSidePartsIndex[1]=leftSidePartsIndex[1]
+bodyParts[leftSidePartsIndex[1]][0][0][0][4]="SolarPanel.mesh"
+bodyParts[leftSidePartsIndex[1]][0][0][0][5]="roll=90 pitch="..math.random(0,180)
+bodyParts[rightSidePartsIndex[1]][0][0][0][6]="roll=-90 pitch="..math.random(0,180)
+bodyParts[rightSidePartsIndex[1]][0][0][0][8]="rotationaxis=\"1,0,0\" rotationrate=2"
+bodyParts[leftSidePartsIndex[1]][0][0][0][0]=1
+bodyParts[leftSidePartsIndex[1]][0][0][1][0]=1
+bodyParts[leftSidePartsIndex[1]][0][0][-1][0]=1
+bodyParts[leftSidePartsIndex[1]][0][1][0][0]=1
+bodyParts[leftSidePartsIndex[1]][0][1][1][0]=1
+bodyParts[leftSidePartsIndex[1]][0][1][-1][0]=1
+bodyParts[leftSidePartsIndex[1]][0][-1][0][0]=1
+bodyParts[leftSidePartsIndex[1]][0][-1][1][0]=1
+bodyParts[leftSidePartsIndex[1]][0][-1][-1][0]=1
+-- End insert solar panel.
+
+-- End insert side parts.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Insert the top parts.
+-- If you have no top parts, be sure to set topPartsIndex[0]=false
+topPartsIndex={}
+topPartsIndex[0]=""
+
+-- Insert the CuboidLandingZone.
+topPartsIndex[1]=7
+bodyParts[topPartsIndex[1]][0][0][0][4]="CuboidLandingZone.mesh"
+bodyParts[topPartsIndex[1]][0][0][0][5]="pitch=-90"
+
+bodyParts[topPartsIndex[1]][0][0][0][0]=1
+bodyParts[topPartsIndex[1]][0][0][0][2]="+-"
+bodyParts[topPartsIndex[1]][1][0][0][0]=1
+bodyParts[topPartsIndex[1]][-1][0][0][0]=1
+bodyParts[topPartsIndex[1]][0][0][1][0]=1
+bodyParts[topPartsIndex[1]][1][0][1][0]=1
+bodyParts[topPartsIndex[1]][-1][0][1][0]=1
+bodyParts[topPartsIndex[1]][0][0][2][0]=1
+bodyParts[topPartsIndex[1]][1][0][2][0]=1
+bodyParts[topPartsIndex[1]][-1][0][2][0]=1
+bodyParts[topPartsIndex[1]][0][0][3][0]=1
+bodyParts[topPartsIndex[1]][1][0][3][0]=1
+bodyParts[topPartsIndex[1]][-1][0][3][0]=1
+-- End insert the CuboidLandingZone.
+
+-- Insert the SatelliteDish.
+topPartsIndex[2]=8
+bodyParts[topPartsIndex[2]][0][0][0][4]="SatelliteDish.mesh"
+bodyParts[topPartsIndex[2]][0][0][0][5]="pitch=-90"
+bodyParts[topPartsIndex[2]][0][0][0][8]="rotationaxis=\"0,1,0\" rotationrate=5"
+
+bodyParts[topPartsIndex[2]][0][0][0][0]=1
+bodyParts[topPartsIndex[2]][0][0][1][0]=1
+bodyParts[topPartsIndex[2]][0][0][-1][0]=1
+bodyParts[topPartsIndex[2]][1][0][0][0]=1
+bodyParts[topPartsIndex[2]][1][0][1][0]=1
+bodyParts[topPartsIndex[2]][1][0][-1][0]=1
+bodyParts[topPartsIndex[2]][-1][0][0][0]=1
+bodyParts[topPartsIndex[2]][-1][0][1][0]=1
+bodyParts[topPartsIndex[2]][-1][0][-1][0]=1
+-- End insert the SatelliteDish.
+
+-- End insert the top parts.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Insert the connection parts, which are used to connect all the bodyparts.
+-- If you're spacestation has no connection parts, be sure to set connPartsIndex[0]=false.
+connPartsIndex={}
+connPartsIndex[0]=""
+
+-- Insert the CuboidConnection.
+connPartsIndex[1]=9
+bodyParts[connPartsIndex[1]][0][0][0][4]="CuboidConnection.mesh"
+bodyParts[connPartsIndex[1]][0][0][0][5]="roll=90"
+bodyParts[connPartsIndex[1]][0][0][0][6]=""
+bodyParts[connPartsIndex[1]][0][0][0][7]="pitch=90"
+-- End insert the CuboidConnection.
+
+-- End insert the connection parts.
+
+-- End create array bodyParts.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Here I define some functions which I will use later.
+
+--This function actualizes the grid, which I have to call always after I have added a new part to the space station.
+function actualizeGrid(Index,x,y,z)
+	for i=math.floor(-pDim/2)+1,math.floor(pDim/2) do
+		for j=math.floor(-pDim/2)+1,math.floor(pDim/2) do
+			for k=math.floor(-pDim/2)+1,math.floor(pDim/2) do
+				if bodyParts[Index][i][j][k][0] == 1 then
+					for l=0,3 do
+						grid[x+i][y+j][z+k][l] = bodyParts[Index][i][j][k][l]
+					end
+				end
+			end
+		end
+	end
+end
+-- End actualizeGrid.
+
+-- This function checks wheter a given parts fits at that position or not.
+-- If the part fits there it returns 1, otherwise 0.
+function checkPart(Index,x,y,z)
+	check=1
+	for i=math.floor(-pDim/2)+1,math.floor(pDim/2) do
+		for j=math.floor(-pDim/2)+1,math.floor(pDim/2) do
+			for k=math.floor(-pDim/2)+1,math.floor(pDim/2) do
+				-- If the part occupies the position (i,j,k), the grid must be empty there ((x+i, y+j, z+k)==0), if not, check is zero,
+				--	which means that the part doesn't fit there.
+				if bodyParts[Index][i][j][k][0] == 1 and grid[x+i][y+j][z+k][0] == 1 then
+					check=0
+				end
+			end
+		end
+	end
+	return check
+end
+-- End checkPart function.
+
+-- This function prints the model with tempPartIndex in the bodyParts array at position lx,ly,lz.
+-- If you need to rotate the model around his own axis, then you have to set movEntity true and define the details of the rotation in
+--	bodyParts[tempPartIndex][0][0][0][8].
+-- If your model needs to be rotated like bodyParts[tempPartIndex][0][0][0][5], then side must be 1, for bodyParts[tempPartIndex][0][0][0][6] side must be 2,
+--	for bodyParts[tempPartIndex][0][0][0][7] side must be 3.
+function printModel(lx,ly,lz,tempPartIndex,movEntity,side)
+	if movEntity == true then
+		print("<MovableEntity scale=1 position=\"") print(lx*gridDim*sSScale) print(",") print(ly*gridDim*sSScale) print(",") print(lz*gridDim*sSScale) print("\" ")
+		print(bodyParts[tempPartIndex][0][0][0][8]) print(">")
+		print("<attached>")
+		lx=0 ly=0 lz=0
+	end
+
+	print("<Model position=\"") print(lx*gridDim*sSScale) print(",") print(ly*gridDim*sSScale) print(",") print(lz*gridDim*sSScale)
+	print("\" scale=") print(sSScale) print(" mesh= \"") print(bodyParts[tempPartIndex][0][0][0][4]) print("\"")
+
+		if side == 1 then
+			print(bodyParts[tempPartIndex][0][0][0][5]) print(">")
+		elseif side == 2 then
+			print(bodyParts[tempPartIndex][0][0][0][6]) print(">")
+		elseif side == 3 then
+			print(bodyParts[tempPartIndex][0][0][0][7]) print(">")
+		end
+
+		print("<attached>")
+			print(bodyParts[tempPartIndex][0][0][0][9])
+		print("</attached>")
+
+	print("</Model>")
+
+	if movEntity == true then
+		print("</attached>")
+		print("</MovableEntity>")
+	end
+end
+-- End function printModel().
+
+-- This function sets a part to a side of the space station.
+-- The arguments lx,ly,lz are the coordinates of the grid, where you want to set the part.
+-- The arguments xAxis,yAxis,zAxis can be 0 or 1, but only one argument out of the three can be 1. This means two of them must always be zero. You have to set xAxis to one,
+--	if your part is attached to a side, which faces into the x-direction (negative or positive, this is later specified with Dir), that means the x-Axis is a normal vector
+--	of the side to which you want to attach the part. The same for yAxis and zAxis.
+-- The argument Dir must be 1 if your side, where you want to attach the part, faces into the positive direction, -1 if the side faces into the negative direction. The side
+--	faces into the positive direction means, that the side of the side where the part will be attached is directed into the direction of the positive direction of the
+--	corresponding axis.
+-- The argument index is the index of the part for the bodyParts array.
+-- The argument printMovEnt must be false if your part doesn't need to be attached to an extra MovableEntity. If your part must be attached to an extra MovableEntity
+--	this argument must be true. The extra MovableEntity is used to rotate the part around his own axis, or something like that.
+-- The argument printSide is like the argument side of the printModel() function. It defines how your part will be rotated. Read the commentary there.
+-- The function returns 0 if the part couldn't be set, because it did not fit there or there was no side to attach the part. It returns 1 if the part is successfully set.
+function setPart(lx,ly,lz,xAxis,yAxis,zAxis,Dir,index,printMovEnt,printSide)
+
+	partSet=0
+	-- For the bodyParts array I use 1 as x-, 2 as y- and 3 as z-Axis for the definition in which directions a part can have connections.
+	coord=1*xAxis+2*yAxis+3*zAxis
+	-- If I try to attach the part from the positive direction to the side of the space station, the part of the station (where I want to attach the new part) must have
+	--	a connection into the positive direction. Otherwise I look from the negative side and so the part of the station must have a connection into the negative direction.
+	if Dir==1 then
+		conn="+"
+	elseif Dir==-1 then
+		conn="-"
+	end
+	-- I look from the direction defined through Dir, and here I check, whether I have reached a side of the space station, which means at position lx,ly,lz is nothing and
+	--	at the next position is a part which can have a connection into the direction from where I look.
+	if grid[lx][ly][lz][0] == 0 and grid[lx+(-1*xAxis*Dir)][ly+(-1*yAxis*Dir)][lz+(-1*zAxis*Dir)][0] == 1 and (grid[lx+(-1*xAxis*Dir)][ly+(-1*yAxis*Dir)][lz+(-1*zAxis*Dir)][coord]=="+-" or grid[lx+(-1*xAxis*Dir)][ly+(-1*yAxis*Dir)][lz+(-1*zAxis*Dir)][coord]==conn) then
+		-- This checks whether the part fits at that position or not.
+		check=checkPart(index,lx,ly,lz)
+		if check == 1 then
+			-- This prints the part.
+			printModel(lx,ly,lz,index,printMovEnt,printSide)
+			partSet=1
+			-- This actualizes the grid array with the values of the array bodyParts at the position index.
+			actualizeGrid(index,lx,ly,lz)
+		end
+	end
+	return partSet
+end
+-- End function setPart().
+
+-- This function sets a part to a side of the space station. It is called spiralSet, because it starts in the middle of the side and goes out in a form of a spiral.
+-- The argument xAxis,yAxis,zAxis,Dir,printMovEnt,printSide are the same as the arguments from the setPart() function, please read the commentary there.
+-- The argument index here must be an array, where you define the index for your part for the bodyParts array. The first used index is 1 and goes up to parts.
+-- The argument parts is the number of different parts which you want to attach to a side.
+function spiralSet(xAxis,yAxis,zAxis,Dir,index,parts,printMovEnt,printSide)
+	if index[0] ~= false then
+		-- The array vector contains the actual position where you try to set the part. vector[0],vector[1] and vector[3] contains the x,y,z-coordinate.
+		vector={}
+		-- This must be done, because there are different sides from where I try to attach a part.
+		coord1=1*yAxis+2*zAxis
+		coord2=math.mod(coord1+1,3)
+		coord3=math.mod(coord2+1,3)
+
+		for pc=1,parts do
+			tempIndex = index[pc]
+			for eachPart=1,bodyParts[tempIndex][0][0][0][10] do
+				partSet=0
+				vector[coord1]=math.floor(Dir*sSSize/2)-2*Dir
+				while vector[coord1]~=math.floor(-1*Dir*sSSize/2)+2*Dir and partSet==0 do
+					round=0
+					while round<=math.floor(sSSize/2)-2 and partSet==0 do
+						vector[coord2]=round
+						vector[coord3]=-round
+						while vector[coord3]<=round and partSet==0 do
+							partSet=setPart(vector[0],vector[1],vector[2],xAxis,yAxis,zAxis,Dir,tempIndex,printMovEnt,printSide)
+							vector[coord3]=vector[coord3]+1
+						end
+						while vector[coord2]>=-round and partSet==0 do
+							partSet=setPart(vector[0],vector[1],vector[2],xAxis,yAxis,zAxis,Dir,tempIndex,printMovEnt,printSide)
+							vector[coord2]=vector[coord2]-1
+						end
+						while vector[coord3]>-round and partSet==0 do
+							partSet=setPart(vector[0],vector[1],vector[2],xAxis,yAxis,zAxis,Dir,tempIndex,printMovEnt,printSide)
+							vector[coord3]=vector[coord3]-1
+						end
+						while vector[coord2]<=round and partSet==0 do
+							partSet=setPart(vector[0],vector[1],vector[2],xAxis,yAxis,zAxis,Dir,tempIndex,printMovEnt,printSide)
+							vector[coord2]=vector[coord2]+1
+						end
+						round=round+1
+					end
+					vector[coord1]=vector[coord1]-Dir
+				end
+			end
+		end
+	end
+end
+-- End function spiralSet().
+
+-- End define functions.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- This is xml code, which means now we attach some parts to the MovableEntity.
+print("<attached>")
+-- End attach to the MovableEntity.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Attach all bodyparts.
+-- Define at which position in the x-direction you're space station will start.
+x=math.random(-math.floor(xLength/2),-math.floor(xLength/2)+xVar)
+-- Define at which position in the x-direction you're space station will end.
+xMax=math.random(math.floor(xLength/2),math.floor(xLength/2)+xVar)
+while x<xMax do
+	-- The same for the y- and z-direction.
+	y=math.random(-math.floor(yLength/2),-math.floor(yLength/2)+yVar)
+	yMax=math.random(math.floor(yLength/2),math.floor(yLength/2)+yVar)
+	while y<yMax do
+		yMax=math.random(math.floor(yLength/2),math.floor(yLength/2)+yVar)
+		z=math.random(-math.floor(zLength/2),-math.floor(zLength/2)+zVar)
+		zMax=math.random(math.floor(zLength/2),math.floor(zLength/2)+zVar)
+		while z<zMax do
+			-- This loop choses a bodypart, which fits at position (x,y,z).
+			-- If after the fifth time the part does still not fit we terminate the loop and set no part at postition (x,y,z).
+			partSet=0
+			counter=0
+			while counter<5 and partSet==0 do
+				-- This choses randomly a bodyPartIndex, which is the index used for the parts in the array bodyParts.
+				tempBodyPartIndex=math.random(1,sSBodyParts)
+				check=checkPart(tempBodyPartIndex,x,y,z)
+				-- If check == 1, this means that the part fits there, so we put it there and break the while true loop, to go on.
+				if check == 1 then
+					-- This prints the chosen part at position (x*gridDim*sSScale,y*gridDim*sSScale,z*gridDim*sSScale).
+					printModel(x,y,z,tempBodyPartIndex,false,1)
+					-- This actualizes the grid array with the values of the array bodyParts at the position tempBodyPartIndex, which is our randomly chosen part.
+					actualizeGrid(tempBodyPartIndex,x,y,z)
+					partSet=1
+				end
+				counter=counter+1
+			end
+			z=z+1
+		end
+		y=y+1
+	end
+	x=x+1
+end
+-- End attach all bodyparts.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Attach backParts, if there are some.
+	spiralSet(0,0,1,1,backPartsIndex,backParts,false,1)
+-- End attach backParts.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Attach frontParts, if there are.
+	spiralSet(0,0,1,-1,frontPartsIndex,frontParts,false,1)
+-- End attach frontParts.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Attach parts on the left side of the space station.
+	spiralSet(1,0,0,-1,leftSidePartsIndex,leftSideParts,true,1)
+-- End attach left side parts.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Attach parts on the right side of the space station.
+	spiralSet(1,0,0,1,rightSidePartsIndex,rightSideParts,true,2)
+-- End attach right side parts.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Attach parts on top of the space station.
+	spiralSet(0,1,0,1,topPartsIndex,topParts,true,1)
+-- End attach top parts.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- Attach all connectionparts.
+-- This iterates through the whole grid array.
+if connPartsIndex[0] ~= false then
+	for x=math.floor(-sSSize/2)+2,math.floor(sSSize/2)-2 do
+		for y=math.floor(-sSSize/2)+2,math.floor(sSSize/2)-2 do
+			for z=math.floor(-sSSize/2)+2,math.floor(sSSize/2)-2 do
+				tempConnPartIndex=connPartsIndex[math.random(1,connParts)]
+				-- This checks whether there has to be a connection part between (x,y,z) and (x+1,y,z) or not. First it checks if there is a part at (x,y,z) and
+				--	then it checks if that part can have a connection into the positive x-direction, if it can, it checks if there is a part at (x+1,y,z) and
+				--	if that part can have a connection into the negative x-direction, if both can, it prints the xml code to set a connection part.
+				if grid[x][y][z][0]==1 and (grid[x][y][z][1]=="+" or grid[x][y][z][1]=="+-") and grid[x+1][y][z][0]==1 and (grid[x+1][y][z][1]=="-" or grid[x+1][y][z][1]=="+-") then
+					-- This prints the connection part, the +1/2 is because the connection is set exactly in the middle of two gridpoints.
+					printModel(x+1/2,y,z,tempConnPartIndex,false,1)
+				end
+				-- The same as in the x-direction, but for the y-direction.
+				if grid[x][y][z][0]==1 and ( grid[x][y][z][2]=="+" or grid[x][y][z][2]=="+-" ) and grid[x][y+1][z][0]==1 and ( grid[x][y+1][z][2]=="-" or grid[x][y+1][z][2]=="+-" ) then
+					printModel(x,y+1/2,z,tempConnPartIndex,false,2)
+				end
+				-- The same as in the x-direction, but for the z-direction.
+				if grid[x][y][z][0]==1 and ( grid[x][y][z][3]=="+" or grid[x][y][z][3]=="+-" ) and grid[x][y][z+1][0]==1 and ( grid[x][y][z+1][3]=="-" or grid[x][y][z+1][3]=="+-" ) then
+					printModel(x,y,z+1/2,tempConnPartIndex,false,3)
+				end
+			end
+		end
+	end
+end
+-- End attach all connectionparts.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+-- This is xml code, which ends the attachment and the MovableEntity.
+print("</attached>")
+print("</MovableEntity>")
+-- End ends attachment and MovableEntity.
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+
+
+end
+-- End createSpaceStationPar() function.
+
+
+
+-- This function is for the lazy guys, which do not care how the space station looks like, so I use some good standard values.
+function createSpaceStation()
+	createSpaceStationPar(0,4,1,2,1,6,1,100)
+end
+-- End createSpaceStaion() function.
+
+
+
Index: /code/branches/rocket2/data/levels/includes/pickups.oxi
===================================================================
--- /code/branches/rocket2/data/levels/includes/pickups.oxi	(revision 6952)
+++ /code/branches/rocket2/data/levels/includes/pickups.oxi	(revision 6952)
@@ -0,0 +1,157 @@
+
+<!-- Health pickups -->
+
+<PickupRepresentation
+    pickupName = "Small Health Boost"
+    pickupDescription = "Adds a small amout of health to the ship."
+    inventoryRepresentation = "SmallHealth"
+    spawnerTemplate = "smallhealthpickupRepresentation"
+>
+    <pickup>
+        <HealthPickup template=smallhealthpickup />
+    </pickup>
+</PickupRepresentation>
+
+<PickupRepresentation
+    pickupName = "Medium Health Boost"
+    pickupDescription = "Adds a medium amout of health to the ship."
+    spawnerTemplate = "mediumhealthpickupRepresentation"
+    inventoryRepresentation = "MediumHealth"
+>
+    <pickup>
+        <HealthPickup template=mediumhealthpickup />
+    </pickup>
+</PickupRepresentation>
+
+<PickupRepresentation
+    pickupName = "Huge Health Boost"
+    pickupDescription = "Adds a huge amout of health to the ship."
+    spawnerTemplate = "hugehealthpickupRepresentation"
+    inventoryRepresentation = "HugeHealth"
+>
+    <pickup>
+        <HealthPickup template=hugehealthpickup />
+    </pickup>
+</PickupRepresentation>
+
+<PickupRepresentation
+    pickupName = "Crazy Madness Health Boost"
+    pickupDescription = "Adds a crazy amout of health to the ship."
+    spawnerTemplate = "crazyhealthpickupRepresentation"
+    inventoryRepresentation = "CrazyMadnessHealth"
+>
+    <pickup>
+        <HealthPickup template=crazyhealthpickup />
+    </pickup>
+</PickupRepresentation>
+
+<!-- Meta pickups -->
+
+<PickupRepresentation
+    pickupName = "Use Pickup"
+    pickupDescription = "Uses all pickups you have."
+    spawnerTemplate = "usepickupRepresentation"
+    inventoryRepresentation = "usePickup"
+>
+    <pickup>
+        <MetaPickup metaType="use" />
+    </pickup>
+</PickupRepresentation>
+
+<PickupRepresentation
+    pickupName = "Drop Pickup"
+    pickupDescription = "Drops all pickups you have."
+    spawnerTemplate = "droppickupRepresentation"
+    inventoryRepresentation = "dropPickup"
+>
+    <pickup>
+        <MetaPickup metaType="drop" />
+    </pickup>
+</PickupRepresentation>
+
+<!-- Speed pickups -->
+
+<PickupRepresentation
+    name = "Small Speed Boost"
+    description = "Multiplies Speed of the Ship by a small amount."
+    spawnerTemplate = "smallspeedpickupRepresentation"
+>
+    <pickup>
+        <SpeedPickup template=smallspeedpickup />
+    </pickup>
+</PickupRepresentation>
+
+<PickupRepresentation
+    name = "Medium Speed Boost"
+    description = "Multiplies Speed of the Ship by a bigger amount."
+    spawnerTemplate = "mediumspeedpickupRepresentation"
+>
+    <pickup>
+        <SpeedPickup template=mediumspeedpickup />
+    </pickup>
+</PickupRepresentation>
+
+<PickupRepresentation
+    name = "Huge Speed Boost"
+    description = "Multiplies Speed of the Ship by a huge amount."
+    spawnerTemplate = "hugespeedpickupRepresentation"
+>
+    <pickup>
+        <SpeedPickup template=hugespeedpickup />
+    </pickup>
+</PickupRepresentation>
+
+<PickupRepresentation
+    name = "Small Jump Boost"
+    description = "Boosts the Ship with a massive amount for a very short time."
+    spawnerTemplate = "smalljumppickupRepresentation"
+>
+    <pickup>
+        <SpeedPickup template=smalljumppickup />
+    </pickup>
+</PickupRepresentation>
+
+<!-- Invisible pickups -->
+
+<PickupRepresentation
+    name = "small Invisibility"
+    description = "Makes you invisible for 5 seconds."
+    spawnerTemplate = "smallinvisiblepickupRepresentation"
+>
+    <pickup>
+        <InvisiblePickup template=smallinvisiblepickup />
+    </pickup>
+</PickupRepresentation>
+
+<PickupRepresentation
+    name = "medium Invisibility"
+    description = "Makes you invisible for 10 seconds."
+    spawnerTemplate = "mediuminvisiblepickupRepresentation"
+>
+    <pickup>
+        <InvisiblePickup template=mediuminvisiblepickup />
+    </pickup>
+</PickupRepresentation>
+
+<PickupRepresentation
+    name = "hunge Invisibility"
+    description = "Makes you invisible for 20 seconds."
+    spawnerTemplate = "hugeinvisiblepickupRepresentation"
+>
+    <pickup>
+        <InvisiblePickup template=hugeinvisiblepickup />
+    </pickup>
+</PickupRepresentation>
+
+<!-- Pickup Collection pickups -->
+
+<PickupRepresentation
+    pickupName = "Triple Pickup"
+    pickupDescription = "Adds health, speed and invisibility."
+    spawnerTemplate = "triplehealthspeedinvisibilitypickupRepresentation"
+>
+    <pickup>
+        <PickupCollection template=triplehealthspeedinvisibilitypickup />
+    </pickup>
+</PickupRepresentation>
+
Index: /code/branches/rocket2/data/levels/includes/weaponsettings1.oxi
===================================================================
--- /code/branches/rocket2/data/levels/includes/weaponsettings1.oxi	(revision 6952)
+++ /code/branches/rocket2/data/levels/includes/weaponsettings1.oxi	(revision 6952)
@@ -0,0 +1,39 @@
+    <weaponslots>
+      <WeaponSlot position="-15,-1.5,-25" yaw=0 pitch=0 roll=0 />
+      <WeaponSlot position="15,-1.5,-25" yaw=0 pitch=0 roll=0 />
+      <WeaponSlot position="0,0,-45" yaw=0 pitch=0 roll=0 />
+    </weaponslots>
+    <weaponsets>
+      <WeaponSet firemode=0 />
+      <WeaponSet firemode=1 />
+    </weaponsets>
+    <weapons>
+      <WeaponPack firemode=0>
+        <LaserGun
+            position="0,0,0"
+            munitionType="LaserGunMunition"
+            bulletLoadingTime="0.2"
+            magazineLoadingTime="5.0"
+            speed="1250"
+            unlimitedMunition=true
+        />
+        <LaserGun
+            position="0,0,0"
+            munitionType="LaserGunMunition"
+            bulletLoadingTime="0.2"
+            magazineLoadingTime="5.0"
+            speed="1250"
+            unlimitedMunition=true
+        />
+      </WeaponPack>
+      <WeaponPack firemode=1>
+        <Fusion
+            position="0,0,0"
+            munitionType="FusionMunition"
+            bulletLoadingTime="0.3"
+            magazineLoadingTime="3"
+            speed="600"
+            unlimitedMunition=true
+        />
+      </WeaponPack>
+    </weapons>
Index: /code/branches/rocket2/data/levels/includes/weaponsettings2.oxi
===================================================================
--- /code/branches/rocket2/data/levels/includes/weaponsettings2.oxi	(revision 6952)
+++ /code/branches/rocket2/data/levels/includes/weaponsettings2.oxi	(revision 6952)
@@ -0,0 +1,46 @@
+    <weaponslots>
+      <WeaponSlot position="-15,-0.5,0" yaw=0 pitch=0 roll=0 />
+      <WeaponSlot position="15,-.5,0" yaw=0 pitch=0 roll=0 />
+      <WeaponSlot position="0,0,-45" yaw=0 pitch=0 roll=0 />
+    </weaponslots>
+    <weaponsets>
+      <WeaponSet firemode=0 />
+      <WeaponSet firemode=1 />
+    </weaponsets>
+    <weapons>
+      <WeaponPack>
+        <links>
+          <DefaultWeaponmodeLink firemode=0 weaponmode=0 />
+          <DefaultWeaponmodeLink firemode=1 weaponmode=1 />
+        </links>
+        <Weapon>
+          <attached>
+            <Model mesh="hs-w01.mesh" roll="195"/>
+            <Model mesh="hs-w01s.mesh" roll="195" position="0.1,-0.5,0"/>
+          </attached>
+          <HsW01 mode=0 munitionpershot=0 delay=0 material="Flares/point_lensflare" muzzleoffset="-2,-0.2,-20" />
+          <HsW01 mode=0 munitionpershot=0 delay=0.125 material="Flares/point_lensflare" muzzleoffset="2,0.2,-20" />
+          <LaserFire mode=1 damage=1 munitionpershot=0 reloadtime=1 muzzleoffset="0,5,0" />
+          <LaserFire mode=1 damage=1 munitionpershot=0 reloadtime=1 muzzleoffset="0,-5,0" />
+        </Weapon>
+        <Weapon>
+          <attached>
+            <Model mesh="hs-w01.mesh" roll="165"/>
+            <Model mesh="hs-w01s.mesh" roll="165" position="-0.1,-0.5,0"/>
+          </attached>
+          <HsW01 mode=0 munitionpershot=0 delay=0  material="Flares/point_lensflare"muzzleoffset="2,-0.2,-20" />
+          <HsW01 mode=0 munitionpershot=0 delay=0.125 material="Flares/point_lensflare" muzzleoffset="-2,0.2,-20" />
+          <!--LaserFire mode=0 munitionpershot=0 muzzleoffset="0,0,-25" /-->
+          <LaserFire mode=1 damage=1 munitionpershot=0 reloadtime=1 muzzleoffset="0,5,0" />
+          <LaserFire mode=1 damage=1 munitionpershot=0 reloadtime=1 muzzleoffset="0,-5,0" />
+        </Weapon>
+      </WeaponPack>
+      <WeaponPack>
+        <links>
+          <DefaultWeaponmodeLink firemode=1 weaponmode=0 />
+        </links>
+        <Weapon>
+          <EnergyDrink mode=0 munitionpershot=0 delay=0  material="Flares/point_lensflare"muzzleoffset="2,-0.2,-20" />
+        </Weapon>
+      </WeaponPack>
+    </weapons>
Index: /code/branches/rocket2/data/levels/includes/weaponsettings3.oxi
===================================================================
--- /code/branches/rocket2/data/levels/includes/weaponsettings3.oxi	(revision 6952)
+++ /code/branches/rocket2/data/levels/includes/weaponsettings3.oxi	(revision 6952)
@@ -0,0 +1,52 @@
+    <weaponslots>
+      <WeaponSlot position="-15.0,-1.5,0" />
+      <WeaponSlot position=" 15.0,-1.5,0" />
+      <WeaponSlot position="    0,   0,0" />
+    </weaponslots>
+    <weaponsets>
+      <WeaponSet firemode=0 />
+      <WeaponSet firemode=1 />
+      <WeaponSet firemode=2 />
+    </weaponsets>
+    <weapons>
+      <WeaponPack>
+        <links>
+          <DefaultWeaponmodeLink firemode=0 weaponmode=0 />
+          <DefaultWeaponmodeLink firemode=1 weaponmode=1 />
+          <DefaultWeaponmodeLink firemode=2 weaponmode=2 />
+        </links>
+        <Weapon>
+          <attached>
+            <Model mesh="LightningGun.mesh" pitch="78" roll="90" yaw="90" position="0,-1.3,0" />
+            <Model mesh="LightningGun-s.mesh" pitch="78" roll="90" yaw="90" position="0.2,-1.3,0" />
+            <Model mesh="hs-w01.mesh" roll="195" position="0,1,0" scale=2 />
+            <Model mesh="hs-w01s.mesh" roll="195" position="0.1,0.5,0" scale=2 />
+          </attached>
+          <HsW01 mode=0 munitionpershot=0 delay=0.125 material="Flares/point_lensflare" muzzleoffset=" 0.7, 1.5,-4" />
+          <HsW01 mode=0 munitionpershot=0 delay=0     material="Flares/point_lensflare" muzzleoffset="-0.9, 1.1,-4" />
+          <LightningGun mode=1 muzzleoffset="0,0,0" />
+        </Weapon>
+        <Weapon>
+          <attached>
+            <Model mesh="LightningGun.mesh" pitch="103" roll="90" yaw="90" position="0,-1.35,0" />
+            <Model mesh="LightningGun-s.mesh" pitch="103" roll="90" yaw="90" position="0.2,-1.35,0" />
+            <Model mesh="hs-w01.mesh" roll="165" position="0,1,0" scale=2 />
+            <Model mesh="hs-w01s.mesh" roll="165" position="-0.1,0.5,0" scale=2 />
+          </attached>
+          <HsW01 mode=0 munitionpershot=0 delay=0     material="Flares/point_lensflare" muzzleoffset=" 0.9, 1.1, -4.0" />
+          <HsW01 mode=0 munitionpershot=0 delay=0.125 material="Flares/point_lensflare" muzzleoffset="-0.7, 1.5, -4.0" />
+          <LightningGun mode=1 muzzleoffset="0,0,0" />
+        </Weapon>
+        <Weapon>
+          <SimpleRocketFire mode=2 muzzleoffset="0,0,0" />
+        </Weapon>
+      </WeaponPack>
+      <WeaponPack>
+        <links>
+          <DefaultWeaponmodeLink firemode=1 weaponmode=0 />
+        </links>
+        <!--Weapon>
+          <EnergyDrink mode=0 munitionpershot=0 delay=0  material="Flares/point_lensflare"muzzleoffset="2,-0.2,-1" />
+        </Weapon-->
+      </WeaponPack>
+    </weapons>
Index: /code/branches/rocket2/data/levels/includes/weaponsettings_H2.oxi
===================================================================
--- /code/branches/rocket2/data/levels/includes/weaponsettings_H2.oxi	(revision 6952)
+++ /code/branches/rocket2/data/levels/includes/weaponsettings_H2.oxi	(revision 6952)
@@ -0,0 +1,45 @@
+    <weaponslots>
+      <WeaponSlot position="-7.5, 4, 8.5" />
+      <WeaponSlot position=" 7.5, 4, 8.5" />
+      <WeaponSlot position=" 0.0, 0,-13" />
+    </weaponslots>
+    <weaponsets>
+      <WeaponSet firemode=0 />
+      <WeaponSet firemode=1 />
+    </weaponsets>
+    <weapons>
+      <WeaponPack>
+        <links>
+          <DefaultWeaponmodeLink firemode=0 weaponmode=0 />
+        </links>
+        <Weapon>
+          <attached>
+            <Model mesh="hs-w01.mesh"  roll="180" position="0.0, 0.5, 0.0" scale=2 />
+            <Model mesh="hs-w01s.mesh" roll="180" position="0.1, 0.0, 0.0" scale=2 />
+          </attached>
+          <HsW01 mode=0 munitionpershot=0 delay=0.125 material="Flares/point_lensflare" muzzleoffset=" 0.8, 0.9,-4" />
+          <HsW01 mode=0 munitionpershot=0 delay=0     material="Flares/point_lensflare" muzzleoffset="-0.8, 0.9,-4" />
+        </Weapon>
+        <Weapon>
+          <attached>
+            <Model mesh="hs-w01.mesh"  roll="180" position=" 0.0, 0.5, 0.0" scale=2 />
+            <Model mesh="hs-w01s.mesh" roll="180" position="-0.1, 0.0, 0.0" scale=2 />
+          </attached>
+          <HsW01 mode=0 munitionpershot=0 delay=0     material="Flares/point_lensflare" muzzleoffset=" 0.8, 0.9, -4.0" />
+          <HsW01 mode=0 munitionpershot=0 delay=0.125 material="Flares/point_lensflare" muzzleoffset="-0.8, 0.9, -4.0" />
+        </Weapon>
+      </WeaponPack>
+      <WeaponPack>
+        <links>
+          <DefaultWeaponmodeLink firemode=1 weaponmode=0 />
+        </links>
+        <Weapon>
+          <attached>
+            <Model mesh="LightningGun.mesh"   pitch="90" roll="90" yaw="90" position="0,  -1.3,0" />
+            <Model mesh="LightningGun-s.mesh" pitch="90" roll="90" yaw="90" position="0.2,-1.3,0" />
+          </attached>
+          <LightningGun mode=0 muzzleoffset="0,0,0" />
+        </Weapon>
+      </WeaponPack>
+    </weapons>
+
Index: /code/branches/rocket2/data/levels/includes/weaponsettings_HXY.oxi
===================================================================
--- /code/branches/rocket2/data/levels/includes/weaponsettings_HXY.oxi	(revision 6952)
+++ /code/branches/rocket2/data/levels/includes/weaponsettings_HXY.oxi	(revision 6952)
@@ -0,0 +1,26 @@
+    <weaponslots>
+      <WeaponSlot position=" 6,-2,2" />
+      <WeaponSlot position="-6,-2,2" />
+    </weaponslots>
+    <weaponsets>
+      <WeaponSet firemode=0 />
+      <WeaponSet firemode=1 />
+    </weaponsets>
+    <weapons>
+      <WeaponPack>
+        <links>
+          <DefaultWeaponmodeLink firemode=0 weaponmode=0 />
+          <DefaultWeaponmodeLink firemode=1 weaponmode=1 />
+        </links>
+        <Weapon>
+          <HsW01 mode=0 munitionpershot=0 delay=0 material="Flares/point_lensflare" />
+          <HsW01 mode=0 munitionpershot=0 delay=0.1 material="Flares/point_lensflare" muzzleoffset=" 0.5,0.6,1.7" />
+          <LightningGun mode=1 muzzleoffset="0,0,0" />
+        </Weapon>
+        <Weapon>
+          <HsW01 mode=0 munitionpershot=0 delay=0  material="Flares/point_lensflare" />
+          <HsW01 mode=0 munitionpershot=0 delay=0.1 material="Flares/point_lensflare" muzzleoffset="-0.5,0.6,1.7" />
+          <LightningGun mode=1 muzzleoffset="0,0,0" />
+        </Weapon>
+      </WeaponPack>
+    </weapons>
Index: /code/branches/rocket2/data/levels/includes/weaponsettings_Transporter.oxi
===================================================================
--- /code/branches/rocket2/data/levels/includes/weaponsettings_Transporter.oxi	(revision 6952)
+++ /code/branches/rocket2/data/levels/includes/weaponsettings_Transporter.oxi	(revision 6952)
@@ -0,0 +1,26 @@
+    <weaponslots>
+      <WeaponSlot position=" 55,-10,20" />
+      <WeaponSlot position="-55,-10,20" />
+    </weaponslots>
+    <weaponsets>
+      <WeaponSet firemode=0 />
+      <WeaponSet firemode=1 />
+    </weaponsets>
+    <weapons>
+      <WeaponPack>
+        <links>
+          <DefaultWeaponmodeLink firemode=0 weaponmode=0 />
+          <DefaultWeaponmodeLink firemode=1 weaponmode=1 />
+        </links>
+        <Weapon>
+          <HsW01 mode=0 munitionpershot=0 delay=0 material="Flares/point_lensflare" />
+          <HsW01 mode=0 munitionpershot=0 delay=0.1 material="Flares/point_lensflare" muzzleoffset=" 0.5,0.6,1.7" />
+          <LightningGun mode=1 muzzleoffset="0,0,0" />
+        </Weapon>
+        <Weapon>
+          <HsW01 mode=0 munitionpershot=0 delay=0  material="Flares/point_lensflare" />
+          <HsW01 mode=0 munitionpershot=0 delay=0.1 material="Flares/point_lensflare" muzzleoffset="-0.5,0.6,1.7" />
+          <LightningGun mode=1 muzzleoffset="0,0,0" />
+        </Weapon>
+      </WeaponPack>
+    </weapons>
Index: /code/branches/rocket2/data/levels/includes/weaponsettings_ghost.oxi
===================================================================
--- /code/branches/rocket2/data/levels/includes/weaponsettings_ghost.oxi	(revision 6952)
+++ /code/branches/rocket2/data/levels/includes/weaponsettings_ghost.oxi	(revision 6952)
@@ -0,0 +1,26 @@
+    <weaponslots>
+      <WeaponSlot position=" 1.3,4.66,-20" />
+      <WeaponSlot position="-1.3,4.66,-20" />
+    </weaponslots>
+    <weaponsets>
+      <WeaponSet firemode=0 />
+      <WeaponSet firemode=1 />
+    </weaponsets>
+    <weapons>
+      <WeaponPack>
+        <links>
+          <DefaultWeaponmodeLink firemode=0 weaponmode=0 />
+          <DefaultWeaponmodeLink firemode=1 weaponmode=1 />
+        </links>
+        <Weapon>
+          <HsW01 mode=0 munitionpershot=0 delay=0 material="Flares/point_lensflare" />
+          <HsW01 mode=0 munitionpershot=0 delay=0.125 material="Flares/point_lensflare" muzzleoffset=" 0.5,0.6,1.7" />
+          <LightningGun mode=1 muzzleoffset="0,0,0" />
+        </Weapon>
+        <Weapon>
+          <HsW01 mode=0 munitionpershot=0 delay=0  material="Flares/point_lensflare" />
+          <HsW01 mode=0 munitionpershot=0 delay=0.125 material="Flares/point_lensflare" muzzleoffset="-0.5,0.6,1.7" />
+          <LightningGun mode=1 muzzleoffset="0,0,0" />
+        </Weapon>
+      </WeaponPack>
+    </weapons>
Index: /code/branches/rocket2/data/levels/includes/weaponsettings_pirate.oxi
===================================================================
--- /code/branches/rocket2/data/levels/includes/weaponsettings_pirate.oxi	(revision 6952)
+++ /code/branches/rocket2/data/levels/includes/weaponsettings_pirate.oxi	(revision 6952)
@@ -0,0 +1,24 @@
+    <weaponslots>
+      <WeaponSlot position=" 4.3,-6,-10" />
+      <WeaponSlot position="-4.3,-6,-10" />
+    </weaponslots>
+    <weaponsets>
+      <WeaponSet firemode=0 />
+      <WeaponSet firemode=1 />
+    </weaponsets>
+    <weapons>
+      <WeaponPack>
+        <links>
+          <DefaultWeaponmodeLink firemode=0 weaponmode=0 />
+          <DefaultWeaponmodeLink firemode=1 weaponmode=1 />
+        </links>
+        <Weapon>
+          <HsW01 mode=0 munitionpershot=0 delay=0 material="Flares/point_lensflare" />
+          <HsW01 mode=0 munitionpershot=0 delay=0.125 material="Flares/point_lensflare" muzzleoffset=" 0.5,0.6,1.7" />
+        </Weapon>
+        <Weapon>
+          <HsW01 mode=0 munitionpershot=0 delay=0  material="Flares/point_lensflare" />
+          <HsW01 mode=0 munitionpershot=0 delay=0.125 material="Flares/point_lensflare" muzzleoffset="-0.5,0.6,1.7" />
+        </Weapon>
+      </WeaponPack>
+    </weapons>
Index: /code/branches/rocket2/data/levels/mylevel.oxw
===================================================================
--- /code/branches/rocket2/data/levels/mylevel.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/mylevel.oxw	(revision 6952)
@@ -0,0 +1,142 @@
+<?lua
+	include("stats.oxo")
+	include("hudtemplates3.oxo")
+	include("underattackhud.oxo")
+	include("templates/spaceship_assff.oxt")
+	include("templates/spaceship_pirate.oxt")
+	include("templates/spaceship_Transporter.oxt")
+?>
+
+<Template name=spaceshipassffplayer>
+  <SpaceShip
+   hudtemplate            = spaceshiphud
+   camerapositiontemplate = spaceshipassffcameras
+   engine                 = spaceshipassffengine
+   spawnparticlesource    = "Orxonox/fairytwirl"
+   spawnparticleduration  = 3
+   explosionchunks        = 6
+
+   health            = 100
+   maxhealth         = 200
+   initialhealth     = 100
+
+   primaryThrust     = 100;
+   auxilaryThrust    = 30;
+   rotationThrust    = 25;
+
+   collisionType     = "dynamic"
+   mass              = 100
+   linearDamping     = 0.7
+   angularDamping    = 0.9999999
+  >
+    <attached>
+      <Model position="0,0,0" yaw=90 pitch=-90 roll=0 scale=4 mesh="assff.mesh" />
+      <BlinkingBillboard position="17,-1.5,0" material="Examples/Flare" colour="1.0, 0.5, 0.3" amplitude=0.1 frequency=0.5 quadratic=1 />
+      <BlinkingBillboard position="-17,-1.5,0" material="Examples/Flare" colour="0.5, 1.0, 0.3" amplitude=0.1 frequency=0.5 phase=180 quadratic=1 />
+      <DistanceTriggerBeacon name="test" />
+    </attached>
+    <collisionShapes>
+      <BoxCollisionShape position="0,0,0"      halfExtents="10, 3, 5" />
+      <BoxCollisionShape position="13,-1.3,0"  halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="-13,-1.3,0" halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="0,0,7"      halfExtents="3, 2, 2" />
+      <BoxCollisionShape position="0,0.1,-11"  halfExtents="2.2, 1.8, 6" />
+      <BoxCollisionShape position="0,0.1,-19"  halfExtents="1.4, 1, 2" />
+    </collisionShapes>
+<?lua
+  include("includes/weaponsettings3.oxi")
+?>
+  </SpaceShip>
+</Template>
+
+<!-- Ausgang: Level ===> name/description -->
+<Level
+  name="Level"
+  description="Level zerstoeren von Transportern"
+  gametype=TeamDeathmatch
+>
+
+	<!-- Ausgang: Szene ===> ambientlight/skybox -->
+	<Scene
+	  ambientlight="0.8,0.8,0.8"
+	  skybox="Orxonox/skypanoramagen1"
+	>
+
+		<!--Light: noch zu aendern -->
+		<Light type=directional position="0,0,0" direction="1000, 0, 0" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 1.0, 0.9" />
+
+
+		<SpawnPoint position="0,0,0" direction="1000,0,0" spawnclass=SpaceShip pawndesign=spaceshipassffplayer team=0/>
+
+<!--
+		<EventTrigger name="testdestroy" activations=1 stayactive="true">
+			<events>
+				<trigger>
+					<SpaceShip position="2000,0,3000" lookat="0,0,0" team=1>
+						<templates>
+							<Template link=spaceshippirate/>
+						</templates>
+						<controller>
+							<AIController activity="false"/>
+						</controller>
+					</SpaceShip>
+				</trigger>
+			</events>
+		</EventTrigger>
+-->
+
+					<SpaceShip position="1000,0,200" lookat="0,0,0">
+						<templates>
+							<Template link=spaceshipassff/>
+						</templates>
+						<controller>
+							<AIController active="false"/>
+						</controller>
+					</SpaceShip>
+
+<DistanceTrigger name="triggername" position="1000,0,0" distance="500" target="DistanceTriggerBeacon" targetname="test" activations=1 stayactive="true" />
+
+		<SpaceShip position="1000,0,0" lookat="2000,0,0" >
+			<templates>
+				<Template link=spaceshipassff />
+			</templates>
+			<controller>
+				<WaypointPatrolController alertnessradius=5000 team=0 active="false" >
+					<waypoints>
+						<Model mesh="cube.mesh" scale=0 position="2000,0,0" />
+					</waypoints>
+					<events>
+						<activity>
+							<EventListener event="triggername" />
+						</activity>
+					</events>
+				</WaypointPatrolController>
+			</controller>
+		</SpaceShip>
+	</Scene>
+</Level>
+
+
+
+<!-- ZUM ERSTELLEN DER DESTROYTRIGGER
+<EventTrigger name="triggername" activations=1 stayactive=true >
+	<events>
+		<trigger>
+			<Spaceship />
+		</trigger>
+	</events>
+</EventTrigger>
+
+<Spaceship>
+	<controller>
+		<SomeController activity="false">
+			<events>
+				<activity>
+					<EventListener event="triggername" />
+				</activity>
+			</events>
+		</SomeController>
+	</controller>
+</Spacehip>
+
+-->
Index: /code/branches/rocket2/data/levels/old/CuboidSpaceStation.oxw
===================================================================
--- /code/branches/rocket2/data/levels/old/CuboidSpaceStation.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/old/CuboidSpaceStation.oxw	(revision 6952)
@@ -0,0 +1,112 @@
+<?lua
+	include("hudtemplates3.oxo")
+?>
+
+<?lua
+	include("templates/spaceship_assff.oxt")
+?>
+
+<Level
+	name = "SpaceStation test Space!"
+	description = "All the new SpaceStations are created here!"
+>
+	<Scene
+		ambientlight = "0.5, 0.5, 0.5"
+		skybox = "Orxonox/Starbox"
+	>
+
+
+
+<!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------->
+<?lua
+	dofile("includes/CuboidSpaceStation.lua")
+?>
+
+<!-- The following examples insert some space station in various ways, so I guess you will understand how to use my .lua file and the functions of it.
+--->
+
+<!-- Here I add a space station at position 0,0,0 without velocity and no rotation.
+--->
+<?lua
+	createSpaceStation()
+?>
+
+
+
+<!-- Here I add a space station at position 0,0,-5000 without velocity and no rotation.
+--->
+<PositionableEntity scale=1 position="0,0,-5000">
+	<attached>
+		<?lua
+			createSpaceStation()
+		?>
+	</attached>
+</PositionableEntity>
+
+
+
+<!-- Here I add a space station at position 5000,0,0 with velocity 50,0,0 and a rotation so that the space station faces into the positive x-axis.
+--->
+<MovableEntity scale=1 position="5000,0,0" velocity="50,0,0" yaw=-90>
+	<attached>
+		<?lua
+			createSpaceStation()
+		?>
+	</attached>
+</MovableEntity>
+
+
+
+<!-- Here I add a space station at position -5000,0,0 without velocity but rotation around his own y-axis.
+--->
+<MovableEntity scale=1 position="-5000,0,0" rotationaxis="0,1,0" rotationrate=5>
+	<attached>
+		<?lua
+			createSpaceStation()
+		?>
+	</attached>
+</MovableEntity>
+
+
+
+<!-- Here I add a space station at position 10000,0,0 which will rotate around the position 0,0,0 and around his own axis in flight direction.
+---- To do so, I create a MovableEntity at position 0,0,0 and attach another MovableEntity with relative coordinates to the first MovableEntity 10000,0,0.
+---- I rotate the first MovableEntity, so the second Entity rotates around 0,0,0 in the x-,z-area with a radius 10000, and so does the space station,
+---- because the space station is attached to the second MovableEntity with relative coordinates 0,0,0 (this is defined in the .lua file).
+---- Then I rotate also the second MovableEntity around his own z-axis, so the space station rotates also around its own axis.
+--->
+<MovableEntity scale=1 position="0,0,0" rotationaxis="0,1,0" rotationrate=3>
+	<attached>
+		<MovableEntity scale=1 position="10000,0,0" rotationaxis="0,0,1" rotationrate=2>
+			<attached>
+				<?lua
+					-- Here I use the createSpaceStationPar(...) function, which has 8 arguments, see the .lua file at the top to understand them.
+					createSpaceStationPar(0,2,1,2,1,2,1,50)
+				?>
+			</attached>
+		</MovableEntity>
+	</attached>
+</MovableEntity>
+
+
+
+<!-------------------------------------------------------------------------------------------------------------------------------------------------------------------------->
+
+
+
+	<ParticleSpawner position="0,0,0" source="Orxonox/BigExplosion1part3" lifetime=2.0 loop=0 autostart=0>
+      <events>
+        <spawn>
+          <EventTrigger delay=1>
+            <events>
+              <trigger>
+                <SpawnPoint position="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+              </trigger>
+            </events>
+          </EventTrigger>
+        </spawn>
+      </events>
+    </ParticleSpawner>
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/old/physicstest.oxw
===================================================================
--- /code/branches/rocket2/data/levels/old/physicstest.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/old/physicstest.oxw	(revision 6952)
@@ -0,0 +1,19 @@
+<Ambient colourvalue="0.8, 0.8, 0.8" />
+<Skybox src="Orxonox/Starbox" />
+<SpaceShip camera="true" position="50,0,0" scale="10" yawpitchroll="0,-90,0" mesh="assff.mesh" maxSpeed="500" maxSideAndBackSpeed="50" maxRotation="1.0" transAcc="200" rotAcc="3.0" transDamp="75" rotDamp="1.0" />
+<Model position="2000,0,0" scale="10" mesh="tomato.mesh" yawpitchroll="-40,30,0" rotationAxis="1,0,0" rotationRate="-30"/>
+<Model position="0,2000,0" scale="10" mesh="tomato.mesh" yawpitchroll="-50,60,0" rotationAxis="1,0,0" rotationRate="-30"/>
+<Model position="0,0,2000" scale="10" mesh="tomato.mesh" yawpitchroll="-50,-30,0" rotationAxis="1,0,0" rotationRate="-30"/>
+<Model position="10000,16000,0" scale="100" mesh="DuBall1.mesh"/>
+<Model position="11400,16000,0" scale="60" mesh="DuBall2.mesh"/>
+
+<HelloBullet/>
+
+
+<?lua
+for i = 1, 226, 1
+do ?>
+  <Model position="<?lua print(math.random() * 40000 - 20000)?>, <?lua print(math.random() * 40000 - 20000) ?>, <?lua print(math.random() * 40000 - 20000) ?>" scale="<?lua print(math.random() * 250 + 20) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" rotationAxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationRate="<?lua print(math.random() * 30 + 15) ?>" />
+<?lua
+end
+?>
Index: /code/branches/rocket2/data/levels/old/physicstest2.oxw
===================================================================
--- /code/branches/rocket2/data/levels/old/physicstest2.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/old/physicstest2.oxw	(revision 6952)
@@ -0,0 +1,280 @@
+<?lua
+  include("spaceshiptemplates_physics.oxw")
+?>
+<?lua
+  include("hudtemplates3.oxo")
+?>
+
+<Level
+ name         = "Sample"
+ description  = "Just a few tests"
+>
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/Starbox"
+   negativeWorldRange = "(-100000, -100000, -100000)"
+   positiveWorldRange = "( 100000,  100000,  100000)"
+   hasPhysics   = true
+  >
+      <!--SpawnPoint position="0,   0,  100"           spawnclass=SpaceShip pawndesign=spaceshipassff />
+    <SpawnPoint position="0,   0, -700" yaw  =180 spawnclass=SpaceShip pawndesign=spaceshipassff />
+    <SpawnPoint position="0, 300, -300" pitch=-90 spawnclass=SpaceShip pawndesign=spaceshipassff /-->
+
+    <!-- axes in ogre's origin of coordinate system for phsics engine testing purposes-->
+    <StaticEntity
+     position        = "0,0,0"
+     name            = "banana"
+     collisionType   = "static"
+     mass            = 1000
+    >
+      <attached>
+        <Model position="0,0,0" scale=100 mesh="plane.mesh" />
+        <Model position="0,-0.0001,0" roll=180 scale=100 mesh="plane.mesh" />
+      </attached>
+      <collisionShapes>
+        <PlaneCollisionShape name="thePlane" planeNormal="0,1,0" planeOffset=0 />
+      </collisionShapes>
+    </StaticEntity>
+
+    <!-- red sphere for phsics engine testing purposes-->
+    <!--StaticEntity position="40,0,0">
+      <attached>
+        <Model position="0,0,0" scale=1 mesh="sphere.mesh" />
+      </attached>
+    </StaticEntity-->
+
+    <!-- yellow cube for phsics engine testing purposes-->
+    <!--StaticEntity position="80,0,0">
+      <attached>
+        <Model position="0,0,0" scale=1 mesh="cube.mesh" />
+      </attached>
+    </StaticEntity-->
+
+    <MovableEntity
+     name            = "blubb"
+     position        = "-150, 20, -500"
+     collisionType   = "kinematic"
+     mass            = 10000
+     velocity        = "30, 0, 0"
+    >
+      <attached>
+        <Model name = "moedeli" position="0,0,0" scale=20 mesh="sphere.mesh" />
+        <StaticEntity name="hahaha" position="0,0,0" collisionType="static">
+          <collisionShapes>
+            <SphereCollisionShape name="firstSphere" radius=20/>
+          </collisionShapes>
+        </StaticEntity>
+      </attached>
+
+      <!--attached>
+        <SphereCollisionShape name = "secondSphere" radius=0.4 position="1,1,1"/>
+        <CompoundCollisionShape position="4,4,4">
+          <SphereCollisionShape name = "thirdSphere" radius=1.0/>
+        </CompoundCollisionShape>
+      </attached-->
+    </MovableEntity>
+
+    <MovableEntity
+     name            = "blubb2"
+     position        = "150, 30, -500"
+     collisionType   = "dynamic"
+     mass            = 10
+     velocity        = "-30, 0, 0"
+    >
+      <attached>
+        <Model position="0,0,0" scale=20 mesh="sphere.mesh" />
+      </attached>
+      <collisionShapes>
+        <SphereCollisionShape name = "secondSphere" radius=20 position="0,0,0"/>
+      </collisionShapes>
+    </MovableEntity>
+
+    <StaticEntity
+     name            = "blubbStatic"
+     position        = "0, 15, -500"
+     collisionType   = "Static"
+     mass            = 10
+    >
+      <attached>
+        <Model position="0,0,0" scale=20 mesh="sphere.mesh" />
+      </attached>
+      <collisionShapes>
+        <SphereCollisionShape name = "secondSphere" radius=20 position="0,0,0"/>
+      </collisionShapes>
+    </StaticEntity>
+
+    <!--SpawnPoint position="0,   0,  100"           spawnclass=SpaceShip pawndesign=spaceshipassff />
+    <SpawnPoint position="0,   0, -700" yaw  =180 spawnclass=SpaceShip pawndesign=spaceshipassff />
+    <SpawnPoint position="0, 300, -300" pitch=-90 spawnclass=SpaceShip pawndesign=spaceshipassff /-->
+
+    <MovableEntity
+     name            = "apple1"
+     position        = "-150, 80, -500"
+     collisionType   = "dynamic"
+     mass            = 10
+     velocity        = "30, 0, 0"
+    >
+      <attached>
+        <Model position="0,0,0" scale=20 mesh="sphere.mesh" />
+      </attached>
+      <collisionShapes>
+        <SphereCollisionShape name = "secondSphere" radius=20 position="0,0,0"/>
+      </collisionShapes>
+    </MovableEntity>
+
+    <MovableEntity
+     name            = "apple2"
+     position        = "50, 80, -500"
+     collisionType   = "dynamic"
+     mass            = 10
+     velocity        = "-30, 0, 0"
+    >
+      <attached>
+        <Model position="0,0,0" scale=20 mesh="sphere.mesh" />
+      </attached>
+      <collisionShapes>
+        <SphereCollisionShape name = "secondSphere" radius=20 position="0,0,0"/>
+        <SphereCollisionShape name = "secondSphere" radius=20 position="1,0,0"/>
+      </collisionShapes>
+    </MovableEntity>
+
+    <MovableEntity
+     name            = "apple3"
+     position        = "150, 80, -500"
+     collisionType   = "dynamic"
+     mass            = 10
+     velocity        = "-30, 0, 0"
+    >
+      <attached>
+        <Model position="0,0,0" scale=20 mesh="sphere.mesh" />
+      </attached>
+      <collisionShapes>
+        <SphereCollisionShape name = "secondSphere" radius=20 position="0,0,0"/>
+      </collisionShapes>
+    </MovableEntity>
+
+    <!--MovableEntity scale=1.5 position="0,0,-300" velocity="0,0,0" rotationaxis="0,1,0" rotationrate=90>
+      <events>
+        <activity>
+          <DistanceTrigger position="0,0,-300" distance=50 target="ControllableEntity" invert=1 />
+        </activity>
+      </events>
+      <attached>
+        <Model position="0,0,0" scale=10 mesh="ast1.mesh" />
+        <StaticEntity position="0,0,100">
+          <attached>
+            <Model position="0,0,0" scale=6 mesh="ast1.mesh" />
+            <MovableEntity position="0,0,0" velocity="0,0,0" rotationaxis="0,0,1" rotationrate=500>
+              <attached>
+                <Model position="0,35,0" scale=2 mesh="ast1.mesh" />
+                <Model position="0,-35,0" scale=2 mesh="ast1.mesh" />
+                <Model position="35,0,0" scale=2 mesh="ast1.mesh">
+                  <attached>
+                    <ParticleEmitter position="0,0,0" source="Orxonox/fire3" />
+                  </attached>
+                </Model>
+                <Model position="-35,0,0" scale=2 mesh="ast1.mesh">
+                  <attached>
+                    <ParticleEmitter position="0,0,0" source="Orxonox/fire3" />
+                  </attached>
+                </Model>
+              </attached>
+            </MovableEntity>
+          </attached>
+        </StaticEntity>
+        <MovableEntity position="0,0,-100" velocity="0,0,0" rotationaxis="0,1,0" rotationrate=200>
+          <attached>
+            <ParticleEmitter position="0,0,0" source="Orxonox/fire3" />
+            <Model position="0,0,0" scale=6 mesh="ast1.mesh" />
+            <Model position="0,0,-50" scale=3 mesh="ast1.mesh" />
+            <Model position="0,0,50" scale=3 mesh="ast1.mesh" />
+          </attached>
+        </MovableEntity>
+      </attached>
+    </MovableEntity-->
+
+
+    <!--ParticleSpawner position="-500,0,-200" source="Orxonox/BigExplosion1part1" lifetime=3.0 loop=1 />
+    <ParticleSpawner position="-500,0,-300" source="Orxonox/BigExplosion1part1" lifetime=3.0 loop=1 />
+    <ParticleSpawner position="-500,0,-400" source="Orxonox/BigExplosion1part1" lifetime=3.0 loop=1 />
+    <ParticleSpawner position="-500,0,-500" source="Orxonox/BigExplosion1part1" lifetime=2.5 loop=1 />
+    <ParticleSpawner position="-500,0,-600" source="Orxonox/BigExplosion1part1" lifetime=2.5 loop=1 /-->
+
+
+    <ParticleSpawner position="0,20,100" source="Orxonox/BigExplosion1part3" lifetime=2.0 loop=0 autostart=0>
+      <events>
+        <spawn>
+          <EventTrigger delay=1>
+            <events>
+              <trigger>
+                <SpawnPoint position="0,20,100" spawnclass=SpaceShip pawndesign=spaceshipassff />
+              </trigger>
+            </events>
+          </EventTrigger>
+        </spawn>
+      </events>
+    </ParticleSpawner>
+
+
+    <!--ParticleEmitter name=fireright position="200,0,0" source="Orxonox/fire3" active=false>
+      <events>
+        <activity>
+          <DistanceTrigger name=firetrigger1 position="200,0,0" distance=100 target="ControllableEntity" />
+        </activity>
+      </events>
+    </ParticleEmitter>
+    <ParticleEmitter name=fireleft position="-200,0,0" source="Orxonox/fire3" active=false>
+      <events>
+        <activity>
+          <DistanceTrigger name=firetrigger2 position="-200,0,0" distance=100 target="ControllableEntity" />
+        </activity>
+      </events>
+    </ParticleEmitter>
+    <ParticleEmitter name=firecenter position="0,0,0" source="Orxonox/fire3" active=false>
+      <events>
+        <activity>
+          <EventListener event=firetrigger1 />
+          <EventListener event=firetrigger2 />
+        </activity>
+      </events>
+    </ParticleEmitter-->
+
+
+    <!--EventDispatcher>
+      <targets>
+        <EventTarget target=fireright />
+        <EventTarget target=firecenter />
+        <EventTarget target=fireleft />
+      </targets>
+      <events>
+        <activity>
+          <DistanceTrigger position="0,0,200" distance=100 target="ControllableEntity" />
+        </activity>
+      </events>
+    </EventDispatcher-->
+
+
+    <!--Model position="0,50,0" scale=3 mesh="assff.mesh">
+      <events>
+        <visibility>
+          <DistanceTrigger position="0,50,0" distance=50 target="ControllableEntity" invert=1 />
+        </visibility>
+      </events>
+    </Model-->
+
+
+    <Model position="0,0,200" scale=10 mesh="ast2.mesh" shadow=true />
+    <!--Model position="0,0,-200" scale=10 mesh="ast1.mesh" shadow=true /-->
+    <Model position="0,200,0" scale=10 mesh="ast3.mesh" shadow=true />
+    <Model position="0,-200,0" scale=10 mesh="ast4.mesh" shadow=true />
+    <Model position="200,0,0" scale=10 mesh="ast5.mesh" shadow=false />
+    <Model position="-200,0,0" scale=10 mesh="ast6.mesh" shadow=false />
+
+    <Model position="1000,-200,0" scale3D="1,100,100" mesh="ast1.mesh" />
+
+    <Model position="0, 0,-100" pitch=-90 roll=-90 scale=4 mesh="assff.mesh" />
+    <!--Model position="0,100,-100" pitch=-90 roll=-90 scale=4 mesh="pirate.mesh" />
+    <Model position="0,300,-100" pitch=-90 roll=-90 scale=4 mesh="spacecruiser.mesh" /-->
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/old/planettest.oxw
===================================================================
--- /code/branches/rocket2/data/levels/old/planettest.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/old/planettest.oxw	(revision 6952)
@@ -0,0 +1,38 @@
+<?lua
+  include("hudtemplates3.oxo")
+?>
+
+<?lua
+  include("templates/spaceship_assff.oxt")
+?>
+
+<Level
+ name         = "Sample"
+ description  = "Just a few tests"
+>
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/Starbox"
+  >
+
+    <ParticleSpawner position="0,0,100" source="Orxonox/BigExplosion1part3" lifetime=2.0 loop=0 autostart=0>
+      <events>
+        <spawn>
+          <EventTrigger delay=1>
+            <events>
+              <trigger>
+                <SpawnPoint position="0,0,100" spawnclass=SpaceShip pawndesign=spaceshipassff />
+              </trigger>
+            </events>
+          </EventTrigger>
+        </spawn>
+      </events>
+    </ParticleSpawner>
+
+
+    <Planet position="2500,0,-9000" scale=1000 pitch=-90 mesh="earth.mesh" rotationaxis="0,0,1" rotationrate="0.1" atmospheresize=130.0f imagesize=1024.0f />
+    <Planet position="0,0,-5001" scale=1000 pitch=-90 mesh="iceplanet.mesh" atmosphere="atmosphere1" rotationaxis="1,1,0" rotationrate="1" atmospheresize=224.0f imagesize=1024.0f />
+    <Model position="0, 0,-100" pitch=-90 roll=-90 scale=4 mesh="assff.mesh" />
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/old/presentation_physics.oxw
===================================================================
--- /code/branches/rocket2/data/levels/old/presentation_physics.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/old/presentation_physics.oxw	(revision 6952)
@@ -0,0 +1,109 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+  math.randomseed(344)
+?>
+
+<Level
+ name         = "Physics"
+ description  = "Just a few tests"
+>
+  <Scene
+   ambientlight = "0.8, 0.8, 0.8"
+   skybox       = "Orxonox/skypanoramagen1"
+   gravity      = "0, -10, 0"
+  >
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+    <StaticEntity
+     position        = "0,0,0"
+     name            = "floor"
+     collisionType   = "static"
+     friction        = 1
+    >
+      <attached>
+        <Model position="0,0,0" scale=100 mesh="plane.mesh" />
+        <Model position="0,-0.0001,0" roll=180 scale=100 mesh="plane.mesh" />
+      </attached>
+      <collisionShapes>
+        <PlaneCollisionShape planeNormal="0,1,0" planeOffset=0 />
+      </collisionShapes>
+    </StaticEntity>
+
+    <MovableEntity
+     position        = "0,250,500"
+     rotationaxis    = "1, 1, 1"
+     rotationrate    = 360
+     velocity        = "0, 0, -80"
+     name            = "ship"
+     collisionType   = "dynamic"
+     friction        = 0.5
+     mass            = 500
+     restitution     = 0
+    >
+      <attached>
+        <Model position="0,0,0" yaw=90 pitch=-90 roll=0 scale=4 mesh="assff.mesh" />
+        <BlinkingBillboard position="17,-1.5,0" material="Examples/Flare" colour="1.0, 0.5, 0.3" amplitude=0.1 frequency=0.5 quadratic=1 />
+        <BlinkingBillboard position="-17,-1.5,0" material="Examples/Flare" colour="0.5, 1.0, 0.3" amplitude=0.1 frequency=0.5 phase=180 quadratic=1 />
+
+        <!--Model position="0,0,0" yaw=90 pitch=-90 roll=0 scale=4 mesh="assff.mesh" />
+        <Model position="0,0,0" scale3D="10, 3, 5" mesh="cube.mesh" />
+        <Model position="13,-1.3,0" scale3D="3, 1, 2" mesh="cube.mesh" />
+        <Model position="-13,-1.3,0" scale3D="3, 1, 2" mesh="cube.mesh" />
+        <Model position="0,0,7" scale3D="3, 2, 2" mesh="cube.mesh" />
+        <Model position="0,0.1,-11" scale3D="2.2, 1.8, 6" mesh="cube.mesh" />
+        <Model position="0,0.1,-19" scale3D="1.4, 1, 2" mesh="cube.mesh" /-->
+      </attached>
+      <collisionShapes>
+        <BoxCollisionShape position="0,0,0"      halfExtents="10, 3, 5" />
+        <BoxCollisionShape position="13,-1.3,0"  halfExtents="3, 1, 2" />
+        <BoxCollisionShape position="-13,-1.3,0" halfExtents="3, 1, 2" />
+        <BoxCollisionShape position="0,0,7"      halfExtents="3, 2, 2" />
+        <BoxCollisionShape position="0,0.1,-11"  halfExtents="2.2, 1.8, 6" />
+        <BoxCollisionShape position="0,0.1,-19"  halfExtents="1.4, 1, 2" />
+      </collisionShapes>
+    </MovableEntity>
+
+    <?lua
+    for i = -20, 20, 8
+    do
+      for i2 = -20, 20, 8
+      do
+        for i3 = -20, 20, 8
+        do ?>
+        <MovableEntity
+         position="<?lua print(i)?>, <?lua print(i3 + 250)?>, <?lua print(i2) ?>"
+         collisionType = "dynamic"
+         mass = 1
+         restitution = 0
+         friction = 0.5
+        >
+          <attached>
+            <Model position="0,0,0" scale=2 mesh="cube.mesh" />
+          </attached>
+          <collisionShapes>
+            <BoxCollisionShape halfExtents="2, 2, 2" />
+          </collisionShapes>
+        </MovableEntity>
+    <?lua
+        end
+      end
+    end
+    ?>
+
+    <ParticleSpawner position="-100,170,30" source="Orxonox/BigExplosion1part3" lifetime=2.0 loop=0 autostart=0>
+      <events>
+        <spawn>
+          <EventTrigger delay=1>
+            <events>
+              <trigger>
+                <SpawnPoint position="-100,170,30" spawnclass=SpaceShip pawndesign=spaceshipassff />
+              </trigger>
+            </events>
+          </EventTrigger>
+        </spawn>
+      </events>
+    </ParticleSpawner>
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/old/princessaeryn.oxw
===================================================================
--- /code/branches/rocket2/data/levels/old/princessaeryn.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/old/princessaeryn.oxw	(revision 6952)
@@ -0,0 +1,315 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+?>
+
+<?lua
+    dofile("includes/CuboidSpaceStation.lua")
+?>
+
+<NotificationQueue
+ name  = "notification"
+ position = "1.0, 1.0"
+ targets = "questsystem"
+/>
+
+<Level
+ name         = "The Tale of Princess Aeryn"
+ description  = "The Tale of Princess Aeryn"
+>
+    <Scene
+        ambientlight = "0.3, 0.3, 0.3"
+        skybox       = "Orxonox/skypanoramagen1"
+    >
+      <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+        <Template name=turboitem baseclass=Turbo>
+          <Turbo
+            playerclass=SpaceShip
+            duration=15
+          />
+        </Template>
+
+        <ParticleSpawner position="200,0,-500" source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <events>
+            <spawn>
+              <PickupSpawner position="200,0,-500" distance=50 respawntimer=25 item=turboitem>
+                <attached>
+                  <Model mesh="sphere.mesh" scale=3 />
+                  <Billboard material="Examples/Flare" colour="0.5, 1.0, 0.3" scale=0.5 />
+                </attached>
+              </PickupSpawner>
+            </spawn>
+          </events>
+        </ParticleSpawner>
+
+        <Template name=turboequipment baseclass=Turbo>
+          <Turbo
+            playerclass=SpaceShip
+            duration=0
+          />
+        </Template>
+
+        <ParticleSpawner position="400,0,-1000" source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <events>
+            <spawn>
+              <PickupSpawner position="400,0,-1000" distance=50 respawntimer=25 item=turboequipment>
+                <attached>
+                  <Model mesh="sphere.mesh" scale=3 />
+                  <Billboard material="Examples/Flare" colour="1.0, 0.5, 0.3" scale=0.5 />
+                </attached>
+              </PickupSpawner>
+            </spawn>
+          </events>
+        </ParticleSpawner>
+
+        <!-- Quest: -->
+        <GlobalQuest id="b80c2c60-e62c-4637-80f8-5aa18dc93b34">
+            <QuestDescription title="The Tale of Princess Aeryn" description="Princess Aeryn has been kidnapped by evil Mr. M and you were just a little too late to save her.\nYou have to find and save her from her captors." failMessage="You cannot fail, how did you?" completeMessage="You did it John. You're a hero. Princess Aeryn however will still not marry you." />
+            <subquests>
+                <GlobalQuest id="43766602-7e2f-4d24-976a-3f9de1474d5b">
+                    <QuestDescription title="Find Aeryn's S.H.O.E.S." description="Oh, the kidnappers must have been in a hurry because they overlooked princess Aeryns S.H.O.E.S. (Super Heavily Organized Escape Ship) hidden in the asteroid field over there.\nFind it and look there for clues to Princess Aeryns whereabouts." completeMessage="You did it, Looking through her stuff you find an odd looking device - Could this be the receiver of Princess Aeryns locator beacon? - But it must be broken, the screen remains blank." />
+                    <complete-effects>
+                        <AddQuest questId="50845552-c8af-4091-947c-76bd850b224e" />
+                    </complete-effects>
+                </GlobalQuest>
+                <GlobalQuest id="50845552-c8af-4091-947c-76bd850b224e">
+                    <QuestDescription title="Repair the receiver." description="There is a space station called 'Serenity Station' near here. An engineer called Nathan Stark who shoud be able to help you lives there." completeMessage="'Yeah Nathan lives here, he'll shurely help you.'\nAnd he does, apparenty the device was just low on batteries so you're now able to locate your beloved Princess Aeryn." />
+                    <hints>
+                        <QuestHint id="b9b10841-b045-4797-b1d3-cfce760e1de6">
+                            <QuestDescription title="The Katratzi Station" description="'We ain't buying!'\n'What do you want?'\n'No there lives no Nathan here.'\n'Fuck off.''" />
+                        </QuestHint>
+                        <QuestHint id="1ee785f8-b71d-4b51-b080-42cec5be8e3c">
+                            <QuestDescription title="The Pegasus Station" description="'Hello friend.'\n'How can we help you?'\n'A Mr. Stark you say? Sorry no man with such a name lives here.'" />
+                        </QuestHint>
+                    </hints>
+                    <complete-effects>
+                        <AddQuest questId="97628524-b243-492c-b7b6-498f325b21d4" />
+                    </complete-effects>
+                </GlobalQuest>
+                <GlobalQuest id="97628524-b243-492c-b7b6-498f325b21d4">
+                    <QuestDescription title="Follow the dots" description="Just follow the dots, they'll lead you right to her." completeMessage="You found Princess Aeryn. Her captors give up at the shere sight ou you." />
+                    <complete-effects>
+                        <CompleteQuest questId="b80c2c60-e62c-4637-80f8-5aa18dc93b34" />
+                    </complete-effects>
+                </GlobalQuest>
+            </subquests>
+        </GlobalQuest>
+
+        <!-- Create spaceship spawner: -->
+        <ParticleSpawner position="0,0,100" source="Orxonox/BigExplosion1part3" lifetime=2.0 loop=0 autostart=0>
+          <events>
+            <spawn>
+              <EventTrigger delay=1>
+                <events>
+                  <trigger>
+                    <SpawnPoint position="0,0,100" spawnclass=SpaceShip pawndesign=spaceshipassff />
+                  </trigger>
+                </events>
+              </EventTrigger>
+            </spawn>
+          </events>
+          <attached>
+            <QuestEffectBeacon position="0,0,0" times=1>
+                <effects>
+                    <AddQuest questId="b80c2c60-e62c-4637-80f8-5aa18dc93b34" />
+                    <AddQuest questId="43766602-7e2f-4d24-976a-3f9de1474d5b" />
+                </effects>
+                <events>
+                    <execute>
+                        <EventListener event=questbeacon1 />
+                    </execute>
+                </events>
+                <attached>
+                    <DistanceTrigger name=questbeacon1 position="0,0,0" distance=10 target="ControllableEntity" />
+                </attached>
+            </QuestEffectBeacon>
+          </attached>
+        </ParticleSpawner>
+
+        <!-- Create world -->
+
+            <!-- Kidnapper flying away -->
+            <MovableEntity position="200,0,0" velocity="-140,0,-140" yaw=45>
+                <attached>
+                    <Model position="0,0,0" scale=4 yaw=180 pitch=-90 roll=-90 mesh="pirate.mesh" />
+                    <ParticleSpawner position="0,0,10" source="Orxonox/fire3" lifetime=2.0 loop=0 autostart=1 />
+                    <QuestEffectBeacon position="0,0,0" times=1 active=false name=trail >
+                        <effects>
+                            <CompleteQuest questId="b80c2c60-e62c-4637-80f8-5aa18dc93b34" />
+                        </effects>
+                        <events>
+                            <execute>
+                                <EventListener event=questbeacon7 />
+                            </execute>
+                        </events>
+                        <attached>
+                            <DistanceTrigger name=questbeacon7 position="0,0,0" distance=10 target="ControllableEntity" />
+                        </attached>
+                    </QuestEffectBeacon>
+                </attached>
+            </MovableEntity>
+
+            <!-- Asteroid field -->
+            <StaticEntity position="-500,0,-3000">
+                <attached>
+                    <?lua
+                        for i = 1, 200
+                        do ?>
+                        <MovableEntity position="<?lua print(math.random() * 2000 - 1000)?>, <?lua print(math.random() * 2000 - 1000) ?>, <?lua print(math.random() * 2000 - 1000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.abs(math.random() * 30 -10)) ?>">
+                            <attached>
+                                <Model scale="<?lua print(math.random() * 50) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+                            </attached>
+                        </MovableEntity>
+                    <?lua
+                        end
+                    ?>
+                    <!-- S.H.O.E.S -->
+                    <StaticEntity position="-300,0,0">
+                        <attached>
+                            <Model position="0,0,0" scale=4 yaw=180 pitch=-90 roll=-90 mesh="assff.mesh" />
+                            <QuestEffectBeacon position="0,0,0" times=-1>
+                                <effects>
+                                    <CompleteQuest questId="43766602-7e2f-4d24-976a-3f9de1474d5b" />
+                                </effects>
+                                <events>
+                                    <execute>
+                                        <EventListener event=questbeacon2 />
+                                    </execute>
+                                </events>
+                                <attached>
+                                    <DistanceTrigger name=questbeacon2 position="0,0,0" distance=50 target="ControllableEntity" />
+                                </attached>
+                            </QuestEffectBeacon>
+                        </attached>
+                    </StaticEntity>
+                </attached>
+            </StaticEntity>
+
+
+
+            <!-- Spacestations -->
+
+            <!-- Serenity Station -->
+            <StaticEntity scale=1 position="0,0,5000" yaw=30>
+                <attached>
+                    <?lua
+                        createSpaceStationPar(65461,2,1,2,1,2,1,100)
+                    ?>
+                    <QuestEffectBeacon position="0,450,0" times=1>
+                        <effects>
+                            <CompleteQuest questId="50845552-c8af-4091-947c-76bd850b224e" />
+                        </effects>
+                        <events>
+                            <execute>
+                                <EventListener event=questbeacon3 />
+                            </execute>
+                        </events>
+                        <attached>
+                            <Billboard position="0,0,0" colour="1.0,1.0,0" material="Examples/Flare" />
+                            <DistanceTrigger name=questbeacon3 position="0,0,0" distance=100 target="ControllableEntity" />
+                        </attached>
+                    </QuestEffectBeacon>
+                </attached>
+            </StaticEntity>
+
+            <!-- Katratzi Station -->
+            <StaticEntity scale=1 position="0,5000,300" yaw=60>
+                <attached>
+                    <?lua
+                        createSpaceStationPar(9851,2,1,2,1,2,1,100)
+                    ?>
+                    <QuestEffectBeacon position="0,450,0" times=1>
+                        <effects>
+                            <AddQuestHint hintId="b9b10841-b045-4797-b1d3-cfce760e1de6" />
+                        </effects>
+                        <events>
+                            <execute>
+                                <EventListener event=questbeacon4 />
+                            </execute>
+                        </events>
+                        <attached>
+                            <Billboard position="0,0,0" colour="1.0,1.0,0" material="Examples/Flare" />
+                            <DistanceTrigger name=questbeacon4 position="0,0,0" distance=100 target="ControllableEntity" />
+                        </attached>
+                    </QuestEffectBeacon>
+                </attached>
+            </StaticEntity>
+
+            <!-- Pegasus Station -->
+            <StaticEntity scale=1 position="-5000,100,1000" roll=30>
+                <attached>
+                    <?lua
+                        createSpaceStationPar(3574,2,1,2,1,2,1,100)
+                    ?>
+                    <QuestEffectBeacon position="200,450,0" times=1>
+                        <effects>
+                            <AddQuestHint hintId="1ee785f8-b71d-4b51-b080-42cec5be8e3c" />
+                        </effects>
+                        <events>
+                            <execute>
+                                <EventListener event=questbeacon5 />
+                            </execute>
+                        </events>
+                        <attached>
+                            <Billboard position="0,0,0" colour="1.0,1.0,0" material="Examples/Flare" />
+                            <DistanceTrigger name=questbeacon5 position="0,0,0" distance=100 target="ControllableEntity" />
+                        </attached>
+                    </QuestEffectBeacon>
+                </attached>
+            </StaticEntity>
+
+            <!-- Trail -->
+            <EventDispatcher>
+                <targets>
+                    <EventTarget target=trail />
+                </targets>
+                <events>
+                    <visibility>
+                        <QuestListener questId="50845552-c8af-4091-947c-76bd850b224e" mode="complete" />
+                    </visibility>
+                    <activity>
+                        <QuestListener questId="50845552-c8af-4091-947c-76bd850b224e" mode="complete" />
+                    </activity>
+                </events>
+            </EventDispatcher>
+
+            <?lua
+                for i = 1, 25
+                do
+            ?>
+                <Billboard position="<?lua print(i*5000/25) ?>,<?lua print(450+i*(5000-450)/25) ?>,5000" colour="1.0,0,0" material="Examples/Flare" name=trail visible=false/>
+            <?lua
+                end
+            ?>
+
+            <!-- Hideout -->
+            <StaticEntity position="5000,5000,5000" >
+                <attached>
+                    <Model scale="100" mesh="ast2.mesh" shadow=false />
+                </attached>
+            </StaticEntity>
+
+            <StaticEntity position="5400,5400,5000" visible=false name=trail >
+                <attached>
+                    <Model position="0,0,0" scale=4 yaw=180 pitch=-90 roll=-90 mesh="pirate.mesh" visible=false name=trail />
+                    <QuestEffectBeacon position="0,0,0" times=1 active=false name=trail >
+                        <effects>
+                            <CompleteQuest questId="97628524-b243-492c-b7b6-498f325b21d4" />
+                        </effects>
+                        <events>
+                            <execute>
+                                <EventListener event=questbeacon6 />
+                            </execute>
+                        </events>
+                        <attached>
+                            <DistanceTrigger name=questbeacon6 position="0,0,0" distance=100 target="ControllableEntity" />
+                        </attached>
+                    </QuestEffectBeacon>
+                </attached>
+            </StaticEntity>
+
+    </Scene>
+</Level>
+
Index: /code/branches/rocket2/data/levels/old/questsystem.oxw
===================================================================
--- /code/branches/rocket2/data/levels/old/questsystem.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/old/questsystem.oxw	(revision 6952)
@@ -0,0 +1,115 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+?>
+
+<NotificationQueue
+ name  = "notification"
+ position = "1.0, 1.0"
+ targets = "all"
+/>
+
+<Level
+ name         = "Questsystem"
+ description  = "Just a few tests"
+>
+    <Scene
+    ambientlight = "0.5, 0.5, 0.5"
+    skybox       = "Orxonox/Starbox"
+    >
+
+        <GlobalQuest id="b80c2c60-e62c-4637-80f8-5aa18dc93b34">
+            <QuestDescription title="The Main QUest" description="This is the main quest hooray. Solve it!" failMessage="You fail. Looser." completeMessage="You Win." />
+            <hints>
+                <QuestHint id="022a859d-08dd-4eac-a085-c28c29c06d48">
+                    <QuestDescription title="The super Hint." description="Be proud of yourself." />
+                </QuestHint>
+            </hints>
+        </GlobalQuest>
+
+        <ParticleSpawner position="0,0,100" source="Orxonox/BigExplosion1part3" lifetime=2.0 loop=0 autostart=0>
+            <events>
+                <spawn>
+                    <EventTrigger delay=1>
+                        <events>
+                            <trigger>
+                                <SpawnPoint position="0,0,100" spawnclass=SpaceShip pawndesign=spaceshipassff />
+                            </trigger>
+                        </events>
+                    </EventTrigger>
+                </spawn>
+            </events>
+        </ParticleSpawner>
+
+        <QuestEffectBeacon position="0,0,100" times=-1>
+            <effects>
+                <AddQuest questId="b80c2c60-e62c-4637-80f8-5aa18dc93b34" />
+            </effects>
+            <events>
+                <execute>
+                    <EventListener event=qebdt1 />
+                </execute>
+            </events>
+            <attached>
+                <Billboard position="0,0,0" colour="1.0,1.0,1.0" material="Examples/Flare" />
+                <DistanceTrigger name=qebdt1 position="0,0,0" distance=10 target="ControllableEntity" />
+            </attached>
+        </QuestEffectBeacon>
+
+        <QuestEffectBeacon position="-100,0,0" times=-1>
+            <effects>
+                <FailQuest questId="b80c2c60-e62c-4637-80f8-5aa18dc93b34" />
+            </effects>
+            <events>
+                <execute>
+                    <EventListener event=qebdt2 />
+                </execute>
+            </events>
+            <attached>
+                <Billboard position="0,0,0" colour="1.0,0,0" material="Examples/Flare" />
+                <DistanceTrigger name=qebdt2 position="0,0,0" distance=10 target="ControllableEntity" />
+            </attached>
+        </QuestEffectBeacon>
+
+        <QuestEffectBeacon position="100,0,0" times=-1>
+            <effects>
+                <CompleteQuest questId="b80c2c60-e62c-4637-80f8-5aa18dc93b34" />
+            </effects>
+            <events>
+                <execute>
+                    <EventListener event=qebdt3 />
+                </execute>
+            </events>
+            <attached>
+                <Billboard position="0,0,0" colour="0,1.0,0" material="Examples/Flare" />
+                <DistanceTrigger name=qebdt3 position="0,0,0" distance=10 target="ControllableEntity" />
+            </attached>
+        </QuestEffectBeacon>
+
+        <QuestEffectBeacon position="0,100,0" times=-1>
+            <effects>
+                <AddQuestHint hintId="022a859d-08dd-4eac-a085-c28c29c06d48" />
+            </effects>
+            <events>
+                <execute>
+                    <EventListener event=qebdt4 />
+                </execute>
+            </events>
+            <attached>
+                <Billboard position="0,0,0" colour="0,0,1.0" material="Examples/Flare" />
+                <DistanceTrigger name=qebdt4 position="0,0,0" distance=10 target="ControllableEntity" />
+            </attached>
+        </QuestEffectBeacon>
+
+        <ParticleEmitter name=firecenter position="0,0,0" source="Orxonox/fire3" active=false>
+            <events>
+                <activity>
+                    <QuestListener questId="b80c2c60-e62c-4637-80f8-5aa18dc93b34" mode="complete" />
+                </activity>
+            </events>
+        </ParticleEmitter>
+
+    </Scene>
+</Level>
+
Index: /code/branches/rocket2/data/levels/old/sample4.oxw
===================================================================
--- /code/branches/rocket2/data/levels/old/sample4.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/old/sample4.oxw	(revision 6952)
@@ -0,0 +1,160 @@
+<?lua
+  include("hudtemplates3.oxo")
+?>
+
+<?lua
+  include("templates/spaceship_assff.oxt")
+?>
+
+<Level
+ name         = "Sample"
+ description  = "Just a few tests"
+>
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/Starbox"
+  >
+    <!--SpawnPoint position="0,   0,  100"           spawnclass=SpaceShip pawndesign=spaceshipassff />
+    <SpawnPoint position="0,   0, -700" yaw  =180 spawnclass=SpaceShip pawndesign=spaceshipassff />
+    <SpawnPoint position="0, 300, -300" pitch=-90 spawnclass=SpaceShip pawndesign=spaceshipassff /-->
+
+    <MovableEntity position="-300,200,-800" velocity="5,0,0" rotationaxis="1,0,0" rotationrate=0>
+      <attached>
+        <Model position="0,0,0" scale=10 mesh="satellite.mesh" />
+        <MovableEntity position="-4,0,0" velocity="0,0,0" rotationaxis="0,0,1" rotationrate=50>
+          <attached>
+            <Model position="4,0,0" scale=10 mesh="satellitedish.mesh"/>
+          </attached>
+        </MovableEntity>
+        <ParticleEmitter pitch=-135 roll=30 position="-14, 3.5,-2.5" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+        <ParticleEmitter pitch=135 roll=30 position="-14, 3.5,-9" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+        <ParticleEmitter pitch=-45 roll=30 position="-14,-3.5,-2.5" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+        <ParticleEmitter pitch=45 roll=30 position="-14,-3.5,-9" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+      </attached>
+    </MovableEntity>
+
+    <MovableEntity scale=1.5 position="0,0,-300" velocity="0,0,0" rotationaxis="0,1,0" rotationrate=90>
+      <events>
+        <activity>
+          <DistanceTrigger position="0,0,-300" distance=50 target="ControllableEntity" invert=1 />
+        </activity>
+      </events>
+      <attached>
+        <Model position="0,0,0" scale=10 mesh="ast1.mesh" />
+        <PositionableEntity position="0,0,100">
+          <attached>
+            <Model position="0,0,0" scale=6 mesh="ast1.mesh" />
+            <MovableEntity position="0,0,0" velocity="0,0,0" rotationaxis="0,0,1" rotationrate=500>
+              <attached>
+                <Model position="0,35,0" scale=2 mesh="ast1.mesh" />
+                <Model position="0,-35,0" scale=2 mesh="ast1.mesh" />
+                <Model position="35,0,0" scale=2 mesh="ast1.mesh">
+                  <attached>
+                    <ParticleEmitter position="0,0,0" source="Orxonox/fire3" />
+                  </attached>
+                </Model>
+                <Model position="-35,0,0" scale=2 mesh="ast1.mesh">
+                  <attached>
+                    <ParticleEmitter position="0,0,0" source="Orxonox/fire3" />
+                  </attached>
+                </Model>
+              </attached>
+            </MovableEntity>
+          </attached>
+        </PositionableEntity>
+        <MovableEntity position="0,0,-100" velocity="0,0,0" rotationaxis="0,1,0" rotationrate=200>
+          <attached>
+            <ParticleEmitter position="0,0,0" source="Orxonox/fire3" />
+            <Model position="0,0,0" scale=6 mesh="ast1.mesh" />
+            <Model position="0,0,-50" scale=3 mesh="ast1.mesh" />
+            <Model position="0,0,50" scale=3 mesh="ast1.mesh" />
+          </attached>
+        </MovableEntity>
+      </attached>
+    </MovableEntity>
+
+
+    <ParticleSpawner position="-500,0,-200" source="Orxonox/BigExplosion1part1" lifetime=3.0 loop=1 />
+    <ParticleSpawner position="-500,0,-300" source="Orxonox/BigExplosion1part1" lifetime=3.0 loop=1 />
+    <ParticleSpawner position="-500,0,-400" source="Orxonox/BigExplosion1part1" lifetime=3.0 loop=1 />
+    <ParticleSpawner position="-500,0,-500" source="Orxonox/BigExplosion1part1" lifetime=2.5 loop=1 />
+    <ParticleSpawner position="-500,0,-600" source="Orxonox/BigExplosion1part1" lifetime=2.5 loop=1 />
+
+
+    <ParticleSpawner position="0,0,100" source="Orxonox/BigExplosion1part3" lifetime=2.0 loop=0 autostart=0>
+      <events>
+        <spawn>
+          <EventTrigger delay=1>
+            <events>
+              <trigger>
+                <SpawnPoint position="0,0,100" spawnclass=SpaceShip pawndesign=spaceshipassff />
+              </trigger>
+            </events>
+          </EventTrigger>
+        </spawn>
+      </events>
+    </ParticleSpawner>
+
+
+    <ParticleEmitter name=fireright position="200,0,0" source="Orxonox/fire3" active=false>
+      <events>
+        <activity>
+          <DistanceTrigger name=firetrigger1 position="200,0,0" distance=100 target="ControllableEntity" />
+        </activity>
+      </events>
+    </ParticleEmitter>
+    <ParticleEmitter name=fireleft position="-200,0,0" source="Orxonox/fire3" active=false>
+      <events>
+        <activity>
+          <DistanceTrigger name=firetrigger2 position="-200,0,0" distance=100 target="ControllableEntity" />
+        </activity>
+      </events>
+    </ParticleEmitter>
+    <ParticleEmitter name=firecenter position="0,0,0" source="Orxonox/fire3" active=false>
+      <events>
+        <activity>
+          <EventListener event=firetrigger1 />
+          <EventListener event=firetrigger2 />
+        </activity>
+      </events>
+    </ParticleEmitter>
+
+
+    <EventDispatcher>
+      <targets>
+        <EventTarget target=fireright />
+        <EventTarget target=firecenter />
+        <EventTarget target=fireleft />
+      </targets>
+      <events>
+        <activity>
+          <DistanceTrigger position="0,0,200" distance=100 target="ControllableEntity" />
+        </activity>
+      </events>
+    </EventDispatcher>
+
+
+    <Model position="0,50,0" scale=3 mesh="assff.mesh">
+      <events>
+        <visibility>
+          <DistanceTrigger position="0,50,0" distance=50 target="ControllableEntity" invert=1 />
+        </visibility>
+      </events>
+    </Model>
+
+
+    <Model position="0,0,200" scale=10 mesh="ast2.mesh" shadow=true />
+    <!--Model position="0,0,-200" scale=10 mesh="ast1.mesh" shadow=true /-->
+    <Model position="0,200,0" scale=10 mesh="ast3.mesh" shadow=true />
+    <Model position="0,-200,0" scale=10 mesh="ast4.mesh" shadow=true />
+    <Model position="200,0,0" scale=10 mesh="ast5.mesh" shadow=false />
+    <Model position="-200,0,0" scale=10 mesh="ast6.mesh" shadow=false />
+
+    <Model position="1000,-200,0" scale3D="1,100,100" mesh="ast1.mesh" />
+
+    <Model position="0, 0,-100" pitch=-90 roll=-90 scale=4 mesh="assff.mesh" />
+    <!--Model position="0,100,-100" pitch=-90 roll=-90 scale=4 mesh="pirate.mesh" />
+    <Model position="0,300,-100" pitch=-90 roll=-90 scale=4 mesh="spacecruiser.mesh" /-->
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/old/spaceshiptemplates_physics.oxw
===================================================================
--- /code/branches/rocket2/data/levels/old/spaceshiptemplates_physics.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/old/spaceshiptemplates_physics.oxw	(revision 6952)
@@ -0,0 +1,87 @@
+<Template name=spaceshipassff>
+  <SpaceShip
+   camerapositiontemplate = spaceshipassffcameras
+
+   health            = 100
+   maxhealth         = 200
+   initialhealth     = 100
+
+   primaryThrust     = 100;
+   auxilaryThrust    = 30;
+   rotationThrust    = 10;
+
+   collisionType     = "dynamic"
+   mass              = 100
+   linearDamping     = 0.7
+   angularDamping    = 0.999
+   name              = "blubbbeliblubb"
+  >
+    <attached>
+      <Model position="0,0,0" yaw=90 pitch=-90 roll=0 scale=4 mesh="assff.mesh" />
+      <!--Light position="0,0,20" diffuse="0,0,1" specular="0,0,1" type=point /-->
+      <BlinkingBillboard position="17,-1.5,0" material="Examples/Flare" colour="1.0, 0.5, 0.3" amplitude=0.1 frequency=0.5 quadratic=1 />
+      <BlinkingBillboard position="-17,-1.5,0" material="Examples/Flare" colour="0.5, 1.0, 0.3" amplitude=0.1 frequency=0.5 phase=180 quadratic=1 />
+      <!--ParticleEmitter position="0,0,-100" source="Orxonox/smoke5" /-->
+    </attached>
+    <collisionShapes>
+      <!--SphereCollisionShape position="0,0,0"      radius=20 /-->
+      <BoxCollisionShape position="0,0,0"      halfExtents="10, 3, 5" />
+      <BoxCollisionShape position="13,-1.3,0"  halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="-13,-1.3,0" halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="0,0,7"      halfExtents="3, 2, 2" />
+      <BoxCollisionShape position="0,0.1,-11"  halfExtents="2.2, 1.8, 6" />
+      <BoxCollisionShape position="0,0.1,-19"  halfExtents="1.4, 1, 2" />
+    </collisionShapes>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipassffcameras>
+  <SpaceShip>
+    <camerapositions>
+      <CameraPosition position="0,10,40" />
+      <CameraPosition position="0,150,-25" pitch=-90 />
+      <CameraPosition position="0,0,-30" yaw=180 />
+      <CameraPosition position="0,3,-14" yaw=0 />
+      <CameraPosition position="-50,5,-8" yaw=-90 />
+      <CameraPosition position="50,5,-8" yaw=90 />
+    </camerapositions>
+  </SpaceShip>
+</Template>
+
+<!--Template name=spaceshippirate>
+  <SpaceShip
+   health            = 100
+   maxhealth         = 200
+   initialhealth     = 100
+
+   maxspeed          = 250
+   maxsecondaryspeed = 50
+   maxrotation       = 100
+   transacc          = 200
+   rotacc            = 140
+   transdamp         = 75
+  >
+    <attached>
+      <Model position="0,-10,-45" yaw=90 pitch=-90 roll=0 scale=4 mesh="pirate.mesh" />
+    </attached>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipspacecruiser>
+  <SpaceShip
+   health            = 100
+   maxhealth         = 200
+   initialhealth     = 100
+
+   maxspeed          = 250
+   maxsecondaryspeed = 50
+   maxrotation       = 100
+   transacc          = 200
+   rotacc            = 140
+   transdamp         = 75
+  >
+    <attached>
+      <Model position="8,-30,-120" yaw=90 pitch=-90 roll=0 scale=4 mesh="spacecruiser.mesh" />
+    </attached>
+  </SpaceShip>
+</Template-->
Index: /code/branches/rocket2/data/levels/old/tutorial_hs08.oxw
===================================================================
--- /code/branches/rocket2/data/levels/old/tutorial_hs08.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/old/tutorial_hs08.oxw	(revision 6952)
@@ -0,0 +1,26 @@
+<Ambient colourvalue="0.8, 0.8, 0.8" />
+<Skybox src="Orxonox/Starbox" />
+
+<!-- This is your own space ship. The complicated XML values are not important -->
+<TutorialShip
+    camera="true" position="0,0,0" scale="10" yawpitchroll="0,0,0" mesh="assff.mesh" maxSpeed="500" maxSideAndBackSpeed="50" maxRotation="1.0" transAcc="200" rotAcc="3.0" transDamp="75" rotDamp="1.0"
+
+SpecialEffects="true"
+
+/>
+
+<!-- A few models flying around -->
+<Model position="2000,0,0" scale="10" mesh="tomato.mesh" yawpitchroll="-40,30,0" rotationAxis="1,0,0" rotationRate="-30"/>
+<Model position="0,2000,0" scale="10" mesh="tomato.mesh" yawpitchroll="-50,60,0" rotationAxis="1,0,0" rotationRate="-30"/>
+<Model position="0,0,2000" scale="10" mesh="tomato.mesh" yawpitchroll="-50,-30,0" rotationAxis="1,0,0" rotationRate="-30"/>
+<Model position="10000,16000,0" scale="100" mesh="DuBall1.mesh"/>
+<Model position="11400,16000,0" scale="60" mesh="DuBall2.mesh"/>
+
+<!-- Embedded lua code (creates random asteroids) -->
+<?lua
+for i = 1, 226, 1
+do ?>
+  <Model position="<?lua print(math.random() * 40000 - 20000)?>, <?lua print(math.random() * 40000 - 20000) ?>, <?lua print(math.random() * 40000 - 20000) ?>" scale="<?lua print(math.random() * 250 + 20) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" rotationAxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationRate="<?lua print(math.random() * 30 + 15) ?>" />
+<?lua
+end
+?>
Index: /code/branches/rocket2/data/levels/pickup.oxw
===================================================================
--- /code/branches/rocket2/data/levels/pickup.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/pickup.oxw	(revision 6952)
@@ -0,0 +1,123 @@
+<?lua
+  include("stats.oxo")
+  include("hudtemplates3.oxo")
+?>
+
+<?lua
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_pirate.oxt")
+  include("templates/pickup_representation_templates.oxt")
+?>
+
+<Level
+ name         = "Sample"
+ description  = "Just a few tests"
+>
+  <Scene
+    ambientlight = "0.8, 0.8, 0.8"
+    skybox       = "Orxonox/Starbox"
+  >
+
+<?lua
+  include("includes/pickups.oxi")
+?>
+    
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+    <SpawnPoint position="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+
+    <!-- Health pickups -->
+    
+    <PickupSpawner position="-25,0,-100" triggerDistance="10" respawnTime="30" maxSpawnedItems="10">
+        <pickup>
+            <HealthPickup template=smallhealthpickup />
+        </pickup>
+    </PickupSpawner>
+    
+    <PickupSpawner position="0,0,-100" triggerDistance="10" respawnTime="30" maxSpawnedItems="10">
+        <pickup>
+            <HealthPickup template=mediumhealthpickup />
+        </pickup>
+    </PickupSpawner>
+    
+    <PickupSpawner position="25,0,-100" triggerDistance="10" respawnTime="30" maxSpawnedItems="10">
+        <pickup>
+            <HealthPickup template=hugehealthpickup />
+        </pickup>
+    </PickupSpawner>
+    
+    <PickupSpawner position="50,0,-100" triggerDistance="10" respawnTime="30" maxSpawnedItems="10">
+        <pickup>
+            <HealthPickup template=crazyhealthpickup />
+        </pickup>
+    </PickupSpawner>
+    
+    <!-- Speed pickups -->
+    
+    <PickupSpawner position="-25,25,-100" triggerDistance="10" respawnTime="10" maxSpawnedItems="99">
+        <pickup>
+            <SpeedPickup template=smallspeedpickup />
+        </pickup>
+    </PickupSpawner>
+
+    <PickupSpawner position="0,25,-100" triggerDistance="10" respawnTime="10" maxSpawnedItems="99">
+        <pickup>
+            <SpeedPickup template=mediumspeedpickup />
+        </pickup>
+    </PickupSpawner>
+
+    <PickupSpawner position="25,25,-100" triggerDistance="10" respawnTime="10" maxSpawnedItems="99">
+        <pickup>
+            <SpeedPickup template=hugespeedpickup />
+        </pickup>
+    </PickupSpawner>
+
+    <PickupSpawner position="50,25,-100" triggerDistance="10" respawnTime="10" maxSpawnedItems="99">
+        <pickup>
+            <SpeedPickup template=smalljumppickup />
+        </pickup>
+    </PickupSpawner>
+    
+    <!-- Invisible pickups -->
+    
+    <PickupSpawner position="-25,50,-100" triggerDistance="10" respawnTime="5" maxSpawnedItems="10">
+        <pickup>
+            <InvisiblePickup template=smallinvisiblepickup />
+        </pickup>
+    </PickupSpawner>
+
+    <PickupSpawner position="0,50,-100" triggerDistance="10" respawnTime="5" maxSpawnedItems="10">
+        <pickup>
+            <InvisiblePickup template=mediuminvisiblepickup />
+        </pickup>
+    </PickupSpawner>
+
+    <PickupSpawner position="25,50,-100" triggerDistance="10" respawnTime="5" maxSpawnedItems="10">
+        <pickup>
+            <InvisiblePickup template=hugeinvisiblepickup />
+        </pickup>
+    </PickupSpawner>
+    
+    <!-- Meta pickups -->
+    
+    <PickupSpawner position="-25,75,-100" triggerDistance="10" respawnTime="5" maxSpawnedItems="10">
+        <pickup>
+            <MetaPickup metaType="use" />
+        </pickup>
+    </PickupSpawner>
+
+    <PickupSpawner position="0,75,-100" triggerDistance="10" respawnTime="5" maxSpawnedItems="10">
+        <pickup>
+            <MetaPickup metaType="drop" />
+        </pickup>
+    </PickupSpawner>
+    
+    <!-- Pickup Collection pickups -->
+    
+    <PickupSpawner position="0,-25,-100" triggerDistance="10" respawnTime="30" maxSpawnedItems="10">
+        <pickup>
+            <PickupCollection template=triplehealthspeedinvisibilitypickup />
+        </pickup>
+    </PickupSpawner>
+    
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/pickup_pps_invi.oxw
===================================================================
--- /code/branches/rocket2/data/levels/pickup_pps_invi.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/pickup_pps_invi.oxw	(revision 6952)
@@ -0,0 +1,46 @@
+<?lua
+  include("stats.oxo")
+  include("hudtemplates3.oxo")
+?>
+
+<?lua
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_pirate.oxt")
+  include("templates/pickup_representation_templates.oxt")
+?>
+
+<Level
+ name         = "Sample"
+ description  = "Just a few tests"
+>
+  <Scene
+    ambientlight = "0.8, 0.8, 0.8"
+    skybox       = "Orxonox/Starbox"
+  >
+
+<?lua
+  include("includes/pickups.oxi")
+?>
+
+    <PickupSpawner position="-75,0,-100" triggerDistance="10" respawnTime="5" maxSpawnedItems="10">
+        <pickup>
+            <InvisiblePickup template=smallinvisiblepickup />
+        </pickup>
+    </PickupSpawner>
+
+    <PickupSpawner position="-50,0,-100" triggerDistance="10" respawnTime="5" maxSpawnedItems="10">
+        <pickup>
+            <InvisiblePickup template=mediuminvisiblepickup />
+        </pickup>
+    </PickupSpawner>
+
+    <PickupSpawner position="-25,0,-100" triggerDistance="10" respawnTime="5" maxSpawnedItems="10">
+        <pickup>
+            <InvisiblePickup template=hugeinvisiblepickup />
+        </pickup>
+    </PickupSpawner>
+
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+    <SpawnPoint position="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/pickup_ppstest1.oxw
===================================================================
--- /code/branches/rocket2/data/levels/pickup_ppstest1.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/pickup_ppstest1.oxw	(revision 6952)
@@ -0,0 +1,98 @@
+<?lua
+  include("stats.oxo")
+  include("hudtemplates3.oxo")
+?>
+
+<?lua
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_pirate.oxt")
+  include("templates/pickup_representation_templates.oxt")
+?>
+
+<Level
+ name         = "Sample"
+ description  = "Just a few tests"
+>
+  <Scene
+    ambientlight = "0.8, 0.8, 0.8"
+    skybox       = "Orxonox/Starbox"
+  >
+
+<?lua
+  include("includes/pickups.oxi")
+?>
+
+    <PickupSpawner position="-25,0,-100" triggerDistance="10" respawnTime="10" maxSpawnedItems="99">
+        <pickup>
+            <SpeedPickup template=smallspeedpickup />
+        </pickup>
+    </PickupSpawner>
+
+    <PickupSpawner position="0,0,-100" triggerDistance="10" respawnTime="10" maxSpawnedItems="99">
+        <pickup>
+            <SpeedPickup template=mediumspeedpickup />
+        </pickup>
+    </PickupSpawner>
+
+    <PickupSpawner position="25,0,-100" triggerDistance="10" respawnTime="10" maxSpawnedItems="99">
+        <pickup>
+            <SpeedPickup template=hugespeedpickup />
+        </pickup>
+    </PickupSpawner>
+
+    <PickupSpawner position="50,0,-100" triggerDistance="10" respawnTime="10" maxSpawnedItems="99">
+        <pickup>
+            <SpeedPickup template=smalljumppickup />
+        </pickup>
+    </PickupSpawner>
+
+
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+    <SpawnPoint position="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+
+
+
+    <MovableEntity scale=1.5 position="0,0,-300" velocity="0,0,0" rotationaxis="0,1,0" rotationrate=90>
+      <events>
+        <activity>
+          <DistanceTrigger position="0,0,-300" distance=50 target="ControllableEntity" invert=1 />
+        </activity>
+      </events>
+      <attached>
+        <Model position="0,0,0" scale=10 mesh="ast1.mesh" />
+        <StaticEntity position="0,0,100">
+          <attached>
+            <Model position="0,0,0" scale=6 mesh="ast1.mesh" />
+            <MovableEntity position="0,0,0" velocity="0,0,0" rotationaxis="0,0,1" rotationrate=500>
+              <attached>
+                <Model position="0,35,0" scale=2 mesh="ast1.mesh" />
+                <Model position="0,-35,0" scale=2 mesh="ast1.mesh" />
+                <Model position="35,0,0" scale=2 mesh="ast1.mesh">
+                  <attached>
+                    <ParticleEmitter position="0,0,0" source="Orxonox/ExplosionComp4" />
+                  </attached>
+                </Model>
+                <Model position="-35,0,0" scale=2 mesh="ast1.mesh">
+                  <attached>
+                    <ParticleEmitter position="0,0,0" source="Orxonox/fire3" />
+                  </attached>
+                </Model>
+              </attached>
+            </MovableEntity>
+          </attached>
+        </StaticEntity>
+        <MovableEntity position="0,0,-100" velocity="0,0,0" rotationaxis="0,1,0" rotationrate=200>
+          <attached>
+            <ParticleEmitter position="0,0,0" source="Orxonox/fire3" />
+            <Model position="0,0,0" scale=6 mesh="ast1.mesh" />
+            <Model position="0,0,-50" scale=3 mesh="ast1.mesh" />
+            <Model position="0,0,50" scale=3 mesh="ast1.mesh" />
+          </attached>
+        </MovableEntity>
+      </attached>
+    </MovableEntity>
+
+    <ExplosionChunk position="-500,0,-200" lifetime=3.0 loop=1/>
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/presentation.oxw
===================================================================
--- /code/branches/rocket2/data/levels/presentation.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/presentation.oxw	(revision 6952)
@@ -0,0 +1,188 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+?>
+
+<Level
+ name         = "Sample"
+ description  = "Just a few tests"
+>
+  <Scene
+   ambientlight = "0.3, 0.3, 0.3"
+   skybox       = "Orxonox/Starbox"
+  >
+    <Light type=directional position="0,0,0" direction="1, -0.3, 0.3" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+    <!--SpawnPoint position="0,   0,  100"           spawnclass=SpaceShip pawndesign=spaceshipassff />
+    <SpawnPoint position="0,   0, -700" yaw  =180 spawnclass=SpaceShip pawndesign=spaceshipassff />
+    <SpawnPoint position="0, 300, -300" pitch=-90 spawnclass=SpaceShip pawndesign=spaceshipassff /-->
+
+
+    <!-- axes in ogre's origin of coordinate system for phsics engine testing purposes-->
+    <!--StaticEntity position="0,0,0">
+      <attached>
+        <Model position="0,0,0" scale=1 mesh="axes.mesh" />
+      </attached>
+    </StaticEntity -->
+
+    <!-- red sphere for phsics engine testing purposes-->
+    <!--StaticEntity position="40,0,0">
+      <attached>
+        <Model position="0,0,0" scale=1 mesh="sphere.mesh" />
+      </attached>
+    </StaticEntity-->
+
+    <!-- yellow cube for phsics engine testing purposes-->
+    <!--StaticEntity position="80,0,0">
+      <attached>
+        <Model position="0,0,0" scale=1 mesh="cube.mesh" />
+      </attached>
+    </StaticEntity-->
+
+    <!-- Carrier with guns not implemented yet -->
+    <MovableEntity position="-2000,-1000,-2000" pitch="-90" roll="90">
+      <attached>
+        <Model position="0,0,0" scale=10 mesh="Carrier.mesh" />
+        <Model position="0,30,20" scale=10 mesh="pirate.mesh" roll="180" />
+        <Model position="-80,-30,20" scale=10 mesh="pirate.mesh" roll="180" />
+      </attached>
+    </MovableEntity>
+
+    <MovableEntity position="-300,200,-800" velocity="5,0,0" rotationaxis="1,0,0" rotationrate=0>
+      <attached>
+        <Model position="0,0,0" scale=10 mesh="satellite.mesh" />
+        <MovableEntity position="-4,0,0" velocity="0,0,0" rotationaxis="0,0,1" rotationrate=50>
+          <attached>
+            <Model position="4,0,0" scale=10 mesh="satellitedish.mesh"/>
+          </attached>
+        </MovableEntity>
+        <ParticleEmitter pitch=-135 roll=30 position="-14, 3.5,-2.5" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+        <ParticleEmitter pitch=135 roll=30 position="-14, 3.5,-9" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+        <ParticleEmitter pitch=-45 roll=30 position="-14,-3.5,-2.5" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+        <ParticleEmitter pitch=45 roll=30 position="-14,-3.5,-9" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+      </attached>
+    </MovableEntity>
+
+    <MovableEntity scale=1.5 position="0,0,-300" velocity="0,0,0" rotationaxis="0,1,0" rotationrate=90>
+      <events>
+        <activity>
+          <DistanceTrigger position="0,0,-300" distance=50 target="ControllableEntity" invert=1 />
+        </activity>
+      </events>
+      <attached>
+        <Model position="0,0,0" scale=10 mesh="ast1.mesh" />
+        <StaticEntity position="0,0,100">
+          <attached>
+            <Model position="0,0,0" scale=6 mesh="ast1.mesh" />
+            <MovableEntity position="0,0,0" velocity="0,0,0" rotationaxis="0,0,1" rotationrate=500>
+              <attached>
+                <Model position="0,35,0" scale=2 mesh="ast1.mesh" />
+                <Model position="0,-35,0" scale=2 mesh="ast1.mesh" />
+                <Model position="35,0,0" scale=2 mesh="ast1.mesh">
+                  <attached>
+                    <ParticleEmitter position="0,0,0" source="Orxonox/ExplosionComp4" />
+                  </attached>
+                </Model>
+                <Model position="-35,0,0" scale=2 mesh="ast1.mesh">
+                  <attached>
+                    <ParticleEmitter position="0,0,0" source="Orxonox/fire3" />
+                  </attached>
+                </Model>
+              </attached>
+            </MovableEntity>
+          </attached>
+        </StaticEntity>
+        <MovableEntity position="0,0,-100" velocity="0,0,0" rotationaxis="0,1,0" rotationrate=200>
+          <attached>
+            <ParticleEmitter position="0,0,0" source="Orxonox/fire3" />
+            <Model position="0,0,0" scale=6 mesh="ast1.mesh" />
+            <Model position="0,0,-50" scale=3 mesh="ast1.mesh" />
+            <Model position="0,0,50" scale=3 mesh="ast1.mesh" />
+          </attached>
+        </MovableEntity>
+      </attached>
+    </MovableEntity>
+
+    <ExplosionChunk position="-500,0,-200" lifetime=3.0 loop=1/>
+
+    <ParticleSpawner position="-500,0,-200" source="Orxonox/ExplosionComp1" lifetime=3.0 loop=1 />
+    <ParticleSpawner position="-500,0,-200" source="Orxonox/ExplosionComp2" lifetime=3.0 loop=1 />
+
+    <ParticleSpawner position="0,0,100" source="Orxonox/ExplosionComp1" lifetime=2.0 loop=0 autostart=0>
+      <events>
+        <spawn>
+          <EventTrigger delay=1>
+            <events>
+              <trigger>
+                <SpawnPoint position="0,0,100" spawnclass=SpaceShip pawndesign=spaceshipassff />
+              </trigger>
+            </events>
+          </EventTrigger>
+        </spawn>
+      </events>
+    </ParticleSpawner>
+
+
+    <ParticleEmitter name=fireright position="200,0,0" source="Orxonox/fire3" active=false>
+      <events>
+        <activity>
+          <DistanceTrigger name=firetrigger1 position="200,0,0" distance=100 target="ControllableEntity" />
+        </activity>
+      </events>
+    </ParticleEmitter>
+    <ParticleEmitter name=fireleft position="-200,0,0" source="Orxonox/fire3" active=true>
+      <events>
+        <activity>
+          <DistanceTrigger name=firetrigger2 position="-200,0,0" distance=100 target="ControllableEntity" />
+        </activity>
+      </events>
+    </ParticleEmitter>
+    <ParticleEmitter name=firecenter position="0,0,0" source="Orxonox/fire3" active=false>
+      <events>
+        <activity>
+          <EventListener event=firetrigger1 />
+          <EventListener event=firetrigger2 />
+        </activity>
+      </events>
+    </ParticleEmitter>
+
+
+    <EventDispatcher>
+      <targets>
+        <EventTarget target=fireright />
+        <EventTarget target=firecenter />
+        <EventTarget target=fireleft />
+      </targets>
+      <events>
+        <activity>
+          <DistanceTrigger position="0,0,200" distance=100 target="ControllableEntity" />
+        </activity>
+      </events>
+    </EventDispatcher>
+
+
+    <Model position="0,50,0" scale=3 mesh="assff.mesh">
+      <events>
+        <visibility>
+          <DistanceTrigger position="0,50,0" distance=50 target="ControllableEntity" invert=1 />
+        </visibility>
+      </events>
+    </Model>
+
+
+    <Model position="0,0,200" scale=10 mesh="ast2.mesh" shadow=true />
+    <!--Model position="0,0,-200" scale=10 mesh="ast1.mesh" shadow=true /-->
+    <Model position="0,200,0" scale=10 mesh="ast3.mesh" shadow=true />
+    <Model position="0,-200,0" scale=10 mesh="ast4.mesh" shadow=true />
+    <Model position="200,0,0" scale=10 mesh="ast5.mesh" shadow=false />
+    <Model position="-200,0,0" scale=10 mesh="ast6.mesh" shadow=false />
+
+    <Model position="1000,-200,0" scale3D="1,100,100" mesh="ast1.mesh" />
+
+    <Model position="0, 0,-100" pitch=-90 roll=-90 scale=4 mesh="assff.mesh" />
+    <!--Model position="0,100,-100" pitch=-90 roll=-90 scale=4 mesh="pirate.mesh" />
+    <Model position="0,300,-100" pitch=-90 roll=-90 scale=4 mesh="spacecruiser.mesh" /-->
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/presentation09.oxw
===================================================================
--- /code/branches/rocket2/data/levels/presentation09.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/presentation09.oxw	(revision 6952)
@@ -0,0 +1,52 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_H2.oxt")
+?>
+
+<Level
+ name         = "Presentation09"
+ description  = "presentation level for Orxonox Convention X"
+
+>
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/skypanoramagen1"
+  >
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+
+<SpawnPoint position="<?lua print(math.sin(1.5) *40000) ?>,<?lua print(math.cos(1.5) *40000) ?>,<?lua print(500) ?>" lookat="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+
+
+<?lua
+max = 20
+for i = 1, max, 1
+do
+    x = math.sin(i/max*6)*40000
+    y = math.cos(i/max*6)*40000
+    z = i*100
+    ?>
+<?lua
+for k = 1, 25, 1
+do
+j = math.random()
+?>
+
+    <MovableEntity position="<?lua print(x + math.random() * 10000-2500) ?>,<?lua print(y + math.random() * 5000-2500) ?>,<?lua print(z + math.random() * 1000-500) ?>" <?lua if i == 5 then ?> collisionType=dynamic linearDamping=0.8 angularDamping=0 mass=<?lua print(j * 50) ?> <?lua end ?> scale=<?lua print(j * 5) ?> rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+      <attached>
+        <Model position="0,0,0" scale=<?lua print(j * 10) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+      </attached>
+      <?lua if i == 5 then ?><collisionShapes>
+        <SphereCollisionShape radius="<?lua print(j * 70) ?>" />
+      </collisionShapes> <?lua end ?>
+    </MovableEntity>
+<?lua
+end
+?>
+<?lua end ?>
+    <Planet position="0,0,0" scale=10000 pitch=-90 mesh="iceplanet.mesh" atmosphere="atmosphere1" rotationaxis="1,1,0" rotationrate="1" atmospheresize=224.0f imagesize=1024.0f />
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/presentation09b.oxw
===================================================================
--- /code/branches/rocket2/data/levels/presentation09b.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/presentation09b.oxw	(revision 6952)
@@ -0,0 +1,383 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_H2.oxt")
+  include("templates/spaceship_pirate.oxt")
+?>
+
+<Level
+ name         = "Presentation09"
+ description  = "presentation level for Orxonox Convention X"
+ gametype     = TeamDeathmatch
+>
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/skypanoramagen2"
+  >
+    <Light type=directional position="0,0,0" direction="0.683, 0.289, 0.670" diffuse="1.0, 1.0, 1.0, 1.0" specular="1.0, 1.0, 1.0, 1.0" />
+
+    <Template name="JumpItem" baseclass="Jump">
+        <Jump velocity="0,0,-1000" jumpsAvailable="4" guiImage="jumpturbinepickup.jpg" guiText="Jump" />
+    </Template>
+    <Template name="HealthImmediateItem" baseclass="HealthImmediate">
+        <HealthImmediate recoveredHealth="100" guiImage="decal.jpg" guiText="Health" />
+    </Template>
+    <Template name="HealthUsableItem" baseclass="HealthUsable">
+        <HealthImmediate recoveredHealth="80" guiImage="goldwrenchpickup.jpg" guiText="Health" />
+    </Template>
+
+    <SpawnPoint position="-3800, 2500, 1500" direction="-0.683, -0.289, -0.670"  spawnclass=SpaceShip pawndesign=spaceshipassff />
+
+    <SpaceShip position="-3900,3000,1000">
+      <templates>
+        <Template link=spaceshipHtwo/>
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=100 team=0>
+          <waypoints>
+            <StaticEntity position="-3850,2800,1450" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+
+    <SpaceShip position="-4100,2600,1600">
+      <templates>
+        <Template link=spaceshipHtwo/>
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=100 team=0>
+          <waypoints>
+            <StaticEntity position="-3850,2800,1450" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+
+    <SpaceShip position="-4000,2500,1500">
+      <templates>
+        <Template link=spaceshipHtwo/>
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=100 team=0>
+          <waypoints>
+            <StaticEntity position="-3850,2800,1450" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+
+    <SpaceShip position="-4100,2700,1500">
+      <templates>
+        <Template link=spaceshipHtwo/>
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=100 team=0 />
+      </controller>
+    </SpaceShip>
+
+    <SpaceShip position="-4150,2750,1550">
+      <templates>
+        <Template link=spaceshipHtwo/>
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=100 team=0 />
+      </controller>
+    </SpaceShip>
+
+    <PickupSpawner item="JumpItem" triggerDistance="20" respawnTime="10000" position="-3800, 2500, 1500">
+        <attached>
+            <!--<Model mesh="jumpthrust.mesh" scale="1.0" />
+            <Billboard material="Examples/Flare" colour="0.5, 1.0, 0.3" scale="0.5" />-->
+        </attached>
+    </PickupSpawner>
+
+    <PickupSpawner item="HealthUsableItem" triggerDistance="20" respawnTime="10000" position="-4150,2750,1550">
+        <attached>
+            <Model mesh="gwrench.mesh" scale="1.0" />
+            <Billboard material="Examples/Flare" colour="0.3, 0.8, 1.0" scale="0.5" />
+        </attached>
+    </PickupSpawner>
+
+    <PickupSpawner item="HealthImmediateItem" triggerDistance="20" respawnTime="3" position="2300, 4300, 2400">
+        <attached>
+            <Model mesh="gwrench.mesh" scale="1.0" />
+            <Billboard material="Examples/Flare" colour="0.9, 1.0, 0.1" scale="0.5" />
+        </attached>
+    </PickupSpawner>
+
+    <Billboard position="-2500, 2400, 1500" material="Examples/Flare" />
+    <EventDispatcher>
+      <targets>
+        <EventTarget target=pirates />
+      </targets>
+      <events>
+        <activity>
+          <DistanceTrigger position="-2500, 2400, 1500" distance=250 target="SpaceShip" stayactive=true />
+        </activity>
+      </events>
+    </EventDispatcher>
+
+<?lua
+for i = 1, 10, 1
+do
+?>
+    <SpaceShip position="<?lua print(5000 + math.random() * 4000 - 2000) ?>,<?lua print(0 + math.random() * 2000 - 1000) ?>,<?lua print(math.random() * 2000 - 1000) ?>">
+      <templates>
+        <Template link=spaceshippirate />
+      </templates>
+      <controller>
+        <WaypointPatrolController name=pirates alertnessradius=1000 team=1 active=false>
+          <waypoints>
+            <StaticEntity position="3100, 2000, 1500" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+<?lua
+end
+?>
+
+<?lua
+for i = 1, 12, 1
+do
+?>
+    <SpaceShip position="<?lua print(2800 + math.random() * 2000 - 1000) ?>,<?lua print(2500+ math.random() * 1000 - 500) ?>,<?lua print(2500 + math.random() * 1000 - 500) ?>" >
+      <templates>
+        <Template link=spaceshipassff />
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=1000 team=0>
+          <waypoints>
+            <StaticEntity position="<?lua print(2800 + math.random() * 1000 - 500) ?>,<?lua print(2500 + math.random() * 1000 - 500) ?>,<?lua print(1500 + math.random() * 1000 - 500) ?>" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+<?lua
+end
+?>
+
+    <Billboard position="2300, 4400, 2500" material="Examples/Flare" />
+    <EventDispatcher>
+      <targets>
+        <EventTarget target=attacker />
+      </targets>
+      <events>
+        <activity>
+          <DistanceTrigger position="2300, 4400, 2500" distance=50 target="SpaceShip" stayactive=true />
+        </activity>
+      </events>
+    </EventDispatcher>
+
+<?lua
+for i = 1, 12, 1
+do
+?>
+    <SpaceShip position="<?lua print(2500 + math.random() * 500 - 250) ?>,<?lua print(4800 + math.random() * 500 - 250) ?>,<?lua print(2500 + math.random() * 500 - 250) ?>" >
+      <templates>
+        <Template link=spaceshipassff />
+      </templates>
+      <controller>
+        <WaypointPatrolController name=attacker alertnessradius=1000 team=0 active=false>
+          <waypoints>
+            <StaticEntity position="<?lua print(2800 + math.random() * 500 - 250) ?>,<?lua print(2500 + math.random() * 500 - 250) ?>,<?lua print(1500 + math.random() * 500 - 250) ?>" />
+            <StaticEntity position="<?lua print(5000 + math.random() * 500 - 250) ?>,<?lua print(0 + math.random() * 500 - 250) ?>,<?lua print(0 + math.random() * 500 - 250) ?>" />
+            <StaticEntity position="<?lua print(7500 + math.random() * 500 - 250) ?>,<?lua print(-2500 + math.random() * 500 - 250) ?>,<?lua print(-1500 + math.random() * 500 - 250) ?>" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+<?lua
+end
+?>
+
+    <StaticEntity position="2800, 2500, 2500">
+        <attached>
+            <CheckPoint />
+            <Model position="400, 0, 0" scale="40" mesh="DuBall2.mesh"/>
+            <Model position="-400, 0, 0" scale="40" mesh="DuBall1.mesh"/>
+        </attached>
+    </StaticEntity>
+<!--
+    <Destroyer position="6500, -2000, -1000" collisionType=dynamic linearDamping=0.8 angularDamping=0 mass=500>
+        <attached>
+            <CheckPoint />
+            <Model position="0,0,0" scale="5" mesh="Carrier.mesh"/>
+            <Backlight
+                mainstate=activity
+                active=false
+                scale=0.4
+                name=bltest
+                position=" 7.6, 0, 6"
+                colour="0.2, 0.65, 1.0, 1.0"
+                width=15
+                length=1500
+                lifetime=2
+                elements=50
+                trailmaterial="Trail/backlighttrail"
+                turnontime=1
+                turnofftime=1
+                material="Flares/ThrusterFlare1"
+            />
+        </attached>
+        <collisionShapes>
+            <BoxCollisionShape position="70,0,-25"      halfExtents="150, 50, 25" />
+            <BoxCollisionShape position="95,75,-16"     halfExtents="70, 10, 12" />
+            <BoxCollisionShape position="95,-75,-16"    halfExtents="70, 10, 12" />
+            <BoxCollisionShape position="77,47,30"      halfExtents="110, 2, 30" />
+            <BoxCollisionShape position="77,-47,30"     halfExtents="110, 2, 30" />
+            <BoxCollisionShape position="77,0,50"       halfExtents="110, 45, 6" />
+            <BoxCollisionShape position="167,0,70"      halfExtents="17, 20, 20" />
+        </collisionShapes>
+    </Destroyer>
+-->
+    <Destroyer
+        position          = "6500,-2000,-1000"
+        collisionType     = dynamic
+        mass              = 100000
+        angularDamping    = 0.9999999
+        health            = 1000
+        maxhealth         = 1000
+        initialhealth     = 1000
+    >
+        <controller>
+          <WaypointPatrolController team=1 />
+        </controller>
+        <attached>
+            <Model mesh="Carrier.mesh" scale="5" />
+            <Backlight
+                mainstate=activity
+                active=false
+                scale=0.4
+                name=bltest
+                position=" 7.6, 0, 6"
+                colour="0.2, 0.65, 1.0, 1.0"
+                width=15
+                length=1500
+                lifetime=2
+                elements=50
+                trailmaterial="Trail/backlighttrail"
+                turnontime=1
+                turnofftime=1
+                material="Flares/ThrusterFlare1"
+            />
+            <?lua for i=0,8,1 do ?>
+                <BlinkingBillboard
+                    position="<?lua print(200-270/8*i)?> ,15,2"
+                    material="Examples/Flare"
+                    colour="1.0, 0.5, 0.3"
+                    phase=<?lua print(-360/8*i)?>
+                    amplitude=0.1
+                    frequency=0.5
+                    quadratic=1
+                />
+
+                <BlinkingBillboard
+                    position="<?lua print(200-270/8*i)?>,-15,2"
+                    material="Examples/Flare"
+                    colour="1.0, 0.5, 0.3"
+                    phase=<?lua print(-360/8*i)?>
+                    amplitude=0.1
+                    frequency=0.5
+                    quadratic=1
+                />
+            <?lua end ?>
+
+            <Backlight
+                scale=1
+                position=" 169, 75, -15"
+                colour="1, 0.85, 0.5, 0.5"
+                width=40
+                length=1000
+                lifetime=5
+                elements=15
+                trailmaterial="Trail/backlighttrail"
+                material="Examples/Flare"
+            />
+            <Backlight
+                scale=1
+                position=" 169, -75, -15"
+                colour="1, 0.85, 0.5, 0.5"
+                width=40
+                length=1000
+                lifetime=5
+                elements=15
+                trailmaterial="Trail/backlighttrail"
+                material="Examples/Flare" />
+        </attached>
+        <collisionShapes>
+            <BoxCollisionShape position="70,0,-25"      halfExtents="150, 50, 25" />
+            <BoxCollisionShape position="95,75,-16"     halfExtents="70, 10, 12" />
+            <BoxCollisionShape position="95,-75,-16"    halfExtents="70, 10, 12" />
+            <BoxCollisionShape position="77,47,30"      halfExtents="110, 2, 30" />
+            <BoxCollisionShape position="77,-47,30"     halfExtents="110, 2, 30" />
+            <BoxCollisionShape position="77,0,50"       halfExtents="110, 45, 6" />
+            <BoxCollisionShape position="167,0,70"      halfExtents="17, 20, 20" />
+        </collisionShapes>
+    </Destroyer>
+
+<?lua
+for i = 1, 10, 1
+do
+?>
+    <SpaceShip position="<?lua print(6200 + math.random() * 2000 - 1000) ?>,<?lua print(-1500 + math.random() * 1000 - 500) ?>,<?lua print(-700 + math.random() * 1000 - 500) ?>" >
+      <templates>
+        <Template link=spaceshippirate />
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=1000 team=1>
+          <waypoints>
+            <StaticEntity position="<?lua print(6000 + math.random() * 1000 - 500) ?>,<?lua print(-2000 + math.random() * 1000 - 500) ?>,<?lua print(-1000 + math.random() * 1000 - 500) ?>" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+<?lua
+end
+?>
+
+<?lua
+for i = 1, 200, 1
+do
+x = math.random() * 100  + (i-70) * 100
+y = math.random() * 3000 - 1500
+z = math.random() * 3000 - 1500 + (i-100) * 10
+s = math.random() * 60 + 30
+?>
+
+    <MovableEntity position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.8 angularDamping=0.8 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 - 15) ?>">
+      <attached>
+        <Model position="0,0,0" scale=<?lua print(s) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+      </attached>
+    </MovableEntity>
+<?lua
+end
+?>
+
+<?lua
+elements = {"BodyDebris1.mesh", "CockpitDebris.mesh", "LightningGun.mesh", "WingDebris1.mesh", "WingDebris2.mesh", "satellitedish.mesh", "Thruster.mesh"}
+sizes = {4, 4, 4, 4, 4, 10, 20}
+elements.length = function()
+    return table.getn(elements)
+end
+for i = 1, 150, 1
+do
+x = math.random() * 750 - 4500
+y = math.random() * 1000 + 2000
+z = math.random() * 500 + 1000
+e = math.floor(math.random()*elements.length()+1)
+?>
+
+    <MovableEntity position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.8 angularDamping=0.8 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 - 15) ?>">
+      <attached>
+        <Model position="0,0,0" scale="<?lua print(sizes[e]) ?>" mesh="<?lua print( elements[e]) ?>" />
+      </attached>
+    </MovableEntity>
+<?lua
+end
+?>
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/presentationHS09.oxw
===================================================================
--- /code/branches/rocket2/data/levels/presentationHS09.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/presentationHS09.oxw	(revision 6952)
@@ -0,0 +1,410 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_H2.oxt")
+  include("templates/spaceship_pirate.oxt")
+?>
+
+<Level
+ name         = "Presentation09"
+ description  = "presentation level for Orxonox Convention X"
+ gametype     = TeamDeathmatch
+ hasPhysics = true
+>
+  <Scene
+   ambientlight = "0.6, 0.4, 0.4"
+   skybox       = "Orxonox/skypanoramagen2"
+  >
+    <Light type=directional position="0,0,0" direction="0.683, 0.289, 0.670" diffuse="0.8, 0.5, 0.5, 1.0" specular="0.8, 0.4, 0.4, 1.0" />
+
+    <Template name="JumpItem" baseclass="Jump">
+        <Jump velocity="0,0,-1000" jumpsAvailable="4" guiImage="jumpturbinepickup.jpg" guiText="Jump" />
+    </Template>
+    <Template name="HealthImmediateItem" baseclass="HealthImmediate">
+        <HealthImmediate recoveredHealth="100" guiImage="decal.jpg" guiText="Health" />
+    </Template>
+    <Template name="HealthUsableItem" baseclass="HealthUsable">
+        <HealthImmediate recoveredHealth="80" guiImage="goldwrenchpickup.jpg" guiText="Health" />
+    </Template>
+
+    <SpawnPoint position="-3800, 2500, 1500" direction="-0.683, -0.289, -0.670"  spawnclass=SpaceShip pawndesign=spaceshipassff />
+
+
+
+    <SpaceShip position="-3900,3000,1000">
+      <templates>
+        <Template link=spaceshipHtwo/>
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=100 team=0>
+          <waypoints>
+            <StaticEntity position="-3850,2800,1450" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+
+    <SpaceShip position="-4100,2600,1600">
+      <templates>
+        <Template link=spaceshipHtwo/>
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=100 team=0>
+          <waypoints>
+            <StaticEntity position="-3850,2800,1450" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+
+    <SpaceShip position="-4000,2500,1500">
+      <templates>
+        <Template link=spaceshipHtwo/>
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=100 team=0>
+          <waypoints>
+            <StaticEntity position="-3850,2800,1450" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+
+    <SpaceShip position="-4100,2700,1500">
+      <templates>
+        <Template link=spaceshipHtwo/>
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=100 team=0 />
+      </controller>
+    </SpaceShip>
+
+    <SpaceShip position="-4150,2750,1550">
+      <templates>
+        <Template link=spaceshipHtwo/>
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=100 team=0 />
+      </controller>
+    </SpaceShip>
+
+    <Billboard material="Test/Fog" position="-3800, 2500, 1500" alpha="0.1" color="1, 1, 1, 0.1" scale="0.5" />
+
+    <PickupSpawner item="JumpItem" triggerDistance="20" respawnTime="10000" position="-3800, 2500, 1500">
+        <attached>
+            <!--<Model mesh="jumpthrust.mesh" scale="1.0" />
+            <Billboard material="Examples/Flare" colour="0.5, 1.0, 0.3" scale="0.5" />-->
+        </attached>
+    </PickupSpawner>
+
+    <PickupSpawner item="HealthUsableItem" triggerDistance="20" respawnTime="10000" position="-4150,2750,1550">
+        <attached>
+            <Model mesh="gwrench.mesh" scale="1.0" />
+            <Billboard material="Examples/Flare" colour="0.3, 0.8, 1.0" scale="0.5" />
+        </attached>
+    </PickupSpawner>
+
+    <PickupSpawner item="HealthImmediateItem" triggerDistance="20" respawnTime="3" position="2300, 4300, 2400">
+        <attached>
+            <Model mesh="gwrench.mesh" scale="1.0" />
+            <Billboard material="Examples/Flare" colour="0.9, 1.0, 0.1" scale="0.5" />
+        </attached>
+    </PickupSpawner>
+
+    <Billboard position="-2500, 2400, 1500" material="Examples/Flare" />
+    <EventDispatcher>
+      <targets>
+        <EventTarget target=pirates />
+      </targets>
+      <events>
+        <activity>
+          <DistanceTrigger position="-2500, 2400, 1500" distance=250 target="SpaceShip" stayactive=true />
+        </activity>
+      </events>
+    </EventDispatcher>
+
+<?lua
+for i = 1, 10, 1
+do
+?>
+    <SpaceShip position="<?lua print(5000 + math.random() * 4000 - 2000) ?>,<?lua print(0 + math.random() * 2000 - 1000) ?>,<?lua print(math.random() * 2000 - 1000) ?>">
+      <templates>
+        <Template link=spaceshippirate />
+      </templates>
+      <controller>
+        <WaypointPatrolController name=pirates alertnessradius=1000 team=1 active=false>
+          <waypoints>
+            <StaticEntity position="3100, 2000, 1500" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+<?lua
+end
+?>
+
+<?lua
+for i = 1, 12, 1
+do
+?>
+    <SpaceShip position="<?lua print(2800 + math.random() * 2000 - 1000) ?>,<?lua print(2500+ math.random() * 1000 - 500) ?>,<?lua print(2500 + math.random() * 1000 - 500) ?>" >
+      <templates>
+        <Template link=spaceshipassff />
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=1000 team=0>
+          <waypoints>
+            <StaticEntity position="<?lua print(2800 + math.random() * 1000 - 500) ?>,<?lua print(2500 + math.random() * 1000 - 500) ?>,<?lua print(1500 + math.random() * 1000 - 500) ?>" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+<?lua
+end
+?>
+
+    <Billboard position="2300, 4400, 2500" material="Examples/Flare" />
+    <EventDispatcher>
+      <targets>
+        <EventTarget target=attacker />
+      </targets>
+      <events>
+        <activity>
+          <DistanceTrigger position="2300, 4400, 2500" distance=50 target="SpaceShip" stayactive=true />
+        </activity>
+      </events>
+    </EventDispatcher>
+
+<?lua
+for i = 1, 12, 1
+do
+?>
+    <SpaceShip position="<?lua print(2500 + math.random() * 500 - 250) ?>,<?lua print(4800 + math.random() * 500 - 250) ?>,<?lua print(2500 + math.random() * 500 - 250) ?>" >
+      <templates>
+        <Template link=spaceshipassff />
+      </templates>
+      <controller>
+        <WaypointPatrolController name=attacker alertnessradius=<?lua print(math.random() * 2000) ?> team=0 active=false>
+          <waypoints>
+            <StaticEntity position="<?lua print(2800 + math.random() * 500 - 250) ?>,<?lua print(2500 + math.random() * 500 - 250) ?>,<?lua print(1500 + math.random() * 500 - 250) ?>" />
+            <StaticEntity position="<?lua print(5000 + math.random() * 500 - 250) ?>,<?lua print(0 + math.random() * 500 - 250) ?>,<?lua print(0 + math.random() * 500 - 250) ?>" />
+            <StaticEntity position="<?lua print(7500 + math.random() * 500 - 250) ?>,<?lua print(-2500 + math.random() * 500 - 250) ?>,<?lua print(-1500 + math.random() * 500 - 250) ?>" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+<?lua
+end
+?>
+
+    <StaticEntity position="2800, 2500, 2500">
+        <attached>
+            <CheckPoint />
+            <Model position="400, 0, 0" scale="40" mesh="DuBall2.mesh"/>
+            <Model position="-400, 0, 0" scale="40" mesh="DuBall1.mesh"/>
+        </attached>
+    </StaticEntity>
+<!--
+    <Destroyer position="6500, -2000, -1000" collisionType=dynamic linearDamping=0.8 angularDamping=0 mass=500>
+        <attached>
+            <CheckPoint />
+            <Model position="0,0,0" scale="5" mesh="Carrier.mesh"/>
+            <Backlight
+                mainstate=activity
+                active=false
+                scale=0.4
+                name=bltest
+                position=" 7.6, 0, 6"
+                colour="0.2, 0.65, 1.0, 1.0"
+                width=15
+                length=1500
+                lifetime=2
+                elements=50
+                trailmaterial="Trail/backlighttrail"
+                turnontime=1
+                turnofftime=1
+                material="Flares/ThrusterFlare1"
+            />
+        </attached>
+        <collisionShapes>
+            <BoxCollisionShape position="70,0,-25"      halfExtents="150, 50, 25" />
+            <BoxCollisionShape position="95,75,-16"     halfExtents="70, 10, 12" />
+            <BoxCollisionShape position="95,-75,-16"    halfExtents="70, 10, 12" />
+            <BoxCollisionShape position="77,47,30"      halfExtents="110, 2, 30" />
+            <BoxCollisionShape position="77,-47,30"     halfExtents="110, 2, 30" />
+            <BoxCollisionShape position="77,0,50"       halfExtents="110, 45, 6" />
+            <BoxCollisionShape position="167,0,70"      halfExtents="17, 20, 20" />
+        </collisionShapes>
+    </Destroyer>
+-->
+    <Destroyer
+        position          = "6500,-2000,-1000"
+        collisionType     = dynamic
+        mass              = 100000
+        angularDamping    = 0.9999999
+        health            = 1000
+        maxhealth         = 1000
+        initialhealth     = 1000
+    >
+        <controller>
+          <WaypointPatrolController team=1 />
+        </controller>
+        <attached>
+            <Model mesh="Carrier.mesh" scale="5" />
+            <Backlight
+                mainstate=activity
+                active=false
+                scale=0.4
+                name=bltest
+                position=" 7.6, 0, 6"
+                colour="0.2, 0.65, 1.0, 1.0"
+                width=15
+                length=1500
+                lifetime=2
+                elements=50
+                trailmaterial="Trail/backlighttrail"
+                turnontime=1
+                turnofftime=1
+                material="Flares/ThrusterFlare1"
+            />
+            <?lua for i=0,8,1 do ?>
+                <BlinkingBillboard
+                    position="<?lua print(200-270/8*i)?> ,15,2"
+                    material="Examples/Flare"
+                    colour="1.0, 0.5, 0.3"
+                    phase=<?lua print(-360/8*i)?>
+                    amplitude=0.1
+                    frequency=0.5
+                    quadratic=1
+                />
+
+                <BlinkingBillboard
+                    position="<?lua print(200-270/8*i)?>,-15,2"
+                    material="Examples/Flare"
+                    colour="1.0, 0.5, 0.3"
+                    phase=<?lua print(-360/8*i)?>
+                    amplitude=0.1
+                    frequency=0.5
+                    quadratic=1
+                />
+            <?lua end ?>
+
+            <Backlight
+                scale=1
+                position=" 169, 75, -15"
+                colour="1, 0.85, 0.5, 0.5"
+                width=40
+                length=1000
+                lifetime=5
+                elements=15
+                trailmaterial="Trail/backlighttrail"
+                material="Examples/Flare"
+            />
+            <Backlight
+                scale=1
+                position=" 169, -75, -15"
+                colour="1, 0.85, 0.5, 0.5"
+                width=40
+                length=1000
+                lifetime=5
+                elements=15
+                trailmaterial="Trail/backlighttrail"
+                material="Examples/Flare" />
+        </attached>
+        <collisionShapes>
+            <BoxCollisionShape position="70,0,-25"      halfExtents="150, 50, 25" />
+            <BoxCollisionShape position="95,75,-16"     halfExtents="70, 10, 12" />
+            <BoxCollisionShape position="95,-75,-16"    halfExtents="70, 10, 12" />
+            <BoxCollisionShape position="77,47,30"      halfExtents="110, 2, 30" />
+            <BoxCollisionShape position="77,-47,30"     halfExtents="110, 2, 30" />
+            <BoxCollisionShape position="77,0,50"       halfExtents="110, 45, 6" />
+            <BoxCollisionShape position="167,0,70"      halfExtents="17, 20, 20" />
+        </collisionShapes>
+    </Destroyer>
+
+<?lua
+for i = 1, 10, 1
+do
+?>
+    <SpaceShip position="<?lua print(6200 + math.random() * 2000 - 1000) ?>,<?lua print(-1500 + math.random() * 1000 - 500) ?>,<?lua print(-700 + math.random() * 1000 - 500) ?>" >
+      <templates>
+        <Template link=spaceshippirate />
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=1000 team=1>
+          <waypoints>
+            <StaticEntity position="<?lua print(6000 + math.random() * 1000 - 500) ?>,<?lua print(-2000 + math.random() * 1000 - 500) ?>,<?lua print(-1000 + math.random() * 1000 - 500) ?>" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+<?lua
+end
+?>
+
+<?lua
+elements = {"asteroid_ice.mesh", "asteroid_UV.mesh", "ast1.mesh", "ast2.mesh", "ast3.mesh", "ast4.mesh", "ast5.mesh", "ast6.mesh"}
+elements.length = function()
+    return table.getn(elements)
+end
+for i = 1, 100, 1
+do
+x = math.random() * 100  + (i) * 100
+y = math.random() * 3000 - 1500
+z = math.random() * 3000 - 1500 + (i-100) * 10
+s = math.random() * 60 + 30
+e = math.floor(math.random()*elements.length()+1)
+?>
+
+    <MovableEntity mass=90000 position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.8 angularDamping=0.8 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 100 - 15) ?>">
+      <attached>
+        <Model position="0,0,0" scale=<?lua print(s) ?> mesh="<?lua print(elements[e])?>" />
+      </attached>
+    </MovableEntity>
+<?lua
+end
+?>
+
+<?lua
+for i = 1, 100, 1
+do
+x = math.random() * 200 + i*200
+y = math.random() * 3000 - 1500
+z = math.random() * 3000 - 1500 + (i-100) * 10
+s = math.random() * 60 + 30
+?>
+  <ParticleSpawner position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" source="Orxonox/Steam" lifetime=3.0 loop=1 />
+<!-- <Billboard material="Test/Fog" position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>"  color="1, 1, 1, 0.01" scale="20" />
+-->
+<?lua
+end
+?>
+
+<?lua
+elements = {"BodyDebris1.mesh", "CockpitDebris.mesh", "LightningGun.mesh", "WingDebris1.mesh", "WingDebris2.mesh", "satellitedish.mesh", "Thruster.mesh"}
+sizes = {4, 4, 4, 4, 4, 10, 20}
+elements.length = function()
+    return table.getn(elements)
+end
+for i = 1, 150, 1
+do
+x = math.random() * 750 - 4500
+y = math.random() * 1000 + 2000
+z = math.random() * 500 + 1000
+e = math.floor(math.random()*elements.length()+1)
+?>
+
+    <MovableEntity mass=90000 position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.8 angularDamping=0.8 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30- 15) ?>">
+      <attached>
+        <Model position="0,0,0" scale="<?lua print(sizes[e]) ?>" mesh="<?lua print( elements[e]) ?>" />
+      </attached>
+    </MovableEntity>
+<?lua
+end
+?>
+<!--
+    <Planet position="1000,0,0" mass=900000 scale=1000 pitch=-90 mesh="iceplanet.mesh" atmosphere="atmosphere1" rotationaxis="1,1,0" rotationrate="1" atmospheresize=224.0f imagesize=1024.0f />
+-->
+</Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/presentationHS09b.oxw
===================================================================
--- /code/branches/rocket2/data/levels/presentationHS09b.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/presentationHS09b.oxw	(revision 6952)
@@ -0,0 +1,270 @@
+<?lua
+  include("stats.oxo")
+  include("hudtemplates3.oxo")
+?>
+
+<?lua
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_pirate.oxt")
+  include("templates/spaceship_ghost.oxt")
+  include("templates/spaceship_HXY.oxt")
+  include("templates/spaceship_Transporter.oxt")
+  include("templates/spaceship_HXY_SL.oxt")
+  include("templates/spaceship_Transporter_SL.oxt")
+?>
+
+<Level
+ name         = "Sample"
+ description  = "Just a few tests"
+ gametype     = TeamDeathmatch
+>
+  <Scene
+    ambientlight = "0.8, 0.8, 0.8"
+    skybox       = "Orxonox/Starbox"
+  >
+
+
+<AmbientSound ambientSource="Mars.ogg" looping="true" playOnLoad="true" />
+
+   <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+<?lua
+   for i = 1, 50, 1
+   do
+   x = math.random() * 2000  + 4000
+   y = math.random() * 4000 - 2000
+   z = math.random() * 2000 - 1000
+   s = math.random() * 100
+   ?>
+
+    <MovableEntity collisiontype=dynamic mass=<?lua print(s*10)?> position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.01 angularDamping=0 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 100 - 15) ?>">
+      <attached>
+        <Model position="0,0,0" scale=<?lua print(s) ?> mesh="asteroid_UV.mesh" />
+      </attached>
+      <collisionShapes>
+        <SphereCollisionShape radius="<?lua print(s*0.9) ?>" />
+      </collisionShapes>
+    </MovableEntity>
+     <ParticleSpawner position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" source="Orxonox/Steam" lifetime=3.0 loop=1 />
+<?lua
+end
+?>
+
+<?lua
+elements = {"BodyDebris1.mesh", "CockpitDebris.mesh", "LightningGun.mesh", "WingDebris1.mesh", "WingDebris2.mesh", "satellitedish.mesh", "Thruster.mesh"}
+sizes = {4, 4, 4, 4, 4, 10, 20}
+elements.length = function()
+    return table.getn(elements)
+end
+for i = 1, 100, 1
+do
+x = math.random() * 750 - 4500
+y = math.random() * 1000 + 2000
+z = math.random() * 500 + 1000
+e = math.floor(math.random()*elements.length()+1)
+?>
+
+    <MovableEntity mass=90000 position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.8 angularDamping=0.8 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30- 15) ?>">
+      <attached>
+        <Model position="0,0,0" scale="<?lua print(sizes[e]) ?>" mesh="<?lua print( elements[e]) ?>" />
+      </attached>
+    </MovableEntity>
+<?lua
+end
+?>
+<?lua
+for i = 1,12, 1
+do
+?>
+    <SpaceShip position="<?lua print(math.random()*500 + 4500) ?>,<?lua print(-(math.random()*500 -250)) ?>,<?lua print(i*50 - 150) ?>" >
+      <templates>
+        <Template link=spaceshipHXYSL />
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=4000 team=0 active=true>
+          <waypoints>
+            <StaticEntity position="5000,<?lua print(math.random()*50)?> ,<?lua print(i*50 -150) ?>" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+<?lua
+end
+?>
+<SpaceShip position="5000,100,100" >
+      <templates>
+        <Template link=spaceshipTransporterSL />
+      </templates>
+      <controller>
+        <WaypointPatrolController name=pirate  target=pirate alertnessradius=1000 team=0 active=false>
+          <waypoints>
+            <StaticEntity position="5000,100,1100" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+</SpaceShip>
+    <Destroyer
+        position          = "-5000,100 ,100"
+        collisionType     = dynamic
+        mass              = 100000
+        angularDamping    = 0.9999999
+        health            = 1000
+        maxhealth         = 1000
+        initialhealth     = 1000
+    >
+        <controller>
+          <WaypointPatrolController team=1 />
+        </controller>
+        <attached>
+            <Model mesh="Carrier.mesh" scale="5" />
+            <Backlight
+                mainstate=activity
+                active=false
+                scale=0.4
+                name=bltest
+                position=" 7.6, 0, 6"
+                colour="0.2, 0.65, 1.0, 1.0"
+                width=15
+                length=1500
+                lifetime=2
+                elements=50
+                trailmaterial="Trail/backlighttrail"
+                turnontime=1
+                turnofftime=1
+                material="Flares/ThrusterFlare1"
+            />
+            <?lua for i=0,8,1 do ?>
+                <BlinkingBillboard
+                    position="<?lua print(200-270/8*i)?> ,15,2"
+                    material="Examples/Flare"
+                    colour="1.0, 0.5, 0.3"
+                    phase=<?lua print(-360/8*i)?>
+                    amplitude=0.1
+                    frequency=0.5
+                    quadratic=1
+                />
+
+                <BlinkingBillboard
+                    position="<?lua print(200-270/8*i)?>,-15,2"
+                    material="Examples/Flare"
+                    colour="1.0, 0.5, 0.3"
+                    phase=<?lua print(-360/8*i)?>
+                    amplitude=0.1
+                    frequency=0.5
+                    quadratic=1
+                />
+            <?lua end ?>
+
+            <Backlight
+                scale=1
+                position=" 169, 75, -15"
+                colour="1, 0.85, 0.5, 0.5"
+                width=40
+                length=1000
+                lifetime=5
+                elements=15
+                trailmaterial="Trail/backlighttrail"
+                material="Examples/Flare"
+            />
+            <Backlight
+                scale=1
+                position=" 169, -75, -15"
+                colour="1, 0.85, 0.5, 0.5"
+                width=40
+                length=1000
+                lifetime=5
+                elements=15
+                trailmaterial="Trail/backlighttrail"
+                material="Examples/Flare" />
+        </attached>
+        <collisionShapes>
+            <BoxCollisionShape position="70,0,-25"      halfExtents="150, 50, 25" />
+            <BoxCollisionShape position="95,75,-16"     halfExtents="70, 10, 12" />
+            <BoxCollisionShape position="95,-75,-16"    halfExtents="70, 10, 12" />
+            <BoxCollisionShape position="77,47,30"      halfExtents="110, 2, 30" />
+            <BoxCollisionShape position="77,-47,30"     halfExtents="110, 2, 30" />
+            <BoxCollisionShape position="77,0,50"       halfExtents="110, 45, 6" />
+            <BoxCollisionShape position="167,0,70"      halfExtents="17, 20, 20" />
+        </collisionShapes>
+    </Destroyer>
+
+   <?lua
+   for i = 1, 50, 1
+   do
+   x = -(math.random() * 2000  + 4000)
+   y = math.random() * 4000 - 2000
+   z = math.random() * 2000 - 1000
+   s = math.random() * 100
+   ?>
+
+    <MovableEntity collisiontype=dynamic mass=<?lua print(s*10)?> position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" linearDamping=0.01 angularDamping=0 rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 100 - 15) ?>">
+      <attached>
+        <Model position="0,0,0" scale=<?lua print(s) ?> mesh="asteroid_ice.mesh" />
+      </attached>
+      <collisionShapes>
+        <SphereCollisionShape radius="<?lua print(s*0.9)?>" />
+      </collisionShapes>
+    </MovableEntity>
+    <ParticleSpawner position="<?lua print(x) ?>,<?lua print(y) ?>,<?lua print(z) ?>" source="Orxonox/Steam" lifetime=3.0 loop=1 />
+<?lua
+end
+?>
+<!--<EventDispatcher>
+      <targets>
+        <EventTarget target=attack />
+        <EventTarget target=wait />
+      </targets>
+      <events>
+        <activity>
+          <DistanceTrigger position="0, 0, 4500" distance=100 target="SpaceShip" stayactive=true />
+        </activity>
+      </events>
+</EventDispatcher>
+
+<EventDispatcher>
+      <targets>
+        <EventTarget target=wait />
+      </targets>
+      <events>
+        <activity>
+          <DistanceTrigger position="0, 0, 4500" distance=100 target="SpaceShip" stayactive=false />
+        </activity>
+      </events>
+</EventDispatcher>-->
+
+<?lua
+for i = 1,25, 1
+do
+?>
+<SpaceShip position="<?lua print(-(math.random()*500 + 4500)) ?>,<?lua print(-(math.random()*500 -250)) ?>,<?lua print(i*50 - 150) ?>" >
+      <templates>
+        <Template link=spaceshipghost />
+      </templates>
+      <controller>
+
+          <WaypointPatrolController name=attack alertnessradius=15000 team=1 active=false>
+          <events>
+           <activity>
+             <DistanceTrigger position="-5000, 100, 100" distance=2000 target="Camera" stayactive=true />
+           </activity>
+          </events>
+          </WaypointPatrolController>
+
+      </controller>
+    </SpaceShip>
+<?lua
+end
+?>
+
+
+
+    <AmbientSound ambientSource="Earth.ogg" looping="true" playOnLoad="false">
+      <events>
+        <activity>
+          <DistanceTrigger position="2000,0,0" distance=500 target="Camera" />
+        </activity>
+      </events>
+    </AmbientSound>
+
+    <SpawnPoint position="5000,0,2000" spawnclass=SpaceShip pawndesign=spaceshipassff  team=0/>
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/presentationLOD.oxw
===================================================================
--- /code/branches/rocket2/data/levels/presentationLOD.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/presentationLOD.oxw	(revision 6952)
@@ -0,0 +1,24 @@
+<?lua
+  include("stats.oxo")
+  include("hudtemplates3.oxo")
+?>
+
+<?lua
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_pirate.oxt")
+?>
+
+<Level
+ name         = "Sample"
+ description  = "Just a few tests"
+>
+  <Scene
+    ambientlight = "0.8, 0.8, 0.8"
+    skybox       = "Orxonox/Starbox"
+  >
+    <Model position="0,10,0" scale=3 mesh="ast3.mesh"/>
+    <Model position="0,-10,0" scale=3 mesh="ast3.mesh"/>
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+    <SpawnPoint position="0,0,100" spawnclass=SpaceShip pawndesign=spaceshipassff />
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/presentationLODdif.oxw
===================================================================
--- /code/branches/rocket2/data/levels/presentationLODdif.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/presentationLODdif.oxw	(revision 6952)
@@ -0,0 +1,35 @@
+<?lua
+  include("stats.oxo")
+  include("hudtemplates3.oxo")
+  include("lodinformation.oxt")
+?>
+
+<?lua
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_pirate.oxt")
+?>
+
+<Level
+ name         = "Sample"
+ description  = "Just a few tests"
+>
+  <lodinformation>
+	  <MeshLodInformation mesh=ast1.mesh lodQuality=4 />
+  </lodinformation>
+  <Scene
+    ambientlight = "0.8, 0.8, 0.8"
+    skybox       = "Orxonox/Starbox"
+  >
+    <Model position="0,10,0" scale=3 mesh="ast3.mesh"/>
+	<Model position="0,-10,0" scale=3 mesh="ast3.mesh" lodLevel="1"/>
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+    <SpawnPoint position="0,0,100" spawnclass=SpaceShip pawndesign=spaceshipassff />
+	
+  </Scene>
+
+  <templates>
+	<Template link=lodtemplate_default />
+  </templates>
+</Level>
+
+ 
Index: /code/branches/rocket2/data/levels/presentation_dm.oxw
===================================================================
--- /code/branches/rocket2/data/levels/presentation_dm.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/presentation_dm.oxw	(revision 6952)
@@ -0,0 +1,95 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_H2.oxt")
+?>
+
+<Level
+ name         = "Presentation"
+ description  = "A simple testlevel"
+>
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/skypanoramagen1"
+  >
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+
+<?lua
+for i = 1, 10, 1
+do ?>
+    <SpawnPoint position="<?lua print(math.random() * 1000 - 500) ?>,<?lua print(math.random() * 1000 - 500) ?>,<?lua print(math.random() * 1000 - 500) ?>" lookat="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+<?lua
+end
+?>
+
+    <GlobalShader compositor="Bloom" visible=false>
+      <events>
+        <visibility>
+          <DistanceTrigger position="0,0,0" distance=30 target="Spectator" switch=true />
+        </visibility>
+      </events>
+    </GlobalShader>
+
+
+<?lua
+for i = 1, 100, 1
+do
+j = math.random()
+?>
+
+    <MovableEntity position="<?lua print(math.random() * 5000-2000) ?>,<?lua print(math.random() * 5000-2000) ?>,<?lua print(math.random() * 5000 - 2000) ?>" collisionType=dynamic linearDamping=0.8 angularDamping=0 mass=<?lua print(j * 50) ?> scale=<?lua print(j * 5) ?> rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+      <attached>
+        <Model position="0,0,0" scale=<?lua print(j * 10) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+      </attached>
+      <collisionShapes>
+        <SphereCollisionShape radius="<?lua print(j * 70) ?>" />
+      </collisionShapes>
+    </MovableEntity>
+<?lua
+end
+?>
+
+<!--
+<?lua
+for i = 1, 70, 1
+do ?>
+  <MovableEntity position="<?lua print(math.random() * 6000 - 3000)?>, <?lua print(math.random() * 6000 - 3000) ?>, <?lua print(math.random() * 1000 + 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 30 + 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+  <MovableEntity position="<?lua print(math.random() * 6000 - 3000)?>, <?lua print(math.random() * 6000 - 3000) ?>, <?lua print(math.random() * -1000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 30 + 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+
+  <MovableEntity position="<?lua print(math.random() * 6000 - 3000)?>, <?lua print(math.random() * 1000 + 3000) ?>, <?lua print(math.random() * 6000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 30 + 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+  <MovableEntity position="<?lua print(math.random() * 6000 - 3000)?>, <?lua print(math.random() * -1000 - 3000) ?>, <?lua print(math.random() * 6000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 30 + 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+
+  <MovableEntity position="<?lua print(math.random() * 1000 + 3000)?>, <?lua print(math.random() * 6000 - 3000) ?>, <?lua print(math.random() * 6000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 30 + 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+  <MovableEntity position="<?lua print(math.random() * -1000 - 3000)?>, <?lua print(math.random() * 6000 - 3000) ?>, <?lua print(math.random() * 6000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 30 + 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+<?lua
+end
+?>
+-->
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/presentation_pong.oxw
===================================================================
--- /code/branches/rocket2/data/levels/presentation_pong.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/presentation_pong.oxw	(revision 6952)
@@ -0,0 +1,232 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("ponghud.oxo")
+?>
+
+<Template name=pongbatcameras defaults=0>
+  <PongBat>
+    <camerapositions>
+      <CameraPosition position="0,200,0" pitch=-90 absolute=true />
+      <CameraPosition position="0,50,160" drag=true mouselook=true />
+      <CameraPosition position="0,40,125" drag=true mouselook=true />
+      <CameraPosition position="0,30, 90" drag=true mouselook=true />
+    </camerapositions>
+  </PongBat>
+</Template>
+
+<Template name=pongbat>
+  <PongBat camerapositiontemplate=pongbatcameras>
+    <attached>
+      <Model position="0,0,3" mesh="cube.mesh" scale3D="14,2,2" />
+      <!--Model roll=180 mesh="pongbat.mesh" scale=0.045 /-->
+    </attached>
+  </PongBat>
+</Template>
+
+<Template name=pongball>
+  <PongBall>
+    <attached>
+      <Model mesh="sphere.mesh" scale=2 />
+      <!--Billboard scale=0.2 colour="1.0, 1.0, 0.5" material="Examples/Flare" /-->
+      <Backlight scale=0.2 colour="1.0, 1.0, 0.5" width=7 length=500 lifetime=0.3 elements=20 trailmaterial="Trail/backlighttrail" material="Examples/Flare" />
+      <Light type=point diffuse="1.0, 1.0, 0.5" specular="1.0, 1.0, 0.5" attenuation="1200, 1.0, 0.0035, 0.00005" />
+      <ParticleSpawner name=hiteffect position="0,0,0" source="Orxonox/sparks2" lifetime=0.01 autostart=0 mainstate=spawn />
+    </attached>
+    <eventlisteners>
+      <EventTarget target=hiteffect />
+    </eventlisteners>
+  </PongBall>
+</Template>
+
+
+<Level
+ name         = "Presentation"
+ description  = "A simple testlevel"
+ gametype     = Pong
+>
+  <AmbientSound source="ambient/mainmenu.wav" playOnLoad=true />
+
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/skypanoramagen1"
+  >
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+<?lua
+for i = 1, 10, 1
+do ?>
+    <SpawnPoint position="<?lua print(math.random() * 1000 - 500) ?>,<?lua print(math.random() * 1000 - 500) ?>,<?lua print(math.random() * 1000 - 500) ?>" lookat="0,0,0" />
+<?lua
+end
+?>
+
+  <MovableEntity rotationrate=5 rotationaxis="0,0,1">
+    <attached>
+      <PongCenterpoint name=pongcenter dimension="200,120" balltemplate=pongball battemplate=pongbat ballspeed=200 ballaccfactor=1.0 batspeed=130 batlength=0.25>
+        <attached>
+          <Model position="0,0,60" mesh="cube.mesh" scale3D="105,1,1" />
+          <Model position="0,0,-60" mesh="cube.mesh" scale3D="105,1,1" />
+
+          <ParticleSpawner name=scoreeffect_right position="120,0, 45" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+          <ParticleSpawner name=scoreeffect_right position="120,0, 30" source="Orxonox/BigExplosion1part2" lifetime=3.0 autostart=0 />
+          <ParticleSpawner name=scoreeffect_right position="120,0, 15" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+          <ParticleSpawner name=scoreeffect_right position="120,0,  0" source="Orxonox/BigExplosion1part2" lifetime=0.1 autostart=0 />
+          <ParticleSpawner name=scoreeffect_right position="120,0,-15" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+          <ParticleSpawner name=scoreeffect_right position="120,0,-30" source="Orxonox/BigExplosion1part2" lifetime=3.0 autostart=0 />
+          <ParticleSpawner name=scoreeffect_right position="120,0,-45" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+
+          <ParticleSpawner name=scoreeffect_left position="-120,0, 45" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+          <ParticleSpawner name=scoreeffect_left position="-120,0, 30" source="Orxonox/BigExplosion1part2" lifetime=3.0 autostart=0 />
+          <ParticleSpawner name=scoreeffect_left position="-120,0, 15" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+          <ParticleSpawner name=scoreeffect_left position="-120,0,  0" source="Orxonox/BigExplosion1part2" lifetime=0.1 autostart=0 />
+          <ParticleSpawner name=scoreeffect_left position="-120,0,-15" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+          <ParticleSpawner name=scoreeffect_left position="-120,0,-30" source="Orxonox/BigExplosion1part2" lifetime=3.0 autostart=0 />
+          <ParticleSpawner name=scoreeffect_left position="-120,0,-45" source="Orxonox/sparks2" lifetime=0.1 autostart=0 />
+
+          <WorldSound name="scoreSound" position="0,0,0" source="sounds/pong_score.wav" >
+            <events>
+              <play>
+                <EventListener event=pongcenter />
+              </play>
+            </events>
+          </WorldSound>
+
+<?lua
+for i = 1, 15, 1
+do ?>
+          <ParticleSpawner name=scoreeffect_center position="<?lua print(math.random() * 200 - 100) ?>,0,<?lua print(math.random() * 120 - 60) ?>" source="Orxonox/sparks2" lifetime=0.02 autostart=0 startdelay=<?lua print(math.random() * 0.7) ?> />
+<?lua
+end
+?>
+
+        </attached>
+      </PongCenterpoint>
+    </attached>
+  </MovableEntity>
+
+  <EventDispatcher>
+    <targets>
+      <EventTarget target=scoreeffect_right />
+      <EventTarget target=scoreeffect_center />
+    </targets>
+    <events>
+      <spawn>
+        <EventFilter>
+          <names>
+            <EventName name=right />
+          </names>
+          <EventListener event=pongcenter />
+        </EventFilter>
+      </spawn>
+    </events>
+  </EventDispatcher>
+  <EventDispatcher>
+    <targets>
+      <EventTarget target=scoreeffect_left />
+      <EventTarget target=scoreeffect_center />
+    </targets>
+    <events>
+      <spawn>
+        <EventFilter>
+          <names>
+            <EventName name=left />
+          </names>
+          <EventListener event=pongcenter />
+        </EventFilter>
+      </spawn>
+    </events>
+  </EventDispatcher>
+
+  <?lua
+    dofile("includes/CuboidSpaceStation.lua")
+  ?>
+
+  <StaticEntity pitch=15>
+    <attached>
+      <MovableEntity rotationrate="-4.15786" rotationaxis="0,0,1">
+        <attached>
+          <StaticEntity position="-2500,0,0" yaw=90 pitch=90>
+            <attached>
+              <?lua
+                createSpaceStationPar(0,2,1,2,1,4,1,50)
+              ?>
+            </attached>
+          </StaticEntity>
+        </attached>
+      </MovableEntity>
+    </attached>
+  </StaticEntity>
+
+  <StaticEntity position="0,1200,-200" yaw=50 pitch=60 roll=45>
+    <attached>
+      <Model scale=10 mesh="Carrier.mesh" />
+      <Model position="0,30,20" scale=10 mesh="pirate.mesh" roll="180" />
+      <Model position="-80,-30,20" scale=10 mesh="pirate.mesh" roll="180" />
+    </attached>
+  </StaticEntity>
+
+  <StaticEntity pitch=70>
+    <attached>
+      <MovableEntity rotationaxis="0,0,1" rotationrate=8.5974>
+        <attached>
+          <StaticEntity yaw=-90 pitch=0 roll=90 position="800,0,0">
+            <attached>
+              <Model position="0,0,0" scale=10 mesh="satellite.mesh" />
+              <MovableEntity position="-4,0,20" velocity="0,0,0" rotationaxis="0,0,1" rotationrate=50>
+                <attached>
+                  <Model position="0,0,0" scale=10 mesh="satellitedish.mesh"/>
+                </attached>
+              </MovableEntity>
+              <ParticleEmitter pitch=-135 roll=30 position="-14, 3.5,-2.5" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+              <ParticleEmitter pitch=135 roll=30 position="-14, 3.5,-9" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+              <ParticleEmitter pitch=-45 roll=30 position="-14,-3.5,-2.5" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+              <ParticleEmitter pitch=45 roll=30 position="-14,-3.5,-9" source="Orxonox/thruster3" lifetime=2.0 loop=1 startdelay=3.0 />
+            </attached>
+          </StaticEntity>
+        </attached>
+      </MovableEntity>
+    </attached>
+  </StaticEntity>
+
+<?lua
+for i = 1, 10, 1
+do ?>
+  <MovableEntity position="<?lua print(math.random() * 600 - 300)?>, <?lua print(math.random() * 600 - 300) ?>, <?lua print(math.random() * 100 + 300) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 10 + 5) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+  <MovableEntity position="<?lua print(math.random() * 600 - 300)?>, <?lua print(math.random() * 600 - 300) ?>, <?lua print(math.random() * -100 - 300) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 10 + 5) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+
+  <MovableEntity position="<?lua print(math.random() * 600 - 300)?>, <?lua print(math.random() * 100 + 300) ?>, <?lua print(math.random() * 600 - 300) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 10 + 5) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+  <MovableEntity position="<?lua print(math.random() * 600 - 300)?>, <?lua print(math.random() * -100 - 300) ?>, <?lua print(math.random() * 600 - 300) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 10 + 5) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+
+  <MovableEntity position="<?lua print(math.random() * 100 + 300)?>, <?lua print(math.random() * 600 - 300) ?>, <?lua print(math.random() * 600 - 300) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 10 + 5) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+  <MovableEntity position="<?lua print(math.random() * -100 - 300)?>, <?lua print(math.random() * 600 - 300) ?>, <?lua print(math.random() * 600 - 300) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 10 + 5) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+<?lua
+end
+?>
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/princessaeryn.oxw
===================================================================
--- /code/branches/rocket2/data/levels/princessaeryn.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/princessaeryn.oxw	(revision 6952)
@@ -0,0 +1,279 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+?>
+
+<?lua
+    dofile("includes/CuboidSpaceStation.lua")
+?>
+
+<Level
+ name         = "The Tale of Princess Aeryn"
+ description  = "The Tale of Princess Aeryn"
+>
+
+    <NotificationQueue
+     name     = "notification"
+     position = "0.55, 0.05"
+     font     = "VeraMono"
+     textsize = 0.020
+     length   = 3
+     width    = 50
+    />
+
+    <Scene
+        ambientlight = "0.3, 0.3, 0.3"
+        skybox       = "Orxonox/skypanoramagen1"
+    >
+      <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+        <!-- Quest: -->
+        <GlobalQuest id="b80c2c60-e62c-4637-80f8-5aa18dc93b34">
+            <QuestDescription title="The Tale of Princess Aeryn" description="Princess Aeryn has been kidnapped by evil Mr. M and you were just a little too late to save her.\nYou have to find and save her from her captors." failMessage="You cannot fail, how did you?" completeMessage="You did it John. You're a hero. Princess Aeryn however will still not marry you." />
+            <subquests>
+                <GlobalQuest id="43766602-7e2f-4d24-976a-3f9de1474d5b">
+                    <QuestDescription title="Find Aeryn's S.H.O.E.S." description="Oh, the kidnappers must have been in a hurry because they overlooked princess Aeryns S.H.O.E.S. (Super Heavily Organized Escape Ship) hidden in the asteroid field over there.\nFind it and look there for clues to Princess Aeryns whereabouts." completeMessage="You did it, Looking through her stuff you find an odd looking device - Could this be the receiver of Princess Aeryns locator beacon? - But it must be broken, the screen remains blank." />
+                    <complete-effects>
+                        <AddQuest questId="50845552-c8af-4091-947c-76bd850b224e" />
+                    </complete-effects>
+                </GlobalQuest>
+                <GlobalQuest id="50845552-c8af-4091-947c-76bd850b224e">
+                    <QuestDescription title="Repair the receiver." description="There is a space station called 'Serenity Station' near here. An engineer called Nathan Stark who shoud be able to help you lives there." completeMessage="'Yeah Nathan lives here, he'll shurely help you.'\nAnd he does, apparenty the device was just low on batteries so you're now able to locate your beloved Princess Aeryn." />
+                    <hints>
+                        <QuestHint id="b9b10841-b045-4797-b1d3-cfce760e1de6">
+                            <QuestDescription title="The Katratzi Station" description="'We ain't buying!'\n'What do you want?'\n'No there lives no Nathan here.'\n'Fuck off.''" />
+                        </QuestHint>
+                        <QuestHint id="1ee785f8-b71d-4b51-b080-42cec5be8e3c">
+                            <QuestDescription title="The Pegasus Station" description="'Hello friend.'\n'How can we help you?'\n'A Mr. Stark you say? Sorry no man with such a name lives here.'" />
+                        </QuestHint>
+                    </hints>
+                    <complete-effects>
+                        <AddQuest questId="97628524-b243-492c-b7b6-498f325b21d4" />
+                    </complete-effects>
+                </GlobalQuest>
+                <GlobalQuest id="97628524-b243-492c-b7b6-498f325b21d4">
+                    <QuestDescription title="Follow the dots" description="Just follow the dots, they'll lead you right to her." completeMessage="You found Princess Aeryn. Her captors give up at the shere sight ou you." />
+                    <complete-effects>
+                        <CompleteQuest questId="b80c2c60-e62c-4637-80f8-5aa18dc93b34" />
+                    </complete-effects>
+                </GlobalQuest>
+            </subquests>
+        </GlobalQuest>
+
+        <!-- Create spaceship spawner: -->
+        <ParticleSpawner position="0,0,100" source="Orxonox/BigExplosion1part3" lifetime=2.0 loop=0 autostart=0>
+          <events>
+            <spawn>
+              <EventTrigger delay=1>
+                <events>
+                  <trigger>
+                    <SpawnPoint position="0,0,100" spawnclass=SpaceShip pawndesign=spaceshipassff />
+                  </trigger>
+                </events>
+              </EventTrigger>
+            </spawn>
+          </events>
+          <attached>
+            <QuestEffectBeacon position="0,0,0" times=1>
+                <effects>
+                    <AddQuest questId="b80c2c60-e62c-4637-80f8-5aa18dc93b34" />
+                    <AddQuest questId="43766602-7e2f-4d24-976a-3f9de1474d5b" />
+                </effects>
+                <events>
+                    <execute>
+                        <EventListener event=questbeacon1 />
+                    </execute>
+                </events>
+                <attached>
+                    <DistanceTrigger name=questbeacon1 position="0,0,0" distance=10 target="Pawn" />
+                </attached>
+            </QuestEffectBeacon>
+          </attached>
+        </ParticleSpawner>
+
+        <!-- Create world -->
+
+            <!-- Kidnapper flying away -->
+            <MovableEntity position="200,0,0" velocity="-140,0,-140" yaw=45>
+                <attached>
+                    <Model position="0,0,0" scale=4 yaw=180 pitch=-90 roll=-90 mesh="pirate.mesh" />
+                    <ParticleSpawner position="0,0,10" source="Orxonox/fire3" lifetime=2.0 loop=0 autostart=1 />
+                    <QuestEffectBeacon position="0,0,0" times=1 active=false name=trail >
+                        <effects>
+                            <CompleteQuest questId="b80c2c60-e62c-4637-80f8-5aa18dc93b34" />
+                        </effects>
+                        <events>
+                            <execute>
+                                <EventListener event=questbeacon7 />
+                            </execute>
+                        </events>
+                        <attached>
+                            <DistanceTrigger name=questbeacon7 position="0,0,0" distance=10 target="Pawn" />
+                        </attached>
+                    </QuestEffectBeacon>
+                </attached>
+            </MovableEntity>
+
+            <!-- Asteroid field -->
+            <StaticEntity position="-500,0,-3000">
+                <attached>
+                    <?lua
+                        for i = 1, 200
+                        do ?>
+                        <MovableEntity position="<?lua print(math.random() * 2000 - 1000)?>, <?lua print(math.random() * 2000 - 1000) ?>, <?lua print(math.random() * 2000 - 1000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.abs(math.random() * 30 -10)) ?>">
+                            <attached>
+                                <Model scale="<?lua print(math.random() * 50) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+                            </attached>
+                        </MovableEntity>
+                    <?lua
+                        end
+                    ?>
+                    <!-- S.H.O.E.S -->
+                    <StaticEntity position="-300,0,0">
+                        <attached>
+                            <Model position="0,0,0" scale=4 yaw=180 pitch=-90 roll=-90 mesh="assff.mesh" />
+                            <QuestEffectBeacon position="0,0,0" times=-1>
+                                <effects>
+                                    <CompleteQuest questId="43766602-7e2f-4d24-976a-3f9de1474d5b" />
+                                </effects>
+                                <events>
+                                    <execute>
+                                        <EventListener event=questbeacon2 />
+                                    </execute>
+                                </events>
+                                <attached>
+                                    <DistanceTrigger name=questbeacon2 position="0,0,0" distance=50 target="Pawn" />
+                                </attached>
+                            </QuestEffectBeacon>
+                        </attached>
+                    </StaticEntity>
+                </attached>
+            </StaticEntity>
+
+
+
+            <!-- Spacestations -->
+
+            <!-- Serenity Station -->
+            <StaticEntity scale=1 position="0,0,5000" yaw=30>
+                <attached>
+                    <?lua
+                        createSpaceStationPar(65461,2,1,2,1,2,1,100)
+                    ?>
+                    <QuestEffectBeacon position="0,450,0" times=1>
+                        <effects>
+                            <CompleteQuest questId="50845552-c8af-4091-947c-76bd850b224e" />
+                        </effects>
+                        <events>
+                            <execute>
+                                <EventListener event=questbeacon3 />
+                            </execute>
+                        </events>
+                        <attached>
+                            <Billboard position="0,0,0" colour="1.0,1.0,0" material="Examples/Flare" />
+                            <DistanceTrigger name=questbeacon3 position="0,0,0" distance=100 target="Pawn" />
+                        </attached>
+                    </QuestEffectBeacon>
+                </attached>
+            </StaticEntity>
+
+            <!-- Katratzi Station -->
+            <StaticEntity scale=1 position="0,5000,300" yaw=60>
+                <attached>
+                    <?lua
+                        createSpaceStationPar(9851,2,1,2,1,2,1,100)
+                    ?>
+                    <QuestEffectBeacon position="0,450,0" times=1>
+                        <effects>
+                            <AddQuestHint hintId="b9b10841-b045-4797-b1d3-cfce760e1de6" />
+                        </effects>
+                        <events>
+                            <execute>
+                                <EventListener event=questbeacon4 />
+                            </execute>
+                        </events>
+                        <attached>
+                            <Billboard position="0,0,0" colour="1.0,1.0,0" material="Examples/Flare" />
+                            <DistanceTrigger name=questbeacon4 position="0,0,0" distance=100 target="Pawn" />
+                        </attached>
+                    </QuestEffectBeacon>
+                </attached>
+            </StaticEntity>
+
+            <!-- Pegasus Station -->
+            <StaticEntity scale=1 position="-5000,100,1000" roll=30>
+                <attached>
+                    <?lua
+                        createSpaceStationPar(3574,2,1,2,1,2,1,100)
+                    ?>
+                    <QuestEffectBeacon position="200,450,0" times=1>
+                        <effects>
+                            <AddQuestHint hintId="1ee785f8-b71d-4b51-b080-42cec5be8e3c" />
+                        </effects>
+                        <events>
+                            <execute>
+                                <EventListener event=questbeacon5 />
+                            </execute>
+                        </events>
+                        <attached>
+                            <Billboard position="0,0,0" colour="1.0,1.0,0" material="Examples/Flare" />
+                            <DistanceTrigger name=questbeacon5 position="0,0,0" distance=100 target="Pawn" />
+                        </attached>
+                    </QuestEffectBeacon>
+                </attached>
+            </StaticEntity>
+
+            <!-- Trail -->
+            <EventDispatcher>
+                <targets>
+                    <EventTarget target=trail />
+                </targets>
+                <events>
+                    <visibility>
+                        <QuestListener questId="50845552-c8af-4091-947c-76bd850b224e" mode="complete" />
+                    </visibility>
+                    <activity>
+                        <QuestListener questId="50845552-c8af-4091-947c-76bd850b224e" mode="complete" />
+                    </activity>
+                </events>
+            </EventDispatcher>
+
+            <?lua
+                for i = 1, 25
+                do
+            ?>
+                <Billboard position="<?lua print(i*5000/25) ?>,<?lua print(450+i*(5000-450)/25) ?>,5000" colour="1.0,0,0" material="Examples/Flare" name=trail visible=false/>
+            <?lua
+                end
+            ?>
+
+            <!-- Hideout -->
+            <StaticEntity position="5000,5000,5000" >
+                <attached>
+                    <Model scale="100" mesh="ast2.mesh" shadow=false />
+                </attached>
+            </StaticEntity>
+
+            <StaticEntity position="5400,5400,5000" visible=false name=trail >
+                <attached>
+                    <Model position="0,0,0" scale=4 yaw=180 pitch=-90 roll=-90 mesh="pirate.mesh" visible=false name=trail />
+                    <QuestEffectBeacon position="0,0,0" times=1 active=false name=trail >
+                        <effects>
+                            <CompleteQuest questId="97628524-b243-492c-b7b6-498f325b21d4" />
+                        </effects>
+                        <events>
+                            <execute>
+                                <EventListener event=questbeacon6 />
+                            </execute>
+                        </events>
+                        <attached>
+                            <DistanceTrigger name=questbeacon6 position="0,0,0" distance=100 target="Pawn" />
+                        </attached>
+                    </QuestEffectBeacon>
+                </attached>
+            </StaticEntity>
+
+    </Scene>
+</Level>
+
Index: /code/branches/rocket2/data/levels/quest_test.oxw
===================================================================
--- /code/branches/rocket2/data/levels/quest_test.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/quest_test.oxw	(revision 6952)
@@ -0,0 +1,362 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_HXY_SL.oxt")
+  include("templates/spaceship_pirate.oxt")
+?>
+
+<Template name=spaceshipassffplayer defaults=0>
+  <SpaceShip template=spaceshipassff name=player>
+    <attached>
+    <DistanceTriggerBeacon name=Me/>
+    </attached>
+  </SpaceShip>
+</Template>
+
+<?lua
+    dofile("includes/CuboidSpaceStation.lua")
+?>	
+	
+<Level
+name="Dani's Testlevel"
+description="Erste Versuche mit den Quests"
+>
+
+    <NotificationQueue
+	     name     = "notification"
+	     position = "0.40, 0.05"
+	     font     = "VeraMono"
+	     textsize = 0.020
+	     length   = 3
+	     width    = 50
+    />
+
+    <Scene
+        ambientlight = "0.3, 0.3, 0.3"
+        skybox       = "Orxonox/skypanoramagen1"
+    >
+	      <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+	      
+	      
+	      <GlobalQuest id="dbd02b4c-ab7c-46fd-bdaf-fd4c19ac1551">
+		<QuestDescription title="Fight for freedom" 
+					description="Just a few hours ago, a group of pirates attacked an killed all your  squad members. Now you are very angry and you want to take revenge. Find the pirates and kill them!"
+					failmessage="You are a loser, now the whole universe will be controlled by the pirates!" 
+					completeMessage="Yeah, you did it! You,ve eliminated the enemies. But why attacked them the Humans here? For tousands of years, there was peace in this sun system.
+								You have to find out what happened exactly and why the pirates attacked..."/>
+			<subquests>
+				<GlobalQuest id="3159b4d4-bc86-4190-ba1d-4530668dfe31">
+					<QuestDescription title="There are more of them..." 
+					description="Now you can see it: There are more pirates... the pirates you killed were only a small part of the whole fleet. You recieved a message from your Headquarter: The pirates have stolen
+							a very important memory stick with secret infos (military locations etc.), the holy stick. You must get it back! Otherwise the humans are in great danger..." 
+					failmessage="" 
+					completeMessage="Unbelievable, you annihilated all pirates and got the stolen memory stick. 
+								But wait... this isn't the memory stick you looked for, this stick is one from a pirate... anyway, it's helpful: There is a map saved on it, which leads you to a pirate - base. Perhaps you'll find more 
+								about their plans there..."/>
+				</GlobalQuest>
+				<GlobalQuest id="8d8ed3a6-74a6-4491-9172-26155cff151d">
+					<QuestDescription title="Find the Base"
+					description="Now you are in possession of the map and it should be easy to find the base. Because you are a Member of an elite-fight-squad, your ship has been pimped before you started your mission.
+						They installed a very modern navigation system, which leads you precisely to your desired destination. Use it to find the pirate - base."
+					failmessage=""
+					completeMessage="The navigation system worked very well and now you should be near a pirate -base." />
+					<hints>
+						<QuestHint id="965101b3-26ce-4fcf-bc71-17cc2a87d2e9">
+						<QuestDescription title="3 Ways?" 
+						description="The different ways leads you to the possible positions where the base could be. The problem is that the map is encrypted and your on board system is not 
+								able to decrypt it exactly. Therefore you have to try 3 possible ways...Tha base is Huge, but it could be that it's invisible when ou are in longer distance (some Big Ships
+								have a special shield aroud them which make them invisible at longer range)."/>
+						</QuestHint>
+						<QuestHint id="9930a598-98bc-4ff8-8cc0-31311a6ccaaa">
+						<QuestDescription title=":(" description="Here isn't the base you look for... try another way."/>
+						</QuestHint>
+					</hints>
+				</GlobalQuest>
+				<GlobalQuest id="8a62408b-c47b-4e02-bd3d-06bb9ec0b363">
+					<QuestDescription title="The Base" 
+					description="Yeah, you found the Base... now let's check if there is the important holy stick..." 
+					failmessage="" 
+					completeMessage="There it is, the Holy stick. Yes, you're right. It looks like a rocket because there are so many rockets in the universe, that it's nearly impossible to find the holy stick between them.
+								Anyway, the pirates found the stick... another part which is confusing. Why did they know where the holy stick is? Perpaps they know more about the humans than you think."/>
+				</GlobalQuest>
+				<GlobalQuest id="85380d05-b791-45d1-82e9-01f0bc930367">
+					<QuestDescription title="Find out more about the pirates" 
+					description= "Now, the Holy stick is back in your possession. Your new mission is "
+					failmessage="" 
+					completeMessage=""/>
+				</GlobalQuest>
+			</subquests>
+			<hints>
+				<QuestHint id="2b85f32c-2433-4f1a-bdd4-f24d20c9403c">
+					<QuestDescription title="Useful to know" description="Pirates like to hide themselves behind asteroids."/>
+				</QuestHint>
+			</hints>
+			<fail-effects>
+			</fail-effects>
+			<complete-effects>
+			</complete-effects>
+		</GlobalQuest>
+		
+	      <ParticleSpawner position="0,0,0" source="Orxonox/BigExplosion1part3" lifetime=2.0 loop=0 autostart=0>
+		  <events>
+		    <spawn>
+		      <EventTrigger delay=1>
+			<events>
+			  <trigger>
+			    <SpawnPoint position="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassffplayer />
+			  </trigger>
+			</events>
+		      </EventTrigger>
+		    </spawn>
+		  </events>
+		  <attached>
+		    <QuestEffectBeacon position="0,0,0" times=1>
+			<effects>
+			    <AddQuest questId="dbd02b4c-ab7c-46fd-bdaf-fd4c19ac1551" />
+			</effects>
+			<events>
+			    <execute>
+				<EventListener event=questbeacon1 />
+			    </execute>
+			</events>
+			<attached>
+			    <DistanceTrigger name=questbeacon1 position="0,0,0" distance=100 target=DistanceTriggerBeacon targetname=Me/>
+			</attached>
+		    </QuestEffectBeacon>
+		  </attached>
+		</ParticleSpawner>
+		
+		
+		
+		<!-- AddSubQuest1 (Questbeacon2)-->
+		<QuestEffectBeacon position="<?lua print(math.random()*100-500)?>,<?lua print(math.random()*100-500)?>,<?lua print(math.random()*200-2000)?>" times=1>
+					<attached>
+						<Billboard position="0,0,0" scale=3 colour="1.0,1.0,0" material="Examples/Flare" />
+						<DistanceTrigger name=questbeacon2  position="0,0,0" distance=200 target="Pawn" />
+					</attached>
+					<effects>
+						<AddQuest questId="3159b4d4-bc86-4190-ba1d-4530668dfe31" />
+					</effects>
+					<events>
+						<execute>
+							<EventListener event=questbeacon2 />
+						</execute>
+					</events>
+			    </QuestEffectBeacon>
+			    
+		<!-- hint (Questbeacon3)-->
+		<QuestEffectBeacon position="0,0,0" times=1>
+					<attached>
+						<DistanceTrigger name=questbeacon3  position="0,0,0" distance=300 target=DistanceTriggerBeacon targetname=Me delay="10" />
+					</attached>
+					<effects>
+						<AddQuestHint hintId="2b85f32c-2433-4f1a-bdd4-f24d20c9403c" />
+					</effects>
+					<events>
+						<execute>
+							<EventListener event=questbeacon3 />
+						</execute>
+					</events>
+			    </QuestEffectBeacon>	
+			    
+			    
+		<!-- finish SubQuest (Questbeacon4)-->
+		<QuestEffectBeacon position="600,300,-6000" times=1>
+					<attached>
+						<Billboard position="0,0,0" scale=3 colour="0,1.0,0" material="Examples/Flare" />
+						<DistanceTrigger name=questbeacon4  position="0,0,0" distance=200 target=DistanceTriggerBeacon targetname=Me />
+					</attached>
+		
+					<effects>
+						<CompleteQuest questId="3159b4d4-bc86-4190-ba1d-4530668dfe31" />
+						<AddQuest questId="8d8ed3a6-74a6-4491-9172-26155cff151d" />
+						<AddQuestHint hintId="965101b3-26ce-4fcf-bc71-17cc2a87d2e9" />
+					</effects>
+					<events>
+						<execute>
+							<EventListener event=questbeacon4 />
+						</execute>
+					</events>
+			    </QuestEffectBeacon>
+			    
+			    
+		<!-- Navihint 1(Questbeacon5)-->
+		<QuestEffectBeacon position="7600,300,-8000" times=1>
+					<attached>
+						<DistanceTrigger name=questbeacon5  position="0,0,0" distance=300 target=DistanceTriggerBeacon targetname=Me />
+					</attached>
+					<effects>
+						<AddQuestHint hintId="9930a598-98bc-4ff8-8cc0-31311a6ccaaa" />
+					</effects>
+					<events>
+						<execute>
+							<EventListener event=questbeacon5 />
+						</execute>
+					</events>
+			    </QuestEffectBeacon>	
+			    
+		<!-- Navi2(Questbeacon6)-->
+		<QuestEffectBeacon position="4600,5300,-11000" times=1>
+					<attached>
+						<DistanceTrigger name=questbeacon6  position="0,0,0" distance=300 target=DistanceTriggerBeacon targetname=Me />
+					</attached>
+					<effects>
+						<CompleteQuest questId="8d8ed3a6-74a6-4491-9172-26155cff151d" />
+						<AddQuest questId="8a62408b-c47b-4e02-bd3d-06bb9ec0b363" />
+						
+					</effects>
+					<events>
+						<execute>
+							<EventListener event=questbeacon6 />
+						</execute>
+					</events>
+			    </QuestEffectBeacon>
+			    
+		<!--Navigation System-->			    
+	<EventDispatcher>
+                <targets>
+                    <EventTarget target=Navi />
+                </targets>
+                <events>
+                    <visibility>
+                        <QuestListener questId="3159b4d4-bc86-4190-ba1d-4530668dfe31" mode="complete" />
+                    </visibility>
+                    <activity>
+                        <QuestListener questId="3159b4d4-bc86-4190-ba1d-4530668dfe31" mode="complete" />
+                    </activity>
+                </events>
+            </EventDispatcher>
+
+            <?lua
+                for i = 0, 30
+                do
+            ?>
+		<Billboard position="<?lua print(i*1000/30+600) ?>,<?lua print(i*2000/30+300) ?>,<?lua print(-i*4000/30-6000) ?>" colour="1.0,0,0" scale=1 material="Examples/Flare" name=Navi visible=false/><!--endpos:1600,2300,-10000-->
+		<Billboard position="<?lua print(i*7000/30+600) ?>,<?lua print(i*0/30+300) ?>,<?lua print(-i*2000/30-6000) ?>" colour="0,1.0,0" scale=1 material="Examples/Flare" name=Navi visible=false/><!--endpos:7600,300,-8000-->
+		<Billboard position="<?lua print(i*4000/30+600) ?>,<?lua print(i*5000/30+300) ?>,<?lua print(-i*5000/30-6000) ?>" colour="0,0,1.0" scale=1 material="Examples/Flare" name=Navi visible=false/><!--endpos:4600,5300,-11000-->
+            <?lua
+                end
+            ?>
+		
+		
+	<StaticEntity scale=1 position="4650,5350,-11050" name=base visible=true active=true yaw=60>
+                <attached>
+                    <?lua
+                        createSpaceStationPar(9851,2,1,2,1,2,1,100)
+                    ?>
+                </attached>
+            </StaticEntity>
+	    
+	<ParticleSpawner position="4650,5350,-11050" source="Orxonox/explosion1" name=base visible=false active=false loop=0/>
+	<Model position="4800,5785,-10725" scale=3 mesh="Rocket.mesh" visible=true active=true name=base />
+	<EventDispatcher>
+                <targets>
+                    <EventTarget target=base />
+                </targets>
+                <events>
+                    <visibility>
+		  <EventTrigger invert=true>
+		    <events>
+		      <trigger>
+		        <QuestListener questId="dbd02b4c-ab7c-46fd-bdaf-fd4c19ac1551" mode="start" />
+		      </trigger>
+		    </events>
+		  </EventTrigger>
+                    </visibility>
+                    <activity>
+	            <EventTrigger invert=true>
+		    <events>
+		      <trigger>
+                             <QuestListener questId="dbd02b4c-ab7c-46fd-bdaf-fd4c19ac1551" mode="start" />
+		      </trigger>
+		    </events>
+		  </EventTrigger>
+                    </activity>
+                </events>
+            </EventDispatcher>
+
+	
+	<EventDispatcher>
+                <targets>
+                    <EventTarget target=base />
+                </targets>
+                <events>
+                    <visibility>
+                        <QuestListener questId="8d8ed3a6-74a6-4491-9172-26155cff151d" mode="complete" />
+                    </visibility>
+                    <activity>
+                        <QuestListener questId="8d8ed3a6-74a6-4491-9172-26155cff151d" mode="complete" />
+                    </activity>
+                </events>
+            </EventDispatcher>
+
+	
+	
+	
+		<!-- pirates -->
+		<?lua
+		for i = 1,1, 1
+		do
+		?>
+		    <SpaceShip position="<?lua print(math.random()*100)?>,<?lua print(math.random()*100)?>,<?lua print(math.random()*100-2000)?>">
+		      <templates>
+			<Template link=spaceshippirate />
+		      </templates>
+		      <controller>
+			<WaypointPatrolController alertnessradius=1000 team=0 active=true>
+			  <waypoints>
+			    <StaticEntity position="0,<?lua print(math.random()*50)?> ,<?lua print(i*50 -2000) ?>" />
+			  </waypoints>
+			</WaypointPatrolController>
+		      </controller>
+		      <attached>
+		      </attached>
+		    </SpaceShip>
+		<?lua
+		end
+		?>
+		
+		<?lua
+		for i = 1,2, 1
+		do
+		?>
+		    <SpaceShip position="600,300,-6000">
+		      <templates>
+			<Template link=spaceshippirate />
+		      </templates>
+		      <controller>
+			<WaypointPatrolController alertnessradius=1000 team=0 active=true>
+			  <waypoints>
+			    <StaticEntity position="600,300,-6000" />
+			  </waypoints>
+			</WaypointPatrolController>
+		      </controller>
+		      <attached>
+		      </attached>
+		    </SpaceShip>
+		<?lua
+		end
+		?>
+		
+		
+	<!-- Asteroid field-->
+            <StaticEntity position="-400,2000,-7000">
+                <attached>
+                    <?lua
+                        for i = 1, 180
+                        do ?>
+                        <MovableEntity position="<?lua print(math.random() * 10000 -5000)?>, <?lua print(math.random() * 10000-5000) ?>, <?lua print(math.random() * 10000 -7000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.abs(math.random() * 30 -10)) ?>">
+                            <attached>
+                                <Model scale="<?lua print(math.random() * 100) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+                            </attached>
+                        </MovableEntity>
+                    <?lua
+                        end
+                    ?>
+		    </attached>
+		</StaticEntity>
+		
+		
+	</Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/questsystem2.oxw
===================================================================
--- /code/branches/rocket2/data/levels/questsystem2.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/questsystem2.oxw	(revision 6952)
@@ -0,0 +1,244 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+?>
+
+<Level
+ name         = "QuestSystem2"
+ description  = "Test level for Questsystem-Features"
+
+>
+
+  <NotificationQueue
+     name     = "notification"
+     position = "0.55, 0.05"
+     font     = "VeraMono"
+     textsize = 0.020
+     length   = 3
+     width    = 50
+    />
+
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/skypanoramagen1"
+  >
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+        <GlobalQuest id="b80c2c60-e62c-4637-80f8-5aa18dc93b34">
+            <QuestDescription title="The Main QUest" description="This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! This is the main quest hooray. Solve it! " failMessage="You fail. Looser." completeMessage="You Win." />
+            <hints>
+                <QuestHint id="022a859d-08dd-4eac-a085-c28c29c06d48">
+                    <QuestDescription title="The super Hint." description="Be proud of yourself." />
+                </QuestHint>
+                <QuestHint id="aa19e785-f110-4f3a-abc4-b5e76556e71">
+                    <QuestDescription title="The super Hint.2" description="Be proud of yourself.2" />
+                </QuestHint>
+                <QuestHint id="93d0bdcb-9ce1-4f96-bc69-8d04e659fb31">
+                    <QuestDescription title="The super Hint.3" description="Be proud of yourself.3" />
+                </QuestHint>
+            </hints>
+            <subquests>
+                <GlobalQuest id="e17f5245-f95b-44a8-b6cf-402274435ed4">
+                    <QuestDescription title="The Main QUest2" description="This is the main quest hooray. Solve it!" failMessage="You fail. Looser." completeMessage="You Win." />
+                    <subquests>
+                        <GlobalQuest id="cff6c1ae-fae7-4e55-8af0-56c939911679">
+                            <QuestDescription title="The Main QUest2.1" description="This is the main quest hooray. Solve it!" failMessage="You fail. Looser." completeMessage="You Win." />
+                        </GlobalQuest>
+                        <GlobalQuest id="c04016a3-1e43-4797-885f-75ababa22e07">
+                            <QuestDescription title="The Main QUest2.2" description="This is the main quest hooray. Solve it!" failMessage="You fail. Looser." completeMessage="You Win." />
+                        </GlobalQuest>
+                    </subquests>
+                </GlobalQuest>
+                <GlobalQuest id="71becf91-1456-4763-a2c9-5d575fbcf087">
+                    <QuestDescription title="The Main QUest3" description="This is the main quest hooray. Solve it!" failMessage="You fail. Looser." completeMessage="You Win." />
+                </GlobalQuest>
+                <GlobalQuest id="ca3198a2-ea9d-48d0-b07a-e30f9aa8e241">
+                    <QuestDescription title="The Main QUest4" description="This is the main quest hooray. Solve it!" failMessage="You fail. Looser." completeMessage="You Win." />
+                </GlobalQuest>
+            </subquests>
+        </GlobalQuest>
+        <GlobalQuest id="d7b9526e-b369-43ca-a377-163007cd0577">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="41f729ed-892d-499a-a977-fd3ade3232c2">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="efc6af59-2a49-4220-8486-dce649350d85">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="c0bb8864-78a4-4984-b33e-19ca703cf022">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="7b1d7fce-b5f2-45e8-9e42-7fda78410892">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="ae4287e4-7a65-4fc2-912b-aebd033fcfb7">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="9312ee34-650b-494b-bf12-12394f94d248">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="d0b610db-aa09-4590-a7a8-1fad9be72bd9">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="3106c2d5-3f90-42fb-a164-bde993b13e20">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="a7a82d75-ebc5-487a-8f20-33fa79bc911d">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="32b2da07-882f-4e8b-8c32-ea548c11d91d">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="8945258e-56ea-45d3-b873-e237e2709866">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="9108702d-f3cd-400f-9c13-b2743886dddb">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="03a4bf9f-57ba-4676-97c8-6197086eff16">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="89311e30-2938-4bcb-ba93-23ca3037cdda">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="5ca628bb-cb62-4c54-9e0e-18139a8c5f02">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="e73aed96-02ca-452a-bdd0-61a3a549cf61">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="694cf67f-3579-41cf-ba52-11d4b311327c">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+        <GlobalQuest id="540ab003-ea02-4556-b95a-053ce191ea7f">
+            <QuestDescription title="Mup" description="" />
+        </GlobalQuest>
+
+<SpawnPoint position="0,0,100" lookat="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+
+        <QuestEffectBeacon position="0,0,100" times=-1>
+            <effects>
+                <AddQuest questId="b80c2c60-e62c-4637-80f8-5aa18dc93b34" />
+                <AddQuest questId="e17f5245-f95b-44a8-b6cf-402274435ed4" />
+                <AddQuest questId="cff6c1ae-fae7-4e55-8af0-56c939911679" />
+                <AddQuest questId="c04016a3-1e43-4797-885f-75ababa22e07" />
+                <AddQuest questId="71becf91-1456-4763-a2c9-5d575fbcf087" />
+                <AddQuest questId="ca3198a2-ea9d-48d0-b07a-e30f9aa8e241" />
+                <AddQuest questId="d7b9526e-b369-43ca-a377-163007cd0577" />
+                <AddQuest questId="41f729ed-892d-499a-a977-fd3ade3232c2" />
+                <AddQuest questId="efc6af59-2a49-4220-8486-dce649350d85" />
+                <AddQuest questId="c0bb8864-78a4-4984-b33e-19ca703cf022" />
+                <AddQuest questId="7b1d7fce-b5f2-45e8-9e42-7fda78410892" />
+                <AddQuest questId="ae4287e4-7a65-4fc2-912b-aebd033fcfb7" />
+                <AddQuest questId="9312ee34-650b-494b-bf12-12394f94d248" />
+                <AddQuest questId="d0b610db-aa09-4590-a7a8-1fad9be72bd9" />
+                <AddQuest questId="3106c2d5-3f90-42fb-a164-bde993b13e20" />
+                <AddQuest questId="a7a82d75-ebc5-487a-8f20-33fa79bc911d" />
+                <AddQuest questId="32b2da07-882f-4e8b-8c32-ea548c11d91d" />
+                <AddQuest questId="8945258e-56ea-45d3-b873-e237e2709866" />
+                <AddQuest questId="9108702d-f3cd-400f-9c13-b2743886dddb" />
+                <AddQuest questId="03a4bf9f-57ba-4676-97c8-6197086eff16" />
+                <AddQuest questId="89311e30-2938-4bcb-ba93-23ca3037cdda" />
+                <AddQuest questId="5ca628bb-cb62-4c54-9e0e-18139a8c5f02" />
+                <AddQuest questId="e73aed96-02ca-452a-bdd0-61a3a549cf61" />
+                <AddQuest questId="694cf67f-3579-41cf-ba52-11d4b311327c" />
+                <AddQuest questId="540ab003-ea02-4556-b95a-053ce191ea7f" />
+            </effects>
+            <events>
+                <execute>
+                    <EventListener event=qebdt1 />
+                </execute>
+            </events>
+            <attached>
+                <Billboard position="0,0,0" colour="1.0,1.0,1.0" material="Examples/Flare" />
+                <DistanceTrigger name=qebdt1 position="0,0,0" distance=10 target="ControllableEntity" />
+            </attached>
+        </QuestEffectBeacon>
+
+        <QuestEffectBeacon position="-100,0,0" times=-1>
+            <effects>
+                <FailQuest questId="b80c2c60-e62c-4637-80f8-5aa18dc93b34" />
+            </effects>
+            <events>
+                <execute>
+                    <EventListener event=qebdt2 />
+                </execute>
+            </events>
+            <attached>
+                <Billboard position="0,0,0" colour="1.0,0,0" material="Examples/Flare" />
+                <DistanceTrigger name=qebdt2 position="0,0,0" distance=10 target="ControllableEntity" />
+            </attached>
+        </QuestEffectBeacon>
+
+        <QuestEffectBeacon position="100,0,0" times=-1>
+            <effects>
+                <CompleteQuest questId="b80c2c60-e62c-4637-80f8-5aa18dc93b34" />
+            </effects>
+            <events>
+                <execute>
+                    <EventListener event=qebdt3 />
+                </execute>
+            </events>
+            <attached>
+                <Billboard position="0,0,0" colour="0,1.0,0" material="Examples/Flare" />
+                <DistanceTrigger name=qebdt3 position="0,0,0" distance=10 target="ControllableEntity" />
+            </attached>
+        </QuestEffectBeacon>
+
+        <QuestEffectBeacon position="0,100,0" times=-1>
+            <effects>
+                <AddQuestHint hintId="022a859d-08dd-4eac-a085-c28c29c06d48" />
+                <AddQuestHint hintId="aa19e785-f110-4f3a-abc4-b5e76556e71" />
+                <AddQuestHint hintId="93d0bdcb-9ce1-4f96-bc69-8d04e659fb31" />
+            </effects>
+            <events>
+                <execute>
+                    <EventListener event=qebdt4 />
+                </execute>
+            </events>
+            <attached>
+                <Billboard position="0,0,0" colour="0,0,1.0" material="Examples/Flare" />
+                <DistanceTrigger name=qebdt4 position="0,0,0" distance=10 target="ControllableEntity" />
+            </attached>
+        </QuestEffectBeacon>
+
+        <ParticleEmitter name=firecenter position="0,0,0" source="Orxonox/fire3" active=false>
+            <events>
+                <activity>
+                    <QuestListener questId="b80c2c60-e62c-4637-80f8-5aa18dc93b34" mode="complete" />
+                </activity>
+            </events>
+        </ParticleEmitter>
+
+<?lua
+max = 20
+for i = 1, max, 1
+do
+    x = math.sin(i/max*6)*40000
+    y = math.cos(i/max*6)*40000
+    z = i*100
+    ?>
+<?lua
+for k = 1, 25, 1
+do
+j = math.random()
+?>
+
+    <MovableEntity position="<?lua print(x + math.random() * 10000-2500) ?>,<?lua print(y + math.random() * 5000-2500) ?>,<?lua print(z + math.random() * 1000-500) ?>" <?lua if i == 5 then ?> collisionType=dynamic linearDamping=0.8 angularDamping=0 mass=<?lua print(j * 50) ?> <?lua end ?> scale=<?lua print(j * 5) ?> rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+      <attached>
+        <Model position="0,0,0" scale=<?lua print(j * 10) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+      </attached>
+      <?lua if i == 5 then ?><collisionShapes>
+        <SphereCollisionShape radius="<?lua print(j * 70) ?>" />
+      </collisionShapes> <?lua end ?>
+    </MovableEntity>
+<?lua
+end
+?>
+<?lua end ?>
+    <Planet position="0,0,0" scale=10000 pitch=-90 mesh="iceplanet.mesh" atmosphere="atmosphere1" rotationaxis="1,1,0" rotationrate="1" atmospheresize=224.0f imagesize=1024.0f />
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/sound.oxw
===================================================================
--- /code/branches/rocket2/data/levels/sound.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/sound.oxw	(revision 6952)
@@ -0,0 +1,48 @@
+<?lua
+  include("stats.oxo")
+  include("hudtemplates3.oxo")
+?>
+
+<?lua
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_pirate.oxt")
+?>
+
+<Level
+ name         = "Sample"
+ description  = "Just a few tests"
+>
+  <Scene
+    ambientlight = "0.8, 0.8, 0.8"
+    skybox       = "Orxonox/Starbox"
+  >
+
+  <AmbientSound ambientSource="Earth.ogg" looping="true" playOnLoad="true" />
+  <AmbientSound ambientSource="Mars.ogg" looping="true">
+    <events>
+        <activity>
+            <DistanceTrigger position="400,0,0" distance=200 target="Camera">
+                <attached>
+                    <ParticleSpawner position="0,0,0" source="Orxonox/fire3" lifetime=0 loop=0 autostart=1 />
+                </attached>
+            </DistanceTrigger>
+        </activity>
+    </events>
+  </AmbientSound>
+  <AmbientSound ambientSource="Jupiter.ogg" looping="true">
+    <events>
+        <activity>
+            <DistanceTrigger position="400,150,0" distance=200 target="Camera">
+                <attached>
+                    <ParticleSpawner position="0,0,0" source="Orxonox/fire3" lifetime=0 loop=0 autostart=1 />
+                </attached>
+            </DistanceTrigger>
+        </activity>
+    </events>
+  </AmbientSound>
+
+
+  <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+  <SpawnPoint position="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/teambasematchlevel.oxw
===================================================================
--- /code/branches/rocket2/data/levels/teambasematchlevel.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/teambasematchlevel.oxw	(revision 6952)
@@ -0,0 +1,220 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("teambasematchhud.oxo")
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_pirate.oxt")
+  include("templates/lodinformation.oxt")
+?>
+
+<Level
+ name         = "Presentation"
+ description  = "A simple testlevel"
+ gametype     = TeamBaseMatch
+>
+  <templates>
+    <Template link=lodtemplate_default />
+  </templates>
+
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/skypanoramagen1"
+  >
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+    <TeamSpawnPoint team=0 position=" 900,0,0" lookat="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+    <TeamSpawnPoint team=1 position="-900,0,0" lookat="0,0,0" spawnclass=SpaceShip pawndesign=spaceshippirate />
+
+    <TeamBaseMatchBase
+     name              = "base 1"
+     position          = "1200, 0, 0"
+     pitch = -90
+
+     health            = 1000
+     maxhealth         = 1000
+     initialhealth     = 1000
+
+     collisionType     = "dynamic"
+     mass              = 10000
+     linearDamping     = 0.9
+     angularDamping    = 0.99999
+    >
+      <attached>
+        <Model scale=10 mesh="DuBall1.mesh" position = "-100,0,0"/>
+        <Model scale=10 mesh="DuBall2.mesh" position = "100,0,0"/>
+        <Billboard scale=7 material="Examples/Flare" colour="0.5,0.5,0.5" position = "-100,0,0"/>
+        <Billboard scale=7 material="Examples/Flare" colour="0.5,0.5,0.5" position = "100,0,0"/>
+<?lua
+for i = 1, 10, 1
+do ?>
+        <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <events><spawn><EventListener event="base 1" /></spawn></events>
+        </ParticleSpawner>
+<?lua
+end
+?>
+      </attached>
+      <collisionShapes>
+        <SphereCollisionShape radius="80"            position = "-100,0,0" />
+        <SphereCollisionShape radius="120"           position = "100,0,0" />
+        <BoxCollisionShape    halfExtents="90,25,45" position = "-155,0,40" />
+      </collisionShapes>
+    </TeamBaseMatchBase>
+
+
+    <TeamBaseMatchBase
+     name              = "base 2"
+     position          = "-1200, 0, 0"
+     pitch = -90
+
+     health            = 1000
+     maxhealth         = 1000
+     initialhealth     = 1000
+
+     collisionType     = "dynamic"
+     mass              = 10000
+     linearDamping     = 0.9
+     angularDamping    = 0.99999
+    >
+      <attached>
+        <Model scale=10 mesh="DuBall1.mesh" position = "-100,0,0"/>
+        <Model scale=10 mesh="DuBall2.mesh" position = "100,0,0"/>
+        <Billboard scale=7 material="Examples/Flare" colour="0.5,0.5,0.5" position = "-100,0,0"/>
+        <Billboard scale=7 material="Examples/Flare" colour="0.5,0.5,0.5" position = "100,0,0"/>
+<?lua
+for i = 1, 10, 1
+do ?>
+        <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <events><spawn><EventListener event="base 2" /></spawn></events>
+        </ParticleSpawner>
+<?lua
+end
+?>
+      </attached>
+      <collisionShapes>
+        <SphereCollisionShape radius="80"            position = "-100,0,0" />
+        <SphereCollisionShape radius="120"           position = "100,0,0" />
+        <BoxCollisionShape    halfExtents="90,25,45" position = "-155,0,40" />
+      </collisionShapes>
+    </TeamBaseMatchBase>
+
+
+    <TeamBaseMatchBase
+     name              = "base 3"
+     position          = "0, 0, 1200"
+     pitch = -90
+
+     health            = 1000
+     maxhealth         = 1000
+     initialhealth     = 1000
+
+     collisionType     = "dynamic"
+     mass              = 10000
+     linearDamping     = 0.9
+     angularDamping    = 0.99999
+    >
+      <attached>
+        <Model scale=10 mesh="DuBall1.mesh" position = "-100,0,0"/>
+        <Model scale=10 mesh="DuBall2.mesh" position = "100,0,0"/>
+        <Billboard scale=7 material="Examples/Flare" colour="0.5,0.5,0.5" position = "-100,0,0"/>
+        <Billboard scale=7 material="Examples/Flare" colour="0.5,0.5,0.5" position = "100,0,0"/>
+<?lua
+for i = 1, 10, 1
+do ?>
+        <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <events><spawn><EventListener event="base 3" /></spawn></events>
+        </ParticleSpawner>
+<?lua
+end
+?>
+      </attached>
+      <collisionShapes>
+        <SphereCollisionShape radius="80"            position = "-100,0,0" />
+        <SphereCollisionShape radius="120"           position = "100,0,0" />
+        <BoxCollisionShape    halfExtents="90,25,45" position = "-155,0,40" />
+      </collisionShapes>
+    </TeamBaseMatchBase>
+
+    <TeamBaseMatchBase
+     name              = "base 4"
+     position          = "0, 0, -1200"
+
+     health            = 1000
+     maxhealth         = 1000
+     initialhealth     = 1000
+     pitch = -90
+
+     collisionType     = "dynamic"
+     mass              = 10000
+     linearDamping     = 0.9
+     angularDamping    = 0.99999
+    >
+      <attached>
+        <Model scale=10 mesh="DuBall1.mesh" position = "-100,0,0"/>
+        <Model scale=10 mesh="DuBall2.mesh" position = "100,0,0"/>
+        <Billboard scale=7 material="Examples/Flare" colour="0.5,0.5,0.5" position = "-100,0,0"/>
+        <Billboard scale=7 material="Examples/Flare" colour="0.5,0.5,0.5" position = "100,0,0"/>
+<?lua
+for i = 1, 10, 1
+do ?>
+        <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <events><spawn><EventListener event="base 4" /></spawn></events>
+        </ParticleSpawner>
+<?lua
+end
+?>
+      </attached>
+      <collisionShapes>
+        <SphereCollisionShape radius="80"            position = "-100,0,0" />
+        <SphereCollisionShape radius="120"           position = "100,0,0" />
+        <BoxCollisionShape    halfExtents="90,25,45" position = "-155,0,40" />
+      </collisionShapes>
+    </TeamBaseMatchBase>
+
+
+    <TeamBaseMatchBase
+     name              = "base 5"
+     position          = "0, 0, 0"
+     pitch = -90
+
+     health            = 1000
+     maxhealth         = 1000
+     initialhealth     = 1000
+
+     collisionType     = "dynamic"
+     mass              = 10000
+     linearDamping     = 0.9
+     angularDamping    = 0.99999
+    >
+      <attached>
+        <Model scale=10 mesh="DuBall1.mesh" position = "-100,0,0"/>
+        <Model scale=10 mesh="DuBall2.mesh" position = "100,0,0"/>
+        <Billboard scale=7 material="Examples/Flare" colour="0.5,0.5,0.5" position = "-100,0,0"/>
+        <Billboard scale=7 material="Examples/Flare" colour="0.5,0.5,0.5" position = "100,0,0"/>
+<?lua
+for i = 1, 10, 1
+do ?>
+        <ParticleSpawner position="<?lua print(math.random() * 400 - 200) ?>,<?lua print(math.random() * 200 - 100) ?>,<?lua print(math.random() * 200 - 100) ?>" startdelay=<?lua print(math.random()) ?> source="Orxonox/BigExplosion1part1" lifetime=2.0 loop=0 autostart=0>
+          <events><spawn><EventListener event="base 5" /></spawn></events>
+        </ParticleSpawner>
+<?lua
+end
+?>
+      </attached>
+      <collisionShapes>
+        <SphereCollisionShape radius="80"            position = "-100,0,0" />
+        <SphereCollisionShape radius="120"           position = "100,0,0" />
+        <BoxCollisionShape    halfExtents="90,25,45" position = "-155,0,40" />
+      </collisionShapes>
+    </TeamBaseMatchBase>
+
+
+
+    <!--Model position="0,0,0" scale=8 mesh="ast1.mesh" />
+    <StaticEntity position="0,0,0" collisionType=static>
+      <collisionShapes>
+        <SphereCollisionShape radius="20" />
+      </collisionShapes>
+    </StaticEntity-->
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/teamdeathmatch.oxw
===================================================================
--- /code/branches/rocket2/data/levels/teamdeathmatch.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/teamdeathmatch.oxw	(revision 6952)
@@ -0,0 +1,81 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_H2.oxt")
+  include("templates/spaceship_pirate.oxt")
+  include("templates/lodinformation.oxt")
+?>
+
+<Level
+ name         = "Waypoints"
+ description  = "Testing waypoings for AI controlled spaceships."
+ gametype     = TeamDeathmatch
+>
+  <templates>
+    <Template link=lodtemplate_default />
+  </templates>
+
+  <Scene
+   ambientlight = "0.7, 0.6, 0.6"
+   skybox       = "Orxonox/skypanoramagen1"
+  >
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+    <TeamSpawnPoint team=0 position="0,  0,0" direction="1,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+    <TeamSpawnPoint team=0 position="0, 50,0" direction="1,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+    <TeamSpawnPoint team=0 position="0,100,0" direction="1,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+    <TeamSpawnPoint team=0 position="0,150,0" direction="1,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+
+    <TeamSpawnPoint team=1 position="2000,  0,0" direction="-1,0,0" spawnclass=SpaceShip pawndesign=spaceshippirate />
+    <TeamSpawnPoint team=1 position="2000, 50,0" direction="-1,0,0" spawnclass=SpaceShip pawndesign=spaceshippirate />
+    <TeamSpawnPoint team=1 position="2000,100,0" direction="-1,0,0" spawnclass=SpaceShip pawndesign=spaceshippirate />
+    <TeamSpawnPoint team=1 position="2000,150,0" direction="-1,0,0" spawnclass=SpaceShip pawndesign=spaceshippirate />
+
+    <TeamSpawnPoint team=2 position="1000,  0,1500" direction="0,0,-1" spawnclass=SpaceShip pawndesign=spaceshipHtwo />
+    <TeamSpawnPoint team=2 position="1000, 50,1500" direction="0,0,-1" spawnclass=SpaceShip pawndesign=spaceshipHtwo />
+    <TeamSpawnPoint team=2 position="1000,100,1500" direction="0,0,-1" spawnclass=SpaceShip pawndesign=spaceshipHtwo />
+    <TeamSpawnPoint team=2 position="1000,150,1500" direction="0,0,-1" spawnclass=SpaceShip pawndesign=spaceshipHtwo />
+
+
+<?lua
+for i = 1, 70, 1
+do ?>
+  <MovableEntity position="<?lua print(math.random() * 6000 - 3000)?>, <?lua print(math.random() * 6000 - 3000) ?>, <?lua print(math.random() * 1000 + 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 50 + 20) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+  <MovableEntity position="<?lua print(math.random() * 6000 - 3000)?>, <?lua print(math.random() * 6000 - 3000) ?>, <?lua print(math.random() * -1000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 50 + 20) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+
+  <MovableEntity position="<?lua print(math.random() * 6000 - 3000)?>, <?lua print(math.random() * 1000 + 3000) ?>, <?lua print(math.random() * 6000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 50 + 20) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+  <MovableEntity position="<?lua print(math.random() * 6000 - 3000)?>, <?lua print(math.random() * -1000 - 3000) ?>, <?lua print(math.random() * 6000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 50 + 20) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+
+  <MovableEntity position="<?lua print(math.random() * 1000 + 3000)?>, <?lua print(math.random() * 6000 - 3000) ?>, <?lua print(math.random() * 6000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 50 + 20) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+  <MovableEntity position="<?lua print(math.random() * -1000 - 3000)?>, <?lua print(math.random() * 6000 - 3000) ?>, <?lua print(math.random() * 6000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 50 + 20) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+<?lua
+end
+?>
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/templates/lodinformation.oxt
===================================================================
--- /code/branches/rocket2/data/levels/templates/lodinformation.oxt	(revision 6952)
+++ /code/branches/rocket2/data/levels/templates/lodinformation.oxt	(revision 6952)
@@ -0,0 +1,8 @@
+<Template name=lodtemplate_default defaults=false>
+  <Level>
+	<lodinformation>
+	  <MeshLodInformation mesh=Carrier.mesh lodQuality=1.8 />
+	  <MeshLodInformation mesh=assff.mesh lodQuality=3 />
+	</lodinformation>
+  </Level>
+</Template>
Index: /code/branches/rocket2/data/levels/templates/pickup_representation_templates.oxt
===================================================================
--- /code/branches/rocket2/data/levels/templates/pickup_representation_templates.oxt	(revision 6952)
+++ /code/branches/rocket2/data/levels/templates/pickup_representation_templates.oxt	(revision 6952)
@@ -0,0 +1,347 @@
+
+<!-- Health pickups: -->
+
+<Template name=smallhealthpickupRepresentation>
+    <PickupRepresentation>
+        <spawner-representation>
+            <StaticEntity>
+                <attached>
+                    <Billboard position="0,0,0" colour="0.50,0.90,0.25" material="Sphere2" scale=0.1>
+                        <attached>
+                            <Billboard position="0,0,0" colour="0.36,0.81,0.10" material="Cross" scale=0.3 />
+                        </attached>
+                    </Billboard>
+                </attached>
+            </StaticEntity>
+        </spawner-representation>
+    </PickupRepresentation>
+</Template>
+
+<Template name=smallhealthpickup>
+  <HealthPickup
+    health = 10
+    healthType = "limited"
+    activationType = "immediate"
+    durationType = "once"
+  />
+</Template>
+
+<Template name=mediumhealthpickupRepresentation>
+    <PickupRepresentation>
+        <spawner-representation>
+            <StaticEntity>
+                <attached>
+                    <Billboard position="0,0,0" colour="0.50,0.90,0.25" material="Sphere2" scale=0.1>
+                        <attached>
+                            <Billboard position="0,0,0" colour="0.36,0.81,0.10" material="Cross" scale=0.5 />
+                        </attached>
+                    </Billboard>
+                </attached>
+            </StaticEntity>
+        </spawner-representation>
+    </PickupRepresentation>
+</Template>
+
+<Template name=mediumhealthpickup>
+  <HealthPickup
+    health = 50
+    healthType = "limited"
+    activationType = "immediate"
+    durationType = "once"
+  />
+</Template>
+
+<Template name=hugehealthpickupRepresentation>
+    <PickupRepresentation>
+        <spawner-representation>
+            <StaticEntity>
+                <attached>
+                    <Billboard position="0,0,0" colour="0.50,0.90,0.25" material="Sphere2" scale=0.1>
+                        <attached>
+                            <Billboard position="0,0,0" colour="0.36,0.81,0.10" material="Cross" scale=0.7 />
+                        </attached>
+                    </Billboard>
+                </attached>
+            </StaticEntity>
+        </spawner-representation>
+    </PickupRepresentation>
+</Template>
+
+<Template name=hugehealthpickup>
+  <HealthPickup
+    health = 100
+    healthType = "limited"
+    activationType = "immediate"
+    durationType = "once"
+  />
+</Template>
+
+<Template name=crazyhealthpickupRepresentation>
+    <PickupRepresentation>
+        <spawner-representation>
+            <StaticEntity>
+                <attached>
+                    <Billboard position="0,0,0" colour="0.50,0.90,0.25" material="Sphere2" scale=0.1>
+                        <attached>
+                            <Billboard position="0,0,0" colour="0.36,0.81,0.10" material="Cross" scale=1.2 />
+                        </attached>
+                    </Billboard>
+                </attached>
+            </StaticEntity>
+        </spawner-representation>
+    </PickupRepresentation>
+</Template>
+
+<Template name=crazyhealthpickup>
+  <HealthPickup
+    health = 1000
+    healthType = "permanent"
+    activationType = "immediate"
+    durationType = "once"
+  />
+</Template>
+
+<!-- Meta pickups: -->
+
+<Template name=usepickupRepresentation>
+    <PickupRepresentation>
+        <spawner-representation>
+            <StaticEntity>
+                <attached>
+                    <Billboard position="0,0,0" colour="0.60,0.97,0.23" material="Sphere2" scale=0.1>
+                        <attached>
+                            <Billboard position="0,0,0" colour="0.40,0.81,0.10" material="Arrow" scale=0.65 />
+                        </attached>
+                    </Billboard>
+                </attached>
+            </StaticEntity>
+        </spawner-representation>
+    </PickupRepresentation>
+</Template>
+
+<Template name=droppickupRepresentation>
+    <PickupRepresentation>
+        <spawner-representation>
+            <StaticEntity>
+                <attached>
+                    <Billboard position="0,0,0" colour="0.95,0.10,0.05" material="Sphere2" scale=0.1>
+                        <attached>
+                            <Billboard position="0,0,0" colour="0.95,0.20,0.10" material="Arrow" scale=0.65 />
+                        </attached>
+                    </Billboard>
+                </attached>
+            </StaticEntity>
+        </spawner-representation>
+    </PickupRepresentation>
+</Template>
+
+<!-- Speed pickups -->
+
+<Template name=smallspeedpickupRepresentation>
+    <PickupRepresentation>
+        <spawner-representation>
+            <StaticEntity>
+                <attached>
+                    <Billboard position="0,0,0" colour="0.99,0.96,0.52" material="Sphere2" scale=0.1>
+                        <attached>
+                            <Billboard position="0,0,0" colour="0.98,0.94,0.22" material="3arrowsup" scale=0.3 />
+                        </attached>
+                    </Billboard>
+                </attached>
+            </StaticEntity>
+        </spawner-representation>
+    </PickupRepresentation>
+</Template>
+
+<Template name=smallspeedpickup>
+  <SpeedPickup
+    duration = 10.0
+    speedAdd = 0.0
+    SpeedMultiply = 10.0
+    activationType = "immediate"
+    durationType = "once"
+  />
+</Template>
+
+<Template name=mediumspeedpickupRepresentation>
+    <PickupRepresentation>
+        <spawner-representation>
+            <StaticEntity>
+                <attached>
+                    <Billboard position="0,0,0" colour="0.99,0.96,0.52" material="Sphere2" scale=0.1>
+                        <attached>
+                            <Billboard position="0,0,0" colour="0.98,0.94,0.22" material="3arrowsup" scale=0.5 />
+                        </attached>
+                    </Billboard>
+                </attached>
+            </StaticEntity>
+        </spawner-representation>
+    </PickupRepresentation>
+</Template>
+
+<Template name=mediumspeedpickup>
+  <SpeedPickup
+    duration = 10.0
+    speedAdd = 0.0
+    SpeedMultiply = 25.0
+    activationType = "immediate"
+    durationType = "once"
+  />
+</Template>
+
+<Template name=hugespeedpickupRepresentation>
+    <PickupRepresentation>
+        <spawner-representation>
+            <StaticEntity>
+                <attached>
+                    <Billboard position="0,0,0" colour="0.99,0.96,0.52" material="Sphere2" scale=0.1>
+                        <attached>
+                            <Billboard position="0,0,0" colour="0.98,0.94,0.22" material="3arrowsup" scale=0.7 />
+                        </attached>
+                    </Billboard>
+                </attached>
+            </StaticEntity>
+        </spawner-representation>
+    </PickupRepresentation>
+</Template>
+
+<Template name=hugespeedpickup>
+  <SpeedPickup
+    duration = 10.0
+    speedAdd = 0.0
+    SpeedMultiply = 50.0
+    activationType = "immediate"
+    durationType = "once"
+  />
+</Template>
+
+<Template name=smalljumppickupRepresentation>
+    <PickupRepresentation>
+        <spawner-representation>
+            <StaticEntity>
+                <attached>
+                    <Billboard position="0,0,0" colour="0.99,0.96,0.52" material="Sphere2" scale=0.1>
+                        <attached>
+                            <Billboard position="0,0,0" colour="1,0,0" material="3arrowsup" scale=0.3 />
+                        </attached>
+                    </Billboard>
+                </attached>
+            </StaticEntity>
+        </spawner-representation>
+    </PickupRepresentation>
+</Template>
+
+<Template name=smalljumppickup>
+  <SpeedPickup
+    duration = 0.7
+    speedAdd = 5000.0
+    SpeedMultiply = 1.0
+    activationType = "immediate"
+    durationType = "once"
+  />
+</Template>
+
+<!-- Invisible pickups -->
+
+<Template name=smallinvisiblepickupRepresentation>
+    <PickupRepresentation>
+        <spawner-representation>
+            <StaticEntity>
+                <attached>
+                    <Billboard position="0,0,0" colour="0.22,0.32,0.86" material="Sphere2" scale=0.1>
+                        <attached>
+                            <Billboard position="0,0,0" colour="0.06,0.14,0.63" material="Eye" scale=0.5 />
+                        </attached>
+                    </Billboard>
+                </attached>
+            </StaticEntity>
+        </spawner-representation>
+    </PickupRepresentation>
+</Template>
+
+<Template name=smallinvisiblepickup>
+  <InvisiblePickup 
+    duration = 5.0
+    activaionType = "immediate"
+    durationType = "once"
+  />
+</Template>
+
+<Template name=mediuminvisiblepickupRepresentation>
+    <PickupRepresentation>
+        <spawner-representation>
+            <StaticEntity>
+                <attached>
+                    <Billboard position="0,0,0" colour="0.22,0.32,0.86" material="Sphere2" scale=0.1>
+                        <attached>
+                            <Billboard position="0,0,0" colour="0.06,0.14,0.63" material="Eye" scale=0.7 />
+                        </attached>
+                    </Billboard>
+                </attached>
+            </StaticEntity>
+        </spawner-representation>
+    </PickupRepresentation>
+</Template>
+
+<Template name=mediuminvisiblepickup>
+  <InvisiblePickup 
+    duration = 10.0
+    activaionType = "immediate"
+    durationType = "once"
+  />
+</Template>
+
+<Template name=hugeinvisiblepickupRepresentation>
+    <PickupRepresentation>
+        <spawner-representation>
+            <StaticEntity>
+                <attached>
+                    <Billboard position="0,0,0" colour="0.22,0.32,0.86" material="Sphere2" scale=0.1>
+                        <attached>
+                            <Billboard position="0,0,0" colour="0.06,0.14,0.63" material="Eye" scale=0.9 />
+                        </attached>
+                    </Billboard>
+                </attached>
+            </StaticEntity>
+        </spawner-representation>
+    </PickupRepresentation>
+</Template>
+
+<Template name=hugeinvisiblepickup>
+  <InvisiblePickup 
+    duration = 20.0
+    activaionType = "immediate"
+    durationType = "once"
+  />
+</Template>
+
+<!-- Pickup Collection pickups -->
+
+<Template name=triplehealthspeedinvisibilitypickupRepresentation>
+    <PickupRepresentation>
+        <spawner-representation>
+            <StaticEntity>
+                <attached>
+                    <Billboard position="0,0,0" colour="0.95,0.85,0.27" material="Sphere2" scale=0.1>
+                        <attached>
+                            <Billboard position="0,20,0" colour="0.36,0.81,0.10" material="Cross" scale=0.25 />
+                            <Billboard position="-20,-10,0" colour="0.98,0.94,0.22" material="3arrowsup" scale=0.25 />
+                            <Billboard position="20,-10,0" colour="0.06,0.14,0.63" material="Eye" scale=0.35 />
+                        </attached>
+                    </Billboard>
+                </attached>
+            </StaticEntity>
+        </spawner-representation>
+    </PickupRepresentation>
+</Template>
+
+<Template name=triplehealthspeedinvisibilitypickup>
+    <PickupCollection>
+        <pickupables>
+            <HealthPickup template=mediumhealthpickup />
+            <SpeedPickup template=mediumspeedpickup />
+            <InvisiblePickup template=mediuminvisiblepickup />
+        </pickupables>
+    </PickupCollection>
+</Template>
+    
Index: /code/branches/rocket2/data/levels/templates/spaceship_H2.oxt
===================================================================
--- /code/branches/rocket2/data/levels/templates/spaceship_H2.oxt	(revision 6952)
+++ /code/branches/rocket2/data/levels/templates/spaceship_H2.oxt	(revision 6952)
@@ -0,0 +1,87 @@
+<Template name=spaceshipHtwo>
+  <SpaceShip
+   hudtemplate            = spaceshiphud
+   camerapositiontemplate = spaceshipHtwocameras
+   engine                 = spaceshipHtwoengine
+   spawnparticlesource    = "Orxonox/fairytwirl"
+   spawnparticleduration  = 3
+   explosionchunks        = 6
+
+   health            = 100
+   maxhealth         = 200
+   initialhealth     = 100
+
+   primaryThrust     = 100;
+   auxilaryThrust    = 30;
+   rotationThrust    = 25;
+
+   collisionType     = "dynamic"
+   mass              = 100
+   linearDamping     = 0.7
+   angularDamping    = 0.9999999
+  >
+
+<?lua
+  include("includes/weaponsettings_H2.oxi")
+?>
+
+    <attached>
+      <Model position="0,0,0" yaw=90 pitch=-90 roll=0 scale3D="3,0.833,0.833" mesh="h2_green.mesh" />
+      <BlinkingBillboard position=" 11.7,4.0,8.5" material="Examples/Flare" colour="1.0, 0.5, 0.3" amplitude=0.1 frequency=0.5 quadratic=1 />
+      <BlinkingBillboard position="-11.7,4.0,8.5" material="Examples/Flare" colour="0.5, 1.0, 0.3" amplitude=0.1 frequency=0.5 phase=180 quadratic=1 />
+    </attached>
+    <collisionShapes>
+      <BoxCollisionShape position="0,0,0"      halfExtents="10, 3, 5" />
+      <BoxCollisionShape position="13,-1.3,0"  halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="-13,-1.3,0" halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="0,0,7"      halfExtents="3, 2, 2" />
+      <BoxCollisionShape position="0,0.1,-11"  halfExtents="2.2, 1.8, 6" />
+      <BoxCollisionShape position="0,0.1,-19"  halfExtents="1.4, 1, 2" />
+    </collisionShapes>
+
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipHtwocameras defaults=0>
+  <SpaceShip>
+    <camerapositions>
+      <CameraPosition position="0,10, 40" drag=true mouselook=true />
+      <CameraPosition position="0,20, 80" drag=true mouselook=true />
+      <CameraPosition position="0,30,120" drag=true mouselook=true />
+    </camerapositions>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipHtwoengine baseclass=MultiStateEngine>
+  <MultiStateEngine
+   boostfactor    = 2
+
+   speedfront     = 150
+   speedback      =  50
+   speedleftright =  50
+   speedupdown    =  50
+
+   accelerationfront     = 500
+   accelerationbrake     = 500
+   accelerationback      =  125
+   accelerationleftright =  125
+   accelerationupdown    =  125
+  >
+    <active>
+      <FadingBillboard mainstate=activity active=false scale=0.05 position=" 0.0, 2.0, 12.0" colour="0.0, 0.65, 0.0, 0.5" material="Examples/FlareZwei_1" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.05 position=" 3.8, 7.5, 11.0" colour="1.0, 1.00, 1.0, 1.0" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.05 position="-3.8, 7.5, 11.0" colour="1.0, 1.00, 1.0, 1.0" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.05 position=" 3.5, 0.0,-10.8" colour="1.0, 1.00, 1.0, 1.0" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.05 position="-3.5, 0.0,-10.8" colour="1.0, 1.00, 1.0, 1.0" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+    </active>
+    <forward>
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position=" 7.06, 1.66, 11.6" colour="0, 0.65, 0, 1.0" width=15 length=1500 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position="-7.26, 1.66, 11.6" colour="0, 0.65, 0, 1.0" width=15 length=1500 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+    </forward>
+    <boost>
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position=" 7.06, 1.66, 11.6" colour="0.5, 0.85, 0.5, 0.7" width=40 length=1000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position="-7.26, 1.66, 11.6" colour="0.5, 0.85, 0.5, 0.7" width=40 length=1000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+    </boost>
+  </MultiStateEngine>
+</Template>
+
Index: /code/branches/rocket2/data/levels/templates/spaceship_HXY.oxt
===================================================================
--- /code/branches/rocket2/data/levels/templates/spaceship_HXY.oxt	(revision 6952)
+++ /code/branches/rocket2/data/levels/templates/spaceship_HXY.oxt	(revision 6952)
@@ -0,0 +1,94 @@
+<Template name=spaceshipHXY>
+  <SpaceShip
+   hudtemplate            = spaceshiphud
+   camerapositiontemplate = spaceshipHXYcameras
+   engine                 = spaceshipHXYengine
+   spawnparticlesource    = "Orxonox/fairytwirl"
+   spawnparticleduration  = 3
+   explosionchunks        = 6
+
+   health            = 100
+   maxhealth         = 200
+   initialhealth     = 100
+
+   primaryThrust     = 100;
+   auxilaryThrust    = 30;
+   rotationThrust    = 25;
+
+   collisionType     = "dynamic"
+   mass              = 100
+   linearDamping     = 0.7
+   angularDamping    = 0.9999999
+  >
+    <attached>
+      <Model position="0,0,0" yaw=180 pitch=-90 roll=0 scale=4 mesh="HXY.mesh" />
+    </attached>
+    <collisionShapes>
+      <BoxCollisionShape position="0,0,0"      halfExtents="10, 3, 5" />
+      <BoxCollisionShape position="13,-1.3,0"  halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="-13,-1.3,0" halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="0,0,7"      halfExtents="3, 2, 2" />
+      <BoxCollisionShape position="0,0.1,-11"  halfExtents="2.2, 1.8, 6" />
+      <BoxCollisionShape position="0,0.1,-19"  halfExtents="1.4, 1, 2" />
+    </collisionShapes>
+
+<?lua
+  include("includes/weaponsettings_HXY.oxi")
+?>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipHXYcameras defaults=0>
+  <SpaceShip>
+    <camerapositions>
+      <CameraPosition position="0,8, 60" drag=true mouselook=true />
+      <CameraPosition position="0,16, 120" drag=true mouselook=true />
+      <CameraPosition position="0,24,180" drag=true mouselook=true />
+      <CameraPosition position="0,60,10" pitch="-80" drag=true mouselook=true />
+    </camerapositions>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipHXYengine baseclass=MultiStateEngine>
+  <MultiStateEngine
+   boostfactor    = 6
+
+   speedfront     = 150
+   speedback      =  50
+   speedleftright =  50
+   speedupdown    =  50
+
+   defEngineSndNormal = "sounds/Engine_low.ogg"
+   defEngineSndBoost = "sounds/Engine_high.ogg"
+
+   accelerationfront     = 500
+   accelerationbrake     = 500
+   accelerationback      =  125
+   accelerationleftright =  125
+   accelerationupdown    =  125
+  >
+    <EffectContainer condition="idle">
+      <WorldSound mainstate="activity" source="sounds/Engine_idle.ogg" looping=1 active=false/>
+    </EffectContainer>
+    <EffectContainer condition="not idle">
+
+    </EffectContainer>
+    <EffectContainer condition="normal or brake">
+
+    </EffectContainer>
+    <EffectContainer condition="normal or boost">
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position=" 2, 0, 20" colour="1, 0.7, 0.1, 1.0" width=10 length=1500 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position="-2, 0, 20" colour="1, 0.7, 0.1, 1.0" width=10 length=1500 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+    </EffectContainer>
+    <EffectContainer condition="boost">
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position=" 2, 0, 20" colour="1, 0.7, 0.1, 0.7" width=25 length=1000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position="-2, 0, 20" colour="1, 0.7, 0.1, 0.7" width=25 length=1000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+    </EffectContainer>
+    <EffectContainer condition="brake">
+      <FadingBillboard mainstate=activity active=false scale=0.3 position=" 2, 0, 20" colour="0.5, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.3 position="-2, 0, 20" colour="0.5, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.15 position=" 2, 0, 20" colour="1.0, 0.0, 0.0, 1.0" material="Flares/backlightflare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.15 position="-2, 0, 20" colour="1.0, 0.0, 0.0, 1.0" material="Flares/backlightflare" turnontime=0.5 turnofftime=0.5 />
+    </EffectContainer>
+  </MultiStateEngine>
+</Template>
Index: /code/branches/rocket2/data/levels/templates/spaceship_HXY_SL.oxt
===================================================================
--- /code/branches/rocket2/data/levels/templates/spaceship_HXY_SL.oxt	(revision 6952)
+++ /code/branches/rocket2/data/levels/templates/spaceship_HXY_SL.oxt	(revision 6952)
@@ -0,0 +1,90 @@
+<Template name=spaceshipHXYSL>
+  <SpaceShip
+   hudtemplate            = spaceshiphud
+   camerapositiontemplate = spaceshipHXYcameras
+   engine                 = spaceshipHXYengine
+   spawnparticlesource    = "Orxonox/fairytwirl"
+   spawnparticleduration  = 3
+   explosionchunks        = 6
+
+   health            = 100
+   maxhealth         = 200
+   initialhealth     = 100
+
+   primaryThrust     = 100;
+   auxilaryThrust    = 30;
+   rotationThrust    = 25;
+
+   collisionType     = "dynamic"
+   mass              = 100
+   linearDamping     = 0.7
+   angularDamping    = 0.9999999
+  >
+    <attached>
+      <Model position="0,0,0" yaw=180 pitch=-90 roll=0 scale=4 mesh="HXY.mesh" />
+    </attached>
+    <collisionShapes>
+      <BoxCollisionShape position="0,0,0"      halfExtents="10, 3, 5" />
+      <BoxCollisionShape position="13,-1.3,0"  halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="-13,-1.3,0" halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="0,0,7"      halfExtents="3, 2, 2" />
+      <BoxCollisionShape position="0,0.1,-11"  halfExtents="2.2, 1.8, 6" />
+      <BoxCollisionShape position="0,0.1,-19"  halfExtents="1.4, 1, 2" />
+    </collisionShapes>
+
+<?lua
+  include("includes/weaponsettings_HXY.oxi")
+?>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipHXYcameras defaults=0>
+  <SpaceShip>
+    <camerapositions>
+      <CameraPosition position="0,8, 60" drag=true mouselook=true />
+      <CameraPosition position="0,16, 120" drag=true mouselook=true />
+      <CameraPosition position="0,24,180" drag=true mouselook=true />
+      <CameraPosition position="0,60,10" pitch="-80" drag=true mouselook=true />
+    </camerapositions>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipHXYengine baseclass=MultiStateEngine>
+  <MultiStateEngine
+   boostfactor    = 6
+
+   speedfront     = 150
+   speedback      =  50
+   speedleftright =  50
+   speedupdown    =  50
+
+   accelerationfront     = 500
+   accelerationbrake     = 500
+   accelerationback      =  125
+   accelerationleftright =  125
+   accelerationupdown    =  125
+  >
+    <EffectContainer condition="idle">
+    </EffectContainer>
+    <EffectContainer condition="not idle">
+
+    </EffectContainer>
+    <EffectContainer condition="normal or brake">
+
+    </EffectContainer>
+    <EffectContainer condition="normal or boost">
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position=" 2, 0, 20" colour="1, 0.7, 0.1, 1.0" width=10 length=1500 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position="-2, 0, 20" colour="1, 0.7, 0.1, 1.0" width=10 length=1500 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+    </EffectContainer>
+    <EffectContainer condition="boost">
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position=" 2, 0, 20" colour="1, 0.7, 0.1, 0.7" width=25 length=1000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position="-2, 0, 20" colour="1, 0.7, 0.1, 0.7" width=25 length=1000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+    </EffectContainer>
+    <EffectContainer condition="brake">
+      <FadingBillboard mainstate=activity active=false scale=0.3 position=" 2, 0, 20" colour="0.5, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.3 position="-2, 0, 20" colour="0.5, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.15 position=" 2, 0, 20" colour="1.0, 0.0, 0.0, 1.0" material="Flares/backlightflare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.15 position="-2, 0, 20" colour="1.0, 0.0, 0.0, 1.0" material="Flares/backlightflare" turnontime=0.5 turnofftime=0.5 />
+    </EffectContainer>
+  </MultiStateEngine>
+</Template>
Index: /code/branches/rocket2/data/levels/templates/spaceship_Transporter.oxt
===================================================================
--- /code/branches/rocket2/data/levels/templates/spaceship_Transporter.oxt	(revision 6952)
+++ /code/branches/rocket2/data/levels/templates/spaceship_Transporter.oxt	(revision 6952)
@@ -0,0 +1,94 @@
+<Template name=spaceshipTransporter>
+  <SpaceShip
+   hudtemplate            = spaceshiphud
+   camerapositiontemplate = spaceshipTransportercameras
+   engine                 = spaceshipTransporterengine
+   spawnparticlesource    = "Orxonox/fairytwirl"
+   spawnparticleduration  = 3
+   explosionchunks        = 6
+
+   health            = 1000
+   maxhealth         = 1500
+   initialhealth     = 1000
+
+   primaryThrust     = 50;
+   auxilaryThrust    = 10;
+   rotationThrust    = 15;
+
+   collisionType     = "dynamic"
+   mass              = 1000
+   linearDamping     = 0.7
+   angularDamping    = 0.9999999
+  >
+    <attached>
+      <Model position="0,0,0" yaw=0 pitch=0 roll=0 scale=10 mesh="Transporter.mesh" />
+    </attached>
+    <collisionShapes>
+      <BoxCollisionShape position="0,0,0"      halfExtents="10, 3, 5" />
+      <BoxCollisionShape position="13,-1.3,0"  halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="-13,-1.3,0" halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="0,0,7"      halfExtents="3, 2, 2" />
+      <BoxCollisionShape position="0,0.1,-11"  halfExtents="2.2, 1.8, 6" />
+      <BoxCollisionShape position="0,0.1,-19"  halfExtents="1.4, 1, 2" />
+    </collisionShapes>
+
+<?lua
+  include("includes/weaponsettings_Transporter.oxi")
+?>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipTransportercameras defaults=0>
+  <SpaceShip>
+    <camerapositions>
+      <CameraPosition position="0,90,350" drag=true mouselook=true />
+      <CameraPosition position="0,150, 400" drag=true mouselook=true />
+      <CameraPosition position="0,200,550" drag=true mouselook=true />
+      <CameraPosition position="0,120,200" pitch="-80" drag=true mouselook=true />
+    </camerapositions>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipTransporterengine baseclass=MultiStateEngine>
+  <MultiStateEngine
+   boostfactor    = 2
+
+   speedfront     = 50
+   speedback      =  10
+   speedleftright =  10
+   speedupdown    =  10
+
+   defEngineSndNormal = "sounds/Engine_low.ogg"
+   defEngineSndBoost = "sounds/Engine_high.ogg"
+
+   accelerationfront     = 20
+   accelerationbrake     = 20
+   accelerationback      = 10
+   accelerationleftright =  10
+   accelerationupdown    =  10
+  >
+    <EffectContainer condition="idle">
+      <WorldSound mainstate="activity" source="sounds/Engine_idle.ogg" looping=1 active=false/>
+    </EffectContainer>
+    <EffectContainer condition="not idle">
+
+    </EffectContainer>
+    <EffectContainer condition="normal or brake">
+
+    </EffectContainer>
+    <EffectContainer condition="normal or boost">
+      <Backlight mainstate=activity active=false scale=2 name=bltest position=" 22, -10, 87" colour="1, 0.7, 0.1, 1.0" width=10 length=3000 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+      <Backlight mainstate=activity active=false scale=2 name=bltest position="-22, -10, 87" colour="1, 0.7, 0.1, 1.0" width=10 length=3000 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+    </EffectContainer>
+    <EffectContainer condition="boost">
+      <Backlight mainstate=activity active=false scale=3 name=bltest position=" 22, -10, 87" colour="1, 0.7, 0.1, 0.7" width=25 length=2000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+      <Backlight mainstate=activity active=false scale=3 name=bltest position="-22, -10, 87" colour="1, 0.7, 0.1, 0.7" width=25 length=2000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+    </EffectContainer>
+    <EffectContainer condition="brake">
+      <FadingBillboard mainstate=activity active=false scale=2 position=" 22, -10, 87" colour="0.5, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=2 position="-22, -10, 87" colour="0.5, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=1 position="22, -10, 87" colour="1.0, 0.0, 0.0, 1.0" material="Flares/backlightflare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=1 position="-22, -10, 87" colour="1.0, 0.0, 0.0, 1.0" material="Flares/backlightflare" turnontime=0.5 turnofftime=0.5 />
+    </EffectContainer>
+  </MultiStateEngine>
+</Template>
Index: /code/branches/rocket2/data/levels/templates/spaceship_Transporter_SL.oxt
===================================================================
--- /code/branches/rocket2/data/levels/templates/spaceship_Transporter_SL.oxt	(revision 6952)
+++ /code/branches/rocket2/data/levels/templates/spaceship_Transporter_SL.oxt	(revision 6952)
@@ -0,0 +1,91 @@
+<Template name=spaceshipTransporterSL>
+  <SpaceShip
+   hudtemplate            = spaceshiphud
+   camerapositiontemplate = spaceshipTransportercameras
+   engine                 = spaceshipTransporterengine
+   spawnparticlesource    = "Orxonox/fairytwirl"
+   spawnparticleduration  = 3
+   explosionchunks        = 6
+
+   health            = 1000
+   maxhealth         = 1500
+   initialhealth     = 1000
+
+   primaryThrust     = 50;
+   auxilaryThrust    = 10;
+   rotationThrust    = 15;
+
+   collisionType     = "dynamic"
+   mass              = 1000
+   linearDamping     = 0.7
+   angularDamping    = 0.9999999
+  >
+    <attached>
+      <Model position="0,0,0" yaw=0 pitch=0 roll=0 scale=10 mesh="Transporter.mesh" />
+    </attached>
+    <collisionShapes>
+      <BoxCollisionShape position="0,0,0"      halfExtents="10, 3, 5" />
+      <BoxCollisionShape position="13,-1.3,0"  halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="-13,-1.3,0" halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="0,0,7"      halfExtents="3, 2, 2" />
+      <BoxCollisionShape position="0,0.1,-11"  halfExtents="2.2, 1.8, 6" />
+      <BoxCollisionShape position="0,0.1,-19"  halfExtents="1.4, 1, 2" />
+    </collisionShapes>
+
+<?lua
+  include("includes/weaponsettings_Transporter.oxi")
+?>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipTransportercameras defaults=0>
+  <SpaceShip>
+    <camerapositions>
+      <CameraPosition position="0,90,350" drag=true mouselook=true />
+      <CameraPosition position="0,150, 400" drag=true mouselook=true />
+      <CameraPosition position="0,200,550" drag=true mouselook=true />
+      <CameraPosition position="0,120,200" pitch="-80" drag=true mouselook=true />
+    </camerapositions>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipTransporterengine baseclass=MultiStateEngine>
+  <MultiStateEngine
+   boostfactor    = 2
+
+   speedfront     = 50
+   speedback      =  10
+   speedleftright =  10
+   speedupdown    =  10
+
+
+   accelerationfront     = 20
+   accelerationbrake     = 20
+   accelerationback      = 10
+   accelerationleftright =  10
+   accelerationupdown    =  10
+  >
+    <EffectContainer condition="idle">
+    </EffectContainer>
+    <EffectContainer condition="not idle">
+
+    </EffectContainer>
+    <EffectContainer condition="normal or brake">
+
+    </EffectContainer>
+    <EffectContainer condition="normal or boost">
+      <Backlight mainstate=activity active=false scale=2 name=bltest position=" 22, -10, 87" colour="1, 0.7, 0.1, 1.0" width=10 length=3000 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+      <Backlight mainstate=activity active=false scale=2 name=bltest position="-22, -10, 87" colour="1, 0.7, 0.1, 1.0" width=10 length=3000 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+    </EffectContainer>
+    <EffectContainer condition="boost">
+      <Backlight mainstate=activity active=false scale=3 name=bltest position=" 22, -10, 87" colour="1, 0.7, 0.1, 0.7" width=25 length=2000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+      <Backlight mainstate=activity active=false scale=3 name=bltest position="-22, -10, 87" colour="1, 0.7, 0.1, 0.7" width=25 length=2000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+    </EffectContainer>
+    <EffectContainer condition="brake">
+      <FadingBillboard mainstate=activity active=false scale=2 position=" 22, -10, 87" colour="0.5, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=2 position="-22, -10, 87" colour="0.5, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=1 position="22, -10, 87" colour="1.0, 0.0, 0.0, 1.0" material="Flares/backlightflare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=1 position="-22, -10, 87" colour="1.0, 0.0, 0.0, 1.0" material="Flares/backlightflare" turnontime=0.5 turnofftime=0.5 />
+    </EffectContainer>
+  </MultiStateEngine>
+</Template>
Index: /code/branches/rocket2/data/levels/templates/spaceship_assff.oxt
===================================================================
--- /code/branches/rocket2/data/levels/templates/spaceship_assff.oxt	(revision 6952)
+++ /code/branches/rocket2/data/levels/templates/spaceship_assff.oxt	(revision 6952)
@@ -0,0 +1,141 @@
+<Template name=spaceshipassff>
+  <SpaceShip
+   hudtemplate            = spaceshiphud
+   camerapositiontemplate = spaceshipassffcameras
+   engine                 = spaceshipassffengine
+   spawnparticlesource    = "Orxonox/fairytwirl"
+   spawnparticleduration  = 3
+   explosionchunks        = 6
+
+   health            = 100
+   maxhealth         = 200
+   initialhealth     = 100
+
+   primaryThrust     = 100;
+   auxilaryThrust    = 30;
+   rotationThrust    = 25;
+
+   collisionType     = "dynamic"
+   mass              = 100
+   linearDamping     = 0.7
+   angularDamping    = 0.9999999
+  >
+    <attached>
+      <Model position="0,0,0" yaw=90 pitch=-90 roll=0 scale=4 mesh="assff.mesh" />
+      <BlinkingBillboard position="17,-1.5,0" material="Examples/Flare" colour="1.0, 0.5, 0.3" amplitude=0.1 frequency=0.5 quadratic=1 />
+      <BlinkingBillboard position="-17,-1.5,0" material="Examples/Flare" colour="0.5, 1.0, 0.3" amplitude=0.1 frequency=0.5 phase=180 quadratic=1 />
+    </attached>
+    <collisionShapes>
+      <BoxCollisionShape position="0,0,0"      halfExtents="10, 3, 5" />
+      <BoxCollisionShape position="13,-1.3,0"  halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="-13,-1.3,0" halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="0,0,7"      halfExtents="3, 2, 2" />
+      <BoxCollisionShape position="0,0.1,-11"  halfExtents="2.2, 1.8, 6" />
+      <BoxCollisionShape position="0,0.1,-19"  halfExtents="1.4, 1, 2" />
+    </collisionShapes>
+<?lua
+  include("includes/weaponsettings3.oxi")
+?>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipassffcameras defaults=0>
+  <SpaceShip>
+    <camerapositions>
+      <CameraPosition position="0,10, 40" drag=true mouselook=true />
+      <CameraPosition position="0,20, 80" drag=true mouselook=true />
+      <CameraPosition position="0,30,120" drag=true mouselook=true />
+      <!--CameraPosition position="0,150,-25" pitch=-90 drag=true />
+      <CameraPosition position="0,0,-40" yaw=180 drag=true />
+      <CameraPosition position="0,3,-14" yaw=0 />
+      <CameraPosition position="-50,5,-8" yaw=-90 drag=true />
+      <CameraPosition position="50,5,-8" yaw=90 drag=true /-->
+    </camerapositions>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipassffengine baseclass=MultiStateEngine>
+  <MultiStateEngine
+   boostfactor    = 2
+
+   speedfront     = 150
+   speedback      =  50
+   speedleftright =  50
+   speedupdown    =  50
+
+   defEngineSndNormal = "sounds/Engine_low.ogg"
+   defEngineSndBoost = "sounds/Engine_high.ogg"
+
+   accelerationfront     = 500
+   accelerationbrake     = 500
+   accelerationback      =  125
+   accelerationleftright =  125
+   accelerationupdown    =  125
+  >
+    <EffectContainer condition="idle">
+      <WorldSound mainstate="activity" source="sounds/Engine_idle.ogg" looping=1 active=false/>
+    </EffectContainer>
+    <EffectContainer condition="not idle">
+      <FadingBillboard mainstate=activity active=false scale=0.1 position="0, 0, 9" colour="0.2, 0.65, 1.0, 1.0" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+<!--
+      <Light mainstate=visibility position=" 8, 0, 8" diffuse="0.3, 0.6, 1.0" specular="0.3, 0.6, 1.0" attenuation="600, 1.0, 0.007, 0.0002" type=point />
+      <Light mainstate=visibility position="-8, 0, 8" diffuse="0.3, 0.6, 1.0" specular="0.3, 0.6, 1.0" attenuation="600, 1.0, 0.007, 0.0002" type=point />
+-->
+    </EffectContainer>
+    <EffectContainer condition="normal or brake">
+
+    </EffectContainer>
+    <EffectContainer condition="normal or boost">
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position=" 7.6, 0, 6" colour="0.2, 0.65, 1.0, 1.0" width=15 length=1500 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position="-7.6, 0, 6" colour="0.2, 0.65, 1.0, 1.0" width=15 length=1500 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+    </EffectContainer>
+    <EffectContainer condition="boost">
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position=" 7.6, 0, 6" colour="0.6, 0.75, 0.8, 0.7" width=40 length=1000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position="-7.6, 0, 6" colour="0.6, 0.75, 0.8, 0.7" width=40 length=1000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+    </EffectContainer>
+    <EffectContainer condition="brake">
+      <FadingBillboard mainstate=activity active=false scale=0.3 position=" 8, 0, 6" colour="0.5, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.3 position="-8, 0, 6" colour="0.5, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.15 position=" 8, 0, 6" colour="1.0, 0.0, 0.0, 1.0" material="Flares/backlightflare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.15 position="-8, 0, 6" colour="1.0, 0.0, 0.0, 1.0" material="Flares/backlightflare" turnontime=0.5 turnofftime=0.5 />
+    </EffectContainer>
+  </MultiStateEngine>
+</Template>
+
+<!--Template name=spaceshippirate>
+  <SpaceShip
+   health            = 100
+   maxhealth         = 200
+   initialhealth     = 100
+
+   maxspeed          = 250
+   maxsecondaryspeed = 50
+   maxrotation       = 100
+   transacc          = 200
+   rotacc            = 140
+   transdamp         = 75
+  >
+    <attached>
+      <Model position="0,-10,-45" yaw=90 pitch=-90 roll=0 scale=4 mesh="pirate.mesh" />
+    </attached>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipspacecruiser>
+  <SpaceShip
+   health            = 100
+   maxhealth         = 200
+   initialhealth     = 100
+
+   maxspeed          = 250
+   maxsecondaryspeed = 50
+   maxrotation       = 100
+   transacc          = 200
+   rotacc            = 140
+   transdamp         = 75
+  >
+    <attached>
+      <Model position="8,-30,-120" yaw=90 pitch=-90 roll=0 scale=4 mesh="spacecruiser.mesh" />
+    </attached>
+  </SpaceShip>
+</Template-->
Index: /code/branches/rocket2/data/levels/templates/spaceship_ghost.oxt
===================================================================
--- /code/branches/rocket2/data/levels/templates/spaceship_ghost.oxt	(revision 6952)
+++ /code/branches/rocket2/data/levels/templates/spaceship_ghost.oxt	(revision 6952)
@@ -0,0 +1,84 @@
+<Template name=spaceshipghost>
+  <SpaceShip
+   hudtemplate            = spaceshiphud
+   camerapositiontemplate = spaceshipghostcameras
+   engine                 = spaceshipghostengine
+   spawnparticlesource    = "Orxonox/fairytwirl"
+   spawnparticleduration  = 3
+   explosionchunks        = 6
+
+   health            = 100
+   maxhealth         = 200
+   initialhealth     = 100
+
+   primaryThrust     = 600;
+   auxilaryThrust    = 30;
+   rotationThrust    = 25;
+
+   collisionType     = "dynamic"
+   mass              = 100
+   linearDamping     = 0.7
+   angularDamping    = 0.9999999
+  >
+
+    <attached>
+      <Model position="0,0,0" scale=2 yaw=90 pitch=-90 roll=0 mesh="ghost.mesh" />
+    </attached>
+    <collisionShapes>
+      <BoxCollisionShape position="0,0,0"      halfExtents="10, 3, 5" />
+      <BoxCollisionShape position="13,-1.3,0"  halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="-13,-1.3,0" halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="0,0,7"      halfExtents="3, 2, 2" />
+      <BoxCollisionShape position="0,0.1,-11"  halfExtents="2.2, 1.8, 6" />
+      <BoxCollisionShape position="0,0.1,-19"  halfExtents="1.4, 1, 2" />
+    </collisionShapes>
+<?lua
+  include("includes/weaponsettings_ghost.oxi")
+?>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipghostcameras defaults=0>
+  <SpaceShip>
+    <camerapositions>
+      <CameraPosition position="0,20,80" drag=true mouselook=true />
+      <CameraPosition position="0,40,160" drag=true mouselook=true />
+      <CameraPosition position="0,50,200" drag=true mouselook=true />
+    </camerapositions>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshipghostengine baseclass=MultiStateEngine>
+  <MultiStateEngine
+   boostfactor    = 2
+
+   speedfront     = 600
+   speedback      =  50
+   speedleftright =  50
+   speedupdown    =  50
+
+   accelerationfront     = 700
+   accelerationbrake     = 300
+   accelerationback      =  100
+   accelerationleftright =  100
+   accelerationupdown    =  100
+  >
+    <EffectContainer condition="normal or boost">
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position=" 7.6, 3, 6" colour="0.0, 0.0, 0.0, 0.5" width=15 length=1500 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position="-7.6, 3, 6" colour="0.0, 0.0, 0.0, 0.5" width=15 length=1500 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+    </EffectContainer>
+    <EffectContainer condition="boost">
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position=" 7.6, 3, 6" colour="0.0, 0.0, 0.0, 0.7" width=40 length=1000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position="-7.6, 3, 6" colour="0.0, 0.0, 0.0, 0.7" width=40 length=1000 lifetime=1 elements=30 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Examples/Flare" />
+    </EffectContainer>
+    <EffectContainer condition="not idle">
+      <Backlight mainstate=activity active=false scale=0.4 position="7.6, 3, 6" colour="1, 1, 1, 1.0" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <Backlight mainstate=activity active=false scale=0.4 position="-7.6, 3, 6" colour="1, 1, 1, 1.0" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+    </EffectContainer>
+    <EffectContainer condition="brake">
+      <FadingBillboard mainstate=activity active=false scale=0.3 position=" 8, 0, 6" colour="0.2, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.3 position="-8, 0, 6" colour="0.2, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+    </EffectContainer>
+</MultiStateEngine>
+</Template>
+
Index: /code/branches/rocket2/data/levels/templates/spaceship_pirate.oxt
===================================================================
--- /code/branches/rocket2/data/levels/templates/spaceship_pirate.oxt	(revision 6952)
+++ /code/branches/rocket2/data/levels/templates/spaceship_pirate.oxt	(revision 6952)
@@ -0,0 +1,88 @@
+<Template name=spaceshippirate>
+  <SpaceShip
+   hudtemplate            = spaceshiphud
+   camerapositiontemplate = spaceshippiratecameras
+   engine                 = spaceshippirateengine
+   spawnparticlesource    = "Orxonox/fairytwirl"
+   spawnparticleduration  = 3
+   explosionchunks        = 6
+
+   health            = 100
+   maxhealth         = 200
+   initialhealth     = 100
+
+   primaryThrust     = 100;
+   auxilaryThrust    = 30;
+   rotationThrust    = 25;
+
+   collisionType     = "dynamic"
+   mass              = 100
+   linearDamping     = 0.7
+   angularDamping    = 0.9999999
+  >
+    <attached>
+      <Model position="0,0,0" yaw=90 pitch=-90 roll=0 scale=4 mesh="pirate.mesh" />
+      <BlinkingBillboard position=" 12.7,-3.8,0" material="Examples/Flare" colour="1.0, 1.0, 1" amplitude=0.04 frequency=1 quadratic=1 />
+      <BlinkingBillboard position="-12.7,-3.8,0" material="Examples/Flare" colour="1.0, 1.0, 1" amplitude=0.04 frequency=1 quadratic=1 phase="90"/>
+      <BlinkingBillboard position=" 8.7,-0.5,2.5" material="Examples/Flare" colour="1.0, 1.0, 1" amplitude=0.04 frequency=1 quadratic=1 phase="30"/>
+      <BlinkingBillboard position="-8.7,-0.5,2.5" material="Examples/Flare" colour="1.0, 1.0, 1" amplitude=0.04 frequency=1 quadratic=1 phase="60"/>
+    </attached>
+    <collisionShapes>
+      <BoxCollisionShape position="0,0,0"      halfExtents="10, 3, 5" />
+      <BoxCollisionShape position="13,-1.3,0"  halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="-13,-1.3,0" halfExtents="3, 1, 2" />
+      <BoxCollisionShape position="0,0,7"      halfExtents="3, 2, 2" />
+      <BoxCollisionShape position="0,0.1,-11"  halfExtents="2.2, 1.8, 6" />
+      <BoxCollisionShape position="0,0.1,-19"  halfExtents="1.4, 1, 2" />
+    </collisionShapes>
+
+<?lua
+  include("includes/weaponsettings_pirate.oxi")
+?>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshippiratecameras defaults=0>
+  <SpaceShip>
+    <camerapositions>
+      <CameraPosition position="0,8, 60" drag=true mouselook=true />
+      <CameraPosition position="0,16, 120" drag=true mouselook=true />
+      <CameraPosition position="0,24,180" drag=true mouselook=true />
+      <CameraPosition position="0,60,10" pitch="-80" drag=true mouselook=true />
+    </camerapositions>
+  </SpaceShip>
+</Template>
+
+<Template name=spaceshippirateengine baseclass=MultiStateEngine>
+  <MultiStateEngine
+   boostfactor    = 2
+
+   speedfront     = 150
+   speedback      =  50
+   speedleftright =  50
+   speedupdown    =  50
+
+   accelerationfront     = 500
+   accelerationbrake     = 500
+   accelerationback      =  125
+   accelerationleftright =  125
+   accelerationupdown    =  125
+  >
+    <active>
+      <FadingBillboard mainstate=activity active=false scale=0.02 position=" 1.3, -4, -15" colour="1.0, 0.65, 0.2, 1.0" material="Examples/FlareZwei" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.02 position=" 0, -4, -15" colour="1.0, 0.65, 0.2, 1.0" material="Examples/FlareZwei" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.02 position="-1.3, -4, -15" colour="1.0, 0.65, 0.2, 1.0" material="Examples/FlareZwei" turnontime=0.5 turnofftime=0.5 />
+    </active>
+    <forward>
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position=" 13, -4,  9.5" colour="1.0, 0.65, 0.2, 1.0" width=8 length=800 lifetime=1 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position="-13, -4,  9.5" colour="1.0, 0.65, 0.2, 1.0" width=8 length=800 lifetime=1 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+    </forward>
+    <boost>
+      <Backlight mainstate=activity active=false scale=0.4 name=bltest position="  0,  5, 15.5" colour="1.0, 0.65, 0.2, 1.0" width=16 length=1600 lifetime=2 elements=50 trailmaterial="Trail/backlighttrail" turnontime=1 turnofftime=1 material="Flares/ThrusterFlare1" />
+    </boost>
+    <brake>
+      <FadingBillboard mainstate=activity active=false scale=0.1 position=" 4.4, -5.5, 5" colour="0.8, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+      <FadingBillboard mainstate=activity active=false scale=0.1 position="-4.4, -5.5, 5" colour="0.8, 0.0, 0.0, 0.3" material="Examples/Flare" turnontime=0.5 turnofftime=0.5 />
+    </brake>
+  </MultiStateEngine>
+</Template>
Index: /code/branches/rocket2/data/levels/test_ghost.oxw
===================================================================
--- /code/branches/rocket2/data/levels/test_ghost.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/test_ghost.oxw	(revision 6952)
@@ -0,0 +1,52 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_ghost.oxt")
+  include("templates/spaceship_pirate.oxt")
+?>
+
+<Level
+ name         = "Presentation09"
+ description  = "presentation level for Orxonox Convention X"
+
+>
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/skypanoramagen1"
+  >
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+
+<SpawnPoint position="<?lua print(math.sin(1.5) *40000) ?>,<?lua print(math.cos(1.5) *40000) ?>,<?lua print(500) ?>" lookat="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipghost />
+
+
+<?lua
+max = 20
+for i = 1, max, 1
+do
+    x = math.sin(i/max*6)*40000
+    y = math.cos(i/max*6)*40000
+    z = i*100
+    ?>
+<?lua
+for k = 1, 25, 1
+do
+j = math.random()
+?>
+
+    <MovableEntity position="<?lua print(x + math.random() * 10000-2500) ?>,<?lua print(y + math.random() * 5000-2500) ?>,<?lua print(z + math.random() * 1000-500) ?>" <?lua if i == 5 then ?> collisionType=dynamic linearDamping=0.8 angularDamping=0 mass=<?lua print(j * 50) ?> <?lua end ?> scale=<?lua print(j * 5) ?> rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+      <attached>
+        <Model position="0,0,0" scale=<?lua print(j * 10) ?> mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" />
+      </attached>
+      <?lua if i == 5 then ?><collisionShapes>
+        <SphereCollisionShape radius="<?lua print(j * 70) ?>" />
+      </collisionShapes> <?lua end ?>
+    </MovableEntity>
+<?lua
+end
+?>
+<?lua end ?>
+    <Planet position="0,0,0" scale=10000 pitch=-90 mesh="iceplanet.mesh" atmosphere="atmosphere1" rotationaxis="1,1,0" rotationrate="1" atmospheresize=224.0f imagesize=1024.0f />
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/tutorial.oxw
===================================================================
--- /code/branches/rocket2/data/levels/tutorial.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/tutorial.oxw	(revision 6952)
@@ -0,0 +1,101 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+?>
+
+<Level
+ name         = "Presentation"
+ description  = "A simple testlevel"
+>
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/skypanoramagen1"
+  >
+
+<Drone name="meineDrohne" primarythrust="80" auxilarythrust="10" rotationthrust="10" mass= "50" linearDamping = "0.9" angularDamping = "0.7">
+  <attached>
+    <Model scale="1" mesh="drone.mesh"/>
+  </attached>
+  <collisionShapes>
+    <BoxCollisionShape position="0,0,0"      halfExtents="10, 10, 10" />
+  </collisionShapes>
+</Drone>
+
+<Drone name="meineDrohne" primarythrust="80" auxilarythrust="10" rotationthrust="10" mass= "50" linearDamping = "0.9" angularDamping = "0.7">
+  <attached>
+    <Model scale="1" mesh="rocket.mesh"/>
+  </attached>
+  <collisionShapes>
+    <BoxCollisionShape position="0,0,0"      halfExtents="10, 10, 10" />
+  </collisionShapes>
+</Drone>
+
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+<Model mesh="hs-w01.mesh" scale=10 position="0,0,-100" />
+<Model mesh="hs-w01s.mesh" scale=10 position="0,0,-100" />
+
+<?lua
+for i = 1, 10, 1
+do ?>
+    <SpawnPoint position="<?lua print(math.random() * 1000 - 500) ?>,<?lua print(math.random() * 1000 - 500) ?>,<?lua print(math.random() * 1000 - 500) ?>" lookat="0,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+<?lua
+end
+?>
+
+    <GlobalShader compositor="Bloom" visible=false>
+      <events>
+        <visibility>
+          <DistanceTrigger position="0,0,0" distance=30 target="Spectator" switch=true />
+        </visibility>
+      </events>
+    </GlobalShader>
+    <Model position="0,0,0" scale=8 mesh="ast1.mesh" />
+    <StaticEntity position="0,0,0" collisionType=static>
+      <collisionShapes>
+        <SphereCollisionShape radius="20" />
+      </collisionShapes>
+    </StaticEntity>
+<!--
+<?lua
+for i = 1, 70, 1
+do ?>
+  <MovableEntity position="<?lua print(math.random() * 6000 - 3000)?>, <?lua print(math.random() * 6000 - 3000) ?>, <?lua print(math.random() * 1000 + 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 30 + 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+  <MovableEntity position="<?lua print(math.random() * 6000 - 3000)?>, <?lua print(math.random() * 6000 - 3000) ?>, <?lua print(math.random() * -1000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 30 + 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+
+  <MovableEntity position="<?lua print(math.random() * 6000 - 3000)?>, <?lua print(math.random() * 1000 + 3000) ?>, <?lua print(math.random() * 6000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 30 + 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+  <MovableEntity position="<?lua print(math.random() * 6000 - 3000)?>, <?lua print(math.random() * -1000 - 3000) ?>, <?lua print(math.random() * 6000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 30 + 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+
+  <MovableEntity position="<?lua print(math.random() * 1000 + 3000)?>, <?lua print(math.random() * 6000 - 3000) ?>, <?lua print(math.random() * 6000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 30 + 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+  <MovableEntity position="<?lua print(math.random() * -1000 - 3000)?>, <?lua print(math.random() * 6000 - 3000) ?>, <?lua print(math.random() * 6000 - 3000) ?>" rotationaxis="<?lua print(math.random()) ?>, <?lua print(math.random()) ?>, <?lua print(math.random()) ?>" rotationrate="<?lua print(math.random() * 30 + 5) ?>">
+    <attached>
+      <Model scale="<?lua print(math.random() * 30 + 10) ?>" mesh="ast<?lua print( math.mod(i,6) + 1) ?>.mesh" shadow=false />
+    </attached>
+  </MovableEntity>
+<?lua
+end
+?>
+-->
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/levels/waypoints.oxw
===================================================================
--- /code/branches/rocket2/data/levels/waypoints.oxw	(revision 6952)
+++ /code/branches/rocket2/data/levels/waypoints.oxw	(revision 6952)
@@ -0,0 +1,157 @@
+<?lua
+  include("hudtemplates3.oxo")
+  include("stats.oxo")
+  include("templates/spaceship_assff.oxt")
+  include("templates/spaceship_H2.oxt")
+  include("templates/spaceship_pirate.oxt")
+?>
+
+<Level
+ name         = "Waypoints"
+ description  = "Testing waypoings for AI controlled spaceships."
+>
+  <Scene
+   ambientlight = "0.5, 0.5, 0.5"
+   skybox       = "Orxonox/skypanoramagen1"
+  >
+    <Light type=directional position="0,0,0" direction="0.253, 0.593, -0.765" diffuse="1.0, 0.9, 0.9, 1.0" specular="1.0, 0.9, 0.9, 1.0" />
+
+    <SpawnPoint position="0,0,0" direction="1,0,0" spawnclass=SpaceShip pawndesign=spaceshipassff />
+
+    <SpaceShip position="0,2000,200" lookat="0,0,0">
+      <templates>
+        <Template link=spaceshipassff />
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=1000 team=10>
+          <waypoints>
+            <Model mesh="cube.mesh" scale=8 position="  0,2000,-200" />
+            <Model mesh="cube.mesh" scale=8 position="  0,2000,-700" />
+            <Model mesh="cube.mesh" scale=8 position="500,2000,-700" />
+            <Model mesh="cube.mesh" scale=8 position="500,2000,-200" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+    <SpaceShip position="0,2000,400" lookat="0,0,0">
+      <templates>
+        <Template link=spaceshipassff />
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=1000 team=10>
+          <waypoints>
+            <Model mesh="cube.mesh" scale=8 position="  0,2000,-200" />
+            <Model mesh="cube.mesh" scale=8 position="  0,2000,-700" />
+            <Model mesh="cube.mesh" scale=8 position="500,2000,-700" />
+            <Model mesh="cube.mesh" scale=8 position="500,2000,-200" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+
+    <SpaceShip position="1500,2000,200" lookat="0,0,0">
+      <templates>
+        <Template link=spaceshipassff />
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=1000 team=11>
+          <waypoints>
+            <Model mesh="cube.mesh" scale=8 position="1500,2000,-200" />
+            <Model mesh="cube.mesh" scale=8 position="1500,2000,-700" />
+            <Model mesh="cube.mesh" scale=8 position="1000,2000,-700" />
+            <Model mesh="cube.mesh" scale=8 position="1000,2000,-200" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+
+    <SpaceShip position="1500,-2000,200" lookat="0,0,0" name=polonaise1>
+      <templates>
+        <Template link=spaceshipassff />
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=1000 team=12>
+          <waypoints>
+            <Model mesh="cube.mesh" scale=8 position="1500,-2000,-200" />
+<!--
+            <Attacher target=polonaise6 deletewithparent=false />
+            <Model mesh="cube.mesh" scale=8 position="1500,-2000,-700" />
+            <Model mesh="cube.mesh" scale=8 position="1000,-2000,-700" />
+            <Model mesh="cube.mesh" scale=8 position="1000,-2000,-200" />
+-->
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+
+<?lua
+for i = 1, 5, 1
+do ?>
+    <SpaceShip position="1500,<?lua print(-2000 + 50*i) ?>,200" lookat="0,0,0" name=polonaise<?lua print(i+1) ?> >
+      <templates>
+        <Template link=spaceshipassff />
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=1000 team=12>
+          <waypoints>
+            <Attacher target=polonaise<?lua print(i) ?> deletewithparent=false />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+<?lua
+end
+?>
+
+
+    <SpaceShip position="-1500,-2000,200" lookat="0,0,0" name=attack1>
+      <templates>
+        <Template link=spaceshipassff />
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=1000 team=13>
+          <waypoints>
+            <Model mesh="cube.mesh" scale=8 position="1500,-2000,-200" />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+
+<?lua
+for i = 1, 5, 1
+do ?>
+    <SpaceShip position="-1500,<?lua print(-2000 + 50*i) ?>,200" lookat="0,0,0" name=attack<?lua print(i+1) ?> >
+      <templates>
+        <Template link=spaceshipassff />
+      </templates>
+      <controller>
+        <WaypointPatrolController alertnessradius=1000 team=13>
+          <waypoints>
+            <Attacher target=attack<?lua print(i) ?> deletewithparent=false />
+          </waypoints>
+        </WaypointPatrolController>
+      </controller>
+    </SpaceShip>
+<?lua
+end
+?>
+
+<!--
+<?lua
+for i = 1, 50, 1
+do ?>
+    <SpaceShip position="<?lua print(math.random() * 1000 - 500) ?>,<?lua print(math.random() * 1000 - 500) ?>,<?lua print(math.random() * 1000 - 500) ?>" lookat="0,0,0" >
+      <templates>
+        <Template link=spaceshipassff />
+      </templates>
+      <controller>
+        <AIController />
+      </controller>
+    </SpaceShip>
+<?lua
+end
+?>
+-->
+
+  </Scene>
+</Level>
Index: /code/branches/rocket2/data/lua/Debugger.lua
===================================================================
--- /code/branches/rocket2/data/lua/Debugger.lua	(revision 6952)
+++ /code/branches/rocket2/data/lua/Debugger.lua	(revision 6952)
@@ -0,0 +1,1358 @@
+
+--{{{  history
+
+--28/03/10 ORX Adjusted show() to work with the Orxonox resource system
+--15/03/06 DCN Created based on RemDebug
+--28/04/06 DCN Update for Lua 5.1
+--01/06/06 DCN Fix command argument parsing
+--             Add step/over N facility
+--             Add trace lines facility
+--05/06/06 DCN Add trace call/return facility
+--06/06/06 DCN Make it behave when stepping through the creation of a coroutine
+--06/06/06 DCN Integrate the simple debugger into the main one
+--07/06/06 DCN Provide facility to step into coroutines
+--13/06/06 DCN Fix bug that caused the function environment to get corrupted with the global one
+--14/06/06 DCN Allow 'sloppy' file names when setting breakpoints
+--04/08/06 DCN Allow for no space after command name
+--11/08/06 DCN Use io.write not print
+--30/08/06 DCN Allow access to array elements in 'dump'
+--10/10/06 DCN Default to breakfile for all commands that require a filename and give '-'
+--06/12/06 DCN Allow for punctuation characters in DUMP variable names
+--03/01/07 DCN Add pause on/off facility
+--19/06/07 DCN Allow for duff commands being typed in the debugger (thanks to Michael.Bringmann@lsi.com)
+--             Allow for case sensitive file systems               (thanks to Michael.Bringmann@lsi.com)
+
+--}}}
+--{{{  description
+
+--A simple command line debug system for Lua written by Dave Nichols of
+--Match-IT Limited. Its public domain software. Do with it as you wish.
+
+--This debugger was inspired by:
+-- RemDebug 1.0 Beta
+-- Copyright Kepler Project 2005 (http://www.keplerproject.org/remdebug)
+
+--Usage:
+--  require('debugger')        --load the debug library
+--  pause(message)             --start/resume a debug session
+
+--An assert() failure will also invoke the debugger.
+
+--}}}
+
+local IsWindows = string.find(string.lower(os.getenv('OS') or ''),'^windows')
+
+local coro_debugger
+local events = { BREAK = 1, WATCH = 2, STEP = 3, SET = 4 }
+local breakpoints = {}
+local watches = {}
+local step_into   = false
+local step_over   = false
+local step_lines  = 0
+local step_level  = {main=0}
+local stack_level = {main=0}
+local trace_level = {main=0}
+local trace_calls = false
+local trace_returns = false
+local trace_lines = false
+local ret_file, ret_line, ret_name
+local current_thread = 'main'
+local started = false
+local pause_off = false
+local _g      = _G
+local cocreate, cowrap = coroutine.create, coroutine.wrap
+local pausemsg = 'pause'
+
+--{{{  local hints -- command help
+--The format in here is name=summary|description
+local hints = {
+
+pause =   [[
+pause(msg)          -- start/resume a debugger session|
+
+This can only be used in your code or from the console as a means to
+start/resume a debug session.
+If msg is given that is shown when the session starts/resumes. Useful to
+give a context if you've instrumented your code with pause() statements.
+]],
+
+poff =    [[
+poff                -- turn off pause() command|
+
+This causes all pause() commands to be ignored. This is useful if you have
+instrumented your code in a busy loop and want to continue normal execution
+with no further interruption.
+]],
+
+pon =     [[
+pon                 -- turn on pause() command|
+
+This re-instates honouring the pause() commands you may have instrumented
+your code with.
+]],
+
+setb =    [[
+setb [line file]    -- set a breakpoint to line/file|
+
+If file is omitted or is "-" the breakpoint is set at the file for the
+currently set level (see "set"). Execution pauses when this line is about
+to be executed and the debugger session is re-activated.
+
+The file can be given as the fully qualified name, partially qualified or
+just the file name. E.g. if file is set as "myfile.lua", then whenever
+execution reaches any file that ends with "myfile.lua" it will pause.
+]],
+
+delb =    [[
+delb [line file]    -- removes a breakpoint|
+
+If file is omitted or is "-" the breakpoint is removed for the file of the
+currently set level (see "set").
+]],
+
+delallb = [[
+delallb             -- removes all breakpoints|
+]],
+
+setw =    [[
+setw <exp>          -- adds a new watch expression|
+
+The expression is evaluated before each line is executed. If the expression
+yields true then execution is paused and the debugger session re-activated.
+The expression is executed in the context of the line about to be executed.
+]],
+
+delw =    [[
+delw <index>        -- removes the watch expression at index|
+
+The index is that returned when the watch expression was set by setw.
+]],
+
+delallw = [[
+delallw             -- removes all watch expressions|
+]],
+
+run     = [[
+run                 -- run until next breakpoint or watch expression|
+]],
+
+step    = [[
+step [N]            -- run next N lines, stepping into function calls|
+
+If N is omitted, use 1.
+]],
+
+over    = [[
+over [N]            -- run next N lines, stepping over function calls|
+
+If N is omitted, use 1.
+]],
+
+out     = [[
+out [N]             -- run lines until stepped out of N functions|
+
+If N is omitted, use 1.
+If you are inside a function, using "out 1" will run until you return
+from that function to the caller.
+]],
+
+goto    = [[
+goto <line>         -- step to line number <line> in the current file|
+
+The line and current file are those in the currently set context level.
+]],
+
+listb   = [[
+listb               -- lists breakpoints|
+]],
+
+listw   = [[
+listw               -- lists watch expressions|
+]],
+
+set     = [[
+set [level]         -- set context to stack level, omitted=show|
+
+If level is omitted it just prints the current level set.
+This sets the current context to the level given. This affects the
+context used for several other functions (e.g. vars). The possible
+levels are those shown by trace.
+]],
+
+vars    = [[
+vars [depth]        -- list context locals to depth, omitted=1|
+
+If depth is omitted then uses 1.
+Use a depth of 0 for the maximum.
+Lists all non-nil local variables and all non-nil upvalues in the
+currently set context. For variables that are tables, lists all fields
+to the given depth.
+]],
+
+fenv    = [[
+fenv [depth]        -- list context function env to depth, omitted=1|
+
+If depth is omitted then uses 1.
+Use a depth of 0 for the maximum.
+Lists all function environment variables in the currently set context.
+For variables that are tables, lists all fields to the given depth.
+]],
+
+glob    = [[
+glob [depth]        -- list globals to depth, omitted=1|
+
+If depth is omitted then uses 1.
+Use a depth of 0 for the maximum.
+Lists all global variables.
+For variables that are tables, lists all fields to the given depth.
+]],
+
+ups     = [[
+ups                 -- list all the upvalue names|
+
+These names will also be in the "vars" list unless their value is nil.
+This provides a means to identify which vars are upvalues and which are
+locals. If a name is both an upvalue and a local, the local value takes
+precedance.
+]],
+
+locs    = [[
+locs                -- list all the locals names|
+
+These names will also be in the "vars" list unless their value is nil.
+This provides a means to identify which vars are upvalues and which are
+locals. If a name is both an upvalue and a local, the local value takes
+precedance.
+]],
+
+dump    = [[
+dump <var> [depth]  -- dump all fields of variable to depth|
+
+If depth is omitted then uses 1.
+Use a depth of 0 for the maximum.
+Prints the value of <var> in the currently set context level. If <var>
+is a table, lists all fields to the given depth. <var> can be just a
+name, or name.field or name.# to any depth, e.g. t.1.f accesses field
+'f' in array element 1 in table 't'.
+
+Can also be called from a script as dump(var,depth).
+]],
+
+tron    = [[
+tron [crl]          -- turn trace on for (c)alls, (r)etuns, (l)lines|
+
+If no parameter is given then tracing is turned off.
+When tracing is turned on a line is printed to the console for each
+debug 'event' selected. c=function calls, r=function returns, l=lines.
+]],
+
+trace   = [[
+trace               -- dumps a stack trace|
+
+Format is [level] = file,line,name
+The level is a candidate for use by the 'set' command.
+]],
+
+info    = [[
+info                -- dumps the complete debug info captured|
+
+Only useful as a diagnostic aid for the debugger itself. This information
+can be HUGE as it dumps all variables to the maximum depth, so be careful.
+]],
+
+show    = [[
+show line file X Y  -- show X lines before and Y after line in file|
+
+If line is omitted or is '-' then the current set context line is used.
+If file is omitted or is '-' then the current set context file is used.
+If file is not fully qualified and cannot be opened as specified, then
+a search for the file in the package[path] is performed using the usual
+"require" searching rules. If no file extension is given, .lua is used.
+Prints the lines from the source file around the given line.
+]],
+
+exit    = [[
+exit                -- exits debugger, re-start it using pause()|
+]],
+
+help    = [[
+help [command]      -- show this list or help for command|
+]],
+
+["<statement>"] = [[
+<statement>         -- execute a statement in the current context|
+
+The statement can be anything that is legal in the context, including
+assignments. Such assignments affect the context and will be in force
+immediately. Any results returned are printed. Use '=' as a short-hand
+for 'return', e.g. "=func(arg)" will call 'func' with 'arg' and print
+the results, and "=var" will just print the value of 'var'.
+]],
+
+what    = [[
+what <func>         -- show where <func> is defined (if known)|
+]],
+
+}
+--}}}
+
+--{{{  local function getinfo(level,field)
+
+--like debug.getinfo but copes with no activation record at the given level
+--and knows how to get 'field'. 'field' can be the name of any of the
+--activation record fields or any of the 'what' names or nil for everything.
+--only valid when using the stack level to get info, not a function name.
+
+local function getinfo(level,field)
+  level = level + 1  --to get to the same relative level as the caller
+  if not field then return debug.getinfo(level) end
+  local what
+  if field == 'name' or field == 'namewhat' then
+    what = 'n'
+  elseif field == 'what' or field == 'source' or field == 'linedefined' or field == 'lastlinedefined' or field == 'short_src' then
+    what = 'S'
+  elseif field == 'currentline' then
+    what = 'l'
+  elseif field == 'nups' then
+    what = 'u'
+  elseif field == 'func' then
+    what = 'f'
+  else
+    return debug.getinfo(level,field)
+  end
+  local ar = debug.getinfo(level,what)
+  if ar then return ar[field] else return nil end
+end
+
+--}}}
+--{{{  local function indented( level, ... )
+
+local function indented( level, ... )
+  io.write( string.rep('  ',level), table.concat({...}), '\n' )
+end
+
+--}}}
+--{{{  local function dumpval( level, name, value, limit )
+
+local dumpvisited
+
+local function dumpval( level, name, value, limit )
+  local index
+  if type(name) == 'number' then
+    index = string.format('[%d] = ',name)
+  elseif type(name) == 'string'
+     and (name == '__VARSLEVEL__' or name == '__ENVIRONMENT__' or name == '__GLOBALS__' or name == '__UPVALUES__' or name == '__LOCALS__') then
+    --ignore these, they are debugger generated
+    return
+  elseif type(name) == 'string' and string.find(name,'^[_%a][_.%w]*$') then
+    index = name ..' = '
+  else
+    index = string.format('[%q] = ',tostring(name))
+  end
+  if type(value) == 'table' then
+    if dumpvisited[value] then
+      indented( level, index, string.format('ref%q;',dumpvisited[value]) )
+    else
+      dumpvisited[value] = tostring(value)
+      if (limit or 0) > 0 and level+1 >= limit then
+        indented( level, index, dumpvisited[value] )
+      else
+        indented( level, index, '{  -- ', dumpvisited[value] )
+        for n,v in pairs(value) do
+          dumpval( level+1, n, v, limit )
+        end
+        indented( level, '};' )
+      end
+    end
+  else
+    if type(value) == 'string' then
+      if string.len(value) > 40 then
+        indented( level, index, '[[', value, ']];' )
+      else
+        indented( level, index, string.format('%q',value), ';' )
+      end
+    else
+      indented( level, index, tostring(value), ';' )
+    end
+  end
+end
+
+--}}}
+--{{{  local function dumpvar( value, limit, name )
+
+local function dumpvar( value, limit, name )
+  dumpvisited = {}
+  dumpval( 0, name or tostring(value), value, limit )
+end
+
+--}}}
+--{{{  local function show(file,line,before,after)
+
+--show +/-N lines of a file around line M
+
+local function show(file,line,before,after)
+
+  line   = tonumber(line   or 1)
+  before = tonumber(before or 10)
+  after  = tonumber(after  or before)
+
+  -- Try to find the file in the Orxonox resources
+  local text = luaState:getSourceCode(file)
+
+  if text == "" then
+    if not string.find(file,'%.') then file = file..'.lua' end
+
+    local f = io.open(file,'r')
+    if not f then
+      --{{{  try to find the file in the path
+    
+      --
+      -- looks for a file in the package path
+      --
+      local path = package.path or LUA_PATH or ''
+      for c in string.gmatch (path, "[^;]+") do
+        local c = string.gsub (c, "%?%.lua", file)
+        f = io.open (c,'r')
+        if f then
+          break
+        end
+      end
+    
+      --}}}
+
+      if f then
+        -- Read file into 'text'
+        text = f:read("*a")
+        f:close()
+      else
+        io.write('Cannot find '..file..'\n')
+        return
+      end
+    end
+  end
+
+  -- Transform line endings to \n
+  text:gsub("\r\n", "\n") -- Windows to Unix
+  text:gsub("\r", "\n")   -- Mac to Unix
+  if text[-1] ~= "\n" then
+      text = text.."\n"
+  end
+  -- Print requested lines
+  local i = 0
+  for l in text:gmatch("[^\n]*[\n]") do
+    i = i + 1
+    if i >= (line-before) then
+      if i > (line+after) then break end
+      if i == line then
+        io.write(i..'***\t'..l)
+      else
+        io.write(i..'\t'..l)
+      end
+    end
+  end
+end
+
+--}}}
+--{{{  local function tracestack(l)
+
+local function gi( i )
+  return function() i=i+1 return debug.getinfo(i),i end
+end
+
+local function gl( level, j )
+  return function() j=j+1 return debug.getlocal( level, j ) end
+end
+
+local function gu( func, k )
+  return function() k=k+1 return debug.getupvalue( func, k ) end
+end
+
+local  traceinfo
+
+local function tracestack(l)
+  local l = l + 1                        --NB: +1 to get level relative to caller
+  traceinfo = {}
+  traceinfo.pausemsg = pausemsg
+  for ar,i in gi(l) do
+    table.insert( traceinfo, ar )
+    local names  = {}
+    local values = {}
+    for n,v in gl(i,0) do
+      if string.sub(n,1,1) ~= '(' then   --ignore internal control variables
+        table.insert( names, n )
+        table.insert( values, v )
+      end
+    end
+    if #names > 0 then
+      ar.lnames  = names
+      ar.lvalues = values
+    end
+    if ar.func then
+      local names  = {}
+      local values = {}
+      for n,v in gu(ar.func,0) do
+        if string.sub(n,1,1) ~= '(' then   --ignore internal control variables
+          table.insert( names, n )
+          table.insert( values, v )
+        end
+      end
+      if #names > 0 then
+        ar.unames  = names
+        ar.uvalues = values
+      end
+    end
+  end
+end
+
+--}}}
+--{{{  local function trace()
+
+local function trace(set)
+  local mark
+  for level,ar in ipairs(traceinfo) do
+    if level == set then
+      mark = '***'
+    else
+      mark = ''
+    end
+    io.write('['..level..']'..mark..'\t'..(ar.name or ar.what)..' in '..ar.short_src..':'..ar.currentline..'\n')
+  end
+end
+
+--}}}
+--{{{  local function info()
+
+local function info() dumpvar( traceinfo, 0, 'traceinfo' ) end
+
+--}}}
+
+--{{{  local function set_breakpoint(file, line)
+
+local function set_breakpoint(file, line)
+  if not breakpoints[line] then
+    breakpoints[line] = {}
+  end
+  breakpoints[line][file] = true
+end
+
+--}}}
+--{{{  local function remove_breakpoint(file, line)
+
+local function remove_breakpoint(file, line)
+  if breakpoints[line] then
+    breakpoints[line][file] = nil
+  end
+end
+
+--}}}
+--{{{  local function has_breakpoint(file, line)
+
+--allow for 'sloppy' file names
+--search for file and all variations walking up its directory hierachy
+--ditto for the file with no extension
+
+local function has_breakpoint(file, line)
+  if not breakpoints[line] then return false end
+  local noext = string.gsub(file,"(%..-)$",'',1)
+  if noext == file then noext = nil end
+  while file do
+    if breakpoints[line][file] then return true end
+    file = string.match(file,"[:/\](.+)$")
+  end
+  while noext do
+    if breakpoints[line][noext] then return true end
+    noext = string.match(noext,"[:/\](.+)$")
+  end
+  return false
+end
+
+--}}}
+--{{{  local function capture_vars(ref,level,line)
+
+local function capture_vars(ref,level,line)
+  --get vars, file and line for the given level relative to debug_hook offset by ref
+
+  local lvl = ref + level                --NB: This includes an offset of +1 for the call to here
+
+  --{{{  capture variables
+  
+  local ar = debug.getinfo(lvl, "f")
+  if not ar then return {},'?',0 end
+  
+  local vars = {__UPVALUES__={}, __LOCALS__={}}
+  local i
+  
+  local func = ar.func
+  if func then
+    i = 1
+    while true do
+      local name, value = debug.getupvalue(func, i)
+      if not name then break end
+      if string.sub(name,1,1) ~= '(' then  --NB: ignoring internal control variables
+        vars[name] = value
+        vars.__UPVALUES__[i] = name
+      end
+      i = i + 1
+    end
+    vars.__ENVIRONMENT__ = getfenv(func)
+  end
+  
+  vars.__GLOBALS__ = getfenv(0)
+  
+  i = 1
+  while true do
+    local name, value = debug.getlocal(lvl, i)
+    if not name then break end
+    if string.sub(name,1,1) ~= '(' then    --NB: ignoring internal control variables
+      vars[name] = value
+      vars.__LOCALS__[i] = name
+    end
+    i = i + 1
+  end
+  
+  vars.__VARSLEVEL__ = level
+  
+  if func then
+    --NB: Do not do this until finished filling the vars table
+    setmetatable(vars, { __index = getfenv(func), __newindex = getfenv(func) })
+  end
+  
+  --NB: Do not read or write the vars table anymore else the metatable functions will get invoked!
+  
+  --}}}
+
+  local file = getinfo(lvl, "source")
+  if string.find(file, "@") == 1 then
+    file = string.sub(file, 2)
+  end
+  -- Orxonox changes: Our resource system is case sensisive, even on Windows
+  --if IsWindows then file = string.lower(file) end
+
+  if not line then
+    line = getinfo(lvl, "currentline")
+  end
+
+  return vars,file,line
+
+end
+
+--}}}
+--{{{  local function restore_vars(ref,vars)
+
+local function restore_vars(ref,vars)
+
+  if type(vars) ~= 'table' then return end
+
+  local level = vars.__VARSLEVEL__       --NB: This level is relative to debug_hook offset by ref
+  if not level then return end
+
+  level = level + ref                    --NB: This includes an offset of +1 for the call to here
+
+  local i
+  local written_vars = {}
+
+  i = 1
+  while true do
+    local name, value = debug.getlocal(level, i)
+    if not name then break end
+    if vars[name] and string.sub(name,1,1) ~= '(' then     --NB: ignoring internal control variables
+      debug.setlocal(level, i, vars[name])
+      written_vars[name] = true
+    end
+    i = i + 1
+  end
+
+  local ar = debug.getinfo(level, "f")
+  if not ar then return end
+
+  local func = ar.func
+  if func then
+
+    i = 1
+    while true do
+      local name, value = debug.getupvalue(func, i)
+      if not name then break end
+      if vars[name] and string.sub(name,1,1) ~= '(' then   --NB: ignoring internal control variables
+        if not written_vars[name] then
+          debug.setupvalue(func, i, vars[name])
+        end
+        written_vars[name] = true
+      end
+      i = i + 1
+    end
+
+  end
+
+end
+
+--}}}
+--{{{  local function trace_event(event, line, level)
+
+local function print_trace(level,depth,event,file,line,name)
+
+  --NB: level here is relative to the caller of trace_event, so offset by 2 to get to there
+  level = level + 2
+
+  local file = file or getinfo(level,'short_src')
+  local line = line or getinfo(level,'currentline')
+  local name = name or getinfo(level,'name')
+
+  local prefix = ''
+  if current_thread ~= 'main' then prefix = '['..tostring(current_thread)..'] ' end
+
+  io.write(prefix..
+           string.format('%08.2f:%02i.',os.clock(),depth)..
+           string.rep('.',depth%32)..
+           (file or '')..' ('..(line or '')..') '..
+           (name or '')..
+           ' ('..event..')\n')
+
+end
+
+local function trace_event(event, line, level)
+
+  if event == 'return' and trace_returns then
+    --note the line info for later
+    ret_file = getinfo(level+1,'short_src')
+    ret_line = getinfo(level+1,'currentline')
+    ret_name = getinfo(level+1,'name')
+  end
+
+  if event ~= 'line' then return end
+
+  local slevel = stack_level[current_thread]
+  local tlevel = trace_level[current_thread]
+
+  if trace_calls and slevel > tlevel then
+    --we are now in the function called, so look back 1 level further to find the calling file and line
+    print_trace(level+1,slevel-1,'c',nil,nil,getinfo(level+1,'name'))
+  end
+
+  if trace_returns and slevel < tlevel then
+    print_trace(level,slevel,'r',ret_file,ret_line,ret_name)
+  end
+
+  if trace_lines then
+    print_trace(level,slevel,'l')
+  end
+
+  trace_level[current_thread] = stack_level[current_thread]
+
+end
+
+--}}}
+--{{{  local function debug_hook(event, line, level, thread)
+
+local function debug_hook(event, line, level, thread)
+  if not started then debug.sethook() return end
+  current_thread = thread or 'main'
+  local level = level or 2
+  trace_event(event,line,level)
+  if event == "call" then
+    stack_level[current_thread] = stack_level[current_thread] + 1
+  elseif event == "return" then
+    stack_level[current_thread] = stack_level[current_thread] - 1
+    if stack_level[current_thread] < 0 then stack_level[current_thread] = 0 end
+  else
+    local vars,file,line = capture_vars(level,1,line)
+    local stop, ev, idx = false, events.STEP, 0
+    while true do
+      for index, value in pairs(watches) do
+        setfenv(value.func, vars)
+        local status, res = pcall(value.func)
+        if status and res then
+          ev, idx = events.WATCH, index
+          stop = true
+          break
+        end
+      end
+      if stop then break end
+      if (step_into)
+      or (step_over and (stack_level[current_thread] <= step_level[current_thread] or stack_level[current_thread] == 0)) then
+        step_lines = step_lines - 1
+        if step_lines < 1 then
+          ev, idx = events.STEP, 0
+          break
+        end
+      end
+      if has_breakpoint(file, line) then
+        ev, idx = events.BREAK, 0
+        break
+      end
+      return
+    end
+    tracestack(level)
+    local last_next = 1
+    local err, next = assert(coroutine.resume(coro_debugger, ev, vars, file, line, idx))
+    while true do
+      if next == 'cont' then
+        return
+      elseif next == 'stop' then
+        started = false
+        debug.sethook()
+        return
+      elseif tonumber(next) then --get vars for given level or last level
+        next = tonumber(next)
+        if next == 0 then next = last_next end
+        last_next = next
+        restore_vars(level,vars)
+        vars, file, line = capture_vars(level,next)
+        err, next = assert(coroutine.resume(coro_debugger, events.SET, vars, file, line, idx))
+      else
+        io.write('Unknown command from debugger_loop: '..tostring(next)..'\n')
+        io.write('Stopping debugger\n')
+        next = 'stop'
+      end
+    end
+  end
+end
+
+--}}}
+--{{{  local function report(ev, vars, file, line, idx_watch)
+
+local function report(ev, vars, file, line, idx_watch)
+  local vars = vars or {}
+  local file = file or '?'
+  local line = line or 0
+  local prefix = ''
+  if current_thread ~= 'main' then prefix = '['..tostring(current_thread)..'] ' end
+  if ev == events.STEP then
+    io.write(prefix.."Paused at file "..file.." line "..line..' ('..stack_level[current_thread]..')\n')
+  elseif ev == events.BREAK then
+    io.write(prefix.."Paused at file "..file.." line "..line..' ('..stack_level[current_thread]..') (breakpoint)\n')
+  elseif ev == events.WATCH then
+    io.write(prefix.."Paused at file "..file.." line "..line..' ('..stack_level[current_thread]..')'.." (watch expression "..idx_watch.. ": ["..watches[idx_watch].exp.."])\n")
+  elseif ev == events.SET then
+    --do nothing
+  else
+    io.write(prefix.."Error in application: "..file.." line "..line.."\n")
+  end
+  if ev ~= events.SET then
+    if pausemsg and pausemsg ~= '' then io.write('Message: '..pausemsg..'\n') end
+    pausemsg = ''
+  end
+  return vars, file, line
+end
+
+--}}}
+
+--{{{  local function debugger_loop(server)
+
+local function debugger_loop(ev, vars, file, line, idx_watch)
+
+  io.write("Lua Debugger\n")
+  local eval_env, breakfile, breakline = report(ev, vars, file, line, idx_watch)
+  io.write("Type 'help' for commands\n")
+
+  local command, args
+
+  --{{{  local function getargs(spec)
+  
+  --get command arguments according to the given spec from the args string
+  --the spec has a single character for each argument, arguments are separated
+  --by white space, the spec characters can be one of:
+  -- F for a filename    (defaults to breakfile if - given in args)
+  -- L for a line number (defaults to breakline if - given in args)
+  -- N for a number
+  -- V for a variable name
+  -- S for a string
+  
+  local function getargs(spec)
+    local res={}
+    local char,arg
+    local ptr=1
+    for i=1,string.len(spec) do
+      char = string.sub(spec,i,i)
+      if     char == 'F' then
+        _,ptr,arg = string.find(args..' ',"%s*([%w%p]*)%s*",ptr)
+        if not arg or arg == '' then arg = '-' end
+        if arg == '-' then arg = breakfile end
+      elseif char == 'L' then
+        _,ptr,arg = string.find(args..' ',"%s*([%w%p]*)%s*",ptr)
+        if not arg or arg == '' then arg = '-' end
+        if arg == '-' then arg = breakline end
+        arg = tonumber(arg) or 0
+      elseif char == 'N' then
+        _,ptr,arg = string.find(args..' ',"%s*([%w%p]*)%s*",ptr)
+        if not arg or arg == '' then arg = '0' end
+        arg = tonumber(arg) or 0
+      elseif char == 'V' then
+        _,ptr,arg = string.find(args..' ',"%s*([%w%p]*)%s*",ptr)
+        if not arg or arg == '' then arg = '' end
+      elseif char == 'S' then
+        _,ptr,arg = string.find(args..' ',"%s*([%w%p]*)%s*",ptr)
+        if not arg or arg == '' then arg = '' end
+      else
+        arg = ''
+      end
+      table.insert(res,arg or '')
+    end
+    return unpack(res)
+  end
+  
+  --}}}
+
+  while true do
+    io.write("[DEBUG]> ")
+    local line = io.read("*line")
+    if line == nil then io.write('\n'); line = 'exit' end
+
+    if string.find(line, "^[a-z]+") then
+      command = string.sub(line, string.find(line, "^[a-z]+"))
+      args    = string.gsub(line,"^[a-z]+%s*",'',1)            --strip command off line
+    else
+      command = ''
+    end
+
+    if command == "setb" then
+      --{{{  set breakpoint
+      
+      local line, filename  = getargs('LF')
+      if filename ~= '' and line ~= '' then
+        set_breakpoint(filename,line)
+        io.write("Breakpoint set in file "..filename..' line '..line..'\n')
+      else
+        io.write("Bad request\n")
+      end
+      
+      --}}}
+
+    elseif command == "delb" then
+      --{{{  delete breakpoint
+      
+      local line, filename = getargs('LF')
+      if filename ~= '' and line ~= '' then
+        remove_breakpoint(filename, line)
+        io.write("Breakpoint deleted from file "..filename..' line '..line.."\n")
+      else
+        io.write("Bad request\n")
+      end
+      
+      --}}}
+
+    elseif command == "delallb" then
+      --{{{  delete all breakpoints
+      breakpoints = {}
+      io.write('All breakpoints deleted\n')
+      --}}}
+
+    elseif command == "listb" then
+      --{{{  list breakpoints
+      for i, v in pairs(breakpoints) do
+        for ii, vv in pairs(v) do
+          io.write("Break at: "..i..' in '..ii..'\n')
+        end
+      end
+      --}}}
+
+    elseif command == "setw" then
+      --{{{  set watch expression
+      
+      if args and args ~= '' then
+        local func = loadstring("return(" .. args .. ")")
+        local newidx = #watches + 1
+        watches[newidx] = {func = func, exp = args}
+        io.write("Set watch exp no. " .. newidx..'\n')
+      else
+        io.write("Bad request\n")
+      end
+      
+      --}}}
+
+    elseif command == "delw" then
+      --{{{  delete watch expression
+      
+      local index = tonumber(args)
+      if index then
+        watches[index] = nil
+        io.write("Watch expression deleted\n")
+      else
+        io.write("Bad request\n")
+      end
+      
+      --}}}
+
+    elseif command == "delallw" then
+      --{{{  delete all watch expressions
+      watches = {}
+      io.write('All watch expressions deleted\n')
+      --}}}
+
+    elseif command == "listw" then
+      --{{{  list watch expressions
+      for i, v in pairs(watches) do
+        io.write("Watch exp. " .. i .. ": " .. v.exp..'\n')
+      end
+      --}}}
+
+    elseif command == "run" then
+      --{{{  run until breakpoint
+      step_into = false
+      step_over = false
+      eval_env, breakfile, breakline = report(coroutine.yield('cont'))
+      --}}}
+
+    elseif command == "step" then
+      --{{{  step N lines (into functions)
+      local N = tonumber(args) or 1
+      step_over  = false
+      step_into  = true
+      step_lines = tonumber(N or 1)
+      eval_env, breakfile, breakline = report(coroutine.yield('cont'))
+      --}}}
+
+    elseif command == "over" then
+      --{{{  step N lines (over functions)
+      local N = tonumber(args) or 1
+      step_into  = false
+      step_over  = true
+      step_lines = tonumber(N or 1)
+      step_level[current_thread] = stack_level[current_thread]
+      eval_env, breakfile, breakline = report(coroutine.yield('cont'))
+      --}}}
+
+    elseif command == "out" then
+      --{{{  step N lines (out of functions)
+      local N = tonumber(args) or 1
+      step_into  = false
+      step_over  = true
+      step_lines = 1
+      step_level[current_thread] = stack_level[current_thread] - tonumber(N or 1)
+      eval_env, breakfile, breakline = report(coroutine.yield('cont'))
+      --}}}
+
+    elseif command == "goto" then
+      --{{{  step until reach line
+      local N = tonumber(args)
+      if N then
+        step_over  = false
+        step_into  = false
+        if has_breakpoint(breakfile,N) then
+          eval_env, breakfile, breakline = report(coroutine.yield('cont'))
+        else
+          local bf = breakfile
+          set_breakpoint(breakfile,N)
+          eval_env, breakfile, breakline = report(coroutine.yield('cont'))
+          if breakfile == bf and breakline == N then remove_breakpoint(breakfile,N) end
+        end
+      else
+        io.write("Bad request\n")
+      end
+      --}}}
+
+    elseif command == "set" then
+      --{{{  set/show context level
+      local level = args
+      if level and level == '' then level = nil end
+      if level then
+        eval_env, breakfile, breakline = report(coroutine.yield(level))
+      end
+      if eval_env.__VARSLEVEL__ then
+        io.write('Level: '..eval_env.__VARSLEVEL__..'\n')
+      else
+        io.write('No level set\n')
+      end
+      --}}}
+
+    elseif command == "vars" then
+      --{{{  list context variables
+      local depth = args
+      if depth and depth == '' then depth = nil end
+      depth = tonumber(depth) or 1
+      dumpvar(eval_env, depth+1, 'variables')
+      --}}}
+
+    elseif command == "glob" then
+      --{{{  list global variables
+      local depth = args
+      if depth and depth == '' then depth = nil end
+      depth = tonumber(depth) or 1
+      dumpvar(eval_env.__GLOBALS__,depth+1,'globals')
+      --}}}
+
+    elseif command == "fenv" then
+      --{{{  list function environment variables
+      local depth = args
+      if depth and depth == '' then depth = nil end
+      depth = tonumber(depth) or 1
+      dumpvar(eval_env.__ENVIRONMENT__,depth+1,'environment')
+      --}}}
+
+    elseif command == "ups" then
+      --{{{  list upvalue names
+      dumpvar(eval_env.__UPVALUES__,2,'upvalues')
+      --}}}
+
+    elseif command == "locs" then
+      --{{{  list locals names
+      dumpvar(eval_env.__LOCALS__,2,'upvalues')
+      --}}}
+
+    elseif command == "what" then
+      --{{{  show where a function is defined
+      if args and args ~= '' then
+        local v = eval_env
+        local n = nil
+        for w in string.gmatch(args,"[%w_]+") do
+          v = v[w]
+          if n then n = n..'.'..w else n = w end
+          if not v then break end
+        end
+        if type(v) == 'function' then
+          local def = debug.getinfo(v,'S')
+          if def then
+            io.write(def.what..' in '..def.short_src..' '..def.linedefined..'..'..def.lastlinedefined..'\n')
+          else
+            io.write('Cannot get info for '..v..'\n')
+          end
+        else
+          io.write(v..' is not a function\n')
+        end
+      else
+        io.write("Bad request\n")
+      end
+      --}}}
+
+    elseif command == "dump" then
+      --{{{  dump a variable
+      local name, depth = getargs('VN')
+      if name ~= '' then
+        if depth == '' or depth == 0 then depth = nil end
+        depth = tonumber(depth or 1)
+        local v = eval_env
+        local n = nil
+        for w in string.gmatch(name,"[^%.]+") do     --get everything between dots
+          if tonumber(w) then
+            v = v[tonumber(w)]
+          else
+            v = v[w]
+          end
+          if n then n = n..'.'..w else n = w end
+          if not v then break end
+        end
+        dumpvar(v,depth+1,n)
+      else
+        io.write("Bad request\n")
+      end
+      --}}}
+
+    elseif command == "show" then
+      --{{{  show file around a line or the current breakpoint
+      
+      local line, file, before, after = getargs('LFNN')
+      if before == 0 then before = 10     end
+      if after  == 0 then after  = before end
+      
+      if file ~= '' and file ~= "=stdin" then
+        show(file,line,before,after)
+      else
+        io.write('Nothing to show\n')
+      end
+      
+      --}}}
+
+    elseif command == "poff" then
+      --{{{  turn pause command off
+      pause_off = true
+      --}}}
+
+    elseif command == "pon" then
+      --{{{  turn pause command on
+      pause_off = false
+      --}}}
+
+    elseif command == "tron" then
+      --{{{  turn tracing on/off
+      local option = getargs('S')
+      trace_calls   = false
+      trace_returns = false
+      trace_lines   = false
+      if string.find(option,'c') then trace_calls   = true end
+      if string.find(option,'r') then trace_returns = true end
+      if string.find(option,'l') then trace_lines   = true end
+      --}}}
+
+    elseif command == "trace" then
+      --{{{  dump a stack trace
+      trace(eval_env.__VARSLEVEL__)
+      --}}}
+
+    elseif command == "info" then
+      --{{{  dump all debug info captured
+      info()
+      --}}}
+
+    elseif command == "pause" then
+      --{{{  not allowed in here
+      io.write('pause() should only be used in the script you are debugging\n')
+      --}}}
+
+    elseif command == "help" then
+      --{{{  help
+      local command = getargs('S')
+      if command ~= '' and hints[command] then
+        io.write(hints[command]..'\n')
+      else
+        for _,v in pairs(hints) do
+          local _,_,h = string.find(v,"(.+)|")
+          io.write(h..'\n')
+        end
+      end
+      --}}}
+
+    elseif command == "exit" then
+      --{{{  exit debugger
+      return 'stop'
+      --}}}
+
+    elseif line ~= '' then
+      --{{{  just execute whatever it is in the current context
+      
+      --map line starting with "=..." to "return ..."
+      if string.sub(line,1,1) == '=' then line = string.gsub(line,'=','return ',1) end
+      
+      local ok, func = pcall(loadstring,line)
+      if func == nil then                             --Michael.Bringmann@lsi.com
+        io.write("Compile error: "..line..'\n')
+      elseif not ok then
+        io.write("Compile error: "..func..'\n')
+      else
+        setfenv(func, eval_env)
+        local res = {pcall(func)}
+        if res[1] then
+          if res[2] then
+            table.remove(res,1)
+            for _,v in ipairs(res) do
+              io.write(tostring(v))
+              io.write('\t')
+            end
+            io.write('\n')
+          end
+          --update in the context
+          eval_env, breakfile, breakline = report(coroutine.yield(0))
+        else
+          io.write("Run error: "..res[2]..'\n')
+        end
+      end
+      
+      --}}}
+    end
+  end
+
+end
+
+--}}}
+
+--{{{  coroutine.create
+
+--This function overrides the built-in for the purposes of propagating
+--the debug hook settings from the creator into the created coroutine.
+
+_G.coroutine.create = function(f)
+  local thread
+  local hook, mask, count = debug.gethook()
+  if hook then
+    local function thread_hook(event,line)
+      hook(event,line,3,thread)
+    end
+    thread = cocreate(function(...)
+                        stack_level[thread] = 0
+                        trace_level[thread] = 0
+                        step_level [thread] = 0
+                        debug.sethook(thread_hook,mask,count)
+                        return f(...)
+                      end)
+    return thread
+  else
+    return cocreate(f)
+  end
+end
+
+--}}}
+--{{{  coroutine.wrap
+
+--This function overrides the built-in for the purposes of propagating
+--the debug hook settings from the creator into the created coroutine.
+
+_G.coroutine.wrap = function(f)
+  local thread
+  local hook, mask, count = debug.gethook()
+  if hook then
+    local function thread_hook(event,line)
+      hook(event,line,3,thread)
+    end
+    thread = cowrap(function(...)
+                      stack_level[thread] = 0
+                      trace_level[thread] = 0
+                      step_level [thread] = 0
+                      debug.sethook(thread_hook,mask,count)
+                      return f(...)
+                    end)
+    return thread
+  else
+    return cowrap(f)
+  end
+end
+
+--}}}
+
+--{{{  function pause()
+
+--
+-- Starts/resumes a debug session
+--
+
+function pause(x)
+  if pause_off then return end               --being told to ignore pauses
+  pausemsg = x or 'pause'
+  local lines
+  local src = getinfo(2,'short_src')
+  if src == "stdin" then
+    lines = 1   --if in a console session, stop now
+  else
+    lines = 2   --if in a script, stop when get out of pause()
+  end
+  if started then
+    --we'll stop now 'cos the existing debug hook will grab us
+    step_lines = lines
+    step_into  = true
+  else
+    coro_debugger = cocreate(debugger_loop)  --NB: Use original coroutune.create
+    --set to stop when get out of pause()
+    trace_level[current_thread] = 0
+    step_level [current_thread] = 0
+    stack_level[current_thread] = 1
+    step_lines = lines
+    step_into  = true
+    started    = true
+    debug.sethook(debug_hook, "crl")         --NB: this will cause an immediate entry to the debugger_loop
+  end
+end
+
+--}}}
+--{{{  function dump()
+
+--shows the value of the given variable, only really useful
+--when the variable is a table
+--see dump debug command hints for full semantics
+
+function dump(v,depth)
+  dumpvar(v,(depth or 1)+1,tostring(v))
+end
+
+--}}}
+--{{{  function debug.traceback(x)
+
+local _traceback = debug.traceback       --note original function
+
+--override standard function
+debug.traceback = function(x)
+  local assertmsg = _traceback(x)        --do original function
+  pause(x)                               --let user have a look at stuff
+  return assertmsg                       --carry on
+end
+
+_TRACEBACK = debug.traceback             --Lua 5.0 function
+
+--}}}
+
Index: /code/branches/rocket2/data/lua/LuaStateInit.lua
===================================================================
--- /code/branches/rocket2/data/lua/LuaStateInit.lua	(revision 6952)
+++ /code/branches/rocket2/data/lua/LuaStateInit.lua	(revision 6952)
@@ -0,0 +1,129 @@
+-- Note: luaState is a pointer to the LuaState instance that created this lua state
+
+-- Redirect print to the C++ print function
+original_print = print
+print = function(s)
+  luaState:luaPrint(s)
+end
+
+-- Create function to log text like COUT, but always prints a line!
+logMessage = function(level, message)
+  luaState:luaLog(level, message)
+end
+cout = logMessage
+
+-- Redirect dofile in order to load with the resource manager
+original_dofile = dofile
+dofile = function(filename)
+  if not luaState:doFile(filename) then
+    error("Error propagation. Do not display")
+  end
+  -- Required because if the file returns a table, it cannot be passed through the C++ function
+  return LuaStateReturnValue -- C-injected global variable
+end
+doFile = dofile
+
+-- Create includeFile function that preparses the file according
+-- to a function provided to the LuaState constructor (in C++)
+include = function(filename)
+  if not luaState:includeFile(filename) then
+    error("Error propagation. Do not display")
+  end
+  -- Required because if the file returns a table, it cannot be passed through the C++ function
+  return LuaStateReturnValue -- C-injected global variable
+end
+
+-- Replace require function with almost similar behaviour
+-- The loaded modules are then stored with their names (where name has no .lua extension)
+-- Furthermore the ".lua" extension is appended to the moduleName parameter when looking for the file
+original_require = require
+_REQUIREDNAME = ""
+LuaStateReturnValue = true
+require = function(moduleName)
+  if not luaState:fileExists(moduleName .. ".lua") then
+    logMessage(2, "Warning: Lua function require() could not find file '" .. moduleName .. ".lua' ")
+    return nil
+  end
+
+  if not _LOADED then
+    _LOADED = {}
+  end
+  if not _LOADED_RETURN_VALUES then
+      _LOADED_RETURN_VALUES = {}
+  end
+
+  if not _LOADED[moduleName] then
+    -- save old value for the required name
+    local _REQUIREDNAME_OLD = _REQUIREDNAME
+    _REQUIREDNAME = moduleName
+
+    if not luaState:doFile(moduleName .. ".lua") then
+      error("Error propagation. Do not display")
+    end
+    -- LuaStateReturnValue is required because if the file returns a table,
+    -- it cannot be passed through the C++ function
+    _LOADED_RETURN_VALUES[moduleName] = LuaStateReturnValue
+    _LOADED[moduleName] = true
+
+    -- restore old value
+    _REQUIREDNAME = _REQUIREDNAME_OLD
+  end
+  local asdf = _LOADED_RETURN_VALUES[moduleName]
+  return asdf
+end
+
+
+-- Load useful tool functions (like handleDefaultArgument)
+require("Tools")
+
+
+-- Include command line debugger for lua 5.1
+-- Note: It doesn't work if the IOConsole was started. Then we replace pause() with a warning
+if _VERSION ~= "Lua 5.0"  and not luaState:usingIOConsole() then
+  require("Debugger")
+else
+  -- Fallback pause function
+  pause = function()
+    logMessage(2, [["Warning: debug() called in Lua, but Debugger is not active.
+Do you have the IOConsole disabled and are you using Lua version 5.1?"]])
+  end
+end
+
+-- General error handler that gets called whenever an error happens at runtime
+errorHandler = function(err)
+  if type(err) == "string" then
+    -- Simply return if the error has already been handled
+    if string.find(err, "Error propagation. Do not display") ~= nil then
+      return err
+    end
+    -- Display the error message
+    logMessage(1, "Lua runtime error: "..err)
+  end
+
+  -- Start debugger if possible
+  if _LOADED and _LOADED["Debugger"] ~= nil then
+    pause()
+  else
+    -- Fallback: print stack trace
+    logMessage(3, debug.traceback(""))
+  end
+  return err -- Hello Lua debugger user! Please type 'set 2' to get to the
+             -- actual position in the stack where the error occurred
+end
+
+
+-- Convenience function for console commands
+orxonox.execute = function(command)
+  orxonox.CommandExecutor:execute(command)
+end
+
+-- Convenience function for config values
+orxonox.getConfig = function(section, entry)
+  return orxonox.SettingsConfigFile:getInstance():getConfig(section, entry)
+end
+orxonox.config = function(section, entry, value)
+  return orxonox.SettingsConfigFile:getInstance():config(section, entry, value)
+end
+orxonox.tconfig = function(section, entry, value)
+  return orxonox.SettingsConfigFile:getInstance():tconfig(section, entry, value)
+end
Index: /code/branches/rocket2/data/lua/Strict.lua
===================================================================
--- /code/branches/rocket2/data/lua/Strict.lua	(revision 6952)
+++ /code/branches/rocket2/data/lua/Strict.lua	(revision 6952)
@@ -0,0 +1,39 @@
+--
+-- strict.lua
+-- checks uses of undeclared global variables
+-- All global variables must be 'declared' through a regular assignment
+-- (even assigning nil will do) in a main chunk before being used
+-- anywhere or assigned to inside a function.
+--
+
+local mt = getmetatable(_G)
+if mt == nil then
+  mt = {}
+  setmetatable(_G, mt)
+end
+
+__STRICT = false
+mt.__declared = {}
+
+mt.__newindex = function (t, n, v)
+  if __STRICT and not mt.__declared[n] then
+    local d = debug.getinfo(2, "S")
+    local w = d and d.what or "C"
+    if w ~= "main" and w ~= "C" then
+      error("assign to undeclared variable '"..n.."'", 2)
+    end
+    mt.__declared[n] = true
+  end
+  rawset(t, n, v)
+end
+  
+mt.__index = function (t, n)
+  if not mt.__declared[n] and debug.getinfo(2, "S").what ~= "C" then
+    error("variable '"..n.."' is not declared", 2)
+  end
+  return rawget(t, n)
+end
+
+function global(...)
+   for _, v in ipairs{...} do mt.__declared[v] = true end
+end
Index: /code/branches/rocket2/data/lua/Tools.lua
===================================================================
--- /code/branches/rocket2/data/lua/Tools.lua	(revision 6952)
+++ /code/branches/rocket2/data/lua/Tools.lua	(revision 6952)
@@ -0,0 +1,24 @@
+function handleDefArg(argument, defaultValue)
+    if argument == nil then
+        return defaultValue
+    else
+        return argument
+    end
+end
+
+function table.findIndex(table, value)
+    for i, v in ipairs(table) do
+        if v == value then
+            return i
+        end
+    end
+    return 0
+end
+
+-- Short forms for TriBool
+TriBool =
+{
+    True     = orxonox.TriBool.True,
+    False    = orxonox.TriBool.False,
+    Dontcare = orxonox.TriBool.Dontcare
+}
Index: /code/branches/rocket2/data/overlays/OrxonoxLoading.overlay
===================================================================
--- /code/branches/rocket2/data/overlays/OrxonoxLoading.overlay	(revision 6952)
+++ /code/branches/rocket2/data/overlays/OrxonoxLoading.overlay	(revision 6952)
@@ -0,0 +1,13 @@
+Orxonox/LoadingScreenSample
+{
+   container Panel(Orxonox/LoadingScreenSample)
+   {
+      metrics_mode pixels
+      vert_align top
+      left 12
+      top 12
+      width 300
+      height 300
+      material Orxonox/LoadingScreenSample
+   }
+}
Index: /code/branches/rocket2/data/overlays/debug.oxo
===================================================================
--- /code/branches/rocket2/data/overlays/debug.oxo	(revision 6952)
+++ /code/branches/rocket2/data/overlays/debug.oxo	(revision 6952)
@@ -0,0 +1,86 @@
+<!-- DEBUG OVERLAY -->
+<OverlayGroup
+ name    = "Debug"
+ scale   = "1.0, 1.0"
+ scroll  = "0, 0"
+ visible = false
+>
+  <OverlayText
+   name     = "FPSTextCaption"
+   position = "0.03, 0.05"
+   font     = "Monofur"
+   caption  = "Frames per second:"
+   textsize = 0.03
+  />
+
+  <DebugFPSText
+   name     = "FPSText"
+   position = "0.3, 0.05"
+   font     = "Monofur"
+   textsize = 0.03
+  />
+
+  <OverlayText
+   name     = "RTRTextCaption"
+   position = "0.03, 0.09"
+   font     = "Monofur"
+   caption  = "Tick time in ms: "
+   textsize = 0.03
+  />
+
+  <DebugRTRText
+   name     = "RTRText"
+   position = "0.3, 0.09"
+   font     = "Monofur"
+   textsize = 0.03
+  />
+
+</OverlayGroup>
+
+<Template name="defaultHUD">
+  <OverlayGroup name = "defaultHUD" scale = "1, 1">
+    <ChatOverlay
+     name     = "chat"
+     position = "0.03, 0.08"
+     font     = "VeraMono"
+     caption  = ""
+     textsize = 0.025
+    />
+
+    <KillMessage
+     name     = "killmessage"
+     position = "0.5, 0.15"
+     font     = "VeraMono"
+     textsize = 0.035
+     colour   = "1.0, 1.0, 0.5, 1.0"
+     align    = "center"
+    />
+
+    <DeathMessage
+     name     = "deathmessage"
+     position = "0.5, 0.20"
+     font     = "VeraMono"
+     textsize = 0.035
+     colour   = "1.0, 0.3, 0.3, 1.0"
+     align    = "center"
+    />
+
+    <AnnounceMessage
+     name     = "announcemessage"
+     position = "0.5, 0.75"
+     font     = "VeraMono"
+     textsize = 0.05
+     colour   = "0.5, 0.5, 1.0, 1.0"
+     align    = "center"
+    />
+
+    <GametypeStatus
+     name     = "state"
+     position = "0.5, 0.85"
+     font     = "VeraMono"
+     textsize = 0.05
+     colour   = "1.0, 1.0, 0.0, 0.8"
+     align    = "center"
+    />
+  </OverlayGroup>
+</Template>
Index: /code/branches/rocket2/data/overlays/hud.oxo
===================================================================
--- /code/branches/rocket2/data/overlays/hud.oxo	(revision 6952)
+++ /code/branches/rocket2/data/overlays/hud.oxo	(revision 6952)
@@ -0,0 +1,109 @@
+<!-- HUD OVERLAY -->
+<OverlayGroup name = "HUD" scale = "1, 1">
+
+  <HUDSpeedBar
+   name       = "SpeedBar1"
+   background = "Orxonox/BarBackground"
+   size       = "0.35, 0.05"
+   position   = "0.0 , 1.0 "
+   pickPoint  = "0, 1"
+   value      = 0
+  >
+    <BarColour position = 0.7 colour = "0.2,0.7,0.2" />
+    <BarColour position = 0.4 colour = "0.7,0.5,0.2" />
+    <BarColour position = 0.1 colour = "0.7,0.2,0.2" />
+  </HUDSpeedBar>
+
+  <!--HUDSpeedBar
+   name       = "SpeedBar2"
+   background = "Orxonox/BarBackground"
+   size       = "0.35, 0.05"
+   position   = "1.0 , 1.0 "
+   pickPoint  = "1, 1"
+   value      = 0
+   rightToLeft = true
+  >
+    <BarColour position = 0.7 colour = "0.2,0.7,0.2" />
+    <BarColour position = 0.4 colour = "0.7,0.5,0.2" />
+    <BarColour position = 0.1 colour = "0.7,0.2,0.2" />
+  </HUDSpeedBar>
+
+  <HUDSpeedBar
+   name       = "SpeedBar3"
+   background = "Orxonox/BarBackground"
+   size       = "0.35, 0.05"
+   position   = "1.0 , 0.0 "
+   pickPoint  = "1, 0"
+   value      = 0
+   rightToLeft = true
+  >
+    <BarColour position = 0.7 colour = "0.2,0.7,0.2" />
+    <BarColour position = 0.4 colour = "0.7,0.5,0.2" />
+    <BarColour position = 0.1 colour = "0.7,0.2,0.2" />
+  </HUDSpeedBar>
+
+  <HUDSpeedBar
+   name       = "SpeedBar4"
+   background = "Orxonox/BarBackground"
+   size       = "0.35, 0.05"
+   position   = "0.0 , 0.0 "
+   pickPoint  = "0, 0"
+   rotation   = 0
+   value      = 0
+  >
+    <BarColour position = 0.7 colour = "0.2,0.7,0.2" />
+    <BarColour position = 0.4 colour = "0.7,0.5,0.2" />
+    <BarColour position = 0.1 colour = "0.7,0.2,0.2" />
+  </HUDSpeedBar-->
+
+  <HUDNavigation
+   name          = "Navigation"
+   correctAspect = true
+   font          = "Monofur"
+   textSize      = 0.05
+   navMarkerSize = 0.03
+   aimMarkerSize = 0.04
+  />
+
+  <HUDRadar
+   name          = "Radar"
+   background    = "Orxonox/Radar"
+   correctAspect = true
+   size          = "0.17, 0.17"
+   position      = "0.5, 1.0"
+   pickPoint     = "0.5, 1.0"
+   rotation      = 0
+   sensitivity   = 1.0
+   halfDotSizeDistance = 3000
+   maximumDotSize      = 0.1
+  />
+
+  <ChatOverlay
+   name     = "chat"
+   position = "0.03, 0.5"
+   font     = "VeraMono"
+   caption  = ""
+   textSize = 0.025
+  />
+</OverlayGroup>
+
+
+<!-- DEBUG OVERLAY -->
+<OverlayGroup name = "Debug" scale = "1.0, 1.0" scroll = "0, 0" visible=false>
+
+  <DebugFPSText
+   name     = "FPSText"
+   position = "0.03, 0.05"
+   font     = "Monofur"
+   caption  = "Frames per second: "
+   textSize = 0.03
+  />
+
+  <DebugRTRText
+   name     = "RTRText"
+   position = "0.03, 0.09"
+   font     = "Monofur"
+   caption  = "Tick time in ms: "
+   textSize = 0.03
+  />
+</OverlayGroup>
Index: /code/branches/rocket2/data/overlays/hudtemplates3.oxo
===================================================================
--- /code/branches/rocket2/data/overlays/hudtemplates3.oxo	(revision 6952)
+++ /code/branches/rocket2/data/overlays/hudtemplates3.oxo	(revision 6952)
@@ -0,0 +1,111 @@
+<!--
+<Template name="defaultHUD">
+  <OverlayGroup name = "defaultHUD" scale = "1, 1">
+    <ChatOverlay
+     name     = "chat"
+     position = "0.03, 0.5"
+     font     = "VeraMono"
+     caption  = ""
+     textsize = 0.025
+    />
+
+    <GametypeStatus
+     name     = "state"
+     position = "0.5, 0.85"
+     font     = "VeraMono"
+     textsize = 0.05
+     colour   = "1.0, 1.0, 0.0, 0.8"
+     align    = "center"
+    />
+  </OverlayGroup>
+</Template>
+-->
+
+<Template name="spectatorhud">
+  <OverlayGroup name = "spectatorhud" scale = "1, 1">
+  </OverlayGroup>
+</Template>
+
+<Template name="spaceshiphud">
+  <OverlayGroup name = "spaceshiphud" scale = "1, 1">
+    <Map />
+
+    <HUDHealthBar
+     name              = "HealthBar1"
+     background        = "Orxonox/HealthBarBackground"
+     size              = "0.35, 0.0875"
+     position          = "0.0 , 0.95 "
+     pickpoint         = "0, 1"
+     bartexture        = "healthbar_bar.tga"
+     textfont          = "VeraMono"
+     textusebarcolour  = true
+     textsize          = 0.039
+     textoffset        = "0.315, 0.05"
+     textpickpoint     = "0, 0"
+     textalign         = "right"
+     correctaspect     = false
+     textcorrectaspect = false
+    >
+      <BarColour position = 0.0 colour = "0.7,0.2,0.2" />
+      <BarColour position = 0.5 colour = "0.7,0.7,0.2" />
+      <BarColour position = 1.0 colour = "0.2,0.7,0.2" />
+    </HUDHealthBar>
+
+    <HUDSpeedBar
+     name          = "SpeedBar1"
+     background    = "Orxonox/BarBackground"
+     size          = "0.35, 0.05"
+     position      = "0.0 , 1.0 "
+     pickpoint     = "0, 1"
+     correctaspect = false
+    >
+      <BarColour position = 0.0 colour = "0.7,0.5,0.2" />
+      <BarColour position = 0.5 colour = "0.2,0.7,0.2" />
+      <BarColour position = 1.0 colour = "0.7,0.2,0.2" />
+    </HUDSpeedBar>
+
+    <HUDNavigation
+     name          = "Navigation"
+     correctaspect = true
+     font          = "Monofur"
+     textsize      = 0.05
+     navMarkerSize = 0.03
+     aimMarkerSize = 0.04
+    />
+
+    <HUDRadar
+     name          = "Radar"
+     background    = "Orxonox/Radar"
+     correctaspect = true
+     size          = "0.17, 0.17"
+     position      = "1.0, 1.0"
+     pickpoint     = "1.0, 1.0"
+     rotation      = 0
+     sensitivity   = 1.0
+     halfDotSizeDistance = 3000
+     maximumDotSize      = 0.1
+    />
+
+    <HUDTimer
+     name     = "Timer"
+     position = "0.5, 0.85"
+     font     = "VeraMono"
+     textsize = 0.1
+     colour   = "1.0, 1.0, 0.0, 0.8"
+     align    = "center"
+    />
+
+    <GUIOverlay
+      name = "QuestGUI"
+      guiname = "QuestGUI"
+      visible = "false"
+    />
+    
+    <GUIOverlay
+      name = "PickupInventory"
+      guiname = "PickupInventory"
+      visible = "false"
+    />
+
+  </OverlayGroup>
+</Template>
Index: /code/branches/rocket2/data/overlays/ponghud.oxo
===================================================================
--- /code/branches/rocket2/data/overlays/ponghud.oxo	(revision 6952)
+++ /code/branches/rocket2/data/overlays/ponghud.oxo	(revision 6952)
@@ -0,0 +1,70 @@
+<Template name="PongHUD">
+  <OverlayGroup name="PongHUD" scale = "1, 1">
+    <PongScore
+     position  = "0.05, 0.05"
+     pickpoint = "0.0, 0.0"
+     font      = "ShareTechMono"
+     textsize  = 0.06
+     colour    = "1.0, 1.0, 1.0, 1.0"
+     align     = "left"
+
+     showleftplayer  = true
+     showrightplayer = false
+     showname        = true
+     showscore       = false
+    />
+
+    <PongScore
+     position  = "0.49, 0.05"
+     pickpoint = "0.0, 0.0"
+     font      = "ShareTechMono"
+     textsize  = 0.06
+     colour    = "1.0, 1.0, 1.0, 1.0"
+     align     = "right"
+
+     showleftplayer  = true
+     showrightplayer = false
+     showname        = false
+     showscore       = true
+    />
+
+    <OverlayText
+     position  = "0.505, 0.05"
+     pickpoint = "0.0, 0.0"
+     font      = "ShareTechMono"
+     textsize  = 0.06
+     colour    = "1.0, 1.0, 1.0, 1.0"
+     align     = "center"
+
+     caption   = ":"
+    />
+
+    <PongScore
+     position  = "0.51, 0.05"
+     pickpoint = "0.0, 0.0"
+     font      = "ShareTechMono"
+     textsize  = 0.06
+     colour    = "1.0, 1.0, 1.0, 1.0"
+     align     = "left"
+
+     showleftplayer  = false
+     showrightplayer = true
+     showname        = false
+     showscore       = true
+    />
+
+    <PongScore
+     position  = "0.95, 0.05"
+     pickpoint = "0.0, 0.0"
+     font      = "ShareTechMono"
+     textsize  = 0.06
+     colour    = "1.0, 1.0, 1.0, 1.0"
+     align     = "right"
+
+     showleftplayer  = false
+     showrightplayer = true
+     showname        = true
+     showscore       = false
+    />
+  </OverlayGroup>
+</Template>
Index: /code/branches/rocket2/data/overlays/stats.oxo
===================================================================
--- /code/branches/rocket2/data/overlays/stats.oxo	(revision 6952)
+++ /code/branches/rocket2/data/overlays/stats.oxo	(revision 6952)
@@ -0,0 +1,56 @@
+<!-- Statistics Overlay -->
+<Template name=defaultScoreboard>
+    <OverlayGroup name = "Stats" scale = "1, 1" visible=false>
+
+      <!--OverlayText
+       name      = "Title"
+       position  = "0.79, 0.19"
+       pickpoint = "1, 1"
+       font      = "Monofur"
+       caption   = "Scoreboard"
+       colour    = "0, 0.75, 0.2, 1"
+       textsize  = 0.04
+      /-->
+
+      <OverlayText
+       name      = "descr1"
+       position  = "0.1, 0.20"
+       pickpoint = "0, 1"
+       font      = "Monofur"
+       caption   = "player name"
+       colour    = "0, 0.75, 0.2, 1"
+       textsize  = 0.04
+      />
+      <OverlayText
+       name      = "descr2"
+       position  = "0.6, 0.20"
+       pickpoint = "0, 1"
+       font      = "Monofur"
+       caption   = "score"
+       colour    = "0, 0.75, 0.2, 1"
+       textsize  = 0.04
+      />
+      <OverlayText
+       name      = "descr3"
+       position  = "0.8, 0.20"
+       pickpoint = "0, 1"
+       font      = "Monofur"
+       caption   = "deaths"
+       colour    = "0, 0.75, 0.2, 1"
+       textsize  = 0.04
+      />
+
+      <!--Stats
+       name     = "Statistics"
+       position = "0.5, 0.7"
+       size = "0.85, 0.4"
+       correctaspect = false
+       pickpoint = "0.5, 0.5"
+      /-->
+
+      <Scoreboard
+       name     = "Scores"
+      />
+
+    </OverlayGroup>
+</Template>
Index: /code/branches/rocket2/data/overlays/teambasematchhud.oxo
===================================================================
--- /code/branches/rocket2/data/overlays/teambasematchhud.oxo	(revision 6952)
+++ /code/branches/rocket2/data/overlays/teambasematchhud.oxo	(revision 6952)
@@ -0,0 +1,90 @@
+<Template name="TeamBaseMatchHUD">
+  <OverlayGroup name="TeamBaseMatchHUD" scale = "1, 1">
+    <OverlayText
+     position  = "0.2, 0.05"
+     pickpoint = "0.0, 0.0"
+     font      = "ShareTechMono"
+     textsize  = 0.04
+     colour    = "1.0, 0.5, 0.5, 1.0"
+     align     = "left"
+     caption   = "Red team"
+    />
+
+    <TeamBaseMatchScore
+     position  = "0.37, 0.05"
+     pickpoint = "0.0, 0.0"
+     font      = "ShareTechMono"
+     textsize  = 0.04
+     colour    = "1.0, 0.8, 0.8, 1.0"
+     align     = "left"
+
+     showleftteam  = true
+     showrightteam = false
+     showbases     = true
+     showscore     = false
+    />
+
+    <TeamBaseMatchScore
+     position  = "0.49, 0.05"
+     pickpoint = "0.0, 0.0"
+     font      = "ShareTechMono"
+     textsize  = 0.04
+     colour    = "1.0, 0.8, 0.8, 1.0"
+     align     = "right"
+
+     showleftteam  = true
+     showrightteam = false
+     showbases     = false
+     showscore     = true
+    />
+
+    <OverlayText
+     position  = "0.505, 0.05"
+     pickpoint = "0.0, 0.0"
+     font      = "ShareTechMono"
+     textsize  = 0.04
+     colour    = "0.8, 0.8, 0.8, 1.0"
+     align     = "center"
+
+     caption   = ":"
+    />
+
+    <TeamBaseMatchScore
+     position  = "0.51, 0.05"
+     pickpoint = "0.0, 0.0"
+     font      = "ShareTechMono"
+     textsize  = 0.04
+     colour    = "0.8, 0.8, 1.0, 1.0"
+     align     = "left"
+
+     showleftteam  = false
+     showrightteam = true
+     showbases     = false
+     showscore     = true
+    />
+
+    <TeamBaseMatchScore
+     position  = "0.63, 0.05"
+     pickpoint = "0.0, 0.0"
+     font      = "ShareTechMono"
+     textsize  = 0.04
+     colour    = "0.8, 0.8, 1.0, 1.0"
+     align     = "right"
+
+     showleftteam  = false
+     showrightteam = true
+     showbases     = true
+     showscore     = false
+    />
+
+    <OverlayText
+     position  = "0.8, 0.05"
+     pickpoint = "0.0, 0.0"
+     font      = "ShareTechMono"
+     textsize  = 0.04
+     colour    = "0.5, 0.5, 1.0, 1.0"
+     align     = "right"
+     caption   = "Blue team"
+    />
+  </OverlayGroup>
+</Template>
Index: /code/branches/rocket2/data/overlays/underattackhud.oxo
===================================================================
--- /code/branches/rocket2/data/overlays/underattackhud.oxo	(revision 6952)
+++ /code/branches/rocket2/data/overlays/underattackhud.oxo	(revision 6952)
@@ -0,0 +1,26 @@
+<Template name="UnderAttackHUD">
+  <OverlayGroup name="UnderAttackHUD" scale = "1, 1">
+    <UnderAttackHealthBar
+     name                 = "HealthBar"
+     background           = "Orxonox/HealthBarBackground"
+     size                 = "0.45, 0.0875"
+     position             = "0.99 , 0.01"
+     pickpoint            = "1, 0"
+     bartexture           = "healthbar_bar.tga"
+     textfont             = "VeraMono"
+     textusebarcolour     = true
+     textsize             = 0.039
+     textoffset           = "0.315, 0.05"
+     textpickpoint        = "0, 0"
+     textalign            = "right"
+     correctaspect        = false
+     textcorrectaspect    = false
+     descriptionpickpoint = "0, 0"
+     descriptionoffset    = "0.5, 1"
+    >
+      <BarColour position = 0.0 colour = "0.7,0.2,0.2" />
+      <BarColour position = 0.5 colour = "0.7,0.7,0.2" />
+      <BarColour position = 1.0 colour = "0.2,0.7,0.2" />
+    </UnderAttackHealthBar>
+  </OverlayGroup>
+</Template>
Index: /code/branches/rocket2/data/particle/Example-Water.particle
===================================================================
--- /code/branches/rocket2/data/particle/Example-Water.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/Example-Water.particle	(revision 6952)
@@ -0,0 +1,35 @@
+particle_system Examples/Water/Rain
+{
+    material        Examples/Droplet
+    particle_width  100
+    particle_height 300
+    cull_each       true
+    quota           100
+    // Make common direction straight down (faster than self oriented)
+    billboard_type  oriented_common
+    common_direction 0 -1 0
+    
+    // Area emitter
+    emitter Box
+    {
+        angle           0
+        emission_rate   20
+        time_to_live    5
+        direction       0 -1 0
+        velocity    	1000
+        colour_range_start  0.3 1 0.3
+        colour_range_end    0.7 1 0.7
+        width           3000
+        height          3000
+        depth           0
+    }
+
+    // Gravity
+    affector LinearForce
+    {
+        force_vector      0 -1000 0
+        force_application add
+    }
+
+}
+
Index: /code/branches/rocket2/data/particle/Example.particle
===================================================================
--- /code/branches/rocket2/data/particle/Example.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/Example.particle	(revision 6952)
@@ -0,0 +1,395 @@
+// Example particle systems
+
+// Exudes greeny particles which float upwards
+particle_system Examples/GreenyNimbus
+{
+    material        Examples/FlarePointSprite
+	point_rendering	true
+	// point rendering means size is controlled by material
+	// provide fallback sizes for hardware that doesn't support point sprite
+    particle_width  30
+    particle_height 30
+    cull_each       false
+	cull_each       false
+    quota           10000
+    billboard_type  point
+    
+    // Area emitter
+    emitter Box
+    {
+        angle           30
+        emission_rate   30
+        time_to_live    5
+        direction       0 1 0
+        velocity    	0
+        colour_range_start  1 1 0
+        colour_range_end    0.3 1 0.3
+        width           60
+        height          60
+        depth           60
+    }
+
+    // Make em float upwards
+    affector LinearForce
+    {
+        force_vector      0 100 0
+        force_application add
+    }
+
+    // Fader
+    affector ColourFader
+    {
+        red -0.25
+        green -0.25
+        blue -0.25
+    }
+
+
+}
+
+// A sparkly purple fountain
+particle_system Examples/PurpleFountain
+{
+    material        Examples/Flare2
+    particle_width  20
+    particle_height 40
+    cull_each       false
+    quota           10000
+    billboard_type  oriented_self
+    
+    // Area emitter
+    emitter Point
+    {
+        angle           15
+        emission_rate   75
+        time_to_live    3
+        direction       0 1 0
+        velocity_min    250
+        velocity_max    300
+        colour_range_start  0 0 0
+        colour_range_end    1 1 1
+    }
+
+    // Gravity
+    affector LinearForce
+    {
+        force_vector      0 -100 0
+        force_application add
+    }
+
+    // Fader
+    affector ColourFader
+    {
+        red -0.25
+        green -0.25
+        blue -0.25
+    }
+}
+
+
+// A downpour
+particle_system Examples/Rain
+{
+    material        Examples/Droplet
+    particle_width  20
+    particle_height 100
+    cull_each       true
+    quota           10000
+    // Make common direction straight down (faster than self oriented)
+    billboard_type  oriented_common
+    common_direction 0 -1 0
+    
+    // Area emitter
+    emitter Box
+    {
+        angle           0
+        emission_rate   100
+        time_to_live    5
+        direction       0 -1 0
+        velocity    	50
+        colour_range_start  0.3 1 0.3
+        colour_range_end    0.7 1 0.7
+        width           1000
+        height          1000
+        depth           0
+    }
+
+    // Gravity
+    affector LinearForce
+    {
+        force_vector      0 -200 0
+        force_application add
+    }
+
+}
+
+// A jet engine (of sorts)
+particle_system Examples/JetEngine1
+{
+	material 		Examples/Flare
+	particle_width 	25
+	particle_height	25
+	cull_each		false
+	quota			200
+	billboard_type	point
+
+	emitter Point
+	{
+		angle 5
+		emission_rate 100
+        time_to_live    1
+        direction       0 -1 0
+        velocity_min    250
+        velocity_max    300
+        colour_range_start  1 1 0.5
+        colour_range_end    1 0.8 0.3
+		
+	}
+	affector ColourFader
+	{
+		red -0.25
+		green -1
+		blue -1
+	}
+	
+}
+particle_system Examples/JetEngine2
+{
+	material 		Examples/Flare
+	particle_width 	15
+	particle_height	15
+	cull_each		false
+	quota			200
+	billboard_type	point
+
+	emitter Point
+	{
+		angle 3
+		emission_rate 100
+        time_to_live    1
+        direction       0 -1 0
+        velocity_min    350
+        velocity_max    400
+        colour_range_start  0.5 1 1
+        colour_range_end    0.3 0.8 1
+		
+	}
+	affector ColourFader
+	{
+		red -1
+		green -1
+		blue -0.5
+	}
+	
+}
+
+// Exudes aureola particles which around the model float upwards
+particle_system Examples/Aureola
+{
+    material        Examples/Aureola
+    particle_width  200
+    particle_height 200
+    cull_each       false
+    quota           100
+    billboard_type  perpendicular_common
+    common_direction 0 1 0
+    common_up_vector 0 0 1
+
+    // Area emitter
+    emitter Box
+    {
+        angle           30
+        emission_rate   4
+        time_to_live    5
+        position        0 -100 0
+        direction       0 1 0
+        velocity_min  	0
+        velocity_max  	30
+        colour_range_start  0.3 0.3 0.3 0.0
+        colour_range_end    0.8 0.8 0.8 0.0
+        width           10
+        height          10
+        depth           30
+    }
+
+    // Make em float upwards
+    affector LinearForce
+    {
+        force_vector      0 70 0
+        force_application add
+    }
+
+    // Fader
+    affector ColourFader2
+    {
+        red1 +0.4
+        green1 +0.4
+        blue1 +0.4
+        alpha1 +0.7
+
+        red2 -0.25
+        green2 -0.25
+        blue2 -0.25
+        alpha2 -0.3333
+
+        state_change 3.5
+    }
+
+    // Rotater
+    affector Rotator
+    {
+        rotation_range_start 0
+        rotation_range_end 360
+        rotation_speed_range_start 0
+        rotation_speed_range_end 180
+    }
+}
+
+
+particle_system Examples/Swarm
+{
+	quota	3000
+	material	Examples/Flare2
+	particle_width	12
+	particle_height	24
+	cull_each	true
+	renderer	billboard
+	sorted	true
+	local_space	false
+	billboard_type	oriented_self
+
+	emitter Box
+	{
+		angle	180
+		colour	1 1 1 1
+		colour_range_start	1 1 1 1
+		colour_range_end	1 1 1 1
+		direction	0 1 0
+		emission_rate	30
+		position	0 0 0
+		velocity	50
+		velocity_min	50
+		velocity_max	1
+		time_to_live	20
+		time_to_live_min	20
+		time_to_live_max	20
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		width	80
+		height	80
+		depth	80
+	}
+
+	affector ColourFader
+	{
+		red	-0.05
+		green	0
+		blue	0
+		alpha	0
+	}
+
+	affector DeflectorPlane
+	{
+		plane_point	0 -50 0
+		plane_normal	0 1 0
+		bounce	1
+	}
+
+	affector DeflectorPlane
+	{
+		plane_point	0 50 0
+		plane_normal	0 -1 0
+		bounce	1
+	}
+
+	affector DeflectorPlane
+	{
+		plane_point	50 0 0
+		plane_normal	-1 0 0
+		bounce	1
+	}
+
+	affector DeflectorPlane
+	{
+		plane_point	-50 0 0
+		plane_normal	1 0 0
+		bounce	1
+	}
+
+	affector DeflectorPlane
+	{
+		plane_point	0 0 50
+		plane_normal	0 0 -1
+		bounce	1
+	}
+
+	affector DeflectorPlane
+	{
+		plane_point	0 0 -50
+		plane_normal	0 0 1
+		bounce	1
+	}
+
+	affector DirectionRandomiser
+	{
+		randomness	60
+	}
+}
+
+
+particle_system Examples/Snow
+{
+	quota	2000
+	material	Examples/Flare
+	particle_width	4
+	particle_height	4
+	cull_each	true
+	renderer	billboard
+	sorted	true
+	local_space	false
+	billboard_type	point
+
+	emitter Box
+	{
+		angle	0
+		colour	1 1 1 1
+		colour_range_start	1 1 1 1
+		colour_range_end	1 1 1 1
+		direction	0 -1 0
+		emission_rate	100
+		position	0 200 0
+		velocity	20
+		velocity_min	20
+		velocity_max	20
+		time_to_live	20
+		time_to_live_min	20
+		time_to_live_max	20
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		width	200
+		height	200
+		depth	1
+	}
+
+	affector DeflectorPlane
+	{
+		plane_point	0 0 0
+		plane_normal	0 1 0
+		bounce	0
+	}
+
+	affector DirectionRandomiser
+	{
+		randomness	10
+	}
+}
+
+
Index: /code/branches/rocket2/data/particle/ExplosionComp1.particle
===================================================================
--- /code/branches/rocket2/data/particle/ExplosionComp1.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/ExplosionComp1.particle	(revision 6952)
@@ -0,0 +1,66 @@
+
+particle_system Orxonox/ExplosionComp1
+{
+	quota	150
+	material	PE/explosion
+	particle_width	20
+	particle_height	40
+	cull_each	true
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Ellipsoid
+	{
+		angle	180
+		colour	1 1 1 1
+		colour_range_start	1 1 1 1
+		colour_range_end	1 1 1 1
+		direction	0 1 0
+		emission_rate	300
+		position	0 0 0
+		velocity	75
+		velocity_min	75
+		velocity_max	75
+		time_to_live	0.6
+		time_to_live_min	0.4
+		time_to_live_max	0.8
+		duration	0.4
+		duration_min	0.3
+		duration_max	0.6
+		repeat_delay	2.5
+		repeat_delay_min	2.5
+		repeat_delay_max	2.5
+		width		20
+		height		20
+		depth		0
+	}
+
+	affector Scaler
+	{
+		rate	5
+	}
+
+	affector DirectionRandomiser
+	{
+		randomness	130.6
+		scope	0.4505
+		keep_velocity	false
+	}
+
+	affector ColourFader
+	{
+		red	1
+		green	1
+		blue	1
+		alpha	-0.06306
+	}
+}
Index: /code/branches/rocket2/data/particle/ExplosionComp2.particle
===================================================================
--- /code/branches/rocket2/data/particle/ExplosionComp2.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/ExplosionComp2.particle	(revision 6952)
@@ -0,0 +1,56 @@
+
+particle_system Orxonox/ExplosionComp2
+{
+	quota	1000
+	material	PE/smoke
+	particle_width	10
+	particle_height	10
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	1 1 1 0.62963
+		colour_range_start	1 1 1 0.62963
+		colour_range_end	1 1 1 0.62963
+		direction	0 1 0
+		emission_rate	2000
+		position	0 0 0
+		velocity	80
+		velocity_min	80
+		velocity_max	80
+		time_to_live	0.8
+		time_to_live_min	0.8
+		time_to_live_max	0.8
+		duration	0.79
+		duration_min	0.79
+		duration_max	0.79
+		repeat_delay	1.5
+		repeat_delay_min	1.5
+		repeat_delay_max	1.5
+	}
+
+	affector Scaler
+	{
+		rate	12.07
+	}
+
+	affector ColourFader
+	{
+		red	-1
+		green	-1
+		blue	-1
+		alpha	-0.4234
+	}
+}
Index: /code/branches/rocket2/data/particle/ExplosionComp4.particle
===================================================================
--- /code/branches/rocket2/data/particle/ExplosionComp4.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/ExplosionComp4.particle	(revision 6952)
@@ -0,0 +1,76 @@
+
+particle_system ExplosionComp4
+{
+	quota	10
+	material	BaseWhite
+	particle_width	100
+	particle_height	100
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+}
+
+particle_system Orxonox/ExplosionComp4
+{
+	quota	500
+	material	PE/explosion
+	particle_width	24.19
+	particle_height	25.08
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	9.73
+		colour	1 1 1 1
+		colour_range_start	1 1 1 1
+		colour_range_end	1 1 1 1
+		direction	0 1 0
+		emission_rate	2000
+		position	0 0 0
+		velocity	300
+		velocity_min	300
+		velocity_max	300
+		time_to_live	0.1802
+		time_to_live_min	0.1802
+		time_to_live_max	0.1802
+		duration	0.08
+		duration_min	0.08
+		duration_max	0.08
+		repeat_delay	0.1802
+		repeat_delay_min	0.1802
+		repeat_delay_max	0.1802
+	}
+
+	affector DirectionRandomiser
+	{
+		randomness	0
+		scope	0.2703
+		keep_velocity	false
+	}
+
+	affector LinearForce
+	{
+		force_vector	-16.8065 62.4805 6.57674
+		force_application	add
+	}
+}
Index: /code/branches/rocket2/data/particle/FireComp2.particle
===================================================================
--- /code/branches/rocket2/data/particle/FireComp2.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/FireComp2.particle	(revision 6952)
@@ -0,0 +1,69 @@
+
+particle_system Orxonox/FireComp2
+{
+	quota	10000
+	material	PE/smoke
+	particle_width	4
+	particle_height	4
+	cull_each	true
+	renderer	billboard
+	sorted	true
+	local_space	true
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	true
+
+	emitter HollowEllipsoid
+	{
+		angle	1.69
+		colour	1 1 1 0.506173
+		colour_range_start	1 1 1 0.506173
+		colour_range_end	1 1 1 0.506173
+		direction	0 1 0
+		emission_rate	1680
+		position	0 60 0
+		velocity	300
+		velocity_min	300
+		velocity_max	300
+		time_to_live	0.2
+		time_to_live_min	0.2
+		time_to_live_max	0.2
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		width	28.83
+		height	39.64
+		depth	88.29
+		inner_width	0.5
+		inner_height	0.5
+		inner_depth	0.5
+	}
+
+	affector DirectionRandomiser
+	{
+		randomness	250
+		scope	0.4865
+		keep_velocity	false
+	}
+
+	affector Scaler
+	{
+		rate	20
+	}
+
+	affector ColourFader
+	{
+		red	-1
+		green	-1
+		blue	-1
+		alpha	0.1351
+	}
+}
Index: /code/branches/rocket2/data/particle/LaserGun.particle
===================================================================
--- /code/branches/rocket2/data/particle/LaserGun.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/LaserGun.particle	(revision 6952)
@@ -0,0 +1,51 @@
+
+particle_system Orxonox/LaserGun
+{
+	quota	1000
+	material	PE/Streak
+	particle_width	1.892
+	particle_height	1.892
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	3.243
+		colour	1 0 0 1
+		colour_range_start	1 0 0 1
+		colour_range_end	1 0.0432099 0 1
+		direction	0 -1 0
+		emission_rate	1027
+		position	0 0 0
+		velocity	113.5
+		velocity_min	113.5
+		velocity_max	113.5
+		time_to_live	0.3604
+		time_to_live_min	0.3604
+		time_to_live_max	0.3604
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	affector ColourFader
+	{
+		red	-1
+		green	0.2613
+		blue	-0.1712
+		alpha	-1
+	}
+}
Index: /code/branches/rocket2/data/particle/Steam.particle
===================================================================
--- /code/branches/rocket2/data/particle/Steam.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/Steam.particle	(revision 6952)
@@ -0,0 +1,44 @@
+
+particle_system Orxonox/Steam
+{
+	quota 1
+	material	PE/smoke
+	particle_width	2000
+	particle_height	2000
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	0
+		colour	1 1 1 0.1
+		colour_range_start	1 1 1 0.1
+		colour_range_end	1 1 1 0.02
+		direction	0 1 0
+		emission_rate	1
+		position	0 0 0
+		velocity	0
+		velocity_min	0
+		velocity_max	0
+		time_to_live	200
+		time_to_live_min	200
+		time_to_live_max	300
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+}
+
Index: /code/branches/rocket2/data/particle/ThrusterFire.particle
===================================================================
--- /code/branches/rocket2/data/particle/ThrusterFire.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/ThrusterFire.particle	(revision 6952)
@@ -0,0 +1,72 @@
+
+particle_system Orxonox/ThrusterFire
+{
+	quota	50
+	material	PE/explosion3
+	particle_width	100
+	particle_height	100
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	vertex
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	0 0 0 0
+		colour_range_start	0 0 0 0
+		colour_range_end	0 0 0 0
+		direction	0 1 0
+		emission_rate	50
+		position	0 0 0
+		velocity	0
+		velocity_min	0
+		velocity_max	20
+		time_to_live	1
+		time_to_live_min	1
+		time_to_live_max	1
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	affector Scaler
+	{
+		rate	40
+	}
+
+	affector Rotator
+	{
+		rotation_speed_range_start	0
+		rotation_speed_range_end	0
+		rotation_range_start	0
+		rotation_range_end	360
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0 0 0 0
+		time0	0
+		colour1	0.3 0.3 0.3 0
+		time1	0.1
+		colour2	0.2 0.2 0.2 0
+		time2	0.4
+		colour3	0 0 0 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/bigexplosion.particle
===================================================================
--- /code/branches/rocket2/data/particle/bigexplosion.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/bigexplosion.particle	(revision 6952)
@@ -0,0 +1,72 @@
+particle_system Orxonox/bigexplosion
+{
+	quota	3000
+	material	PE/explosion
+	particle_width	100
+	particle_height	100
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	vertex
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	0 0 0 0
+		colour_range_start	0 0 0 0
+		colour_range_end	0 0 0 0
+		direction	0 1 0
+		emission_rate	2000
+		position	0 0 0
+		velocity	300
+		velocity_min	300
+		velocity_max	300
+		time_to_live	1.4
+		time_to_live_min	1.4
+		time_to_live_max	1.8
+		duration	0.3
+		duration_min	0.3
+		duration_max	0.3
+		repeat_delay	5
+		repeat_delay_min	5
+		repeat_delay_max	5
+	}
+
+	affector Scaler
+	{
+		rate	20
+	}
+
+	affector Rotator
+	{
+		rotation_speed_range_start	0
+		rotation_speed_range_end	-7.2
+		rotation_range_start	0
+		rotation_range_end	360
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0.5 0.5 0.5 0
+		time0	0
+		colour1	0.4 0.4 0.4 0
+		time1	0.1
+		colour2	0.2 0.2 0.2 0
+		time2	0.3
+		colour3	0 0 0 0
+		time3	1.4
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1.5
+	}
+}
+
Index: /code/branches/rocket2/data/particle/bigexplosion1part1.particle
===================================================================
--- /code/branches/rocket2/data/particle/bigexplosion1part1.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/bigexplosion1part1.particle	(revision 6952)
@@ -0,0 +1,64 @@
+
+particle_system Orxonox/BigExplosion1part1
+{
+	quota	100
+	material	PE/Flare
+	particle_width	60
+	particle_height	60
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	top_center
+	billboard_rotation_type	vertex
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	1 1 1 1
+		colour_range_start	1 1 1 1
+		colour_range_end	1 1 1 1
+		direction	0 1 0
+		emission_rate	1000
+		position	0 0 0
+		velocity	50
+		velocity_min	50
+		velocity_max	100
+		time_to_live	1.3
+		time_to_live_min	1.3
+		time_to_live_max	1.6
+		duration	0.1
+		duration_min	0.1
+		duration_max	0.1
+		repeat_delay	1000000
+		repeat_delay_min	1000000
+		repeat_delay_max	1000000
+	}
+
+	affector Scaler
+	{
+		rate	40
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	1 1 1 0
+		time0	0
+		colour1	1 1 0.8 0
+		time1	0.1
+		colour2	0.1 0.1 0.1 0
+		time2	0.6
+		colour3	0 0 0 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/bigexplosion1part2.particle
===================================================================
--- /code/branches/rocket2/data/particle/bigexplosion1part2.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/bigexplosion1part2.particle	(revision 6952)
@@ -0,0 +1,64 @@
+
+particle_system Orxonox/BigExplosion1part2
+{
+	quota	50
+	material	PE/ringflare
+	particle_width	60
+	particle_height	60
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	vertex
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	1 1 1 1
+		colour_range_start	1 1 1 1
+		colour_range_end	1 1 1 1
+		direction	0 1 0
+		emission_rate	250
+		position	0 0 0
+		velocity	0
+		velocity_min	0
+		velocity_max	80
+		time_to_live	1.3
+		time_to_live_min	1.3
+		time_to_live_max	1.3
+		duration	0.2
+		duration_min	0.2
+		duration_max	0.2
+		repeat_delay	1000000
+		repeat_delay_min	1000000
+		repeat_delay_max	1000000
+	}
+
+	affector Scaler
+	{
+		rate	40
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0.5 0.5 0.5 0
+		time0	0
+		colour1	1 1 1 0
+		time1	0.1
+		colour2	0.1 0.1 0.1 0
+		time2	0.6
+		colour3	0 0 0 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/bigexplosion1part3.particle
===================================================================
--- /code/branches/rocket2/data/particle/bigexplosion1part3.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/bigexplosion1part3.particle	(revision 6952)
@@ -0,0 +1,64 @@
+
+particle_system Orxonox/BigExplosion1part3
+{
+	quota	120
+	material	PE/point_lensflare
+	particle_width	18
+	particle_height	18
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Ring
+	{
+		angle	0
+		colour	0 0 0 1
+		colour_range_start	0 0 0 1
+		colour_range_end	0 0 0 1
+		direction	0 1 0
+		emission_rate	1200
+		position	0 0 0
+		velocity	0
+		velocity_min	0
+		velocity_max	0
+		time_to_live	1
+		time_to_live_min	1
+		time_to_live_max	1
+		duration	0.1
+		duration_min	0.1
+		duration_max	0.1
+		repeat_delay	1000000
+		repeat_delay_min	1000000
+		repeat_delay_max	1000000
+		width	150
+		height	150
+		depth	0
+		inner_width	0.99
+		inner_height	0.99
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0 0 0 0
+		time0	0
+		colour1	1 1 1 0
+		time1	0.5
+		colour2	0 0 0 0
+		time2	1
+		colour3	0.5 0.5 0.5 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/emitted_emitter.particle
===================================================================
--- /code/branches/rocket2/data/particle/emitted_emitter.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/emitted_emitter.particle	(revision 6952)
@@ -0,0 +1,56 @@
+// Example emitted emitters
+particle_system Examples/Fireworks
+{
+     material Examples/Flare
+     point_rendering            false
+     particle_width             10
+     particle_height            10
+     cull_each                  false
+     quota                      1000
+     emit_emitter_quota         10
+     billboard_type             point
+     
+     // Emitter that emits multiple Point emitters with name 'explosion'
+     emitter Box
+     {
+         name                    mainEmitter
+         emit_emitter            explosion
+         angle                   30
+         emission_rate           1000
+         time_to_live            3
+         direction               0 1 0
+         velocity                200
+     }
+
+     // This Point emitter is emitted by the Box emitter and emits billboard particles itself
+     emitter Point
+     {
+         name                    explosion
+         angle                   360
+         emission_rate           1000
+         time_to_live            2
+         direction               0 1 0
+         velocity                80
+         duration                0.1
+         repeat_delay_min        2
+         repeat_delay_max        3
+     }
+
+     // Make em float downwards
+     affector LinearForce
+     {
+         force_vector            0 -100 0
+         force_application       add
+     } 
+
+     // Give em some nice colours
+     affector ColourInterpolator
+     {
+         time0                   0
+         colour0                 1 1 0
+         time1                   0.5
+         colour1                 1 0 0
+         time2                   0.9
+         colour2                 0 0 1
+     }
+} 
Index: /code/branches/rocket2/data/particle/engineglow.particle
===================================================================
--- /code/branches/rocket2/data/particle/engineglow.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/engineglow.particle	(revision 6952)
@@ -0,0 +1,40 @@
+
+particle_system Orxonox/engineglow
+{
+	quota	200
+	material	PE/bigFlame
+	particle_width	12
+	particle_height	12
+	cull_each	false
+	renderer	billboard
+	billboard_type	point
+
+	emitter HollowEllipsoid
+	{
+		angle	0
+		colour	0.46875 0.8125 0.93359375 1
+		colour_range_start	.6640625 .91796875 .92578125 1
+		colour_range_end	.08203125 .7578125 .98046875 1
+		direction	0 1 0
+		emission_rate	45
+		position	0 0 0
+		velocity	5
+		velocity_min	4
+		velocity_max	6
+		time_to_live	0.5
+		time_to_live_min	0.2
+		time_to_live_max	0.9
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		width	4
+		height	2.5
+		depth	1.3
+		inner_width	0.5
+		inner_height	0.3
+		inner_depth	0.2
+	}
+}
Index: /code/branches/rocket2/data/particle/explosion1.particle
===================================================================
--- /code/branches/rocket2/data/particle/explosion1.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/explosion1.particle	(revision 6952)
@@ -0,0 +1,64 @@
+
+particle_system Orxonox/explosion1
+{
+	quota	200
+	material	PE/explosion
+	particle_width	100
+	particle_height	40
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	1 0.9 0.8 1
+		colour_range_start	1 0.9 0.8 1
+		colour_range_end	1 0.9 0.8 1
+		direction	0 1 0
+		emission_rate	2000
+		position	0 0 0
+		velocity	0
+		velocity_min	0
+		velocity_max	75
+		time_to_live	0.75
+		time_to_live_min	0.75
+		time_to_live_max	0.75
+		duration	0.1
+		duration_min	0.1
+		duration_max	0.1
+		repeat_delay	1000000
+		repeat_delay_min	1000000
+		repeat_delay_max	1000000
+	}
+
+	affector Scaler
+	{
+		rate	20
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0.2 0.2 0.2 0
+		time0	0
+		colour1	0.4 0.3 0.2 0
+		time1	0.3
+		colour2	0.1 0.1 0.1 0
+		time2	0.5
+		colour3	0 0 0 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/explosion2.particle
===================================================================
--- /code/branches/rocket2/data/particle/explosion2.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/explosion2.particle	(revision 6952)
@@ -0,0 +1,64 @@
+
+particle_system Orxonox/explosion2
+{
+	quota	150
+	material	PE/explosion
+	particle_width	50
+	particle_height	20
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	1 0.9 0.8 1
+		colour_range_start	1 0.9 0.8 1
+		colour_range_end	1 0.9 0.8 1
+		direction	0 1 0
+		emission_rate	300
+		position	0 0 0
+		velocity	0
+		velocity_min	0
+		velocity_max	75
+		time_to_live	0.75
+		time_to_live_min	0.75
+		time_to_live_max	0.75
+		duration	0.5
+		duration_min	0.5
+		duration_max	0.5
+		repeat_delay	5
+		repeat_delay_min	5
+		repeat_delay_max	5
+	}
+
+	affector Scaler
+	{
+		rate	20
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	1 1 1 0
+		time0	0
+		colour1	0.7 0.7 1 0
+		time1	0.5
+		colour2	0.2 0.3 0.5 0
+		time2	0.7
+		colour3	0 0 0 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/explosion2b.particle
===================================================================
--- /code/branches/rocket2/data/particle/explosion2b.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/explosion2b.particle	(revision 6952)
@@ -0,0 +1,67 @@
+
+particle_system Orxonox/explosion2b
+{
+	quota	150
+	material	PE/explosion
+	particle_width	20
+	particle_height	40
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	vertex
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Ellipsoid
+	{
+		angle	180
+		colour	0 0 0 1
+		colour_range_start	0 0 0 1
+		colour_range_end	0 0 0 1
+		direction	0 1 0
+		emission_rate	300
+		position	0 0 0
+		velocity	0
+		velocity_min	0
+		velocity_max	75
+		time_to_live	0.75
+		time_to_live_min	0.75
+		time_to_live_max	0.75
+		duration	0.5
+		duration_min	0.5
+		duration_max	0.5
+		repeat_delay	5
+		repeat_delay_min	5
+		repeat_delay_max	5
+		width	20
+		height	20
+		depth	0
+	}
+
+	affector Scaler
+	{
+		rate	20
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0.8 1 1 0
+		time0	0
+		colour1	0.5 0.7 1 0
+		time1	0.5
+		colour2	0.2 0.3 0.5 0
+		time2	0.7
+		colour3	0 0 0 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/explosion3.particle
===================================================================
--- /code/branches/rocket2/data/particle/explosion3.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/explosion3.particle	(revision 6952)
@@ -0,0 +1,72 @@
+
+particle_system Orxonox/explosion3
+{
+	quota	10
+	material	PE/explosion3
+	particle_width	7
+	particle_height	7
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	vertex
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	0 0 0 0
+		colour_range_start	0 0 0 0
+		colour_range_end	0 0 0 0
+		direction	0 1 0
+		emission_rate	40
+		position	0 0 0
+		velocity	0
+		velocity_min	0
+		velocity_max	0
+		time_to_live	0.5
+		time_to_live_min	0.5
+		time_to_live_max	0.5
+		duration	0.1
+		duration_min	0.1
+		duration_max	0.1
+		repeat_delay	5
+		repeat_delay_min	5
+		repeat_delay_max	5
+	}
+
+	affector Scaler
+	{
+		rate	20
+	}
+
+	affector Rotator
+	{
+		rotation_speed_range_start	0
+		rotation_speed_range_end	0
+		rotation_range_start	0
+		rotation_range_end	360
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0 0 0 0
+		time0	0
+		colour1	0.5 0.5 0.5 0
+		time1	0.2
+		colour2	0.1 0.1 0.1 0
+		time2	0.6
+		colour3	0 0 0 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/explosion4.particle
===================================================================
--- /code/branches/rocket2/data/particle/explosion4.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/explosion4.particle	(revision 6952)
@@ -0,0 +1,71 @@
+particle_system Orxonox/explosion4
+{
+	quota	1000
+	material	PE/explosion3
+	particle_width	10
+	particle_height	10
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	vertex
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	0 0 0 0
+		colour_range_start	0 0 0 0
+		colour_range_end	0 0 0 0
+		direction	0 1 0
+		emission_rate	2000
+		position	0 0 0
+		velocity	15
+		velocity_min	15
+		velocity_max	15
+		time_to_live	1
+		time_to_live_min	1
+		time_to_live_max	1.4
+		duration	0.05
+		duration_min	0.05
+		duration_max	0.05
+		repeat_delay	5
+		repeat_delay_min	5
+		repeat_delay_max	5
+	}
+
+	affector Scaler
+	{
+		rate	20
+	}
+
+	affector Rotator
+	{
+		rotation_speed_range_start	0
+		rotation_speed_range_end	-7.2
+		rotation_range_start	0
+		rotation_range_end	360
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0.5 0.5 0.5 0
+		time0	0
+		colour1	0.4 0.4 0.4 0
+		time1	0.2
+		colour2	0.2 0.2 0.2 0
+		time2	0.5
+		colour3	0 0 0 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/fairytwirl.particle
===================================================================
--- /code/branches/rocket2/data/particle/fairytwirl.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/fairytwirl.particle	(revision 6952)
@@ -0,0 +1,64 @@
+
+particle_system Orxonox/fairytwirl
+{
+	quota	500
+	material	PE/lensflare
+	particle_width	2
+	particle_height	2
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Ring
+	{
+		angle	0
+		colour	0 0 0 1
+		colour_range_start	0 0 0 1
+		colour_range_end	0 0 0 1
+		direction	0 1 0
+		emission_rate	500
+		position	0 -10 0
+		velocity	15
+		velocity_min	15
+		velocity_max	15
+		time_to_live	1
+		time_to_live_min	1
+		time_to_live_max	1
+		duration	1
+		duration_min	1
+		duration_max	1
+		repeat_delay	1000000
+		repeat_delay_min	1000000
+		repeat_delay_max	1000000
+		width	35
+		height	35
+		depth	20
+		inner_width	0.99
+		inner_height	0.99
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0 0 0 0
+		time0	0
+		colour1	1 1 1 0
+		time1	0.5
+		colour2	0 0 0 0
+		time2	1
+		colour3	0.5 0.5 0.5 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/fire3.particle
===================================================================
--- /code/branches/rocket2/data/particle/fire3.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/fire3.particle	(revision 6952)
@@ -0,0 +1,72 @@
+
+particle_system Orxonox/fire3
+{
+	quota	50
+	material	PE/explosion3
+	particle_width	20
+	particle_height	20
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	vertex
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	0 0 0 0
+		colour_range_start	0 0 0 0
+		colour_range_end	0 0 0 0
+		direction	0 1 0
+		emission_rate	50
+		position	0 0 0
+		velocity	0
+		velocity_min	0
+		velocity_max	20
+		time_to_live	1
+		time_to_live_min	1
+		time_to_live_max	1
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	affector Scaler
+	{
+		rate	40
+	}
+
+	affector Rotator
+	{
+		rotation_speed_range_start	0
+		rotation_speed_range_end	0
+		rotation_range_start	0
+		rotation_range_end	360
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0 0 0 0
+		time0	0
+		colour1	0.3 0.3 0.3 0
+		time1	0.1
+		colour2	0.2 0.2 0.2 0
+		time2	0.4
+		colour3	0 0 0 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/fire4.particle
===================================================================
--- /code/branches/rocket2/data/particle/fire4.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/fire4.particle	(revision 6952)
@@ -0,0 +1,67 @@
+
+particle_system Orxonox/fire4
+{
+	quota	25
+	material	PE/explosion3
+	particle_width	4
+	particle_height	4
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	vertex
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	0 0 0 0
+		colour_range_start	0 0 0 0
+		colour_range_end	0 0 0 0
+		direction	0 1 0
+		emission_rate	35
+		position	0 0 0
+		velocity	5
+		velocity_min	5
+		velocity_max	10
+		time_to_live	0.25
+		time_to_live_min	0.25
+		time_to_live_max	0.25
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	affector Rotator
+	{
+		rotation_speed_range_start	0
+		rotation_speed_range_end	0
+		rotation_range_start	0
+		rotation_range_end	360
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	1 1 1 0
+		time0	0
+		colour1	0.6 0.6 0.6 0
+		time1	0.1
+		colour2	0.4 0.4 0.4 0
+		time2	0.4
+		colour3	0 0 0 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/forcefield.particle
===================================================================
--- /code/branches/rocket2/data/particle/forcefield.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/forcefield.particle	(revision 6952)
@@ -0,0 +1,554 @@
+particle_system Orxonox/ForceFieldPurpleBig
+{
+	quota	10000
+	material	PE/smoke
+	particle_width	30
+	particle_height	500
+	cull_each	true
+	renderer	billboard
+	sorted		false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	1 0 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Cylinder
+	{
+		angle	0
+		colour_range_start	0.744444 0 1 0.05
+		colour_range_end	0.533333 0 1 0.05
+		emission_rate	10
+                direction 0 0 -1
+		velocity	87.1
+		velocity_min	87.1
+		velocity_max	87.1
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	1
+		width 600
+		height 600
+	}
+
+	emitter Cylinder
+	{
+		angle	0
+		colour_range_start	0.3 0 0.3 0.05
+		colour_range_end	0.4 0 0.5 0.05
+		emission_rate	10
+                direction 0 0 -1
+		velocity	77.42
+		velocity_min	77.42
+		velocity_max	77.42
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	0
+		width 300
+		height 300
+	}
+	
+	emitter Cylinder
+	{
+		angle	1 1 1 0.05
+		colour_range_start	0.9 0.9 0.9 0.05
+		colour_range_end	1 1 1 0.05
+		emission_rate	5
+                direction 0 0 -1
+		velocity	77.42
+		velocity_min	77.42
+		velocity_max	77.42
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	0
+		width 900
+		height 900
+	}
+}
+
+particle_system Orxonox/ForceFieldPurpleSmall
+{
+	quota	10000
+	material	PE/smoke
+	particle_width	30
+	particle_height	500
+	cull_each	true
+	renderer	billboard
+	sorted		false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	1 0 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Cylinder
+	{
+		angle	0
+		colour_range_start	0.744444 0 1 0.05
+		colour_range_end	0.533333 0 1 0.05
+		emission_rate	7
+                direction 0 0 -1
+		velocity	87.1
+		velocity_min	87.1
+		velocity_max	87.1
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	1
+		width 300
+		height 300
+	}
+
+	emitter Cylinder
+	{
+		angle	0
+		colour_range_start	0.3 0 0.3 0.05
+		colour_range_end	0.4 0 0.5 0.05
+		emission_rate	6
+                direction 0 0 -1
+		velocity	77.42
+		velocity_min	77.42
+		velocity_max	77.42
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	0
+		width 200
+		height 200
+	}
+	
+	emitter Cylinder
+	{
+		angle	1 1 1 0.05
+		colour_range_start	0.9 0.9 0.9 0.05
+		colour_range_end	1 1 1 0.05
+		emission_rate	4
+                direction 0 0 -1
+		velocity	77.42
+		velocity_min	77.42
+		velocity_max	77.42
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	0
+		width 500
+		height 500
+	}
+}	
+
+particle_system Orxonox/ForceFieldGreenBig
+{
+	quota	10000
+	material	PE/smoke
+	particle_width	30
+	particle_height	500
+	cull_each	true
+	renderer	billboard
+	sorted		false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	1 0 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Cylinder
+	{
+		angle	0
+		colour_range_start	0 0.744444 1 0.05
+		colour_range_end	0 0.533333 1 0.05
+		emission_rate	10
+                direction 0 0 -1
+		velocity	87.1
+		velocity_min	87.1
+		velocity_max	87.1
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	1
+		width 600
+		height 600
+	}
+
+	emitter Cylinder
+	{
+		angle	0
+		colour_range_start	0 0.455556 0 0.05
+		colour_range_end	0 0.8 0 0.05
+		emission_rate	10
+                direction 0 0 -1
+		velocity	77.42
+		velocity_min	77.42
+		velocity_max	77.42
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	0
+		width 300
+		height 300
+	}
+	
+	emitter Cylinder
+	{
+		angle	1 1 1 0.05
+		colour_range_start	0.9 0.9 0.9 0.05
+		colour_range_end	1 1 1 0.05
+		emission_rate	5
+                direction 0 0 -1
+		velocity	77.42
+		velocity_min	77.42
+		velocity_max	77.42
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	0
+		width 900
+		height 900
+	}
+}
+
+particle_system Orxonox/ForceFieldGreenSmall
+{
+	quota	10000
+	material	PE/smoke
+	particle_width	30
+	particle_height	500
+	cull_each	true
+	renderer	billboard
+	sorted		false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	1 0 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Cylinder
+	{
+		angle	0
+		colour	0 0.744444 1 0.05
+		colour_range_start	0 0.744444 1 0.05
+		colour_range_end	0 0.533333 1 0.05
+		emission_rate	7
+                direction 0 0 -1
+		velocity	87.1
+		velocity_min	87.1
+		velocity_max	87.1
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	1
+		width 300
+		height 300
+	}
+
+	emitter Cylinder
+	{
+		angle	0
+		colour	0 0.455556 0 0.05
+		colour_range_start	0 0.455556 0 0.05
+		colour_range_end	0 0.8 0 0.05
+		emission_rate	6
+                direction 0 0 -1
+		velocity	77.42
+		velocity_min	77.42
+		velocity_max	77.42
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	0
+		width 200
+		height 200
+	}
+	
+	emitter Cylinder
+	{
+		angle	1 1 1 0.05
+		colour_range_start	0.9 0.9 0.9 0.05
+		colour_range_end	1 1 1 0.05
+		emission_rate	4
+                direction 0 0 -1
+		velocity	77.42
+		velocity_min	77.42
+		velocity_max	77.42
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	0
+		width 500
+		height 500
+	}
+}
+
+			
+particle_system Orxonox/ForceFieldBlueBig
+{
+	quota	10000
+	material	PE/smoke
+	particle_width	30
+	particle_height	500
+	cull_each	true
+	renderer	billboard
+	sorted		false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	1 0 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Cylinder
+	{
+		angle	0
+		colour_range_start	0 0 0.744444 0.05
+		colour_range_end	0.5 0 0.533333 0.05
+		emission_rate	10
+                direction 0 0 -1
+		velocity	87.1
+		velocity_min	87.1
+		velocity_max	87.1
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	1
+		width 600
+		height 600
+	}
+
+	emitter Cylinder
+	{
+		angle	0
+		colour_range_start	0 0.3 0.455556 0.05
+		colour_range_end	0 0.5 0.8 0.05
+		emission_rate	10
+                direction 0 0 -1
+		velocity	77.42
+		velocity_min	77.42
+		velocity_max	77.42
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	0
+		width 300
+		height 300
+	}
+	
+	emitter Cylinder
+	{
+		angle	1 1 1 0.05
+		colour_range_start	0.9 0.9 0.9 0.05
+		colour_range_end	1 1 1 0.05
+		emission_rate	5
+                direction 0 0 -1
+		velocity	77.42
+		velocity_min	77.42
+		velocity_max	77.42
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	0
+		width 900
+		height 900
+	}
+}
+
+particle_system Orxonox/ForceFieldBlueSmall
+{
+	quota	10000
+	material	PE/smoke
+	particle_width	30
+	particle_height	500
+	cull_each	true
+	renderer	billboard
+	sorted		false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	1 0 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Cylinder
+	{
+		angle	0
+		colour_range_start	0 0 0.744444 0.05
+		colour_range_end	0.5 0 0.533333 0.05
+		emission_rate	7
+                direction 0 0 -1
+		velocity	87.1
+		velocity_min	87.1
+		velocity_max	87.1
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	1
+		width 300
+		height 300
+	}
+
+	emitter Cylinder
+	{
+		angle	0
+		colour_range_start	0 0.3 0.455556 0.05
+		colour_range_end	0 0.5 0.8 0.05
+		emission_rate	6
+                direction 0 0 -1
+		velocity	77.42
+		velocity_min	77.42
+		velocity_max	77.42
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	0
+		width 200
+		height 200
+	}
+	
+	emitter Cylinder
+	{
+		angle	1 1 1 0.05
+		colour_range_start	0.9 0.9 0.9 0.05
+		colour_range_end	1 1 1 0.05
+		emission_rate	4
+                direction 0 0 -1
+		velocity	77.42
+		velocity_min	77.42
+		velocity_max	77.42
+		time_to_live	30
+		time_to_live_min	30
+		time_to_live_max	30
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		depth	0
+		width 500
+		height 500
+	}
+}
Index: /code/branches/rocket2/data/particle/laser.particle
===================================================================
--- /code/branches/rocket2/data/particle/laser.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/laser.particle	(revision 6952)
@@ -0,0 +1,47 @@
+particle_system Orxonox/laser
+{
+	quota	200
+	material	PE/point_lensflare
+	particle_width	7.08
+	particle_height	7.08
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	0 1 0.275862 1
+		colour_range_start	0 1 0.275862 1
+		colour_range_end	0 1 0.275862 1
+		direction	0 1 0
+		emission_rate	80
+		position	0 0 0
+		velocity	11
+		velocity_min	11
+		velocity_max	11
+		time_to_live	0.7
+		time_to_live_min	0.7
+		time_to_live_max	1
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	1.6
+		repeat_delay_min	1.6
+		repeat_delay_max	1.6
+	}
+
+	affector Scaler
+	{
+		rate	-8.8
+	}
+}
Index: /code/branches/rocket2/data/particle/load.particle
===================================================================
--- /code/branches/rocket2/data/particle/load.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/load.particle	(revision 6952)
@@ -0,0 +1,141 @@
+particle_system Orxonox/load
+{
+	quota	50
+	material	PE/ringflare
+	particle_width	1
+	particle_height	1.3
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	5
+		colour	1 1 1 1
+		colour_range_start	1 1 1 1
+		colour_range_end	1 1 1 1
+		direction	0 1 0
+		emission_rate	4
+		position	0 -5 0
+		velocity	5
+		velocity_min	5
+		velocity_max	5
+		time_to_live	1
+		time_to_live_min	1
+		time_to_live_max	1
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	emitter Point
+	{
+		angle	5
+		colour	1 1 1 1
+		colour_range_start	1 1 1 1
+		colour_range_end	1 1 1 1
+		direction	1 0 0
+		emission_rate	3
+		position	-5 0 0
+		velocity	5
+		velocity_min	5
+		velocity_max	5
+		time_to_live	1
+		time_to_live_min	1
+		time_to_live_max	1
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	emitter Point
+	{
+		angle	5
+		colour	1 1 1 1
+		colour_range_start	1 1 1 1
+		colour_range_end	1 1 1 1
+		direction	-1 0 0
+		emission_rate	3
+		position	5 0 0
+		velocity	5
+		velocity_min	5
+		velocity_max	5
+		time_to_live	1
+		time_to_live_min	1
+		time_to_live_max	1
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	emitter Point
+	{
+		angle	5
+		colour	1 1 1 1
+		colour_range_start	1 1 1 1
+		colour_range_end	1 1 1 1
+		direction	0 -1 0
+		emission_rate	4
+		position	0 5 0
+		velocity	5
+		velocity_min	5
+		velocity_max	5
+		time_to_live	1
+		time_to_live_min	1
+		time_to_live_max	1
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	affector Scaler
+	{
+		rate	14.4
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	1 1 0.5 0
+		time0	1
+		colour1	0.5 0.5 0.5 0
+		time1	1
+		colour2	0.5 0.5 0.5 0
+		time2	1
+		colour3	0.5 0.5 0.5 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+
+	affector DirectionRandomiser
+	{
+		randomness	15
+		scope	0.8
+		keep_velocity	false
+	}
+
+	
+}
Index: /code/branches/rocket2/data/particle/particlecanon.particle
===================================================================
--- /code/branches/rocket2/data/particle/particlecanon.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/particlecanon.particle	(revision 6952)
@@ -0,0 +1,43 @@
+particle_system Orxonox/particlecanon
+{
+	quota	1000
+	material	PE/point_lensflare
+	particle_width	6
+	particle_height	6
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	1
+		colour	0.965517 0.544828 0 1
+		colour_range_start	0.965517 0.544828 0 1
+		colour_range_end	0.965517 0.544828 0 1
+		direction	0 1 0
+		emission_rate	1220
+		position	0 0 0
+		velocity	300
+		velocity_min	300
+		velocity_max	300
+		time_to_live	0.05
+		time_to_live_min	0.05
+		time_to_live_max	0.05
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+}
Index: /code/branches/rocket2/data/particle/ray1.particle
===================================================================
--- /code/branches/rocket2/data/particle/ray1.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/ray1.particle	(revision 6952)
@@ -0,0 +1,30 @@
+
+particle_system Orxonox/ray1
+{
+	quota	1000
+	material	PE/lensflare
+	particle_width	4
+	particle_height	4
+	cull_each	false
+	renderer	billboard
+	billboard_type	point
+
+	emitter Point
+	{
+		angle	0
+		colour	1 1 1 1
+		colour_range_start	1 1 1 1
+		colour_range_end	1 1 1 1
+		direction	0 1 0
+		emission_rate	100
+		position	0 0 0
+		velocity	50
+		time_to_live	8
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+}
Index: /code/branches/rocket2/data/particle/ray2.particle
===================================================================
--- /code/branches/rocket2/data/particle/ray2.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/ray2.particle	(revision 6952)
@@ -0,0 +1,38 @@
+
+particle_system Orxonox/ray2
+{
+	quota	1200
+	material	PE/lensflare
+	particle_width	4
+	particle_height	4
+	cull_each	false
+	renderer	billboard
+	billboard_type	point
+
+	emitter Ring
+	{
+		angle	0
+		colour	1 1 1 1
+		colour_range_start	1 1 1 1
+		colour_range_end	1 1 1 1
+		direction	0 1 0
+		emission_rate	7
+		position	0 0 0
+		velocity	20
+		velocity_min	20
+		velocity_max	50
+		time_to_live	10
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		width	15
+		height	15
+		depth	15
+		inner_width	0.5
+		inner_height	0.5
+	}
+
+}
Index: /code/branches/rocket2/data/particle/repairGold.particle
===================================================================
--- /code/branches/rocket2/data/particle/repairGold.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/repairGold.particle	(revision 6952)
@@ -0,0 +1,49 @@
+
+particle_system Orxonox/repairGold
+{
+	quota	200
+	material	PE/lensflare
+	particle_width	47.38
+	particle_height	47.38
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter HollowEllipsoid
+	{
+		angle	180
+		colour	0.91358 0.734568 0 1
+		colour_range_start	0.91358 0.734568 0 1
+		colour_range_end	0.91358 0.734568 0 1
+		direction	0 1 0
+		emission_rate	216.2
+		position	0 0 0
+		velocity	1
+		velocity_min	1
+		velocity_max	1
+		time_to_live	0.5405
+		time_to_live_min	0.5405
+		time_to_live_max	0.5405
+		duration	1.441
+		duration_min	1.441
+		duration_max	1.622
+		repeat_delay	0.7207
+		repeat_delay_min	0.7207
+		repeat_delay_max	0.7207
+		width	200
+		height	200
+		depth	200
+		inner_width	0.9
+		inner_height	0.9
+		inner_depth	0.9
+	}
+}
Index: /code/branches/rocket2/data/particle/repairSilver.particle
===================================================================
--- /code/branches/rocket2/data/particle/repairSilver.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/repairSilver.particle	(revision 6952)
@@ -0,0 +1,49 @@
+
+particle_system Orxonox/repairSilver
+{
+	quota	500
+	material	PE/lensflare
+	particle_width	47.38
+	particle_height	47.38
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter HollowEllipsoid
+	{
+		angle	0
+		colour	0.691358 0.814815 1 1
+		colour_range_start	0.691358 0.814815 1 1
+		colour_range_end	0.691358 0.814815 1 1
+		direction	0 1 0
+		emission_rate	342.3
+		position	0 0 0
+		velocity	1
+		velocity_min	1
+		velocity_max	1
+		time_to_live	0.4
+		time_to_live_min	0.4
+		time_to_live_max	0.4
+		duration	0.7
+		duration_min	0.7
+		duration_max	0.7
+		repeat_delay	0.7207
+		repeat_delay_min	0.7207
+		repeat_delay_max	0.7207
+		width	200
+		height	200
+		depth	200
+		inner_width	0.9
+		inner_height	0.9
+		inner_depth	0.9
+	}
+}
Index: /code/branches/rocket2/data/particle/rocketfire.particle
===================================================================
--- /code/branches/rocket2/data/particle/rocketfire.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/rocketfire.particle	(revision 6952)
@@ -0,0 +1,50 @@
+particle_system Orxonox/rocketfire
+{
+	quota	300
+	material	PE/explosion
+	particle_width	15
+	particle_height	5
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Ellipsoid
+	{
+		angle	2
+		colour	1 0.682759 1 1
+		colour_range_start	1 0.682759 1 1
+		colour_range_end	1 0.682759 1 1
+		direction	0 0 1
+		emission_rate	1200
+		position	0 0 3
+		velocity	10
+		velocity_min	10
+		velocity_max	48
+		time_to_live	0.1
+		time_to_live_min	0.1
+		time_to_live_max	0.2
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		width	1.5
+		height	1.5
+		depth	10
+	}
+
+	affector Scaler
+	{
+		rate	-20
+	}
+}
Index: /code/branches/rocket2/data/particle/rocketfire2.particle
===================================================================
--- /code/branches/rocket2/data/particle/rocketfire2.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/rocketfire2.particle	(revision 6952)
@@ -0,0 +1,50 @@
+particle_system Orxonox/rocketfire2
+{
+	quota	300
+	material	PE/explosion
+	particle_width	5
+	particle_height	2
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Ellipsoid
+	{
+		angle	2
+		colour	1 0.682759 1 1
+		colour_range_start	1 0.682759 1 1
+		colour_range_end	1 0.682759 1 1
+		direction	0 0 1
+		emission_rate	1200
+		position	0 0 3
+		velocity	10
+		velocity_min	10
+		velocity_max	48
+		time_to_live	0.1
+		time_to_live_min	0.1
+		time_to_live_max	0.2
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		width	0.8
+		height	0.8
+		depth	4
+	}
+
+	affector Scaler
+	{
+		rate	-20
+	}
+}
Index: /code/branches/rocket2/data/particle/shot1.particle
===================================================================
--- /code/branches/rocket2/data/particle/shot1.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/shot1.particle	(revision 6952)
@@ -0,0 +1,36 @@
+particle_system Orxonox/shot1
+{
+	quota	5000
+	material	PE/lensflare
+	particle_width	3
+	particle_height	3
+	cull_each	false
+	renderer	billboard
+	billboard_type	point
+
+	emitter Cylinder
+	{
+		angle	0
+		colour	1 1 0 1
+		colour_range_start	1 1 0 1
+		colour_range_end	0.3 1 0.3 1
+		direction	0 1 0
+		emission_rate	260.9
+		position	0 0 0
+		velocity	120
+		velocity_min	120
+		velocity_max	120
+		time_to_live	2
+		time_to_live_min	2
+		time_to_live_max	2
+		duration	0.1
+		duration_min	0.1
+		duration_max	0.1
+		repeat_delay	0.5
+		repeat_delay_min	0.5
+		repeat_delay_max	0.5
+		width	0.5
+		height	0.5
+		depth	5
+	}
+}
Index: /code/branches/rocket2/data/particle/shot2.particle
===================================================================
--- /code/branches/rocket2/data/particle/shot2.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/shot2.particle	(revision 6952)
@@ -0,0 +1,56 @@
+
+particle_system Orxonox/shot2
+{
+	quota	25
+	material	PE/point_lensflare
+	particle_width	40
+	particle_height	100
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	0
+		colour	0 0 0 1
+		colour_range_start	0 0 0 1
+		colour_range_end	0.5 0.5 0.7 1
+		direction	0 -1 0
+		emission_rate	40
+		position	0 0 0
+		velocity	200
+		velocity_min	200
+		velocity_max	300
+		time_to_live	0.5
+		time_to_live_min	0.5
+		time_to_live_max	0.5
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	affector Scaler
+	{
+		rate	-20
+	}
+
+	affector ColourFader
+	{
+		red	-0.8
+		green	-0.8
+		blue	-0.5
+		alpha	0
+	}
+}
Index: /code/branches/rocket2/data/particle/shot2_small.particle
===================================================================
--- /code/branches/rocket2/data/particle/shot2_small.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/shot2_small.particle	(revision 6952)
@@ -0,0 +1,56 @@
+
+particle_system Orxonox/shot2_small
+{
+	quota	25
+	material	PE/point_lensflare
+	particle_width	10
+	particle_height	25
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	true
+
+	emitter Point
+	{
+		angle	0
+		colour	0 0 0 1
+		colour_range_start	0.4 0.4 0.6 1
+		colour_range_end	0.5 0.5 0.7 1
+		direction	0 -1 0
+		emission_rate	80
+		position	0 0 0
+		velocity	1
+		velocity_min	1
+		velocity_max	1
+		time_to_live	0.25
+		time_to_live_min	0.25
+		time_to_live_max	0.25
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	affector Scaler
+	{
+		rate	-20
+	}
+
+	affector ColourFader
+	{
+		red	-1.6
+		green	-1.6
+		blue	-1.0
+		alpha	0
+	}
+}
Index: /code/branches/rocket2/data/particle/shot3_small.particle
===================================================================
--- /code/branches/rocket2/data/particle/shot3_small.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/shot3_small.particle	(revision 6952)
@@ -0,0 +1,56 @@
+
+particle_system Orxonox/shot3_small
+{
+	quota	25
+	material	PE/point_lensflare
+	particle_width	10
+	particle_height	25
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	true
+
+	emitter Point
+	{
+		angle	0
+		colour	0 0 0 1
+		colour_range_start	0.4 0.4 0.6 1
+		colour_range_end	0.5 0.5 0.7 1
+		direction	0 -1 0
+		emission_rate	80
+		position	0 0 0
+		velocity	1
+		velocity_min	1
+		velocity_max	1
+		time_to_live	0.25
+		time_to_live_min	0.25
+		time_to_live_max	0.25
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	affector Scaler
+	{
+		rate	-15
+	}
+
+	affector ColourFader
+	{
+		red	-1.6
+		green	-1.6
+		blue	-1.0
+		alpha	0
+	}
+}
Index: /code/branches/rocket2/data/particle/shotTest.particle
===================================================================
--- /code/branches/rocket2/data/particle/shotTest.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/shotTest.particle	(revision 6952)
@@ -0,0 +1,55 @@
+
+particle_system Orxonox/shotTest
+{
+	quota	3000
+	material	PE/bigFlame
+	particle_width	1
+	particle_height	10
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	true
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	7.2
+		colour	1 0 0 0.9
+		colour_range_start	1 0 0 0.9
+		colour_range_end	1 0.185185 0 0.9
+		direction	0 1 0
+		emission_rate	2000
+		position	0 0 0
+		velocity	300
+		velocity_min	300
+		velocity_max	300
+		time_to_live	0.2
+		time_to_live_min	0.2
+		time_to_live_max	0.2
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	affector DirectionRandomiser
+	{
+		randomness	500
+		scope	1
+		keep_velocity	false
+	}
+
+	affector Scaler
+	{
+		rate	20
+	}
+}
Index: /code/branches/rocket2/data/particle/smoke.particle
===================================================================
--- /code/branches/rocket2/data/particle/smoke.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/smoke.particle	(revision 6952)
@@ -0,0 +1,45 @@
+particle_system Orxonox/smoke
+{
+	quota	300
+	material	PE/explosion
+	particle_width	6.94
+	particle_height	7.93
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Ellipsoid
+	{
+		angle	13
+		colour	0.156897 0.326207 1 1
+		colour_range_start	0.156897 0.326207 1 1
+		colour_range_end	0.156897 0.326207 1 1
+		direction	0 1 0
+		emission_rate	65
+		position	0 0 0
+		velocity	25
+		velocity_min	25
+		velocity_max	25
+		time_to_live	2.2
+		time_to_live_min	2.2
+		time_to_live_max	2.2
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		width	3
+		height	3
+		depth	0
+	}
+}
Index: /code/branches/rocket2/data/particle/smoke1.particle
===================================================================
--- /code/branches/rocket2/data/particle/smoke1.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/smoke1.particle	(revision 6952)
@@ -0,0 +1,43 @@
+// Example particle systems
+
+// smoke
+particle_system Examples/Smoke
+{
+    	material        	Examples/Smoke
+    	particle_width  	55
+    	particle_height 	55
+    	cull_each       	true
+    	quota           	500
+    	billboard_type  	point
+		sorted				true
+    
+    	// Area emitter
+    	emitter Point
+    	{
+		angle               		11
+        	emission_rate       		15
+        	time_to_live        		4
+        	direction           		0 1 0
+        	velocity_min        		150
+        	velocity_max        		240    	
+	}
+
+	affector ColourImage
+	{
+		image		smokecolors.tga
+	}
+
+   	affector Rotator
+   	{
+        	rotation_range_start  		0
+        	rotation_range_end   	 	360
+        	rotation_speed_range_start  	-60
+        	rotation_speed_range_end    	200
+   	}
+
+   	affector Scaler
+   	{
+       	rate 	100
+   	}
+
+}
Index: /code/branches/rocket2/data/particle/smoke2.particle
===================================================================
--- /code/branches/rocket2/data/particle/smoke2.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/smoke2.particle	(revision 6952)
@@ -0,0 +1,45 @@
+
+particle_system Orxonox/smoke2
+{
+	quota	1000
+	material	PE/smoke
+	particle_width	4
+	particle_height	4
+	cull_each	false
+	renderer	billboard
+	billboard_type	point
+
+	emitter Ellipsoid
+	{
+		angle	150
+		colour	0.0547945 0.0547945 0.0547945 0.9
+		colour_range_start	0.0547945 0.0547945 0.0547945 0.9
+		colour_range_end	0.0547945 0.0547945 0.0547945 0.9
+		direction	0 1 0
+		emission_rate	40
+		position	0 0 0
+		velocity	2
+		velocity_min	2
+		velocity_max	2
+		time_to_live	3
+		time_to_live_min	3
+		time_to_live_max	5
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		width	0.2
+		height	0.2
+		depth	0.2
+	}
+
+	affector ColourFader
+	{
+		red	0.3
+		green	0.3
+		blue	0.3
+		alpha	-0.35
+	}
+}
Index: /code/branches/rocket2/data/particle/smoke3.particle
===================================================================
--- /code/branches/rocket2/data/particle/smoke3.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/smoke3.particle	(revision 6952)
@@ -0,0 +1,79 @@
+
+particle_system Orxonox/smoke3
+{
+	quota	10
+	material	PE/smoke2
+	particle_width	30
+	particle_height	30
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	vertex
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	0 0 0 0
+		colour_range_start	0 0 0 0
+		colour_range_end	0 0 0 0
+		direction	0 1 0
+		emission_rate	10
+		position	0 0 0
+		velocity	7
+		velocity_min	7
+		velocity_max	7
+		time_to_live	5
+		time_to_live_min	5
+		time_to_live_max	5
+		duration	1
+		duration_min	1
+		duration_max	1
+		repeat_delay	1000000
+		repeat_delay_min	1000000
+		repeat_delay_max	1000000
+	}
+
+	affector Scaler
+	{
+		rate	20
+	}
+
+	affector DirectionRandomiser
+	{
+		randomness	150
+		scope	1
+		keep_velocity	true
+	}
+
+	affector Rotator
+	{
+		rotation_speed_range_start	-20
+		rotation_speed_range_end	20
+		rotation_range_start	0
+		rotation_range_end	0
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0 0 0 0
+		time0	0
+		colour1	0.5 0.5 0.5 0.2
+		time1	0.2
+		colour2	0.5 0.5 0.5 0.5
+		time2	0.5
+		colour3	0 0 0 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/smoke4.particle
===================================================================
--- /code/branches/rocket2/data/particle/smoke4.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/smoke4.particle	(revision 6952)
@@ -0,0 +1,72 @@
+
+particle_system Orxonox/smoke4
+{
+	quota	10
+	material	PE/smoke3
+	particle_width	7
+	particle_height	7
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	vertex
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	0 0 0 0
+		colour_range_start	0 0 0 0
+		colour_range_end	0 0 0 0
+		direction	0 1 0
+		emission_rate	15
+		position	0 0 0
+		velocity	20
+		velocity_min	20
+		velocity_max	20
+		time_to_live	1.5
+		time_to_live_min	1.5
+		time_to_live_max	1.5
+		duration	0.3
+		duration_min	0.3
+		duration_max	0.3
+		repeat_delay	1000000
+		repeat_delay_min	1000000
+		repeat_delay_max	1000000
+	}
+
+	affector Scaler
+	{
+		rate	15
+	}
+
+	affector Rotator
+	{
+		rotation_speed_range_start	-50
+		rotation_speed_range_end	50
+		rotation_range_start	0
+		rotation_range_end	0
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0 0 0 0
+		time0	0
+		colour1	0.5 0.5 0.5 0.4
+		time1	0.2
+		colour2	0.5 0.5 0.5 0.8
+		time2	0.5
+		colour3	0 0 0 0
+		time3	1
+		colour4	0.5 0.5 0.5 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/smoke5.particle
===================================================================
--- /code/branches/rocket2/data/particle/smoke5.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/smoke5.particle	(revision 6952)
@@ -0,0 +1,72 @@
+
+particle_system Orxonox/smoke5
+{
+	quota	80
+	material	PE/smoke3
+	particle_width	40
+	particle_height	40
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	vertex
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	0 0 0 0
+		colour_range_start	0 0 0 0
+		colour_range_end	0 0 0 0
+		direction	0 1 0
+		emission_rate	20
+		position	0 0 0
+		velocity	7
+		velocity_min	7
+		velocity_max	7
+		time_to_live	3
+		time_to_live_min	3
+		time_to_live_max	3
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	affector Scaler
+	{
+		rate	30
+	}
+
+	affector Rotator
+	{
+		rotation_speed_range_start	-50
+		rotation_speed_range_end	50
+		rotation_range_start	0
+		rotation_range_end	0
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0 0 0 0
+		time0	0
+		colour1	0.5 0.5 0.5 0.4
+		time1	0.05
+		colour2	0.3 0.3 0.3 0.8
+		time2	0.5
+		colour3	0.1 0.1 0.1 0.4
+		time3	0.8
+		colour4	0 0 0 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/smoke6.particle
===================================================================
--- /code/branches/rocket2/data/particle/smoke6.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/smoke6.particle	(revision 6952)
@@ -0,0 +1,64 @@
+
+particle_system Orxonox/smoke6
+{
+	quota	50
+	material	PE/smoke2
+	particle_width	25
+	particle_height	10
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	0 0 0 1
+		colour_range_start	0 0 0 1
+		colour_range_end	0 0 0 1
+		direction	0 1 0
+		emission_rate	50
+		position	0 0 0
+		velocity	40
+		velocity_min	40
+		velocity_max	60
+		time_to_live	1.5
+		time_to_live_min	1.5
+		time_to_live_max	1.5
+		duration	1
+		duration_min	1
+		duration_max	1
+		repeat_delay	5
+		repeat_delay_min	5
+		repeat_delay_max	5
+	}
+
+	affector Scaler
+	{
+		rate	100
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0.3 0.3 0.3 0.0
+		time0	0.1
+		colour1	0.2 0.2 0.2 0.2
+		time1	0.2
+		colour2	0.2 0.2 0.2 0.2
+		time2	0.6
+		colour3	0 0 0 0
+		time3	1
+		colour4	0 0 0 0
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/smoke7.particle
===================================================================
--- /code/branches/rocket2/data/particle/smoke7.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/smoke7.particle	(revision 6952)
@@ -0,0 +1,72 @@
+
+particle_system Orxonox/smoke7
+{
+	quota	25
+	material	PE/smoke2
+	particle_width	8
+	particle_height	8
+	cull_each	false
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	vertex
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	0 0 0 0
+		colour_range_start	0 0 0 0
+		colour_range_end	0 0 0 0
+		direction	0 1 0
+		emission_rate	25
+		position	0 0 0
+		velocity	5
+		velocity_min	5
+		velocity_max	10
+		time_to_live	1.0
+		time_to_live_min	1.0
+		time_to_live_max	1.0
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	affector Scaler
+	{
+		rate	3
+	}
+
+	affector Rotator
+	{
+		rotation_speed_range_start	0
+		rotation_speed_range_end	0
+		rotation_range_start	0
+		rotation_range_end	360
+	}
+
+	affector ColourInterpolator
+	{
+		colour0	0.2 0.2 0.2 0
+		time0	0
+		colour1	0.15 0.15 0.15 0.7
+		time1	0.1
+		colour2	0.15 0.15 0.15 1
+		time2	0.6
+		colour3	0.1 0.1 0.1 0
+		time3	1
+		colour4	0.5 0.5 0.5 1
+		time4	1
+		colour5	0.5 0.5 0.5 0
+		time5	1
+	}
+}
Index: /code/branches/rocket2/data/particle/sparks.particle
===================================================================
--- /code/branches/rocket2/data/particle/sparks.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/sparks.particle	(revision 6952)
@@ -0,0 +1,61 @@
+
+particle_system Orxonox/sparks
+{
+	quota	100
+	material	PE/lensflare
+	particle_width	4
+	particle_height	4
+	cull_each	true
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	point
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Ellipsoid
+	{
+		angle	180
+		colour	0.8 0.6 0.4 1
+		colour_range_start	0.8 0.6 0.4 1
+		colour_range_end	1 0.7 0.5 1
+		direction	0 -1 0
+		emission_rate	2000
+		position	0 0 0
+		velocity	1
+		velocity_min	1
+		velocity_max	1
+		time_to_live	4
+		time_to_live_min	4
+		time_to_live_max	4
+		duration	0.05
+		duration_min	0.05
+		duration_max	0.05
+		repeat_delay	5
+		repeat_delay_min	5
+		repeat_delay_max	5
+		width	75
+		height	75
+		depth	75
+	}
+
+	affector DirectionRandomiser
+	{
+		randomness	250
+		scope	0.1
+		keep_velocity	true
+	}
+
+	affector ColourFader
+	{
+		red	-0.25
+		green	-0.20
+		blue	-0.15
+		alpha	0
+	}
+}
Index: /code/branches/rocket2/data/particle/sparks2.particle
===================================================================
--- /code/branches/rocket2/data/particle/sparks2.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/sparks2.particle	(revision 6952)
@@ -0,0 +1,51 @@
+
+particle_system Orxonox/sparks2
+{
+	quota	1000
+	material	PE/Flare
+	particle_width	15
+	particle_height	40
+	cull_each	true
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	oriented_self
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Point
+	{
+		angle	180
+		colour	0.1 0.1 0.1 1
+		colour_range_start	0.1 0.1 0.1 1
+		colour_range_end	1 1 1 1
+		direction	0 0 -1
+		emission_rate	5000
+		position	0 0 0
+		velocity	10
+		velocity_min	15
+		velocity_max	150
+		time_to_live	0.5
+		time_to_live_min	0.5
+		time_to_live_max	0.5
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+	}
+
+	affector ColourFader
+	{
+		red	-2.0
+		green	-2.0
+		blue	-2.0
+		alpha	0
+	}
+}
Index: /code/branches/rocket2/data/particle/tes3.particle
===================================================================
--- /code/branches/rocket2/data/particle/tes3.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/tes3.particle	(revision 6952)
@@ -0,0 +1,59 @@
+particle_system Orxonox/tes3
+{
+	quota	500
+	material	PE/lensflare
+	particle_width	10
+	particle_height	10
+	cull_each	true
+	renderer	billboard
+	sorted	false
+	local_space	false
+	iteration_interval	0
+	nonvisible_update_timeout	0
+	billboard_type	perpendicular_self
+	billboard_origin	center
+	billboard_rotation_type	texcoord
+	common_up_vector	0 1 0
+	point_rendering	false
+	accurate_facing	false
+
+	emitter Cylinder
+	{
+		angle	180
+		colour	1 1 1 1
+		colour_range_start	1 1 1 1
+		colour_range_end	1 1 1 1
+		direction	0 -1 0
+		emission_rate	100
+		position	0 100 0
+		velocity	26
+		velocity_min	26
+		velocity_max	26
+		time_to_live	9.6
+		time_to_live_min	9.6
+		time_to_live_max	9.6
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		width	200
+		height	200
+		depth	1
+	}
+
+	affector DeflectorPlane
+	{
+		plane_point	0 0 0
+		plane_normal	0 1 0
+		bounce	2
+	}
+
+	affector DirectionRandomiser
+	{
+		randomness	7
+		scope	1
+		keep_velocity	true
+	}
+}
Index: /code/branches/rocket2/data/particle/thruster1.particle
===================================================================
--- /code/branches/rocket2/data/particle/thruster1.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/thruster1.particle	(revision 6952)
@@ -0,0 +1,53 @@
+particle_system Orxonox/thruster1
+{
+	quota	100
+	material	PE/bigFlame
+	particle_width	15
+	particle_height	15
+	cull_each	false
+	renderer	billboard
+	billboard_type	point
+
+	emitter HollowEllipsoid
+	{
+		angle	0
+		colour	0.493151 0.246575 0.0410959 1
+		colour_range_start	0.493151 0.246575 0.0410959 1
+		colour_range_end	0.684932 0.547945 0.315068 1
+		direction	0 1 0
+		emission_rate	300
+		position	0 0 0
+		velocity	100
+		velocity_min	18
+		velocity_max	30
+		time_to_live	0.25
+		time_to_live_min	0
+		time_to_live_max	0.25
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		width	5
+		height	5
+		depth	2.8
+		inner_width	0.8
+		inner_height	0.8
+		inner_depth	0.8
+	}
+
+
+	affector ColourFader2
+	{
+		red1	0
+		green1	0
+		blue1	0
+		alpha1	0
+		red2	-0.3
+		green2	-0.6
+		blue2	-0.6
+		alpha2	0
+		state_change	0.25
+	}
+}
Index: /code/branches/rocket2/data/particle/thruster2.particle
===================================================================
--- /code/branches/rocket2/data/particle/thruster2.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/thruster2.particle	(revision 6952)
@@ -0,0 +1,47 @@
+particle_system Orxonox/thruster2
+{
+	quota	150
+	material	PE/bigFlame
+	particle_width	15
+	particle_height	15
+	cull_each	false
+	renderer	billboard
+	billboard_type	point
+
+	emitter HollowEllipsoid
+	{
+		angle	0
+		colour	0.4 0.3 0.8 1
+		colour_range_start	0.4 0.3 0.8 1
+		colour_range_end	0.5 0.4 0.9 1
+		direction	0 1 0
+		emission_rate	400
+		position	0 0 0
+		velocity	5
+		velocity_min	4
+		velocity_max	6
+		time_to_live	0.1
+		time_to_live_min	0.15
+		time_to_live_max	0.25
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		width	4
+		height	2.5
+		depth	1.3
+		inner_width	0.5
+		inner_height	0.3
+		inner_depth	0.2
+	}
+
+	affector ColourFader
+	{
+		red	-0.5
+		green	-0.5
+		blue	-0.6
+		alpha	-0.5
+	}
+}
Index: /code/branches/rocket2/data/particle/thruster3.particle
===================================================================
--- /code/branches/rocket2/data/particle/thruster3.particle	(revision 6952)
+++ /code/branches/rocket2/data/particle/thruster3.particle	(revision 6952)
@@ -0,0 +1,53 @@
+particle_system Orxonox/thruster3
+{
+	quota	100
+	material	PE/bigFlame
+	particle_width	2
+	particle_height	2
+	cull_each	false
+	renderer	billboard
+	billboard_type	point
+
+	emitter HollowEllipsoid
+	{
+		angle	0
+		colour	0.493151 0.246575 0.0410959 1
+		colour_range_start	0.493151 0.246575 0.0410959 1
+		colour_range_end	0.684932 0.547945 0.315068 1
+		direction	-1 0 0
+		emission_rate	300
+		position	0 0 0
+		velocity	6
+		velocity_min	5
+		velocity_max	7
+		time_to_live	0.125
+		time_to_live_min	0.100
+		time_to_live_max	0.125
+		duration	0
+		duration_min	0
+		duration_max	0
+		repeat_delay	0
+		repeat_delay_min	0
+		repeat_delay_max	0
+		width	1
+		height	1
+		depth	2.8
+		inner_width	0.8
+		inner_height	0.8
+		inner_depth	0.8
+	}
+
+
+	affector ColourFader2
+	{
+		red1	0
+		green1	0
+		blue1	0
+		alpha1	0
+		red2	-0.2
+		green2	-0.5
+		blue2	-0.5
+		alpha2	0
+		state_change	0.1
+	}
+}
Index: /code/branches/rocket2/data/tcl/init.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/init.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/init.tcl	(revision 6952)
@@ -0,0 +1,298 @@
+# Check if Tcl was properly initialized
+info library
+
+# Create orxonox namespace
+namespace eval orxonox {}
+
+# query --
+# Sends a query to the CommandExecutor of Orxonox and waits for the response.
+# This dummy procedure will be changed to it's real implementation by Orxonox itself.
+#
+# Arguments:
+# args - The command to send to Orxonox
+
+proc query args {
+    return -code error "Can't query Orxonox now"
+}
+
+
+# crossquery --
+# Sends a query to another Tcl-interpreter in Orxonox and waits for the response.
+# This dummy procedure will be changed to it's real implementation by Orxonox itself.
+#
+# Arguments:
+# id   - The ID of the other interpreter
+# args - The command to send to Orxonox
+
+proc crossquery {id args} {
+    return -code error "Can't query interpreter with ID $id now"
+}
+
+
+# execute --
+# Sends a command to the queue of Orxonox where it will be executed by the CommandExecutor after some time
+# This dummy procedure will be changed to it's real implementation by Orxonox itself.
+#
+# Arguments:
+# args - The command
+
+proc execute args {
+    return -code error "Can't execute a command now"
+}
+
+
+# crossexecute --
+# Sends a command to the queue of another Tcl-interpreter where it will be executed by after some time
+# This dummy procedure will be changed to it's real implementation by Orxonox itself.
+#
+# Arguments:
+# id   - The ID of the other interpreter
+# args - The command
+
+proc crossexecute {id args} {
+    return -code error "Can't execute a command now"
+}
+
+
+# running --
+# Returns true if the interpreter is still suposed to be running
+# This dummy procedure will be changed to it's real implementation by Orxonox itself.
+
+proc running {} {
+    return 1
+}
+
+
+# orxonox::while --
+# Works like while but breaks the loop if orxonox::running returns false
+
+proc ::orxonox::while {condition body} {
+    set condition_cmd [list expr $condition]
+    ::tcl::while {1} {
+        if {![uplevel 1 $condition_cmd] || ![::running]} {
+            break
+        }
+        uplevel 1 $body
+    }
+}
+
+
+# orxonox::for --
+# Works like for but breaks the loop if orxonox::running returns false
+
+proc ::orxonox::for {start condition step body} {
+    set condition_cmd [list expr $condition]
+    uplevel 1 $start
+    ::tcl::while {1} {
+        if {![uplevel 1 $condition_cmd] || ![::running]} {
+            break
+        }
+        uplevel 1 $body
+        uplevel 1 $step
+    }
+}
+
+
+# add the path to this file to the auto path
+
+set filepath [info script]
+#set ::orxonox::mediapath [string range $filepath 0 [string last "/" $filepath]]
+set ::orxonox::mediapath [file dirname $filepath]
+if {[lsearch $auto_path $::orxonox::mediapath] == -1} {
+    lappend auto_path $::orxonox::mediapath
+}
+unset filepath
+
+
+# save the start directory and the library directory
+
+proc psd {} "return [pwd]"
+proc pld {} "return $::orxonox::mediapath"
+
+set pwd [pwd]
+set psd [psd]
+set pld [pld]
+
+
+# modify cd to automatically set $pwd
+
+if {[llength [info command ::tcl::cd]] == 0} {
+    rename cd ::tcl::cd
+}
+proc cd {{path "~"}} {
+    global pwd
+    ::tcl::cd $path
+    set pwd [pwd]
+}
+
+
+# change the working directory to the media path
+
+cd $::orxonox::mediapath
+
+
+# Redefines puts to write directly into the Orxonox console if the channel is stdout or stderr.
+
+if {[llength [info command ::tcl::puts]] == 0} {
+    rename puts ::tcl::puts
+}
+proc puts args {
+    set argc [llength $args]
+    if {$argc < 1 || $argc > 3} {
+        error "wrong # args: should be \"puts ?-nonewline? ?channelId? string\""
+    }
+
+    set newline 1
+    set input $args
+
+    if {$argc > 1 && [lindex $input 0] == "-nonewline"} {
+        set newline 0
+        set input [lrange $input 1 end]
+    } elseif {$argc == 3} {
+        if {[lindex $input 2] == "nonewline"} {
+            set newline 0
+            set input [lrange $input 0 1]
+        } else {
+            error "bad argument \"[lindex $input 2]\": should be \"nonewline\""
+        }
+    }
+
+    if {[llength $input] == 1} {
+        set input [list stdout [join $input]]
+    }
+
+    foreach {channel s} $input break
+
+    if {$channel == "stdout" || $channel == "stderr"} {
+        execute puts $newline $s
+    } else {
+        eval [concat ::tcl::puts $args]
+    }
+}
+
+
+# Redefines unknown to send unknown commands back to orxonox
+
+if {[llength [info commands unknown]] != 0} {
+    # check if a command named "undefined_proc" exists, if yes rename it temporarily
+    set undefined_was_defined 0
+    if {[llength [info commands undefined_proc]] != 0} {
+        set undefined_was_defined 0
+        rename undefined_proc _undefined
+    }
+
+    # get the returned errormessage if an undefined_proc command is called
+    if {[llength [info commands ::tcl::unknown]] == 0} {
+        set errorcode [catch {unknown undefined_proc} result]
+    } else {
+        set errorcode [catch {::tcl::unknown undefined_proc} result]
+    }
+
+    if {$errorcode} {
+        set result_list [split $result]
+        set ::orxonox::errormessage_unknown [list]
+
+        # parse the error message (the original message was something like "invalid command name "undefined_proc"" but we just want "invalid command name")
+        foreach token $result_list {
+            if {![string match "*undefined_proc*" $token]} {
+                lappend ::orxonox::errormessage_unknown $token
+            }
+        }
+
+        unset result_list
+        unset token
+
+        set ::orxonox::errormessage_unknown_length [llength $::orxonox::errormessage_unknown]
+
+        # rename the original unknown procedure
+        if {[llength [info commands ::tcl::unknown]] == 0} {
+            rename unknown ::tcl::unknown
+        }
+
+        # define the modified version of unknown
+        # we implement two versions, because tcl8.4 complains if this fork is moved inside [unknown]
+        if {[info tclversion] >= 8.5} {
+            # version >= 8.5
+            proc unknown args {
+                global ::orxonox::errormessage_unknown ::orxonox::errormessage_unknown_length
+
+                set cmd [concat ::tcl::unknown $args]
+                set errorcode [catch {eval $cmd} result options]
+                set resultlist [split $result]
+                set success 1
+
+                if {$errorcode && [llength $resultlist] >= $::orxonox::errormessage_unknown_length} {
+                    for {set i 0} {$i < $::orxonox::errormessage_unknown_length} {incr i} {
+                        if {[lindex $::orxonox::errormessage_unknown $i] != [lindex $resultlist $i]} {
+                            set success 0
+                            break
+                        }
+                    }
+                } else {
+                    set success 0
+                }
+
+                if {!$success} {
+                    return -code $errorcode -options $options $result
+                } else {
+                    return [query $args]
+                }
+            }
+        } else {
+            # version < 8.5
+            proc unknown args {
+                global ::orxonox::errormessage_unknown ::orxonox::errormessage_unknown_length
+
+                set cmd [concat ::tcl::unknown $args]
+                set errorcode [catch {eval $cmd} result]
+                set resultlist [split $result]
+                set success 1
+
+                if {$errorcode && [llength $resultlist] >= $::orxonox::errormessage_unknown_length} {
+                    for {set i 0} {$i < $::orxonox::errormessage_unknown_length} {incr i} {
+                        if {[lindex $::orxonox::errormessage_unknown $i] != [lindex $resultlist $i]} {
+                            set success 0
+                            break
+                        }
+                    }
+                } else {
+                    set success 0
+                }
+
+                if {!$success} {
+                    return -code $errorcode $result
+                } else {
+                    return [query $args]
+                }
+            }
+        }
+
+        set success 1
+    } else {
+        set success 0
+    }
+
+    unset errorcode
+    unset result
+
+    # if the "undefined_proc" command was renamed previously, undo this
+    if {$undefined_was_defined} {
+        rename _undefined undefined_proc
+    }
+
+    unset undefined_was_defined
+
+    if {!$success} {
+        unset success
+        # something went wrong, use the default method
+        proc unknown args {
+            return [query $args]
+        }
+    }
+    unset success
+} else {
+    # no original unknown procedure defined, use the default method
+    proc unknown args {
+        return [query $args]
+    }
+}
Index: /code/branches/rocket2/data/tcl/irc.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irc.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irc.tcl	(revision 6952)
@@ -0,0 +1,6 @@
+proc every {ms body} { eval $body; after $ms [list every $ms $body] }
+package require irk
+set conn [irk::connect orxonox $nickname]
+irk::join $conn #orxonox
+every 25 {}
+vwait termination
Index: /code/branches/rocket2/data/tcl/irk/README
===================================================================
--- /code/branches/rocket2/data/tcl/irk/README	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/README	(revision 6952)
@@ -0,0 +1,76 @@
+IRK README
+==========
+
+Welcome to IRK, a Tcl IRC client library. IRK is intended for Tcl
+programmers that want to use the IRC protocol for communication. It
+can be used to ease the creation of IRC "bots", as shown by the
+examples in the examples directory, and it can also serve as the basis
+for graphical chat clients. Finally, it can be used to allow IRKs to
+find each other without centralized coordination, by meeting on a
+designated IRC server and channel. It is therefore ideal for setting
+up the initial contact for P2P programs without requiring a central
+registry or server.
+
+LICENSE
+=======
+
+IRK is distributed under the BSD license, the same license as Tcl.
+
+INSTALLATION
+============
+
+IRK is written in pure Tcl, which means it requires no extensions. It
+works with Tcl 8.0 and all later releases of Tcl.
+
+IRK has been tested on Solaris 7, Red Hat Linux 7.2, Windows 98,
+Windows 2000 and FreeBSD 4.2. It should work on any platform that is
+able to support Tcl 8.0 or later.
+
+Just drop this directory into one of the directories in Tcl's auto
+path. In your Tcl scripts, add the line:
+
+	package require irk
+
+and the IRK package should load into your Tcl interpreter.
+
+USAGE
+=====
+
+Read docs/usage.txt for a short overview of the commands provided by
+IRK.
+
+RECENT CHANGES AND CURRENT VERSION
+==================================
+
+Please read docs/changes.txt to see a list of all changes, ordered
+chronologically by release.
+
+REQUIREMENTS
+============
+
+IRK is event driven, and it requires the event loop to be active. If
+you want to use IRK from tclsh or other programs embedding a Tcl
+interpreter where the event loop is inactive, enter the event loop by
+adding the following line somewhere in your program:
+
+	vwait infinitely
+
+If you are using IRK in Wish, you do not need to take any action.
+
+TODO
+====
+
+Please docs/todo.txt for a list of planned enhancements.
+
+CREDITS AND CONTACT
+===================
+
+IRK benefited from examination of the Zircon and savIRC code written
+by Lindsay Marshall and Saverio Castellano, respectively. The future
+OO wrapper API is based on an idea suggested by Dave N. Welton.
+
+You can contact Jacob Levy, the author of IRK, at jyl@best.com. Please
+do drop a note if you use IRK, or if you have suggestions for
+enhancements, or if you run into problems.
+
+
Index: /code/branches/rocket2/data/tcl/irk/docs/changes.txt
===================================================================
--- /code/branches/rocket2/data/tcl/irk/docs/changes.txt	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/docs/changes.txt	(revision 6952)
@@ -0,0 +1,22 @@
+IRK 0.01, 02/07/2002
+    This is the first release of IRK.
+
+    What's implemented:
+
+    * Connection management.
+    * Integrated support for SOCKS5 to get through firewalls.
+    * Rudimentary flow control and queueing. Needs more work.
+    * Ping, MOTD, and informational messages management.
+    * Channel and nick management.
+    * Users on channels tracking.
+    * CTCP and all its subcommands.
+    * Special CTCP TCL protocol for communication between IRKs. All Tcl code
+      received from remote IRKs is run in a safe interpreter.
+    * Generalized persistent authorization and password management mechanism.
+    * Two usage examples:
+      + tontalou.tcl: a "bot" modelled after SmallSaints on DalNet. This
+        bot is unfinished.
+      + fortunebot.tcl: a "bot" that demonstrates grabbing a page from
+        the web and presenting its information in IRC.
+      Unfortunately no documentation is provided for these bots but they do
+      provide excellent examples on how you can use IRK to write Tcl "bots".
Index: /code/branches/rocket2/data/tcl/irk/docs/todo.txt
===================================================================
--- /code/branches/rocket2/data/tcl/irk/docs/todo.txt	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/docs/todo.txt	(revision 6952)
@@ -0,0 +1,10 @@
+TODO LIST FOR IRK
+=================
+
+* Implement DCC.
+* Implement object based command structure.
+* Implement event bindings modelled after the Tk Text widget.
+* Improve flow control.
+* Implement the last remaining RFC1439 protocol elements.
+* Implement proxy IRK commands for CTCP TCL safe interpreters.
+* Implement /mode commands.
Index: /code/branches/rocket2/data/tcl/irk/docs/usage.txt
===================================================================
--- /code/branches/rocket2/data/tcl/irk/docs/usage.txt	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/docs/usage.txt	(revision 6952)
@@ -0,0 +1,59 @@
+A VERY ABBREVIATED INTRO TO IRK
+===============================
+
+All IRK commands are found within the ::irk namespace.
+
+To open a connection with an IRC server, use:
+
+   set conn [irk::connect twisted panda1]
+
+This opens a connection to the server named 'twisted' (This is
+actually the server twisted.ma.us.dal.net) with the nickname
+'panda1'. It also saves the connection token in the variable 'conn'
+for later use.
+
+If you're behind a SOCKS5 firewall, you can configure IRK to use a
+SOCKS5 proxy:
+
+   irk::config -sockproxy <proxyhost> -sockport <port>
+
+Do this before attempting to open connections to servers outside the
+firewall. After this step all communication with remote IRC servers
+goes through the SOCKS5 proxy. At present it is not possible to have
+connections simultaneously to IRC servers inside and outside the firewall.
+
+You can open any number of connections to different servers at the
+same time, limited only by the resources available on the host
+machine. Most IRC servers disallow opening two or more connections
+from the same user to a single server.
+
+Next, to join a channel, type:
+
+   irk::join $conn #mycoolchannel
+
+You can join any number of channels (no limits except those imposed by
+the server).
+
+To talk to a channel, do:
+
+   irk::say $conn #mycoolchannel {Wow, I'm on IRC!}
+
+The message "Wow, I'm on IRC!" (without the quotes) is sent to the
+channel #mycoolchannel.
+
+You can also send a private message to a specific nickname, via:
+
+   irk::say $conn somenick {Hey, I'm talking to you}
+
+To leave a channel use irk::leave. To close a connection with a server
+use irk::close. Read lib/irkcommand.tcl for all the commands
+provided. Full documentation will be provided eventually.
+
+The above API is likely to be subsumed by a more OO API that will look
+something like this:
+
+   set conn [irk::connect twisted panda1]
+   set mychan [$conn join #mycoolchannel]
+   $mychan say {Wow, I'm on IRC!}
+   set somenick [$conn user somenick]
+   $somenick say {Hey, I'm taling to you}
Index: /code/branches/rocket2/data/tcl/irk/examples/fortunebot.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/examples/fortunebot.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/examples/fortunebot.tcl	(revision 6952)
@@ -0,0 +1,151 @@
+# fortunebot.tcl --
+#
+# Demo bot using the irc TCL client library. This is a VERY simple bot that
+# demonstrates some simple uses of the irc TCL library.
+#
+# The bot sits on any number of channels and networks. It periodically grabs
+# a fortune from a web site and sends the fortune with appropriate delays
+# between each line to all channels on all networks it is on.
+
+# Example use in Tcl:
+#
+# % source fortunebot.tcl
+# % set token [irc::connect ....]
+# % fortune::join $token #mychannel
+# % fortune::start 120
+#
+# What this does:
+# * Loads the bot, which in turn will load the IRC library and HTTP.
+# * Connect to IRC
+# * Send the bot to join #mychannel
+# * Start the bot, with 120 seconds delay. Now it'll do its actions every
+#   120 seconds.
+#
+# To stop the bot:
+#
+# % fortune::stop
+#
+# Make him leave a channel:
+#
+# % fortune::leave $token #mychannel
+
+package require irk
+package require http
+
+namespace eval fortune {
+    variable state
+
+    array set state {
+	linedelay		2000
+	fortuneurl		http://www.earth.com/fortune
+    }
+}
+
+# Bot control:
+
+proc ::fortune::start {{delay 60}} {
+    variable state
+
+    # Compute the delay in milliseconds:
+
+    set state(delay) [expr $delay * 1000]
+
+    # Schedule the bot to run each $delay milliseconds:
+
+    set state(after) [after $state(delay) [list ::fortune::doquote]]
+}
+
+proc ::fortune::stop {} {
+    variable state
+
+    # Stop the bot if its running:
+
+    if {[info exists state(after)]} {
+	after cancel $state(after)
+	unset state(after)
+    }
+}
+
+
+# This is the actual body of the bot:
+#
+# Grab a quote from a web page and post it to all channels we're on:
+
+proc ::fortune::doquote {} {
+    variable state
+
+    # Grab the quote. The command callback does all the work:
+
+    http::geturl $state(fortuneurl) -command ::fortune::httpdone
+
+    # Finally reschedule ourselves, after events are one-shots
+
+    set state(after) [after $state(delay) [list ::fortune::doquote]]
+}
+
+proc ::fortune::httpdone {http} {
+    variable state
+    upvar #0 $http response
+
+    # Scrape the fortune off of the page:
+
+    set fortune [grabfortune $response(body)]
+
+    # Discard the HTTP array:
+
+    unset response
+
+    # Check if the quote is too long. If it is then punt.
+
+    if {[llength $fortune] > 3} {
+	return
+    }
+
+    # Say this quote on all channels on all connections we're on:
+
+    foreach conn [irk::connections] {
+	tell $fortune $conn
+    }
+}
+
+# This procedure scrapes the quote off of an HTML page:
+
+proc ::fortune::grabfortune {body} {
+    set body [split $body "\n"]
+    set beg [lsearch $body <PRE>]
+    set end [lsearch $body </PRE>]
+    return [lrange $body [expr $beg+1] [expr $end-1]]
+}
+
+# This procedure sends the quote to all channels we want the bot to be on:
+
+proc ::fortune::tell {fort conn} {
+    variable state
+
+    # Send the fortune to each channel we're on:
+
+    foreach chan [irk::onchannels $conn] {
+	tellchan $fort $conn $chan
+    }
+}
+
+# Asynchronously send lines to the channel:
+
+proc ::fortune::tellchan {fort conn channel} {
+    variable state
+
+    # Check if we are still on the channel:
+
+    if {![irk::onchannel $conn $channel]} {
+	return
+    }
+
+    # OK we're still on this channel, so say the current line and schedule
+    # the next line for later:
+
+    if {[llength $fort] > 0} {
+	irk::say $conn $channel [lindex $fort 0]
+	after $state(linedelay) \
+	    [list ::fortune::tellchan [lrange $fort 1 end] $conn $channel]
+    }
+}
Index: /code/branches/rocket2/data/tcl/irk/examples/mysaint.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/examples/mysaint.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/examples/mysaint.tcl	(revision 6952)
@@ -0,0 +1,277 @@
+# mysaint.tcl
+#
+# I got the inspiration to write this bot from the SmallSaints
+# bot on DalNet and the request of some Malay friends to create a clone.
+#
+# The bot sits on a channel and simply counts words that each user says.
+
+package require irk
+
+namespace eval ::mysaint {
+
+    variable state
+
+    set state(thisdir) [file dir [info script]]
+    set state(words,save) [file join $state(thisdir) savedwords.dat]
+    set state(save,interval) 30000
+
+    # For each identified user, there are several entries in the state array:
+    #
+    # state($user,words)	How many words they have total.
+    # state($user,session)	How many words they said this time.
+    # state($user,password)	What's their password
+    # state($user,ident)	What's their ident
+    #
+    # We also keep a mapping from nicknames to users:
+    #
+    # state($nick,user)		What's the user mask associated with this
+    #				nick name
+
+    proc initialize {} {
+	variable state
+	variable thisdir
+
+	# Set up a timer to save words:
+
+	set state(saver) [after $state(save,interval) ::mysaint::save]
+
+	# See if we have a saved words file. If so, read it in.
+
+	if {[file exists $state(words,save)]} {
+	    uplevel #0 source $state(words,save)
+	}
+    }
+
+    proc userSays {token nick user comm dest rest} {
+	if {[string match "!*" [lindex $rest 0]]} {
+	    userSaysCommand $token $dest $nick $user \
+		    [lindex $rest 0] [lrange $rest 1 end]
+	} else {
+	    userSaysWords $nick $user [llength $rest]
+	}
+    }
+
+    proc userSaysWords {nick user n} {
+	variable state
+
+	set seconds [clock seconds]
+	if {![info exists state($user,session,time)]} {
+	    set state($user,session,time) [clock seconds]
+	}
+	set state($user,time) $seconds
+
+	if {![info exists state($user,session)]} {
+	    set state($user,session) $n
+	} else {
+	    incr state($user,session) $n
+	}
+	if {![info exists state($user,words)]} {
+	    set state($user,words) $n
+	} else {
+	    incr state($user,words) $n
+	}
+
+	set state($nick,user) $user
+    }
+
+    proc userSaysCommand {token dest nick user cmd rest} {
+	variable state
+
+	# Determine destination of any reply we're going to send:
+
+	if {![string compare $dest $state(nick)]} {
+	    set dest $nick
+	}
+
+	switch -exact $cmd {
+	    "!help"	{userAsksHelp $token $nick}
+	    "!time"	{userAsksTime $token $nick $user $rest $dest}
+	    "!heard"	{userAsksHeard $token $nick $user $rest $dest}
+	    "!words"	{userAsksWords $token $nick $user $rest $dest}
+	    "!donate"	{userDonates $token $nick $user $rest $dest}
+	    "!pass"	{::irk::pass $token mysaint $nick $user $rest}
+	    "!ident"	{::irk::id $token mysaint $nick $user $rest}
+	    "!newpass"	{::irk::np $token mysaint $nick $user $rest}
+	}
+    }
+
+    proc userAsksHelp {token nick} {
+	::irk::say $token $nick \
+		[list Hello $nick, the following commands are supported: ]
+	::irk::say $token $nick "!help ---- prints this message"
+	::irk::say $token $nick "!words --- how many words you have"
+	::irk::say $token $nick "!donate -- to donate words to someone"
+	after 2000 [list ::irk::say $token $nick \
+				"!heard --- when did some speak last time"]
+	after 2500 [list ::irk::say $token $nick \
+				"!time ---- when someone connected"]
+	after 5000 [list ::irk::say $token $nick \
+		    "Note: To donate you have to have a password"]
+	after 7500 [list ::irk::say $token $nick \
+		    "Note: You can get a password with !pass"]
+    }
+
+    proc userAsksWords {token nick user rest dest} {
+	variable state
+
+	set target [lindex $rest 0]
+	if {[string compare $target ""]} {
+	    if {[catch {set user $state($target,user)}]} {
+		set who "The unknown user $target"
+		set target "The unknown user $target"
+	    } else {
+		set who $user
+	    }
+	} else {
+	    set who ""
+	}
+	if {[string compare $who ""]} {
+	    if {[catch {set words $state($who,words)}]} {
+		set words 0
+	    }
+	    if {[catch {set session $state($who,session)}]} {
+		set session 0
+	    }
+	    set reply \
+		    "$nick, $target has $session words now, total $words words"
+	} else {
+	    if {[catch {set words $state($user,words)}]} {
+		set words 0
+	    }
+	    if {[catch {set session $state($user,session)}]} {
+		set session 0
+	    }
+	    set reply \
+		    "$nick, you have $session words now, $words total words"
+	}
+	::irk::say $token $dest $reply
+    }
+
+    proc userAsksHeard {token nick user rest dest} {
+	variable state
+
+	set target [lindex $rest 0]
+	if {[string compare $target ""]} {
+	    if {[catch {set user $state($target,user)}]} {
+		set answer "I haven't heard $target speak recently."
+	    } else {
+		set time $state($user,time)
+		set time [clock format $time]
+		set answer "I heard $target speak last at $time"
+	    }
+	} else {
+	    set answer "I'm talking to you just now, $nick"
+	}
+
+	::irk::say $token $dest $answer
+    }
+
+    proc userAsksTime {token nick user rest dest} {
+	variable state
+
+	set target [lindex $rest 0]
+	if {[string compare $target ""]} {
+	    if {[catch {set user $state($target,user)}]} {
+		set answer "I don't know when $target connected"
+	    } else {
+		if {[catch {set time $state($user,session,time)}]} {
+		    set answer "I don't know when $target connected"
+		} else {
+		    set time [clock format $time]
+		    set answer \
+			    "I first noticed $target at $time"
+		}
+	    }
+	} else {
+	    if {[catch {set user $state($nick,user)}]} {
+		set answer "$nick, I don't know when you connected"
+	    } else {
+		if {[catch {set time $state($user,session,time)}]} {
+		    set answer "$nick, I don't know when you connected"
+		} else {
+		    set time [clock format $time]
+		    set answer \
+			    "$nick, I first noticed you at $time"
+		}
+	    }
+	}
+
+	::irk::say $token $dest $answer
+    }
+
+    # Start the bot:
+
+    proc start {token} {
+	variable state
+
+	set state($token,token) $token
+
+	set symsrv $::irk::state($token,symsrv)
+	set state(nick) $::irk::state(-$symsrv,nick)
+	set nick $state(nick)
+
+	foreach chan [::irk::onchannels $token] {
+	    ::irk::setaction2 $token PRIVMSG $chan ::mysaint::userSays
+	}
+	::irk::setaction2 $token PRIVMSG $nick ::mysaint::userSays
+
+	# Set up a timer to save the words info.
+
+	if {![info exists state(saver)]} {
+	    initialize
+	}
+
+	return ""
+    }
+
+    # Stop the bot:
+
+    proc stop {} {
+	variable state
+
+	foreach conn [array names state *,token] {
+	    stopcon $state($conn)
+	}
+
+	after cancel $state(saver)
+	catch {unset state(saver)}
+
+	return ""
+    }
+    proc stopcon {token} {
+	variable state
+
+	if {[catch {set symsrv $::irk::state($token,symsrv)}]} {
+	    return
+	}
+	set nick $state(nick)
+
+	foreach chan [::irk::onchannels $token] {
+	    ::irk::remaction2 $token PRIVMSG $chan ::mysaint::userSays
+	}
+	::irk::remaction2 $token PRIVMSG $nick ::mysaint::userSays
+
+	return ""
+    }
+
+    # Save words to a disk file:
+
+    proc save {} {
+	variable state
+
+	puts "Saving words in $state(words,save)"
+
+	# First of all reschedule ourselves:
+
+	set state(saver) [after $state(save,interval) ::mysaint::save]
+
+	# Save the words:
+
+	set pt "*,words"
+	if {![catch {set fd [open $state(words,save) w]}]} {
+	    puts $fd "array set ::mysaint::state [list [array get state $pt]]"
+
+	    catch {close $fd}
+	}
+    }	
+}
Index: /code/branches/rocket2/data/tcl/irk/irk.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/irk.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/irk.tcl	(revision 6952)
@@ -0,0 +1,24 @@
+# IRK: A client library for IRC programming written in Tcl.
+
+# We need the socks package to get through firewalls:
+
+package require socks
+
+# We provide the IRK package:
+
+package provide irk 0.1
+
+set thisdir [file dir [info script]]
+
+# Source the rest of the package:
+
+source [file join $thisdir lib irkstate.tcl]
+source [file join $thisdir lib irkconnect.tcl]
+source [file join $thisdir lib irkdispatch.tcl]
+source [file join $thisdir lib irkreceive.tcl]
+source [file join $thisdir lib irkcommand.tcl]
+source [file join $thisdir lib irkflow.tcl]
+source [file join $thisdir lib irkutil.tcl]
+source [file join $thisdir lib irkctcptcl.tcl]
+source [file join $thisdir lib irkauth.tcl]
+source [file join $thisdir lib irkservers.tcl]
Index: /code/branches/rocket2/data/tcl/irk/lib/irkauth.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/lib/irkauth.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/lib/irkauth.tcl	(revision 6952)
@@ -0,0 +1,303 @@
+# irkauth.tcl:
+#
+# Various procedures that deal with user authentication:
+
+namespace eval ::irk {
+
+    # The AUTH module keeps information about each user and facility ($fac)
+    # in the state array:
+    #
+    # auth(auth,$fac,$user)		If set, then $user has authenticated
+    #					successfully for the facility $fac.
+    # auth(user,$fac,$user,pass)	The password for this $user and $fac.
+    # auth(user,$fac,$user,ident)	The ident token for this $user & $fac.
+    #
+    # auth(ident,$fac,$ident,pass)	The password for this $ident and $fac.
+    # auth(ident,$fac,$ident,user)	The user for this $ident and $fac.
+    #
+    # auth(identcounter,$fac)		The ident token counter for $fac. This
+    #					is incremented each time a new user
+    #					establishes themselves with $fac.
+
+    # This procedure can be called by programs using the IRK library
+    # when a user sends a password.
+
+    proc pass {token fac nick user rest} {
+	variable auth
+
+	if {[llength $rest] != 1} {
+	    # Incorrect syntax:
+
+	    set reply "$nick, syntax is !pass <yourpass> (one word, no spaces)"
+	} elseif {[info exists auth(user,$fac,$user,pass)]} {
+
+	    # If this user has already established a password,
+	    # check that they're giving the right password.
+
+	    if {[string compare $auth(user,$fac,$user,pass) \
+				[lindex $rest 0]]} {
+		set reply "$nick, sorry, wrong password!"
+	    } else {
+		set reply "$nick, thanks for entering your password!"
+		set auth(auth,$fac,$user) 1
+	    }
+	} else {
+
+	    # This is the first time we're seeing this user. Accept
+	    # their password and send them an ident token. They can
+	    # use the ident token to reestablish themselves when their
+	    # user mask changes significantly.
+
+	    if {![info exists auth(identcounter,$fac)]} {
+		set auth(identcounter,$fac) 0
+	    }
+	    set ident $auth(identcounter,$fac)
+	    incr auth(identcounter,$fac)
+
+	    set auth(ident,$fac,$ident,user) $user
+	    set auth(ident,$fac,$ident,pass) [lindex $rest 0]
+
+	    set auth(user,$fac,$user,ident) $ident
+	    set auth(user,$fac,$user,pass) [lindex $rest 0]
+
+	    # Save the changes
+
+	    saveauth
+
+	    # Save them a step and also authorize them:
+
+	    set auth(ident,$fac,$user) 1
+
+	    set reply [list \
+	        $nick, your password is [lindex $rest 0]. Your ident is \
+	        $ident, write it down, you will need it later to \
+		reidentify yourself if your user mask changes. \
+		You user mask is currently $user. You are now authorised \
+		to use $fac.]
+	}
+
+	# Tell them what happened:
+
+	::irk::say $token $nick $reply
+
+	return ""
+    }
+
+    # This procedure can be called by programs when the user attempts to
+    # reestablish themselves with the existing ident and password.
+
+    proc id {token fac nick user rest} {
+	variable auth
+
+	set len [llength $rest]
+	set reply "Wrong syntax. Call !ident or !ident <ident> <pass>"
+
+	if {$len == 0} {
+
+	    # Calling ident with zero arguments. The user is trying to
+	    # retrieve their ident. Give it to them only if they did
+	    # identify successfully with the correct password.
+
+	    if {![info exists auth(user,$fac,$user,pass)]} {
+		set reply "$nick, first set a password"
+	    } elseif {[info exists auth(auth,$fac,$user)]} {
+		set reply \
+		    "$nick, your ident is $auth(user,$fac,$user,ident)"
+	    } else {
+		set reply \
+		   "$nick, identify with password before getting your ident!"
+	    }
+	} elseif {$len == 2} {
+
+	    # Calling ident with two arguments. The user is trying to
+	    # establish a new value for $user to associate with this
+	    # ident and password. If $auth($ident,pass) is the password
+	    # she gave, then they're the rightfull owner of the ident and
+	    # so we now recognize the new $user mask.
+
+	    set ident [lindex $rest 0]
+	    set pass [lindex $rest 1]
+
+	    if {[info exists auth(ident,$fac,$ident,pass)]} {
+		if {![string compare $auth(ident,$fac,$ident,pass) $pass]} {
+
+		    # Identify the old user mask they were using:
+
+		    set olduser $auth(ident,$fac,$ident,user)
+
+		    # Clean up the state associated with the old mask:
+
+		    array unset auth user,$fac,$olduser,*
+		    catch {unset auth(ident,$face,$olduser)}
+
+		    # Link up the new state:
+
+		    set auth(ident,$fac,$ident,user) $user
+
+		    set auth(user,$fac,$user,ident) $ident
+		    set auth(user,$fac,$user,pass) $pass
+
+		    # Save the changes
+
+		    saveauth
+
+		    # Save them a step and also treat them as authenticated:
+
+		    set auth(ident,$fac,$user) 1
+
+		    set reply \
+			    "OK, $nick, I'm now recognising you as $user.\
+			     You are now authorised to use $fac."
+		} else {
+		    set reply "$nick, sorry, wrong ident or password"
+		}
+	    } else {
+		set reply "$nick, sorry, wrong ident or password"
+	    }
+	}
+
+	# Tell them what happened:
+
+	::irk::say $token $nick $reply
+
+	return ""
+    }
+
+    # This procedure can be invoked by a program when a user tries to
+    # change her password.
+
+    proc np {token fac nick user rest} {
+	variable auth
+
+	set reply "Wrong syntax. Call !newpass <oldpass> <newpass>"
+
+	if {[llength $rest] == 2} {
+	    set opw [lindex $rest 0]
+	    set npw [lindex $rest 1]
+
+	    if {![info exists auth(user,$fac,$user,pass)]} {
+		# Unknown $user, probably their user mask changed. Help
+		# them reestablish the connection.
+
+		set reply \
+		   [list $nick, I don't have you in my database. Perhaps \
+			 your user mask changed drastically. If so, please \
+			 reestablish your user mask by using !ident <ident> \
+			 <oldpass>.]
+	    } elseif {[string compare $auth(user,$fac,$user,pass) $opw]} {
+		# Wrong old password!
+
+		set reply "$nick, sorry, wrong old password!"
+	    } else {
+		# Their user mask matches and they gave the correct old
+		# password, so we accept their new password:
+
+		set ident $auth(user,$fac,$user,ident)
+
+		set auth(ident,$fac,$ident,pass) $npw
+		set auth(user,$fac,$user,pass) $npw
+
+		# Save the changes:
+
+		saveauth
+
+		# Save them a step by also recording that they
+		# authenticated:
+
+		set auth(auth,$fac,$user) 1
+
+		set reply "OK, $nick, your new password is now $npw"
+	    }
+	}
+
+	# Tell them what happened:
+
+	::irk::say $token $nick $reply
+
+	return ""
+    }
+
+    # This procedure can be called by programs when the user wants to
+    # "log out" or lose her authentication with a given facility:
+
+    proc logout {token fac nick user rest} {
+	variable auth
+
+	set reply "You were not logged into $fac. Now you certainly aren't."
+
+	if {[info exists auth(auth,$fac,$user)]} {
+	    unset auth(auth,$fac,$user)
+
+	    set reply \
+		[list $nick, you logged out successfully from $fac. Thank you \
+		      for using $fac.]
+	}
+
+	# Tell them what happened:
+
+	::irk::say $token $nick $reply
+
+	return ""
+    }
+
+    # Is the user authenticated with the given facility?
+
+    proc userauthenticated {fac user} {
+	variable auth
+
+	# If auth(auth,$fac,$user) exists, then she is authenticated.
+
+	if {[info exists auth(auth,$fac,$user)]} {
+	    return 1
+	}
+	return 0
+    }
+
+    # This procedure automatically saves the authorization database:
+
+    proc saveauth {} {
+	variable state
+	variable auth
+
+	puts "Saving!"
+
+	# Define the patterns to save:
+
+	set p1 "identcounter,*"
+	set p2 "user,*"
+	set p3 "ident,*"
+
+	# Try to open the save file:
+
+	if {[info exists state(auth,save,file)]} {
+	    if {![catch {set fd [open $state(auth,save,file) w]}]} {
+		puts $fd "array set ::irk::auth [list [array get auth $p1]]"
+		puts $fd "array set ::irk::auth [list [array get auth $p2]]"
+		puts $fd "array set ::irk::auth [list [array get auth $p3]]"
+
+		catch {close $fd}
+	    }
+	}
+    }
+
+    # This procedure restores the authorization database:
+
+    proc restoreauth {} {
+	variable state
+
+	if {[info exists state(auth,save,file)]} {
+	    catch {uplevel #0 source $state(auth,save,file)}
+	}
+	set state(auth,restored) 1
+    }
+
+    # If this is the first time we're loading the IRK package, then
+    # restore the authorization database. Otherwise we'd be overwriting
+    # a potentially unsaved state.
+
+    variable state
+
+    if {![info exists state(auth,restored)]} {
+	restoreauth
+    }
+}
Index: /code/branches/rocket2/data/tcl/irk/lib/irkcommand.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/lib/irkcommand.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/lib/irkcommand.tcl	(revision 6952)
@@ -0,0 +1,420 @@
+# irkcommand.tcl:
+#
+# Various commands that can be invoked by the user of the IRK library:
+
+namespace eval irk {
+
+    # Say something to a user or to a channel
+
+    proc say {token chan saying} {
+	variable state
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid irc connection"
+	}
+	if {![string compare "" $saying]} {
+	    return
+	}
+	sendit $sock "PRIVMSG $chan :[string trim $saying]"
+    }
+
+    # Send a NOTICE to a user or a channel
+
+    proc notice {token chan args} {
+	variable state
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid irc connection"
+	}
+	sendit $sock "NOTICE $chan :$args"
+    }
+
+    # Send a raw command to the server:
+
+    proc send {token args} {
+	variable state
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid irc connection"
+	}
+	puts $sock $args
+    }
+
+    # Change your NICK
+
+    proc nick {token {newnick ""}} {
+	variable state
+
+	if {![string compare "" $newnick]} {
+	    return $state($token,nick)
+	}
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid irc connection"
+	}
+	puts $sock "NICK $newnick"
+    }
+
+    # Join a channel
+
+    proc join {token chans {keys ""}} {
+	variable state
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid irc connection"
+	}
+	puts $sock "JOIN $chans $keys"
+    }
+
+    # Leave a channel
+
+    proc leave {token chans {partmsg ""}} {
+	variable state
+
+	if {![string compare $partmsg ""]} {
+	    if {[info exists state(partmsg)]} {
+		set partmsg $state(partmsg)
+	    }
+	}
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid irc connection"
+	}
+	puts $sock "PART $chans $partmsg"
+    }
+
+    # Return a list of all connections that are open:
+
+    proc connections {} {
+	variable state
+
+	if {![info exists state(connections)]} {
+	    return {}
+	}
+	return $state(connections)
+    }
+
+    # Return a list of channels we're on in a give connection:
+
+    proc onchannels {token} {
+	variable state
+
+	if {![info exists state($token,channels)]} {
+	    return {}
+	}
+	return $state($token,channels)
+    }
+
+    # Returns 1 if we are on the given channel.
+
+    proc onchannel {token channel} {
+	variable state
+
+	if {![info exists state($token,channels)]} {
+	    return 0
+	}
+
+	set idx [lsearch $state($token,channels) $channel]
+	if {$idx == -1} {
+	    return 0
+	}
+	return 1
+    }
+
+    # Return a list of users on a given channel (we must be on that channel).
+
+    proc whoison {token chan} {
+	variable state
+
+	if {![info exists state($token,$chan,NAMES)]} {
+	    return {}
+	}
+	return $state($token,$chan,NAMES)
+    }
+
+    # Ping a server
+
+    proc ping {token} {
+	variable state
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid irc connection"
+	}
+	set state($token,PINGSTART) [clock clicks -millis]
+	puts $sock "PING $state($token,host)"
+    }
+
+    # Quit this connection
+
+    proc quit {token} {
+	disconnect $token
+    }
+
+    # Query information about someone
+
+    proc whois {token nick} {
+	variable state
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid irc connection"
+	}
+	puts $sock "WHOIS $nick"
+    }
+
+    # Set an away message
+
+    proc away {token args} {
+	variable state
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid irc connection"
+	}
+	puts $sock "AWAY :$args"
+    }
+
+    # This procedure lets the client do CTCP actions:
+
+    proc ctcp {token target action args} {
+	variable state
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid irc connection"
+	}
+	sendit $sock "PRIVMSG $target :\001$action $args\001"
+    }
+
+    # This command implements the TCL CTCP protocol:
+
+    proc tcl {token target args} {
+	variable state
+
+	# Send it to the channel:
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid irc connection"
+	}
+	sendit $sock "PRIVMSG $target :\001TCL $args\001"
+
+	# Apply it locally:
+
+	if {[info exists state($token,channel,ctcp,TCL,LOCAL)]} {
+	    $state($token,channel,ctcp,TCL,LOCAL) \
+		    $token $state($token,nick) $state($token,user) \
+		    PRIVMSG $target TCL $args
+	}
+    }
+
+    # These procedures add and remove action handlers:
+
+    # These procedures add actions that will be called when the user
+    # with the given nick causes the supplied comm(and) to be executed
+    # on the given dest(ination). This is the most specific form of action.
+
+    proc addaction3 {token nick comm dest cmd} {
+	variable state
+
+	if {![info exists state($token,$nick,$comm,$dest)]} {
+	    set state($token,$nick,$comm,$dest) [list $cmd]
+	} else {
+	    lappend state($token,$nick,$comm,$dest) $cmd
+	}
+    }
+
+    proc setaction3 {token nick comm dest cmd} {
+	variable state
+
+	set state($token,$nick,$comm,$dest) [list $cmd]
+    }
+
+    # This procedure removes an action set by either of the above two
+    # procedures.
+
+    proc remaction3 {token nick comm dest cmd} {
+	variable state
+
+	if {![info exists state($token,$nick,$comm,$dest)]} {
+	    return
+	}
+	set cmds $state($token,$nick,$comm,$dest)
+	set idx [lsearch $cmds $cmd]
+	if {$idx == -1} {
+	    return
+	}
+	set state($token,$nick,$comm,$dest) [lreplace $cmds $idx $idx]
+	if {![string compare "" $state($token,$nick,$comm,$dest)]} {
+	    unset state($token,$nick,$comm,$dest)
+	}
+    }
+
+    # These procedures add actions that will be called when the
+    # specific comm(and) is caused for the given dest(ination).
+
+    proc addaction2 {token comm dest cmd} {
+	variable state
+
+	if {![info exists state($token,$comm,$dest)]} {
+	    set state($token,$comm,$dest) [list $cmd]
+	} else {
+	    lappend state($token,$comm,$dest) $cmd
+	}
+    }
+
+    proc setaction2 {token comm dest cmd} {
+	variable state
+
+	set state($token,$comm,$dest) [list $cmd]
+    }
+
+    # This procedure removes an action set by either of the above two
+    # procedures.
+
+    proc remaction2 {token comm dest cmd} {
+	variable state
+
+	if {![info exists state($token,$comm,$dest)]} {
+	    return
+	}
+	set cmds $state($token,$comm,$dest)
+	set idx [lsearch $cmds $cmd]
+	if {$idx == -1} {
+	    return
+	}
+	set state($token,$comm,$dest) [lreplace $cmds $idx $idx]
+	if {![string compare "" $state($token,$comm,$dest)]} {
+	    unset state($token,$comm,$dest)
+	}
+    }
+
+    # These procedures add actions that will be called when the
+    # specific comm(and) is caused any dest(ination).
+
+    proc addaction1 {token comm cmd} {
+	variable state
+
+	if {![info exists state($token,$comm)]} {
+	    set state($token,$comm) [list $cmd]
+	} else {
+	    lappend state($token,$comm) $cmd
+	}
+    }
+
+    proc setaction1 {token comm cmd} {
+	variable state
+
+	set state($token,$comm) [list $cmd]
+    }
+
+    # This procedure removes an action set by either of the above two
+    # procedures.
+
+    proc remaction1 {token comm cmd} {
+	variable state
+
+	if {![info exists state($token,$comm)]} {
+	    return
+	}
+	set cmds $state($token,$comm)
+	set idx [lsearch $cmds $cmd]
+	if {$idx == -1} {
+	    return
+	}
+	set state($token,$comm) [lreplace $cmds $idx $idx]
+	if {![string compare "" $state($token,$comm)]} {
+	    unset state($token,$comm)
+	}
+    }
+
+    # These procedures add global actions that will be called
+    # when the specific comm(and) is caused on any dest(ination) and
+    # any irc connection. These are the lowest priority commands.
+
+    proc addactionglobal {comm cmd} {
+	variable state
+
+	if {![info exists state(cmd,$comm)]} {
+	    set state(cmd,$comm) [list $cmd]
+	} else {
+	    lappend state(cmd,$comm) $cmd
+	}
+    }
+
+    proc setactionglobal {comm cmd} {
+	variable state
+
+	set state(cmd,$comm) [list $cmd]
+    }
+
+    # This procedure removes an action set by either of the above two
+    # procedures.
+
+    proc remactionglobal {comm cmd} {
+	variable state
+
+	if {![info exists state(cmd,$comm)]} {
+	    return
+	}
+	set cmds $state(cmd,$comm)
+	set idx [lsearch $cmds $cmd]
+	if {$idx == -1} {
+	    return
+	}
+	set state(cmd,$comm) [lreplace $cmds $idx $idx]
+	if {![string compare "" $state(cmd,$comm)]} {
+	    unset state(cmd,$comm)
+	}
+    }
+
+    # This procedure manages configuration information for IRC:
+
+    proc config {args} {
+	if {$args == {}} {
+	    return [collectConfig]
+	}
+
+	if {[llength $args] == 1} {
+	    return [queryConfig [lindex $args 0]]
+	}
+
+	if {[expr [llength $args] % 2] != 0} {
+	    error "incorrect number of argument, must be multiple of 2"
+	}
+
+	setConfig $args
+    }
+
+    # Helper procedure to return a list with all important user settable
+    # configuration information.
+
+    proc collectConfig {} {
+	variable state
+
+	set config {}
+
+	foreach name [array names state "-*"] {
+	    lappend config [list $name $state($name)]
+	}
+	return $config
+    }
+
+    # Helper procedure to return the value of one option.
+
+    proc queryConfig {option} {
+	variable state
+
+	if {![info exists state($option)]} {
+	    return {}
+	}
+	return $state($option)
+    }
+
+    # Helper procedure to modify the configuration of a set of options.
+
+    proc setConfig {theargs} {
+	variable state
+
+	foreach {opt val} $theargs {
+	    if {![string match "-*" $opt]} {
+		continue
+	    }
+	    set state($opt) $val
+	}
+    }
+}
Index: /code/branches/rocket2/data/tcl/irk/lib/irkconnect.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/lib/irkconnect.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/lib/irkconnect.tcl	(revision 6952)
@@ -0,0 +1,239 @@
+# irkconnect.tcl:
+#
+# This file provides the IRK commands to connect to remote servers
+# as well as some attendant utility procedures:
+
+namespace eval ::irk {
+
+    # The "connect" procedure returns a token
+    # for the connection to this server.
+    #
+    # symsrv		The symbolic name of the server to connect to.
+    # nick		The nick name to use.
+    # user		The user name to use.
+    # pass		The password to use. 
+    # disp		The command dispatcher expression to use.
+
+    proc connect {{symsrv ""} {nick ""} {user ""} {pass ""} {disp ""}} {
+	variable state
+
+	# Auto initialize the list of connections. We do this so that
+	# the list is not reset each time the irk.tcl file is sourced.
+
+	if {![info exists state(connections)]} {
+	    set state(connections) {}
+	}
+
+	# Try to convert the symbolic server name to a
+	# server description. This may throw an error,
+	# we propagate it.
+
+	set servdesc [locate $symsrv]
+
+	# If the nickname is not specified, there must be
+	# a nick setting in the state array; use that
+
+	if {![string compare $nick ""]} {
+	    if {![info exists state(-$symsrv,nick)]} {
+		error "No nick given or set in global state"
+	    }
+	    set nick $state(-$symsrv,nick)
+	}
+
+	# If a global nick is not set, save this nick for use
+	# as a global nick.
+
+	if {![info exists state(-$symsrv,nick)]} {
+	    set state(-$symsrv,nick) $nick
+	}
+
+	# If user is not supplied, see if there is a global
+	# user registered in the IRK package state. If not,
+	# invent a user.
+
+	if {![string compare $user ""]} {
+	    if {[info exists state(-$symsrv,user)]} {
+		set user $state(-$symsrv,user)
+	    } else {
+		set user $nick
+		set state(-$symsrv,user) $user
+	    }
+	}
+
+	# If a password is not supplied, see if there is a global
+	# one registered. If so, use that. Otherwise, do not
+	# use a password.
+
+	if {![string compare $pass ""]} {
+	    if {[info exists state(-$symsrv,pass)]} {
+		set pass $state(-$symsrv,pass)
+	    }
+	}
+
+	# If a dispatcher expression is not supplied, there must be a
+	# global dispatcher expression in the state array, and use that.
+
+	if {![string compare $disp ""]} {
+	    if {![info exists state(dispatcher)]} {
+		error "ERROR: o dispatch given or found in global state"
+	    }
+	    set disp $state(dispatcher)
+	}
+
+	# Try to connect to the given server.
+
+	set h [lindex $servdesc 0]
+	set p [randselect [lindex $servdesc 1]]
+
+	set s [opensocket $h $p]
+
+	# The socket is line buffered and consumed by the
+	# supplied consumer
+
+	fconfigure $s -translation auto -buffering line
+	fileevent $s readable [list ::irk::consumer $s]
+
+
+	# Identify ourselves to the IRK server: If a password is given
+	# send that first. Then send the nick name and user name.
+
+	if {[string compare $pass ""]} {
+	    puts $s "PASS $pass"
+	}
+
+	puts $s "NICK $nick"
+	puts $s "USER $user $h $h :$user"
+
+	# Make a connection token:
+
+	set contok [contok $s $symsrv]
+
+	# Save the state for this new connection
+
+	lappend state(connections) $contok
+
+	set state($contok,port) $p
+	set state($contok,host) $h
+	set state($contok,symsrv) $symsrv
+	set state($contok,nick) $nick
+	set state($contok,user) $user
+	set state($contok,pass) $pass
+	set state($contok,disp) $disp
+
+	# Set up some default behavior for the connection:
+
+	setupDefaultActions $contok $nick
+
+	# Collect information about who the server thinks we are
+
+	puts $s "WHOIS $nick"
+
+	# Finally return the token for this connection:
+
+	return $contok
+    }
+
+    # This procedure makes an easy to remember connection token. It takes
+    # the symbolic server's name and appends _<n> to it, where n is an
+    # integer starting at 0 and monotonically increasing for every new
+    # connection to that server.
+    #
+    # Once it figures out what the connection token is going to be,
+    # it associates it with the given socket so it can be used.
+
+    proc contok {sock symsrv} {
+	variable state
+
+	# Compute the symbolic name for this connection:
+
+	if {![info exists state($symsrv,counter)]} {
+	    set state($symsrv,counter) 0
+	}
+	set contok ${symsrv}_$state($symsrv,counter)
+	incr state($symsrv,counter)
+
+	# Associate the symbolic name with the socket:
+
+	set state($contok,socket) $sock
+	set state($sock,contok) $contok
+
+	return $contok
+    }
+
+    # The locate procedure tries to convert the symbolic name for
+    # a connection to a server/port specification.
+
+    proc locate {s} {
+	variable symsrv
+	variable state
+
+	# If the caller specified "" as the name of the server, select
+	# a random one from the list of known servers.
+
+	if {![string compare $s ""]} {
+	    set s [randselect $state(servers)]
+	}
+
+	# Now see if the requested server exists:
+
+	if {![info exists symsrv($s)]} {
+	    error \
+		"Could not find a match for symbolic IRK server name \"$s\""
+	}
+
+	# It does, return the server specification:
+
+	return $symsrv($s)
+    }
+
+    # opensocket connects to the requested server and port, either
+    # directly or through a SOCKS5 proxy.
+
+    proc opensocket {server port} {
+	variable state
+
+	if {[info exists state(-socksproxy)] \
+		&& [info exists state(-socksport)]} {
+	    set sock [socket $state(-socksproxy) $state(-socksport)]
+	    return [::socks::init $sock $server $port]
+	}
+
+	return [socket $server $port]
+    }
+
+    # The disconnect procedure disconnects from a given connection
+    # identified by its symbolic name, and cleans up state associated
+    # with the connection.
+
+    proc disconnect {contok} {
+	variable state
+
+	if {[catch {set s $state($contok,socket)} err]} {
+	    error "ERROR: $contok: No such IRC connection"
+	}
+
+	# Send a QUIT message.
+
+	if {[info exists state(quitmsg)]} {
+	    set q ":$state($contok,nick) $state(quitmsg)"
+	} else {
+	    set q ":$state($contok,nick) quit"
+	}
+	puts $s "QUIT $q"
+
+	# Try to close the connection with the server.
+
+	catch {close $s}
+
+	# And clean up all state associated with this connection:
+
+	array unset state $contok,*
+	
+	# Remove this connection from the list of active connections:
+
+	set i [lsearch $state(connections) $s]
+	set state(connections) [lreplace $state(connections) $i $i]
+
+	return ""
+    }
+}
Index: /code/branches/rocket2/data/tcl/irk/lib/irkctcptcl.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/lib/irkctcptcl.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/lib/irkctcptcl.tcl	(revision 6952)
@@ -0,0 +1,45 @@
+# irkctcptcl.tcl:
+#
+# This file implements the IRK CTCP TCL protocol:
+
+namespace eval ::irk {
+
+    # This procedure sets up a safe interpreter for the channel in which
+    # the CTCP TCL action occurs:
+
+    proc setupInterp {token chan} {
+	variable state
+
+	if {![info exists state($token,$chan,interp)]} {
+	    catch {interp delete ${token}${chan}}
+	    set state($token,$chan,interp) [safe::interpCreate ${token}${chan}]
+	    safe::loadTk $state($token,$chan,interp)
+	}
+	if {![interp exists ${token}${chan}]} {
+	    set state($token,$chan,interp) [safe::interpCreate ${token}${chan}]
+	    safe::loadTk $state($token,$chan,interp)
+	}
+    }
+
+    # This procedure dispatches the Tcl command embedded within the
+    # CTCP TCL action to the associated interpreter:
+
+    proc RECV,CTCP,TCL {token nick user comm dest action rest} {
+	variable state
+
+	puts stderr "Tcl command is: $rest [llength $rest]"
+	setupInterp $token $dest
+	interp eval $state($token,$dest,interp) [::join $rest]
+    }
+
+    # This procedure dispatches the Tcl command embedded within the
+    # CTCP TCL action for local execution on the issuer's side:
+
+    proc RECV,CTCP,TCL,LOCAL {token nick user comm dest action rest} {
+	variable state
+
+	puts stderr "Tcl command is: $rest [llength $rest]"
+	setupInterp $token $dest
+	interp eval $state($token,$dest,interp) $rest
+    }
+}
Index: /code/branches/rocket2/data/tcl/irk/lib/irkdispatch.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/lib/irkdispatch.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/lib/irkdispatch.tcl	(revision 6952)
@@ -0,0 +1,248 @@
+# irkdispatch.tcl:
+#
+# Based on the input received from the server, dispatch control to various
+# command procedures.
+
+namespace eval ::irk {
+
+    # This procedure sets up the default actions for a connection:
+
+    proc setupDefaultActions {s nick} {
+	variable state
+
+	# Catch any unexpected PRIVMSG actions:
+
+	set state($s,PRIVMSG,$nick)	$state(PRIVMSG,unsolicited)
+
+	# Set up CTCP global actions:
+
+	set state($s,cmd,ctcp,PING)	::irk::RECV,CTCP,PING
+	set state($s,cmd,ctcp,TIME)	::irk::RECV,CTCP,TIME
+	set state($s,cmd,ctcp,VERSION)	::irk::RECV,CTCP,VERSION
+	set state($s,cmd,ctcp,USERINFO) \
+					::irk::RECV,CTCP,USERINFO
+
+	# Set up CTCP channel specific actions:
+
+	set state($s,channel,ctcp,ACTION) \
+					::irk::RECV,CTCP,ACTION
+
+	# Set up the CTCP TCL protocol:
+
+	set state($s,channel,ctcp,TCL)	::irk::RECV,CTCP,TCL
+	set state($s,channel,ctcp,TCL,LOCAL) \
+					::irk::RECV,CTCP,TCL,LOCAL
+
+	# Deal with CTCP commands we do not understand:
+
+	set state($s,cmd,ctcp,error) 	::irk::RECV,CTCP,ERROR
+	set state($s,channel,ctcp,error) \
+					::irk::RECV,CTCP,ERROR
+    }
+
+    # The consumer procedure consumes input received from
+    # a connection. It calls the dispatcher for the given connection
+    # with each input line.
+
+    proc consumer {s} {
+	variable state
+
+	if {[eof $s]} {
+	    disconnect $s
+	} else {
+	    set l [gets $s]
+	    if {[info exists state($s,trace)]} {
+		$state($s,trace) $l
+	    }
+	    if {[string compare $l ""]} {
+		dissect $state($s,contok) $l
+	    }
+	}
+    }
+
+    # This procedure dissects the input into its parts:
+
+    proc dissect {token line} {
+	variable state
+
+	# Make a list out of the line:
+
+	set line [split $line " "]
+
+	# Split first token into nickname and user mask:
+
+	set nandu [split [lindex $line 0] \!]
+
+	# Call dispatcher for this connection:
+
+	$state($token,disp) \
+		$token \
+		[lindex $nandu 0] \
+		[lindex $nandu 1] \
+		[lindex $line 1] \
+		[lindex $line 2] \
+		[lrange $line 3 end]
+    }
+
+    # This procedure is the default command dispatcher:
+    
+    proc defaultDispatcher {token nick user comm dest rest} {
+	variable state
+
+	# Check if the nick starts with ':'. If not then this is
+	# a special action, handled by the built in actions.
+
+	if {![string match ":*" $nick]} {
+	    return [specialAction $token $nick $user $comm $dest $rest]
+	}
+
+	# Trim off the leading ':' on the $nick, if present.
+
+	if {[string match ":*" $nick]} {
+	    set nick [string range $nick 1 end]
+	}
+
+	# If a ':' is present in the $dest, trim that off too.
+
+	if {[string match ":*" $dest]} {
+	    set dest [string range $dest 1 end]
+	}
+
+	# If a ':' is present in the $rest, trim that off too.
+
+	set firstrest [lindex $rest 0]
+	if {[string match ":*" $firstrest]} {
+	    set firstrest [string range $firstrest 1 end]
+	    set rest [lreplace $rest 0 0 $firstrest]
+	}
+
+	# Clean up the payload:
+
+	set rest [split [string trim [eval concat $rest]] " "]
+
+	# Now try to dispatch to specific handlers.
+	#
+	# First see if there is a handler for the specific combination
+	# of $token, $nick, $comm and $dest. This is used for PRIVMSG.
+
+	if {[info exists state($token,$nick,$comm,$dest)]} {
+	    foreach cmd $state($token,$nick,$comm,$dest) {
+		if {[catch {set res [$cmd $token $nick $user \
+					  $comm $dest $rest]} err]} {
+		    if {[info exists state(errorhandler)]} {
+			$state(errorhandler) $err $token $comm $dest
+		    }
+		    return
+		}
+
+		# If this handler said to go on to a more general handler,
+		# then don't return. Otherwise return.
+
+		if {[string compare $res pass]} {
+		    return
+		}
+	    }
+	}
+
+	# If there's a handler for $token, $comm and $dest, use that.
+
+	if {[info exists state($token,$comm,$dest)]} {
+	    foreach cmd $state($token,$comm,$dest) {
+		if {[catch {set res [$cmd $token $nick $user \
+					  $comm $dest $rest]} err]} {
+		    if {[info exists state(errorhandler)]} {
+			$state(errorhandler) $err $token $comm $dest
+		    }
+		    return
+		}
+
+		# If this handler said to go on to a more general handler,
+		# then don't return. Otherwise return.
+
+		if {[string compare $res pass]} {
+		    return
+		}
+	    }
+	}
+
+	# See if there's a handler for $token and $comm. If so use that.
+
+	if {[info exists state($token,$comm)]} {
+	    foreach cmd $state($token,$comm) {
+		if {[catch {set res [$cmd $token $nick $user \
+					  $comm $dest $rest]} err]} {
+		    if {[info exists state(errorhandler)]} {
+			$state(errorhandler) $err $token $comm $dest
+		    }
+		    return
+		}
+
+		# If this handler said to go on to a more general handler,
+		# then don't return. Otherwise return.
+
+		if {[string compare $res pass]} {
+		    return
+		}
+	    }
+	}
+
+	# See if there's a global handler for the command. All the
+	# default handlers are defined here.
+
+	if {[info exists state(cmd,$comm)]} {
+	    foreach cmd $state(cmd,$comm) {
+		if {[catch {set res [$cmd $token $nick $user \
+					  $comm $dest $rest]} err]} {
+		    if {[info exists state(errorhandler)]} {
+			$state(errorhandler) $err $token $comm $dest
+		    }
+		    return
+		}
+
+		# If this handler said to go on to a more general handler,
+		# then don't return. Otherwise return.
+
+		if {[string compare $res pass]} {
+		    return
+		}
+	    }
+	}
+
+	# If all of the above fail, send this input to the default
+	# action handler:
+
+	if {[catch {set res [$state(action) \
+				$token $nick $user \
+				$comm $dest $rest]} err]} {
+	    if {[info exists state(errorhandler)]} {
+		$state(errorhandler) $err $token $comm $dest
+	    }
+	    return
+	}
+    }
+
+    # This procedure deals with special actions (built in, cannot
+    # easily be modified by users). I use this to e.g deal with
+    # PING, NOTICE, ERROR etc., automatically.
+
+    proc specialAction {token nick user comm dest rest} {
+	variable state
+
+	# The nick is the special action selector:
+
+	$state(special,$nick) $token $nick $user $comm $dest $rest
+    }
+
+    # This is the default error handler:
+
+    proc echoerror {args} {
+	puts stderr $args
+    }
+
+    # This procedure provides a default tracing facility (it just prints
+    # the lines received to stderr):
+
+    proc trace {args} {
+	puts stderr "Received: $args"
+    }
+}
Index: /code/branches/rocket2/data/tcl/irk/lib/irkflow.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/lib/irkflow.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/lib/irkflow.tcl	(revision 6952)
@@ -0,0 +1,102 @@
+# irkflow.tcl
+#
+# Simple flow control management so as to avoid flooding.
+
+namespace eval ::irk {
+
+    # For each combination of destination+connection, we keep three items:
+    # 
+    # flowctl($dest,$conn,after)	The "after" token for the next time
+    #					we send anything to this destination.
+    # flowctl($dest,$conn,queue)	A list of items to send to this
+    #					destination on this connection.
+    # flowctl($dest,$conn,lastsend)	The time we last sent to this
+    #					destination on this connection.
+    #
+    # NOTE: We do not limit the length of each item to send. This
+    # would lead to extremely hard to diagnose bugs due to commands
+    # (e.g. ctcp's) getting cut up into chunks.
+
+    variable flowctl
+
+    # The following setting controls how often (in msecs) we can send
+    # to a given connection. It should not be modified by user code or
+    # flooding may occur.
+
+    set flowctl(floodlimit) 1500
+
+    # This procedure sends an item to a specific destination+connection.
+    # If possible, the item is sent right away. Otherwise it is enqueued
+    # for later sending.
+
+    proc sendit {conn item} {
+	variable flowctl
+
+	# If this connection has a backlog, append the new
+	# items. Otherwise, check if the previous send was
+	# less than flowctl(floodlimit) msecs ago. If so, enqueue
+	# it for later sending. Otherwise send it now and record
+	# the time we sent this item.
+
+	if {[info exists flowctl($conn,after)]} {
+	    lappend flowctl($conn,queue) $item
+	} else {
+	    if {[catch {set lastsend $flowctl($conn,lastsend)}]} {
+		set lastsend 0
+	    }
+	    set now [clock clicks -milliseconds]
+	    set lim $flowctl(floodlimit)
+	    if {[expr $now - $lastsend] < $lim} {
+		lappend flowctl($conn,queue) $item
+		set wait [expr ($lim - ($now - $lastsend))]
+		set flowctl($conn,after) \
+			[after $wait [list ::irk::sendlater $conn]]
+	    } else {
+		set flowctl($conn,lastsend) $now
+		puts $conn $item
+	    }
+	}
+
+	return ""
+    }
+
+    # This procedure does the sending when flow control for a connection
+    # is activated.
+
+    proc sendlater {conn} {
+	variable flowctl
+
+	# First of all clear the after entry.
+
+	unset flowctl($conn,after)
+
+	# Grab the first item on the queue:
+
+	if {[info exists flowctl($conn,queue)]} {
+	    set items $flowctl($conn,queue)
+	    if {[string compare $items ""]} {
+		set item [lindex $items 0]
+		set rest [lrange $items 1 end]
+		if {[string compare $rest ""]} {
+		    set flowctl($conn,queue) $rest
+		    set flowctl($conn,after) \
+			    [after $flowctl(floodlimit) \
+				[list ::irk::sendlater $conn]]
+		} else {
+		    unset flowctl($conn,queue)
+		}
+
+		# Record time we last sent to this destination.
+
+		set flowctl($conn,lastsend) [clock clicks -milliseconds]
+
+		# Send this item:
+
+		puts $conn $item
+	    } else {
+		unset flowctl($conn,queue)
+	    }
+	}
+    }
+}
+
Index: /code/branches/rocket2/data/tcl/irk/lib/irkqueue.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/lib/irkqueue.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/lib/irkqueue.tcl	(revision 6952)
@@ -0,0 +1,103 @@
+# irkenqueue.tcl
+#
+# Simple flow control management so as to avoid flooding.
+
+namespace eval ::irk {
+
+    # For each combination of destination+connection, we keep three items:
+    # 
+    # flowctl($dest,$conn,after)	The "after" token for the next time
+    #					we send anything to this destination.
+    # flowctl($dest,$conn,queue)	A list of items to send to this
+    #					destination on this connection.
+    # flowctl($dest,$conn,lastsend)	The time we last sent to this
+    #					destination on this connection.
+    #
+    # NOTE: We do not limit the length of each item to send. This
+    # would lead to extremely hard to diagnose bugs due to commands
+    # (e.g. ctcp's) getting cut up into chunks.
+
+    variable flowctl
+
+    # The following setting determines the number of seconds that must
+    # pass between sends to any one destination+connection. If fewer
+    # seconds have passed since the last send, then flow control is
+    # activated for this destination+connection.
+
+    set flowctl(sendlimit) 2
+
+    # This procedure sends an item to a specific destination+connection.
+    # If possible, the item is sent right away. Otherwise it is enqueued
+    # for later sending.
+
+    proc enqueue {dest conn item} {
+	variable flowctl
+
+	# If this destination has a backlog, append the new
+	# items. Otherwise, check if the previous send was
+	# less than 2 seconds ago. If so, enqueue it for
+	# later sending. Otherwise send it now and record
+	# the time we sent this item.
+
+	if {[info exists flowctl($dest,$conn,after)]} {
+	    lappend flowctl($dest,$conn,queue) $item
+	} else {
+	    if {[catch {set lastsend $flowctl($dest,$conn,lastsend)}]} {
+		set lastsend 0
+	    }
+	    set now [clock seconds]
+	    set lim $flowctl(sendlimit)
+	    if {[expr $now - $lastsend] < $lim} {
+		lappend flowctl($dest,$conn,queue) $item
+		set wait [expr ($lim - ($now - $lastsend)) * 1000]
+		set flowctl($dest,$conn,after) \
+			[after $wait [list ::irk::sender $dest $conn]]
+	    } else {
+		set flowctl($dest,$conn,lastsend) $now
+		puts $conn $item
+	    }
+	}
+
+	return ""
+    }
+
+    # This procedure does the sending when flow control for a connection
+    # is activated.
+
+    proc sender {dest conn} {
+	variable flowctl
+
+	# First of all clear the after entry.
+
+	unset flowctl($dest,$conn,after)
+
+	# Grab the first item on the queue:
+
+	if {[info exists flowctl($dest,$conn,queue)]} {
+	    set items $flowctl($dest,$conn,queue)
+	    if {[string compare $items ""]} {
+		set item [lindex $items 0]
+		set rest [lrange $items 1 end]
+		if {[string compare $rest ""]} {
+		    set lim [expr $flowctl(sendlimit) * 1000]
+		    set flowctl($dest,$conn,queue) $rest
+		    set flowctl($dest,$conn,after) \
+			    [after $lim [list ::irk::sender $dest $conn]]
+		} else {
+		    unset flowctl($dest,$conn,queue)
+		}
+
+		# Record time we last sent to this destination.
+
+		set flowctl($dest,$conn,lastsend) [clock seconds]
+
+		# Send this item:
+
+		puts $conn $item
+	    } else {
+		unset flowctl($dest,$conn,queue)
+	    }
+	}
+    }
+}
+
Index: /code/branches/rocket2/data/tcl/irk/lib/irkreceive.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/lib/irkreceive.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/lib/irkreceive.tcl	(revision 6952)
@@ -0,0 +1,618 @@
+# irkreceive.tcl:
+#
+# Various commands invoked in response to input received from the server:
+
+namespace eval irk {
+
+    # This procedure deals with the PING special action:
+
+    proc RECV,PING {token nick user comm dest rest} {
+	variable state
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid IRK connection"
+	}
+	puts $sock "PONG :$comm $rest"
+
+	return ""
+    }
+
+    # This procedure deals with the NOTICE special action:
+
+    proc RECV,NOTICE {token nick user comm dest rest} {
+	variable state
+
+	append state($token,GLOBALNOTICES) "$rest\n"
+
+	return ""
+    }
+
+
+    # This procedure deals with the ERROR special action:
+
+    proc RECV,ERROR {token nick user comm dest rest} {
+	variable state
+
+	set rest [eval concat $rest]
+	append state($token,ERRORS) "$nick $dest $rest\n"
+#	puts "Got ERROR: $token $nick ---> $dest: $rest"
+	orxonox::execute error "Got ERROR: $token $nick ---> $dest: $rest"
+
+	return ""
+    }
+
+    # This procedure deals with the AWAY response:
+
+    proc RECV,AWAY {token nick user comm dest rest} {
+	set id [lindex $rest 0]
+	set rest [lrange $rest 1 end]
+	set rest [lreplace $rest 0 0 [string range [lindex $rest 0] 1 end]]
+	set rest [eval concat $rest]
+	puts "$id is away: $rest"
+
+	return ""
+    }
+    
+    # This procedure deals with the WHOIS USER message:
+
+    proc RECV,WHOIS,NICK,USER {token nick user comm dest rest} {
+	variable state
+
+	# Split the rest of the line on space:
+
+	foreach {unick uuser uhost ustar urnm} [split $rest " "] break
+
+	# If the WHOIS information is about this user, save it specially:
+
+	if {[isus $token $unick]} {
+	    set state($token,uuser)	$uuser
+	    set state($token,uhost)	$uhost
+	    set state($token,urnm)	$urnm
+	}
+
+	# Save the information for a regular user:
+
+	set state($token,ident,$unick,uuser)	$uuser
+	set state($token,ident,$unick,uhost)	$uhost
+	set state($token,ident,$unick,urnm)	$urnm
+    }
+
+    # This procedure deals with the WHOIS SERVER message:
+
+    proc RECV,WHOIS,NICK,SERVER {token nick user comm dest rest} {
+	variable state
+
+	# Split the rest of the line on space:
+
+	foreach {unick userv} [split $rest " "] break
+
+	# If the WHOIS information is about this user, save it specially:
+
+	if {[isus $token $unick]} {
+	    set state($token,userv) $userv
+	}
+
+	# Save the information for a regular user:
+
+	set state($token,ident,$unick,userv) $userv
+    }
+
+    # This procedure deals with the WHOIS IDENT message
+
+    proc RECV,WHOIS,NICK,IDENT {token nick user comm dest rest} {
+	variable state
+
+	# Extract the nick of the user who has identified
+
+	set unick [lindex [split $rest " "] 0]
+
+	# If the WHOIS information is about this user, save it specially:
+
+	if {[isus $token $unick]} {
+	    set state($token,ident) 1
+	}
+
+	# Save the information for a regular user:
+
+	set state($token,ident,$unick,ident) 1
+    }	
+
+    # This procedure deals with the WHOIS CONNECTTIME message:
+
+    proc RECV,WHOIS,NICK,CONNECTTIME {token nick user comm dest rest} {
+	variable state
+
+	# Split the rest of the input on space:
+
+	foreach {unick idle connecttime} [split $rest " "] break
+
+	# Format the connect time for this user:
+
+	set connecttime [clock format $connecttime]
+
+	# If the WHOIS information is about this user, save it specially:
+
+	if {[isus $token $unick]} {
+	    set state($token,connecttime) $connecttime
+	}
+
+	# Save the information for a regular user:
+
+	set state($token,ident,$unick,connecttime) $connecttime
+    }
+
+    # Handle the WHOIS CHANNELS message:
+
+    proc RECV,WHOIS,NICK,CHANNELS {token nick user comm dest rest} {
+	variable state
+
+	# Split the rest on space.
+
+	set rest [split $rest " "]
+
+	# Get the nick for which this is the channel list:
+
+	set unick [lindex $rest 0]
+	set rest [lrange $rest 1 end]
+
+	# The first channel may have an extra ":", if it does get rid of it.
+
+	set firstchan [lindex $rest 0]
+	if {[string match ":*" $firstchan]} {
+	    set rest [lreplace $rest 0 0 [string range $firstchan 1 end]]
+	}
+
+	# If the WHOIS information is about this user, save it specially:
+
+	if {[isus $token $unick]} {
+	    set state($token,channels) $channels
+	}
+
+	# Save the information for a regular user:
+
+	set state($token,ident,$unick,channels) $rest
+    }
+
+    # This procedure deals with the WHOIS END message:
+
+    proc RECV,WHOIS,NICK,END {token nick user comm dest rest} {
+	variable state
+
+	set state($token,whois,done) 1
+    }
+
+    # This procedure deals with various MOTD actions:
+
+    proc RECV,MOTD {token nick user comm dest rest} {
+	variable state
+
+	append state($token,MOTD) "${rest}\n"
+
+	return ""
+    }
+
+    # This procedure deals with PONG actions:
+
+    proc RECV,PONG {token nick user comm dest rest} {
+	variable state
+
+	if {[info exists state($token,PINGSTART)]} {
+	    set elapsed \
+		[expr [clock clicks -millis] - $state($token,PINGSTART)]
+	    puts "$nick: $elapsed msecs"
+	    unset state($token,PINGSTART)
+	}
+
+	return ""
+    }
+
+    # This procedure deals with NOTICE received from a regular user:
+
+    proc RECV,NOTICE,USER {token nick user comm dest rest} {
+	if {[string match "\001*" [lindex $rest 0]]} {
+	    set rest [ctcpcleanup $rest]
+	    RECV,NOTICE,CTCP,USER $token $nick $user $comm $dest \
+		    [lindex $rest 0] [lrange $rest 1 end]
+	} else {
+	    set rest [eval concat $rest]
+	    puts "$nick sends $dest a notice: $rest"
+	}
+
+	return ""
+    }
+
+    # This procedure helps with CTCP notice actions:
+
+    proc RECV,NOTICE,CTCP,USER {token nick user comm dest action rest} {
+	variable state
+
+	if {[info exists state($token,response,ctcp,$action)]} {
+	    $state($token,response,ctcp,$action) \
+					$token $nick $user $comm $dest \
+					$action $rest
+	} else {
+	    $state($token,response,ctcp,error) \
+					$token $nick $user $comm $dest \
+					$action $rest
+	}
+
+	return ""
+    }
+
+    # This procedure deals with JOIN actions:
+
+    proc RECV,JOIN {token nick user comm dest rest} {
+	variable state
+
+	# Check if it's us that joined the channel or someone else.
+
+	if {[isus $token $nick]} {
+#	    puts "You joined $dest"
+          orxonox::irc::info $token "You joined $dest"
+
+	    addChannel $token $dest
+	} else {
+#	    puts "$nick joined $dest"
+          orxonox::irc::info $token "$nick joined $dest"
+
+	    addToChannel $token $nick $dest
+	}
+
+	return ""
+    }
+
+    # This procedure deals with PART actions:
+
+    proc RECV,PART {token nick user comm dest rest} {
+	variable state
+
+	set chan [string tolower $dest]
+
+	if {[isus $token $nick]} {
+#	    puts "You left channel $chan"
+          orxonox::irc::info $token "You left channel $chan"
+	} else {
+#	    puts "$nick left [string tolower $dest]"
+          orxonox::irc::info $token "$nick left [string tolower $dest]"
+	}	    
+	removeFromChannel $token $nick $chan
+	removeFromChannel $token @$nick $chan
+
+	return ""
+    }
+
+    # This procedure deals with MODE actions:
+
+    proc RECV,MODE {token nick user comm dest rest} {
+	set rest [eval concat $rest]
+#	puts "$nick sets mode $dest $rest"
+      orxonox::irc::info "$nick $token sets mode $dest $rest"
+
+	return ""
+    }
+
+    # This procedure deals with NICK actions:
+
+    proc RECV,NICK {token nick user comm dest rest} {
+	variable state
+
+	set newnick [string range $dest 0 end]
+
+	# If our nick changed, remember it as the nick associated with
+	# this connection:
+
+	if {[isus $token $nick]} {
+	    set state($token,nick) $newnick
+	    set state($token,$newnick,PRIVMSG)	$state(PRIVMSG,unsolicited)
+	    catch {unset state($token,$nick,PRIVMSG)}
+	}
+
+	# Replace the old nick with the new in all channels that we're on:
+
+	replaceAllChannels $token $nick $newnick
+
+#	puts "$nick ${user} ($token) changes his/her nickname to $newnick"
+      orxonox::irc::info $token "$nick changes his/her nickname to $newnick"
+
+	return ""
+    }
+
+    # This procedure deals with QUIT actions:
+
+    proc RECV,QUIT {token nick user comm dest rest} {
+	variable state
+
+	set rest [eval concat $rest]
+#	puts "Received QUIT $token $nick $rest"
+      orxonox::irc::info $token "Received QUIT $token $nick $rest"
+
+	if {[string match ":*" $dest]} {
+	    set dest [string range $dest 1 end]
+	}
+	if {[isus $token $nick]} {
+#	    puts "You left the server $state($token,host) ($dest $rest)"
+          orxonox::irc::info $token "You left the server $state($token,host) ($dest $rest)"
+	    forgetConnection $token
+	} else {
+	    puts "$nick quits IRK ($dest $rest)"
+	    removeFromAllChannels $token $nick
+	    removeFromAllChannels $token @$nick
+	}
+
+	return ""
+    }
+
+    # This procedure deals with expected PRIVMSG actions:
+
+    proc RECV,PRIVMSG {token nick user comm dest rest} {
+	if {[string match "\001*" [lindex $rest 0]]} {
+	    set rest [ctcpcleanup $rest]
+	    RECV,PRIVMSG,CTCP,CHANNEL $token $nick $user $comm $dest \
+		    [lindex $rest 0] [lrange $rest 1 end]
+	} else {
+#	    puts "$nick$dest: [eval concat $rest]"
+          orxonox::irc::say $token $nick [eval concat $rest]
+	}
+
+	return ""
+    }
+
+    # This procedure handles CTCP actions on the channel:
+
+    proc RECV,PRIVMSG,CTCP,CHANNEL {token nick user comm dest action rest} {
+	variable state
+
+	if {[info exists state($token,channel,ctcp,$action)]} {
+	    $state($token,channel,ctcp,$action) \
+					$token $nick $user $comm $dest \
+					$action $rest
+	} else {
+	    $state($token,channel,ctcp,error) \
+					$token $nick $user $comm $dest \
+					$action $rest
+	}
+
+	return ""
+    }
+
+    # This procedure stores the result of USERHOST actions:
+
+    proc RECV,USERHOST {token nick user comm dest rest} {
+	return ""
+    }
+
+    # This procedure stores the channel topic:
+
+    proc RECV,CHANNEL,TOPIC {token nick user comm dest rest} {
+	variable state
+
+	set chan [lindex $rest 0]
+	set rest [lrange $rest 1 end]
+	if {[string match ":*" [lindex $rest 0]]} {
+	    set rest [lreplace $rest 0 0 \
+			       [string range [lindex $rest 0] 1 end]]
+	}
+	set state($token,$chan,TOPIC) $rest
+	set state($token,$chan,TOPIC,SETBY) $nick
+	set state($token,$chan,TOPIC,SETAT) [clock format [clock seconds]]
+
+	return ""
+    }
+
+    # This procedure stores the channel byline:
+
+    proc RECV,CHANNEL,SETBY {token nick user comm dest rest} {
+	variable state
+
+	set chan [lindex $rest 0]
+	set rest [lrange $rest 1 end]
+	if {[string match ":*" [lindex $rest 0]]} {
+	    set rest [lreplace $rest 0 0 \
+			       [string range [lindex $rest 0] 1 end]]
+	}
+	set state($token,$chan,TOPIC,SETBY) [lindex $rest 0]
+	set state($token,$chan,TOPIC,SETAT) [clock format [lindex $rest 1]]
+
+	return ""
+    }
+
+    # This procedure deals with unsolicited PRIVMSG actions:
+
+    proc RECV,PRIVMSG,unsolicited {token nick user comm dest rest} {
+	if {[string match "\001*" [lindex $rest 0]]} {
+	    set rest [ctcpcleanup $rest]
+	    RECV,PRIVMSG,CTCP,USER $token $nick $user $comm $dest \
+		    [lindex $rest 0] [lrange $rest 1 end]
+	} else {
+#	    puts "$nick: [eval concat $rest]"
+          orxonox::irc::privmsg $nick $nick [eval concat $rest]
+	}
+
+	return ""
+    }
+
+    # This procedure helps with CTCP private messages:
+
+    proc RECV,PRIVMSG,CTCP,USER {token nick user comm dest action rest} {
+	variable state
+
+	if {[info exists state($token,cmd,ctcp,$action)]} {
+	    $state($token,cmd,ctcp,$action) \
+					$token $nick $user $comm $dest \
+					$action $rest
+	} else {
+	    $state($token,cmd,ctcp,error) \
+					$token $nick $user $comm $dest \
+					$action $rest
+	}
+
+	return ""
+    }
+
+    # This procedure deals with a KICK action:
+
+    proc RECV,KICK {token nick user comm dest rest} {
+	set kicked [lindex $rest 0]
+	if {[string match ":*" $kicked]} {
+	    set kicked [string range $kicked 1 end]
+	}
+	set reason [eval concat [lrange $rest 1 end]]
+	if {[string match ":*" $reason]} {
+	    set reason [string range $reason 1 end]
+	}
+
+	if {[isus $token $kicked]} {
+#	    puts "$nick kicked you from $dest because $reason"
+          orxonox::irc::info $token "$nick kicked you from $dest because $reason"
+
+	    removeChannel $token $dest
+	} else {
+#	    puts "$nick kicks $kicked from $dest because $reason"
+          orxonox::irc::info $token "$nick kicks $kicked from $dest because $reason"
+
+	    removeFromChannel $token $kicked $dest
+	    removeFromChannel $token @$kicked $dest
+	}
+
+	return ""
+    }
+
+    # These procedures collect the name list for a channel:
+
+    proc RECV,CHANNEL,NAMELIST {token nick user comm dest rest} {
+	variable state
+
+	# Scan forward in $rest for the channel name:
+
+	for {set i 0; set l [llength $rest]} {$i < $l} {incr i} {
+	    if {[string match "#*" [lindex $rest $i]]} {
+		break
+	    }
+	}
+
+	# Didn't find it?
+
+	if {$i == $l} {
+	    return
+	}
+
+	# Extract the channel name and the rest of the input:
+
+	set chan [lindex $rest $i]
+	set rest [lrange $rest [expr $i + 1] end]
+	set rest [lreplace $rest 0 0 [string range [lindex $rest 0] 1 end]]
+	set rest [eval concat $rest]
+
+	if {![info exists state($token,$chan,NAMES)]} {
+	    set state($token,$chan,NAMES) ""
+	}
+	set state($token,$chan,NAMES) [concat $state($token,$chan,NAMES) $rest]
+
+	return ""
+    }
+
+    proc RECV,CHANNEL,NAMELIST,END {token nick user comm dest rest} {
+	variable state
+
+	set chan [lindex $rest 0]
+	set $state($token,$chan,NAMES) [split $state($token,$chan,NAMES) " "]
+    }
+
+    # This procedure deals with a request from the server to send a PONG
+    # with a given code.
+
+    proc RECV,PONG,REQUEST {token nick user comm dest rest} {
+	set pongcode [lindex $rest [expr [llength $rest] - 1]]
+	puts $token "PONG $pongcode"
+
+	return ""
+    }
+
+    # This procedure deals with a CTCP PING request:
+
+    proc RECV,CTCP,PING {token nick user comm dest action rest} {
+	variable state
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid IRK connection"
+	}
+	puts $sock "NOTICE $nick :\001PING ${rest}\001"
+
+	return ""
+    }
+
+    # This procedure deals with a CTCP TIME request:
+
+    proc RECV,CTCP,TIME {token nick user comm dest action rest} {
+	variable state
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid IRK connection"
+	}
+	puts $sock \
+	    "NOTICE $nick :\001TIME :[clock format [clock seconds]]\001"
+
+	return ""
+    }
+
+    # This procedure deals with a CTCP VERSION request:
+
+    proc RECV,CTCP,VERSION {token nick user comm dest action rest} {
+	variable state
+	global tcl_platform
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid IRK connection"
+	}
+	set version "$state(-useragent):$state(-version):$tcl_platform(os)"
+	puts $sock "NOTICE $nick :\001VERSION ${version}\001"
+    }
+
+    # This procedure deals with a CTCP USERINFO request:
+
+    proc RECV,CTCP,USERINFO {token nick user comm dest action rest} {
+	variable state
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid IRK connection"
+	}
+	puts $sock "NOTICE $nick :\001USERINFO $state(-$token,user)\001"
+    }
+
+    # This procedure deals with CTCP ACTION messages:
+
+    proc RECV,CTCP,ACTION {token nick user comm dest action rest} {
+#	puts "$nick $rest"
+      orxonox::irc::action $token $nick $rest
+
+	return ""
+    }
+
+    # This procedure is a catch all for CTCP actions that we do not
+    # understand:
+
+    proc RECV,CTCP,ERROR {token nick user comm dest action rest} {
+	variable state
+
+	if {[catch {set sock $state($token,socket)}]} {
+	    error "$token: not a valid IRC connection"
+	}
+	if {[llength $rest] > 0} {
+	    puts $sock \
+		"NOTICE $nick :\001ERRMSG $action $rest: unknown CTCP\001"
+	} else {
+	    puts $sock "NOTICE $nick :\001ERRMSG $action: unknown CTCP\001"
+	}
+    }
+
+    # This is the default action, used by the default dispatcher
+    # when no action can be found for the given $token, $nick, $user,
+    # $comm, and $dest.
+
+    proc defaultAction {token nick user comm dest rest} {
+#	puts "$token: $nick $user: $comm -> $dest ... [eval concat $rest]"
+      orxonox::execute log "$token: $nick $user: $comm -> $dest ... [eval concat $rest]"
+
+	return ""
+    }
+}
Index: /code/branches/rocket2/data/tcl/irk/lib/irkservers.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/lib/irkservers.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/lib/irkservers.tcl	(revision 6952)
@@ -0,0 +1,57 @@
+# irkservers.tcl:
+#
+# This file defines the servers that are known to the Tcl IRK library.
+# It is actually a Tcl script and is source'd by the irk.tcl file.
+
+namespace eval ::irk {
+
+    # This procedure helps define a new server:
+
+    proc defineserver {symname host ports} {
+	variable state
+	variable symsrv
+
+	# Auto initialize the list of known (symbolic names for) servers:
+
+	if {![info exists state(servers)]} {
+	    set state(servers) {}
+	}
+
+	# Add an entry in the list of (symbolic names for) servers:
+
+	lappend state(servers) $symname
+
+	# Add an entry for the contact information of this symbolic server:
+
+	set symsrv($symname) [list $host $ports]
+    }
+
+    # OK, now define a bunch of servers. This is where you can add your
+    # own, or edit if things change:
+
+    defineserver twisted	twisted.ma.us.dal.net {6660 6661 6662 6663}
+    defineserver dalnet		irc.dal.net			6667
+    defineserver undernet	McLean.VA.us.undernet.org	{6667 6668}
+    defineserver efnet		irc.Prison.NET			6666
+    defineserver ircnet		irc.stealth.net			{6663 6664}
+    defineserver powersurf	irc.powersurfr.com		6667
+    defineserver coins		coins.dal.net	{6667 6668 6669 7000}
+    defineserver sodre		sodre.on.ca.dal.net {6667 6668 6669 7000}
+    defineserver austnet	au.austnet.org 6667
+    defineserver nznet		nz.austnet.org 6667
+    defineserver sgnet		sg.austnet.org 6667
+    defineserver us.efnet	us.rr.efnet.net 6667
+    defineserver eu.efnet	eu.rr.efnet.net 6667
+    defineserver ca.efnet	ca.rr.efnet.net 6667
+    defineserver au.efnet	au.rr.efnet.net 6667
+    defineserver us.ircnet	us.ircnet.org {6665 6666 6667 6668}
+    defineserver eu.ircnet	eu.ircnet.org {6665 6666 6667 6668}
+    defineserver ca.ircnet	ca.ircnet.org {6665 6666 6667 6668}
+    defineserver au.ircnet	au.ircnet.org {6665 6666 6667 6668}
+    defineserver us.undernet	us.undernet.org 6667
+    defineserver eu.undernet	eu.undernet.org 6667
+    defineserver othernet	irc.othernet.org 6667
+    defineserver de.quakenet  de.quakenet.org 6667
+    defineserver datacore     irc.datacore.ch 6667
+    defineserver orxonox      irc.orxonox.net 6667
+}
Index: /code/branches/rocket2/data/tcl/irk/lib/irkstate.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/lib/irkstate.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/lib/irkstate.tcl	(revision 6952)
@@ -0,0 +1,134 @@
+# irkstate.tcl:
+#
+# This file defines the contents of the ::irk::state array
+
+namespace eval ::irk {
+
+    # The state array contains all the state for the IRK package:
+    #
+    # These options can be configured with irk::config:
+    #
+    # state(-useragent)		Name of this IRK user agent.
+    # state(-version)		Version of this IRK user agent.
+    #
+    # state(-sockproxy)		Name of SOCKS5 proxy to use (optional).
+    # state(-socksport)		Port on which SOCKS5 server accepts
+    #				connections (optional).
+    #
+    # state(-$symsrv,nick)	If set and connect is called without giving
+    #				a nick, use this as the nickname.
+    # state(-$symsrv,user)	If set and connect is called without giving
+    #				a user, this is used. Otherwise, if it's not
+    #				set when connect is called without a user,
+    #				it is set to the given nickname (and used).
+    # state(-$symsrv,pass)	If set, and connect is called without giving
+    #				a password, this is used.
+    #
+    # state(-quitmessage)	If set, the message is sent when a connection
+    #				is closed, as part of a QUIT command.
+    #
+    # These options cannot be configured with irk::config:
+    #
+    # state(connections)	A list of all active connections.
+    # state(dispatcher)		The default command dispatcher (must be set).
+    # state(action)		The default action (must be set).
+    # state(servers)		List of known servers (further described in
+    #				the symsrv array below).
+    #
+    # The following state is kept per connection (identified by $contok):
+    #
+    # state($contok,socket)	The socket for a given connection
+    # state($contok,port)	The port of a given connection
+    # state($contok,host)	The host of a given connection
+    # state($contok,symsrv)	The symbolic name of the server for
+    #				this connection.
+    # state($contok,nick)	The nick name used on a given connection
+    # state($contok,user)	The real user used on a given connection
+    # state($contok,pass)	The password used on a given connection
+    # state($contok,disp)	The command dispatcher for the connection
+    #
+    # Depending on the dispatcher associated with each connection, there
+    # may be many more settings of the general form:
+    #
+    # state($contok,action,...)
+    #
+    # System wide responses to common commands are handled by
+    # special actions, stored in the state array:
+    #
+    # state(PRIVMSG,unsolicited)
+    #				Action that responds to unsolicited private
+    #				messages directed at this user's nickname.
+    # state(special,PING)	Responds to PING messages.
+    # state(special,NOTICE)	Responds to NOTICE messages.
+    # state(special,ERROR)	Responds to ERROR messages.
+    #
+    # The IRK library provides a unified authorization mechanism, implemented
+    # in irkauth.tcl. The state array contains two settings that affect the
+    # behavior of the authorization mechanism:
+    #
+    # state(auth,save,file)	Name of a file to save the authorization
+    #				information in. Defaults to auth.dat in the
+    #				directory containing the IRK package.
+    # state(auth,save,interval)	The number of milliseconds that pass between
+    #				autosaves of the authorization data.
+    
+    variable state
+    array set state {
+	-useragent		"Tcl IRK Library"
+	-version		0.1
+	-quitmessage		"gives up the ghost"
+
+	dispatcher		::irk::defaultDispatcher
+	action			::irk::defaultAction
+
+	cmd,QUIT		::irk::RECV,QUIT
+	cmd,JOIN		::irk::RECV,JOIN
+	cmd,PART		::irk::RECV,PART
+	cmd,MODE		::irk::RECV,MODE
+	cmd,NICK		::irk::RECV,NICK
+	cmd,PONG		::irk::RECV,PONG
+	cmd,PRIVMSG		::irk::RECV,PRIVMSG
+	cmd,NOTICE		::irk::RECV,NOTICE,USER
+	cmd,KICK		::irk::RECV,KICK
+	cmd,001			::irk::RECV,MOTD
+	cmd,002			::irk::RECV,MOTD
+	cmd,003			::irk::RECV,MOTD
+	cmd,004			::irk::RECV,MOTD
+	cmd,005			::irk::RECV,MOTD
+	cmd,250			::irk::RECV,MOTD
+	cmd,251			::irk::RECV,MOTD
+	cmd,252			::irk::RECV,MOTD
+	cmd,253			::irk::RECV,MOTD
+	cmd,254			::irk::RECV,MOTD
+	cmd,255			::irk::RECV,MOTD
+	cmd,265			::irk::RECV,MOTD
+	cmd,266			::irk::RECV,MOTD
+	cmd,301			::irk::RECV,AWAY
+	cmd,307			::irk::RECV,WHOIS,NICK,IDENT
+	cmd,311			::irk::RECV,WHOIS,NICK,USER
+	cmd,312			::irk::RECV,WHOIS,NICK,SERVER
+	cmd,317			::irk::RECV,WHOIS,NICK,CONNECTTIME
+	cmd,318			::irk::RECV,WHOIS,NICK,END
+	cmd,319			::irk::RECV,WHOIS,NICK,CHANNELS
+	cmd,372			::irk::RECV,MOTD
+	cmd,375			::irk::RECV,MOTD
+	cmd,376			::irk::RECV,MOTD
+	cmd,332			::irk::RECV,CHANNEL,TOPIC
+	cmd,333			::irk::RECV,CHANNEL,SETBY
+	cmd,353			::irk::RECV,CHANNEL,NAMELIST
+	cmd,366			::irk::RECV,CHANNEL,NAMELIST,END
+
+	cmd,513			::irk::RECV,PONG,REQUEST
+
+	special,PING		::irk::RECV,PING
+	special,NOTICE		::irk::RECV,NOTICE
+	special,ERROR		::irk::RECV,ERROR
+
+	PRIVMSG,unsolicited	::irk::RECV,PRIVMSG,unsolicited
+
+	errorhandler		::irk::echoerror
+
+	auth,save,file		[file join [file dir [info script]] auth.dat]
+	auth,save,interval	300000
+    }
+}
Index: /code/branches/rocket2/data/tcl/irk/lib/irkutil.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/lib/irkutil.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/lib/irkutil.tcl	(revision 6952)
@@ -0,0 +1,144 @@
+# irkutil.tcl:
+#
+# Utility procedures used throughout the IRK package.
+
+namespace eval ::irk {
+
+    # The randselect randomly selects an element of a given list.
+
+    proc randselect {l} {
+	lindex $l [expr int(floor(rand() * [llength $l]))]
+    }
+
+    # Remove a user from the list of users on a channel
+
+    proc removeFromChannel {token user chan} {
+	variable state
+
+	# If it's us that left the channel, forget the channel:
+
+	if {![string compare $state($token,nick) $user]} {
+	    removeChannel $token $chan
+	    return
+	}
+
+	# Try to retrieve the channel's user list:
+
+	if {[catch {set users $state($token,$chan,NAMES)}]} {
+	    return
+	}
+	set idx [lsearch $users $user]
+	if {$idx == -1} {
+	    return
+	}
+
+	# Remove the user:
+
+	set state($token,$chan,NAMES) [lreplace $users $idx $idx]
+    }
+
+    # Remove a user from all the channels I am on (for QUIT etc.)
+
+    proc removeFromAllChannels {token user} {
+	variable state
+
+	foreach chan $state($token,channels) {
+	    removeFromChannel $token $user $chan
+	}
+    }
+
+    # Add a user to a channel I am on.
+
+    proc addToChannel {token user chan} {
+	variable state
+
+	lappend state($token,$chan,NAMES) $user
+    }
+
+    # Add a channel to the list of channels we're on:
+
+    proc addChannel {token chan} {
+	variable state
+
+	lappend state($token,channels) $chan
+    }
+
+    # Remove a channel from the list of channels we're on:
+
+    proc removeChannel {token chan} {
+	variable state
+
+	if {[catch {set channels $state($token,channels)}]} {
+	    return
+	}
+	set idx [lsearch $channels $chan]
+	if {$idx == -1} {
+	    return
+	}
+
+	# Remove this channel from the list of channels we're on:
+
+	set state($token,channels) [lreplace $channels $idx $idx]
+
+	# Forget all state for this channel:
+
+	array unset state $token,$chan,*
+    }
+
+    # This procedure cleans up all state associated with a connection:
+
+    proc forgetConnection {token} {
+	variable state
+
+	array unset state $token,*
+    }
+
+    # This procedure updates the channel names for all channels we're on
+    # due to a nick change.
+
+    proc replaceAllChannels {token nick newnick} {
+	variable state
+
+	# If we're not on any channels, then no need to replace.
+
+	if {![info exists state($token,channels)]} {
+	    return
+	}
+
+	# Replace the old nick with the new nick in all the channels I'm on.
+
+	foreach chan $state($token,channels) {
+	    if {[catch {set names $state($token,$chan,NAMES)}]} {
+		continue
+	    }
+	    set idx [lsearch $names $nick]
+	    if {$idx != -1} {
+		set state($token,$chan,NAMES) \
+			[lreplace $names $idx $idx $newnick]
+	    }
+	}
+    }
+
+    # This procedure determines whether a nick is our nick.
+    
+    proc isus {token nick} {
+	variable state
+
+	if {![string compare $nick $state($token,nick)]} {
+	    return 1
+	}
+	return 0
+    }
+
+    # This procedure cleans up input received as part of a CTCP action.
+
+    proc ctcpcleanup {l} {
+	if {[llength $l] > 1} {
+	    set h [string range [lindex $l 0] 1 end]
+	    set t [string range [lindex $l end] 0 end-1]
+	    return [lreplace [lreplace $l 0 0 $h] end end $t]
+	}
+	return [string range $l 1 end-1]
+    }
+	
+}
Index: /code/branches/rocket2/data/tcl/irk/pkgIndex.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/pkgIndex.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/pkgIndex.tcl	(revision 6952)
@@ -0,0 +1,12 @@
+# Tcl package index file, version 1.1
+# This file is generated by the "pkg_mkIndex" command
+# and sourced either when an application starts up or
+# by a "package unknown" script.  It invokes the
+# "package ifneeded" command to set up package-related
+# information so that packages will be loaded automatically
+# in response to "package require" commands.  When this
+# script is sourced, the variable $dir must contain the
+# full path name of this file's directory.
+
+package ifneeded socks 1.2 [list source [file join $dir socks socks.tcl]]
+package ifneeded irk 0.1 [list source [file join $dir irk.tcl]]
Index: /code/branches/rocket2/data/tcl/irk/socks/socks.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/irk/socks/socks.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/irk/socks/socks.tcl	(revision 6952)
@@ -0,0 +1,347 @@
+# Socks5 Client Library v1.2
+#
+# Original author: (C)2000 Kerem 'Waster_' HADIMLI
+#
+# Author contact information:
+#   E-mail :  waster@iname.com
+#   ICQ#   :  27216346
+#   Jabber :  waster@jabber.org   (New IM System - http://www.jabber.org)
+#
+# Cleaned up a little by Jacob Levy, jyl@best.com (01/07/2001)
+#
+# * Moved everything into the ::socks:: namespace.
+# * Parameterized so that constants do not get reset for every connection.
+# * Uniform error handling and cleanup.
+# * Incremented the version number to 1.2.
+#
+# How to use:
+#
+# Step 1: Create your client socket connected to the SOCKS5 server.
+#
+# Step 2: Call socks::init sock host port ?auth? ?user? ?pass?
+#    where:
+#
+#	sock		The socket from step #1.
+#	host		The remote host to connect to through the proxy.
+#	port		The remote port to connect to through the proxy.
+#	auth		Optional. If 1, it means that we do an
+#			authentication with the proxy server.
+#	user		Optional. If present, the user name to use for
+#			authentication with the proxy server.
+#	pass		Optional. If present, the password for the user
+#			name to use for authentication with the
+#			proxy server.
+#
+# If auth == 1, user and pass are not present, and socks::state(username)
+# and socks::state(pass) are set, then socks::init uses the values from
+# socks::state(username) and socks::state(password) for user name and
+# password, respectively.
+#
+# If anything goes wrong during the attempt to connect through the
+# proxy server, socks::init throws an appropriate error and closes
+# the socket. If the operation succeeds, socks::init returns $sock.
+#
+# You can set up your socket with fconfigure before calling socks::init,
+# the socks::init procedure is careful to restore the state to what it
+# was before the call upon successful completion. Likewise, you can
+# have fileevent handlers installed for handling socket readable and
+# socket writable events. These will also be preserved.
+
+# This file provides the "socks" package:
+
+package provide socks 1.2
+
+# Global settings:
+
+namespace eval ::socks {
+    variable state
+
+    array set state {
+	protocolversion		"\x05"
+	cmdconnect		"\x01"
+	addresstype		"\x03"
+	reserved		"\x00"
+
+	noauthmethod		"\x00"
+	noauthlengthstr		"\x01"
+
+	authmethod		"\x00\x02"
+	authlengthstr		"\x02"
+
+	nomatchingmethod	"\xFF"
+	nomatchlengthstr	"\x01"
+
+	authenticationversion	"\x01"
+
+	errorheader		"Error: "
+	error1			"General SOCKS server failure"
+	error2			"Connection not allowed by ruleset"
+	error3			"Network unreachable"
+	error4			"Host unreachable"
+	error5			"Connection refused"
+	error6			"TTL expired"
+	error7			"Command not supported"
+	error8			"Address type not supported"
+	errorUnknown		"Unknown error"
+
+	errorDisconnect		"SOCKS server disconnected"
+	errorNotSOCKS5		"SOCKS server does not support SOCKS 5"
+	errorMustAuthenticate	"SOCKS server demands user/pass authentication"
+	errorAuthMethodNotSup	"SOCKS server doesn't support user/pass auth"
+	errorWrongUserPass	"Wrong user name or password"
+	errorIncorrectAuthVal	"Incorrect value for $auth, expecting 1 or 0"
+	errorMissingUserAndPass	"Missing user and pass, required for auth == 1"
+    }
+}
+
+# Error handling and cleanup:
+
+proc ::socks::Error {sock errorMsg} {
+    variable state
+
+    # Attempt to close the socket. This also cancels any installed
+    # fileevent handlers, so no need to do that explicitly.
+
+    catch {close $sock}
+
+    # Clean up the state we keep about this socket:
+
+    catch {array unset state $sock,*}
+
+    # Report the requested error:
+
+    error "$state(errorheader)$state($errorMsg)"
+}
+    
+# Main entry point: socks::init
+#
+# See comment at head of file for how to use.
+
+proc ::socks::init {sock addr port {auth 0} {user {}} {pass {}}} {
+    variable state
+
+    # Save current configuration state for $sock
+
+    set currentConfiguration [fconfigure $sock]
+
+    # We cannot configure -peername so if its present (it should be)
+    # then remove it from the list of options.
+
+    set idx [lsearch $currentConfiguration -peername]
+    if {$idx != -1} {
+	set currentConfiguration \
+	    [lreplace $currentConfiguration $idx [expr $idx + 1]]
+    }
+
+    # Same for -sockname.
+
+    set idx [lsearch $currentConfiguration -sockname]
+    if {$idx != -1} {
+	set currentConfiguration \
+	    [lreplace $currentConfiguration $idx [expr $idx + 1]]
+    }
+
+    # Save any currently installed handler for fileevent readable:
+
+    set currentReadableHandler [fileevent $sock readable]
+
+    # If the user has "set and forget" user name and password, and
+    # indicates that she wants to use them, use them now:
+
+    if {($auth == 1) && (![string compare {} $user]) \
+	    && (![string compare {} $pass])} {
+	if {[info exists state(username)] && [info exists state(password)]} {
+	    set auth 1
+	    set user $state(username)
+	    set pass $state(password)
+	} else {
+	    Error $sock errorMissingUserAndPass
+	}
+    }
+
+    # Figure out the authentication method to use:
+
+    if {$auth == 0} {
+	set nmethods $state(noauthlengthstr)
+	set method $state(noauthmethod)
+    } elseif {$auth == 1} {
+	set nmethods $state(authlengthstr)
+	set method $state(authmethod)
+    } else {
+	Error $sock errorIncorrectAuthVal
+    }
+
+    # Encode the length of the address given (binary 1 byte):
+
+    set domainlen "[binary format c [string length $addr]]"
+
+    # Encode the port (network byte order, 2 bytes):
+
+    set port [binary format S $port]
+
+    if {$auth == 1} {
+	# Encode the length of the user given (binary 1 byte):
+
+	set userlen "[binary format c [string length $user]]"
+
+	# Encode the length of the password given (binary 1 byte):
+
+	set passlen "[binary format c [string length $pass]]"
+    }
+
+    # Set up initial state for the given socket:
+
+    set state($sock,state) $sock
+    set state($sock,data) ""
+
+    # Prepare the socket:
+
+    fconfigure $sock -translation {binary binary} -blocking 0
+    fileevent $sock readable "::socks::readable $sock"
+
+    # Tell the server what version and authentication method we're using:
+
+    puts -nonewline $sock "$state(protocolversion)$nmethods$method"
+    flush $sock
+
+    # Wait for server response and retrieve the information sent by the
+    # server:
+
+    vwait ::socks::state($sock,state)
+    set serverReply $state($sock,data)
+
+    if {[eof $sock]} {
+	Error $sock errorDisconnect
+    }
+
+    # Analyze the server's reply:
+
+    set serverVersion ""
+    set serverMethod $state(nomatchingmethod)
+
+    binary scan $serverReply "cc" serverVersion serverMethod
+
+    # Check for various error conditions:
+
+    if {$serverVersion != 5} {
+
+	# Server does not support SOCKS5 protocol
+
+	Error $sock errorNotSOCKS5
+    }
+
+    # If server demands authentication, do that step now:
+
+    if {$serverMethod == 2} {
+
+	if {$auth == 0} {
+
+	    # We didn't supply user/pass but server wants us to authenticate:
+
+	    Error $sock errorMustAuthenticate
+	}
+
+	puts -nonewline $sock \
+	    "$state(authenticationversion)$userlen$user$passlen$pass"
+	flush $sock
+
+	# Wait again for server reply:
+
+	vwait ::socks::state($sock,state)
+	set serverReply $state($sock,data)
+
+	# Analyze the server reply:
+
+	set authenticationVersion ""
+	set serverStatus "\x00"
+
+	binary scan $serverReply "cc" authenticationVersion serverStatus
+
+	# Deal with errors:
+
+	if {$authenticationVersion != 1} {
+
+	    # Server does not support our user/pass authentication method:
+
+	    Error $sock errorAuthMethodNotSup
+	}
+
+	if {$serverStatus != 0} {
+
+	    # We supplied wrong user/pass combination:
+
+	    Error $Sock errorWrongUserPass
+	}
+    } elseif {$serverMethod != 0} {
+
+	# Unknown method. Clean up:
+
+	Error $sock errorUnsupportedMethod
+    }
+
+    # Finally tell the server to connect us to the requested host and port:
+
+    puts -nonewline $sock \
+	"$state(protocolversion)$state(cmdconnect)$state(reserved)"
+    puts -nonewline $sock "$state(addresstype)$domainlen$addr$port"
+    flush $sock
+
+    # Wait again for server response:
+
+    vwait ::socks::state($sock,state)
+    set serverReply $state($sock,data)
+
+    if {[eof $sock]} {
+	Error $sock errorDisconnect
+    }
+
+    # Analyze server reply:
+
+    set serverVersion ""
+    set serverReplyCode ""
+
+    binary scan $serverReply "cc" serverVersion serverReplyCode
+
+    # Deal with errors:
+
+    if {$serverVersion != 5} {
+	Error $sock errorNotSOCKS5
+    }
+
+    if {$serverReplyCode != 0} {
+	if {($serverReplyCode > 0) && ($serverReplyCode < 9)} {
+	    Error $sock error$serverReplyCode
+	}
+	Error $sock errorUnknown
+    }
+
+    # All done, clean up state, reconfigure $sock to its original state,
+    # remove our fileevent handler and potentially restore the original
+    # one if one was present.
+
+    fileevent $sock readable {}
+    if {[string compare $currentReadableHandler ""]} {
+	fileevent $sock readable $currentReadableHandler
+    }
+    catch {eval fconfigure $sock $currentConfiguration}
+    catch {array unset state $sock,*}
+
+    # For good measure return the socket:
+
+    return $sock
+}
+
+# This procedure reads input available from the server socket and then
+# changes a state variable so that the main program will be woken up.
+
+proc ::socks::readable {sock} {
+    variable state
+
+    # Wake up the vwait:
+
+    set state($sock,state) $sock
+
+    # Read the data:
+
+    set state($sock,data) [read $sock]
+}
Index: /code/branches/rocket2/data/tcl/remote.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/remote.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/remote.tcl	(revision 6952)
@@ -0,0 +1,2 @@
+set telnetserverthreadid [TclThreadManager create]
+TclThreadManager execute $telnetserverthreadid source $pld/telnet_server.tcl
Index: /code/branches/rocket2/data/tcl/telnet_server.tcl
===================================================================
--- /code/branches/rocket2/data/tcl/telnet_server.tcl	(revision 6952)
+++ /code/branches/rocket2/data/tcl/telnet_server.tcl	(revision 6952)
@@ -0,0 +1,213 @@
+ #!/usr/bin/env tclsh
+ # Pseudo-telnet server.  Includes basic auth, but no separate identities
+ # or proper multi-threaded operation, so whoever runs this had better
+ # trust those he gives identities/passwords to and they had better trust
+ # each other too.  Note this script does not support command-line arguments.
+
+ ## The names of this array are IP addresses of hosts that are not permitted
+ ## to connect to any of our services.  Admin account(s) can change this
+ ## at run-time, though this info is not maintained across whole-server shutdowns.
+ array set denyHosts {}
+
+ ## Keep the Tcl-thread busy
+ proc every {ms body} { eval $body; after $ms [list every $ms $body] }
+ every 200 {}
+
+ ## Create a server on the given port with the given name/password map
+ ## and the given core interaction handler.
+ proc telnetServer {port {passmap} {handlerCmd remoteCommand}} {
+     if {$port == 0} {
+         return -code error "Only non-zero port numbers are supported"
+     }
+     set server [socket -server [list connect $port $handlerCmd] $port]
+     global passwords services
+     foreach {id pass} $passmap {set passwords($port,$id) $pass}
+     set services($server) $handlerCmd
+     return $server
+ }
+
+ ## Removes the server on the given port, cleaning up the extra state too.
+ proc closedownServer {server} {
+     global services passwords connections auth
+     set port [lindex [fconfigure $server -sockname] 2]
+     catch {close $server}
+     unset services($server)
+     foreach passmap [array names passwords $port,*] {
+         unset passwords($passmap)
+     }
+     # Hmph!  Have to remove unauthorized connections too, though any
+     # connection which has been authorized can continue safely.
+     foreach {client data} [array get connections] {
+         if {$port == [lindex $data 0] && !$auth($client)} {
+             disconnect $client
+         }
+     }
+ }
+
+ ## Handle an incoming connection to the given server
+ proc connect {serverport handlerCmd client clienthost clientport} {
+     global auth cmd denyHosts connections
+     if {[info exist denyHosts($clienthost)]} {
+         puts stdout "${clienthost}:${clientport} attempted connection"
+         catch {puts $client "Connection denied"}
+         catch {close $client}
+         return
+     }
+     puts stdout "${clienthost}:${clientport} connected on $client"
+     fileevent $client readable "handle $serverport $client"
+     set auth($client) 0
+     set cmd($client) $handlerCmd
+     set connections($client) [list $serverport $clienthost $clientport]
+     fconfigure $client -buffering none
+     catch {puts -nonewline $client "Login: "}
+ }
+
+ ## Disconnect the given client, cleaning up any connection-specific data
+ proc disconnect {client} {
+     catch {close $client}
+     global auth cmd connections
+     unset auth($client)
+     unset cmd($client)
+     unset connections($client)
+     puts stdout "$client disconnected"
+ }
+
+ ## Handle data sent from the client.  Log-in is handled directly by this
+ ## procedure, and requires the name and password on the same line
+ proc handle {serverport client} {
+     global passwords auth cmd
+     if {[gets $client line] < 0} {
+         disconnect $client
+         return
+     }
+     if {[string equal $line "logout"] || [string equal $line "quit"]} {
+         disconnect $client
+         return
+     }
+     if {[string equal $line "exit"]} {
+         set ::termination 1
+         return
+     }
+     if {$auth($client)} {
+         eval $cmd($client) [list $client $line 0]
+         eval $cmd($client) [list $client $line 1]
+         return
+     }
+     foreach {id pass} [split $line] {break}
+     if {![info exist pass]} {
+         catch {puts -nonewline $client "Login: "}
+         return
+     }
+     if {
+         [info exist passwords($serverport,$id)] &&
+         [string equal $passwords($serverport,$id) $pass]
+     } then {
+         set auth($client) 1
+         puts stdout "$id logged in on $client"
+         catch {puts $client "Welcome, $id!"}
+         eval $cmd($client) [list $client $line 1]
+         return
+     }
+     puts stdout "AUTH FAILURE ON $client"
+     catch {puts $client "Unknown name or password"}
+     disconnect $client
+ }
+
+ ## Standard handler for logged-in conversations and prompt-generation.
+ proc execCommand {client line prompt} {
+     global tcl_platform
+     if {$prompt} {
+         catch {puts -nonewline $client "\$ "}
+         return
+     }
+     switch $tcl_platform(platform) {
+         unix {
+             catch {exec sh -c $line <@$client >@$client 2>@$client}
+         }
+         default {
+             catch {exec $line} data
+             puts $client $data
+         }
+     }
+ }
+
+ ## Administration service handler.  Chains to the normal handler for
+ ## everything it doesn't recognise itself.
+ proc admin {client line prompt} {
+     if {$prompt} {
+         catch {puts -nonewline $client "# "}
+         return
+     }
+     set cmd [split $line]
+     global denyHosts connections services
+     if {[string equal $line "shutdown"]} {
+         set ::termination 1
+         puts stdout "Shutdown requested on $client"
+         catch {puts $client "System will shut down as soon as possible"}
+         return -code return "SHUTTING DOWN"
+     } elseif {[string equal [lindex $cmd 0] "deny"]} {
+         set denyHosts([lindex $cmd 1]) 1
+     } elseif {[string equal [lindex $cmd 0] "allow"]} {
+         catch {unset denyHosts([lindex $cmd 1])}
+     } elseif {[string equal $line "denied"]} {
+         foreach host [array names denyHosts] {
+             catch {puts $client $host}
+         }
+     } elseif {[string equal $line "connections"]} {
+         set len 0
+         foreach conn [array names connections] {
+             if {$len < [string length $conn]} {
+                 set len [string length $conn]
+             }
+         }
+         foreach {conn details} [array get connections] {
+             catch {puts $client [format "%-*s = %s" $len $conn $details]}
+         }
+     } elseif {[string equal [lindex $cmd 0] "close"]} {
+         set sock [lindex $cmd 1]
+         if {[info exist connections($sock)]} {
+             disconnect $sock
+         }
+     } elseif {[string equal $line "services"]} {
+         set len 0
+         foreach serv [array names services] {
+             if {$len < [string length $serv]} {
+                 set len [string length $serv]
+             }
+         }
+         foreach {serv handler} [array get services] {
+             set port [lindex [fconfigure $serv -sockname] 2]
+             catch {puts $client [format "%-*s (port %d) = handler %s" $len $serv $port $handler]}
+         }
+     } elseif {[string equal [lindex $cmd 0] "addService"]} {
+         set service [eval telnetServer [lrange $cmd 1 end]]
+         catch {puts $client "Created service as $service"}
+     } elseif {[string equal [lindex $cmd 0] "removeService"]} {
+         set service [lindex $cmd 1]
+         if {[info exist services($service)]} {
+             closedownServer $service
+         }
+     } else {
+         # CHAIN TO DEFAULT
+         execCommand $client $line 0
+     }
+ }
+ 
+ ## Executes a given command
+ proc remoteCommand {client line prompt} {
+     global tcl_platform
+     if {$prompt} {
+         catch {puts -nonewline $client "\$ "}
+         return
+     }
+     catch {eval $line} data
+     puts $client $data
+ }
+
+ telnetServer 2560 {orxonox rocks} remoteCommand
+ telnetServer 2561 {orxadmin *****} admin
+
+ puts stdout "Ready for service"
+
+ vwait termination
+ execute exit
Index: /code/branches/rocket2/doc/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/doc/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/doc/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,5 @@
+# Add a "doc" target with CMake build system.
+# And configure doxy.config.in to doxy.config
+#
+# target "doc" allows building the documentation with doxygen/dot on WIN32 and Linux
+ADD_SUBDIRECTORY(api)
Index: /code/branches/rocket2/doc/api/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/doc/api/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/doc/api/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,88 @@
+# Add a "doc" target with CMake build system.
+# And configure doxy.config.in to doxy.config
+#
+# target "doc" allows building the documentation with doxygen/dot on WIN32 and Linux
+# Creates .chm windows help file if MS HTML help workshop
+# (available from http://msdn.microsoft.com/workshop/author/htmlhelp)
+# is installed with its DLLs in PATH.
+#
+#
+# Please note, that the tools, e.g.:
+# doxygen, dot, latex, dvips, makeindex, gswin32, etc.
+# must be in path.
+#
+# Note about Visual Studio Projects:
+# MSVS hast its own path environment which may differ from the shell.
+# See "Menu Tools/Options/Projects/VC++ Directories" in VS 7.1
+#
+# author Jan Woetzel 2004-2006
+# www.mip.informatik.uni-kiel.de/~jw
+# Adjustments for Orxonox by Reto Grieder
+
+FIND_PACKAGE(Doxygen QUIET)
+
+IF (DOXYGEN_FOUND)
+  # click+jump in Emacs and Visual Studio (for doxy.config) (jw)
+  IF(CMAKE_BUILD_TOOL MATCHES "msdev|devenv")
+    SET(DOXY_WARN_FORMAT "\"$file($line) : $text \"")
+  ELSE()
+    SET(DOXY_WARN_FORMAT "\"$file:$line: $text \"")
+  ENDIF()
+
+  SET(DOXY_INPUT_DIR  ${CMAKE_CURRENT_SOURCE_DIR})
+  SET(DOXY_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR})
+
+  # we need latex for doxygen because of the formulas
+  # Orxonox doesn't
+  #FIND_PACKAGE(LATEX)
+  #IF    (NOT LATEX_COMPILER)
+  #  MESSAGE(STATUS "latex command LATEX_COMPILER not found but usually required. You will probably get warnings and user inetraction on doxy run.")
+  #ENDIF (NOT LATEX_COMPILER)
+  #IF    (NOT MAKEINDEX_COMPILER)
+  #  MESSAGE(STATUS "makeindex command MAKEINDEX_COMPILER not found but usually required.")
+  #ENDIF (NOT MAKEINDEX_COMPILER)
+  #IF    (NOT DVIPS_CONVERTER)
+  #  MESSAGE(STATUS "dvips command DVIPS_CONVERTER not found but usually required.")
+  #ENDIF (NOT DVIPS_CONVERTER)
+
+  IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in)
+    CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/doxy.config.in ${CMAKE_CURRENT_BINARY_DIR}/doxy.config @ONLY)
+    # use (configured) doxy.config from (out of place) BUILD tree:
+    SET(DOXY_CONFIG ${CMAKE_CURRENT_BINARY_DIR}/doxy.config)
+    SET(DOXY_LOGFILE ${CMAKE_CURRENT_BINARY_DIR}/doxy.log)
+  ELSE()
+    MESSAGE(FATAL_ERROR "Warning: Could not find dox.config.in in the root directory.")
+  ENDIF()
+
+  ADD_CUSTOM_TARGET(doc ${DOXYGEN_EXECUTABLE} ${DOXY_CONFIG})
+
+  # create a windows help .chm file using hhc.exe
+  # HTMLHelp DLL must be in path!
+  # fallback: use hhw.exe interactively
+  IF(WIN32)
+    FIND_PACKAGE(HTMLHelp)
+    IF(HTML_HELP_COMPILER)
+      SET(TMP ${DOXY_OUTPUT_DIR}/html/index.hhp)
+      STRING(REGEX REPLACE "/" "\\\\" HHP_FILE ${TMP})
+      ADD_CUSTOM_TARGET(doc_chm ${HTML_HELP_COMPILER} ${HHP_FILE})
+      ADD_DEPENDENCIES(doc_chm doc)
+      # Adding a dependency somehow adds doc target as default build target
+      SET_TARGET_PROPERTIES(doc doc_chm PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE)
+    ENDIF(HTML_HELP_COMPILER)
+  ENDIF (WIN32)
+
+
+  # Installation
+  INSTALL(
+    FILES ${DOXY_CONFIG} ${CMAKE_CURRENT_BINARY_DIR}/doxy.log
+    DESTINATION ${DOC_INSTALL_DIRECTORY}/api OPTIONAL
+  )
+  # Install command always needs the directory
+  IF(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/html)
+    FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html)
+  ENDIF()
+  INSTALL(
+    DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html
+    DESTINATION ${DOC_INSTALL_DIRECTORY}/api
+  )
+ENDIF(DOXYGEN_FOUND)
Index: /code/branches/rocket2/doc/api/doxy.config.in
===================================================================
--- /code/branches/rocket2/doc/api/doxy.config.in	(revision 6952)
+++ /code/branches/rocket2/doc/api/doxy.config.in	(revision 6952)
@@ -0,0 +1,1249 @@
+# Doxyfile 1.4.5
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "@PROJECT_NAME@"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = "@ORXONOX_VERSION@ Codename: @ORXONOX_VERSION_NAME@"
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = @DOXY_OUTPUT_DIR@
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, 
+# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, 
+# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, 
+# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, 
+# Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = @CMAKE_SOURCE_DIR@
+
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = @CMAKE_SOURCE_DIR@
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
+# include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = YES
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = YES
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is YES.
+
+SHOW_DIRECTORIES       = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the Folder
+# Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page. This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = @DOXY_WARN_FORMAT@
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = @DOXY_LOGFILE@
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = @CMAKE_SOURCE_DIR@/src \
+                         @CMAKE_CURRENT_SOURCE_DIR@ \
+                         @CMAKE_BINARY_DIR@/src/OrxonoxConfig.h \
+                         @CMAKE_BINARY_DIR@/src/SpecialConfig.h
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS          = *.cpp \
+                         *.cc \
+                         *.h \
+                         *.hh \
+                         *.hpp \
+                         *.dox
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = @CMAKE_SOURCE_DIR@/src/external/bullet/
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = */.svn/*
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = @CMAKE_CURRENT_SOURCE_DIR@/examples/
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = *.cpp \
+                         *.cc \
+                         *.h \
+                         *.hh \
+                         INSTALL DEPENDENCIES CHANGELOG LICENSE LGPL
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = YES
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = @CMAKE_CURRENT_SOURCE_DIR@/images/
+
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 2
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+HTML_HEADER            = 
+
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+#LATEX_CMD_NAME         = latex
+LATEX_CMD_NAME          = @LATEX_COMPILER@
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+#MAKEINDEX_CMD_NAME     = makeindex
+MAKEINDEX_CMD_NAME     = @MAKEINDEX_COMPILER@
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = YES
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = DOXYGEN_SHOULD_SKIP_THIS
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = @DOXY_OUTPUT_DIR@/html/@PROJECT_NAME@.TAGFILE
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = @DOXYGEN_DOT_EXECUTABLE_PATH@
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = @CMAKE_CURRENT_SOURCE_DIR@/dot
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that a graph may be further truncated if the graph's 
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH 
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), 
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 1000
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = YES
Index: /code/branches/rocket2/doc/api/main.dox
===================================================================
--- /code/branches/rocket2/doc/api/main.dox	(revision 6952)
+++ /code/branches/rocket2/doc/api/main.dox	(revision 6952)
@@ -0,0 +1,4 @@
+/**
+@mainpage
+    Orxonox Doxygen Reference
+*/
Index: /code/branches/rocket2/src/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,146 @@
+ #
+ #             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:
+ #    Configures the compilers and sets build options.
+ #
+
+# Required macros and functions
+INCLUDE(FlagUtilities)
+INCLUDE(TargetUtilities)
+
+# Configure the two headers and set some options
+INCLUDE(OrxonoxConfig.cmake)
+
+################ Library Defines ################
+
+# Disable Boost auto linking completely
+ADD_COMPILER_FLAGS("-DBOOST_ALL_NO_LIB")
+
+# If no defines are specified, these libs get linked statically
+ADD_COMPILER_FLAGS("-DBOOST_ALL_DYN_LINK" WIN32 LINK_BOOST_DYNAMIC)
+ADD_COMPILER_FLAGS("-DENET_DLL"           WIN32 LINK_ENET_DYNAMIC)
+ADD_COMPILER_FLAGS("-DLUA_BUILD_AS_DLL"   WIN32 LINK_LUA_DYNAMIC)
+ADD_COMPILER_FLAGS("-DOIS_DYNAMIC_LIB")
+ADD_COMPILER_FLAGS("-DZLIB_DLL"           WIN32 LINK_ZLIB_DYNAMIC)
+# If no defines are specified, these libs get linked dynamically
+ADD_COMPILER_FLAGS("-DCEGUI_STATIC"       WIN32 NOT LINK_CEGUI_DYNAMIC)
+ADD_COMPILER_FLAGS("-DOGRE_STATIC_LIB"    WIN32 NOT LINK_OGRE_DYNAMIC)
+ADD_COMPILER_FLAGS("-DSTATIC_BUILD"       WIN32 NOT LINK_TCL_DYNAMIC)
+
+# Use TinyXML++
+ADD_COMPILER_FLAGS("-DTIXML_USE_TICPP")
+
+############## Include Directories ##############
+
+# Set the search paths for include files
+INCLUDE_DIRECTORIES(
+  # External
+  ${OGRE_INCLUDE_DIR}
+  ${CEGUI_INCLUDE_DIR}
+  ${ENET_INCLUDE_DIR}
+  ${Boost_INCLUDE_DIRS}
+  ${OPENAL_INCLUDE_DIRS}
+  ${ALUT_INCLUDE_DIR}
+  ${VORBIS_INCLUDE_DIR}
+  ${OGG_INCLUDE_DIR}
+  ${LUA_INCLUDE_DIR}
+  ${TCL_INCLUDE_PATH}
+  ${DIRECTX_INCLUDE_DIR}
+  ${ZLIB_INCLUDE_DIR}
+  ${VLD_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(CEGUILUA_USE_INTERNAL_LIBRARY)
+  INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/external/ceguilua/ceguilua-${CEGUI_VERSION})
+ENDIF()
+
+################### Tolua Bind ##################
+
+# Create directory because the tolua application doesn't work otherwise
+IF(NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/toluabind/${CMAKE_CFG_INTDIR})
+  FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/toluabind/${CMAKE_CFG_INTDIR})
+ENDIF()
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/toluabind/${CMAKE_CFG_INTDIR})
+
+################ Sub Directories ################
+
+ADD_SUBDIRECTORY(external)
+ADD_SUBDIRECTORY(libraries)
+ADD_SUBDIRECTORY(orxonox)
+ADD_SUBDIRECTORY(modules)
+
+################ Executable ################
+
+INCLUDE_DIRECTORIES(
+  ${CMAKE_CURRENT_SOURCE_DIR}/libraries
+  ${CMAKE_CURRENT_SOURCE_DIR}/orxonox
+)
+
+# Translate argument
+IF(ORXONOX_USE_WINMAIN)
+  SET(ORXONOX_WIN32 WIN32)
+ENDIF()
+
+ORXONOX_ADD_EXECUTABLE(orxonox-main
+  # When defined as WIN32 this removes the console window on Windows
+  ${ORXONOX_WIN32}
+  LINK_LIBRARIES
+    orxonox
+  SOURCE_FILES
+    Orxonox.cc
+  OUTPUT_NAME orxonox
+)
+
+# Get name to configure the run scripts
+GET_TARGET_PROPERTY(_exec_loc orxonox-main LOCATION)
+GET_FILENAME_COMPONENT(_exec_name ${_exec_loc} NAME)
+SET(ORXONOX_EXECUTABLE_NAME ${_exec_name} CACHE INTERNAL "")
+
+
+# When using Visual Studio we want to use the output directory as working
+# directory and we also want to specify where the external dlls
+# (lua, ogre, etc.) are. The problem hereby is that these information cannot
+# be specified in CMake because they are not stored in the actual project file.
+# This workaround will create a configured *.vcproj.user file that holds the
+# right values. When starting the solution for the first time,
+# these get written to the *vcproj.yourPCname.yourname.user
+IF(MSVC)
+  IF(CMAKE_CL_64)
+    SET(MSVC_PLATFORM "x64")
+  ELSE()
+    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")
+ENDIF(MSVC)
Index: /code/branches/rocket2/src/Orxonox.cc
===================================================================
--- /code/branches/rocket2/src/Orxonox.cc	(revision 6952)
+++ /code/branches/rocket2/src/Orxonox.cc	(revision 6952)
@@ -0,0 +1,75 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Entry point of the program.
+*/
+
+#include "SpecialConfig.h"
+
+#ifdef ORXONOX_USE_WINMAIN
+# ifndef WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN
+# endif
+#include <windows.h>
+#endif
+
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "orxonox/Main.h"
+
+/*
+@brief
+    Main method. Game starts here (except for static initialisations).
+*/
+#ifdef ORXONOX_USE_WINMAIN
+INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT)
+#else
+int main(int argc, char** argv)
+#endif
+{
+    try
+    {
+#ifndef ORXONOX_USE_WINMAIN
+        std::string strCmdLine;
+        for (int i = 1; i < argc; ++i)
+            strCmdLine = strCmdLine + argv[i] + ' ';
+#endif
+
+        return orxonox::main(strCmdLine);
+    }
+    catch (...)
+    {
+        COUT(0) << "Orxonox failed to initialise: " << orxonox::Exception::handleMessage() << std::endl;
+        COUT(0) << "Terminating program." << std::endl;
+        return 1;
+    }
+}
Index: /code/branches/rocket2/src/OrxonoxConfig.cmake
===================================================================
--- /code/branches/rocket2/src/OrxonoxConfig.cmake	(revision 6952)
+++ /code/branches/rocket2/src/OrxonoxConfig.cmake	(revision 6952)
@@ -0,0 +1,106 @@
+ #
+ #             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:
+ #    Configures the header files OrxonoxConfig.h and SpecialConfig.h
+ #    and sets some other options. All the build related options should be
+ #    found and set here if possible.
+ #
+
+#################### Options ####################
+
+# Default linking is SHARED
+SET(ORXONOX_DEFAULT_LINK SHARED)
+
+# Use, i.e. don't skip the full RPATH for the build tree
+SET(CMAKE_SKIP_BUILD_RPATH  FALSE)
+
+# Global switch to disable Precompiled Header Files
+IF(PCH_COMPILER_SUPPORT)
+  OPTION(PCH_ENABLE "Global PCH switch" TRUE)
+ENDIF()
+
+# Global switch to disable multiple file compilations
+OPTION(DISABLE_COMPILATIONS "Global multi-file compilation switch" FALSE)
+
+# Use WinMain() or main()?
+IF(WIN32)
+  OPTION(ORXONOX_USE_WINMAIN "Use WinMain (doesn't show console) or main" FALSE)
+ENDIF()
+
+################ Platform Config ################
+
+# Check endianness
+INCLUDE(TestBigEndian)
+TEST_BIG_ENDIAN(ORXONOX_BIG_ENDIAN)
+IF(NOT ORXONOX_BIG_ENDIAN)
+  SET(ORXONOX_LITTLE_ENDIAN TRUE)
+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})
+SET(ORXONOX_PLATFORM_APPLE ${APPLE})
+SET(ORXONOX_PLATFORM_UNIX ${UNIX})
+IF(UNIX AND NOT APPLE)
+  SET(ORXONOX_PLATFORM_LINUX TRUE)
+ENDIF()
+
+# Check __forceinline
+IF(MSVC)
+  INCLUDE(CheckCXXSourceCompiles)
+  SET(_source "int main() { return 0; } __forceinline void test() { return; }")
+  CHECK_CXX_SOURCE_COMPILES("${_source}" HAVE_FORCEINLINE)
+ENDIF(MSVC)
+
+# Check iso646.h include (literal operators)
+INCLUDE(CheckIncludeFileCXX)
+CHECK_INCLUDE_FILE_CXX(iso646.h HAVE_ISO646_H)
+
+# XCode and Visual Studio support multiple configurations. In order to tell
+# about the active one we have to define the macro for each configuration
+ADD_COMPILER_FLAGS("-DCMAKE_BUILD_TYPE=Debug"          Debug)
+ADD_COMPILER_FLAGS("-DCMAKE_BUILD_TYPE=Release"        Release)
+ADD_COMPILER_FLAGS("-DCMAKE_BUILD_TYPE=RelWithDebInfo" RelWithDebInfo)
+ADD_COMPILER_FLAGS("-DCMAKE_BUILD_TYPE=MinSizeRel"     MinSizeRel)
+
+############## Configured Headers ###############
+
+SET(GENERATED_FILE_COMMENT
+   "DO NOT EDIT THIS FILE! <br>
+    It has been automatically generated by CMake from OrxonoxConfig.h.in")
+# Copy and configure OrxonoxConfig which gets included in every file
+CONFIGURE_FILE(OrxonoxConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/OrxonoxConfig.h)
+# This file only gets included by very few classes to avoid a large recompilation
+CONFIGURE_FILE(SpecialConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/SpecialConfig.h)
+
+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
+)
Index: /code/branches/rocket2/src/OrxonoxConfig.h.in
===================================================================
--- /code/branches/rocket2/src/OrxonoxConfig.h.in	(revision 6952)
+++ /code/branches/rocket2/src/OrxonoxConfig.h.in	(revision 6952)
@@ -0,0 +1,220 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ *   Original code: OgrePlatform.h, licensed under the LGPL. The code
+ *   has changed almost completely though.
+ *
+ *   Caution: Do not configure this file CMake configuration (Debug, Release, etc.)
+ *            dependent! XCode and Visual Studio have the same file for all.
+ *
+ */
+
+/**
+@file
+@brief
+    Various constants for compiler, architecture and platform.
+@remarks
+    @GENERATED_FILE_COMMENT@
+*/
+
+#ifndef _OrxonoxConfig_H__
+#define _OrxonoxConfig_H__
+
+/*---------------------------------
+ * Platform and compiler related options
+ *-------------------------------*/
+#cmakedefine ORXONOX_PLATFORM_WINDOWS
+#cmakedefine ORXONOX_PLATFORM_LINUX
+#cmakedefine ORXONOX_PLATFORM_APPLE
+#cmakedefine ORXONOX_PLATFORM_UNIX /* Apple and Linux */
+
+// Determine compiler and set ORXONOX_COMP_VER
+#if defined( _MSC_VER )
+#  define ORXONOX_COMPILER_MSVC
+#  define ORXONOX_COMP_VER _MSC_VER
+
+#elif defined( __GNUC__ )
+#  define ORXONOX_COMPILER_GCC
+#  define ORXONOX_COMP_VER (((__GNUC__)*100) + \
+        (__GNUC_MINOR__*10) + \
+        __GNUC_PATCHLEVEL__)
+#  if defined(__MINGW32__)
+#    define ORXONOX_COMPILER_MINGW
+#  endif
+
+#elif defined( __BORLANDC__ )
+#  define ORXONOX_COMPILER_BORLAND
+#  define ORXONOX_COMP_VER __BCPLUSPLUS__
+
+#else
+#  pragma error "No known compiler. Abort!"
+
+#endif
+
+// Endianness
+#cmakedefine ORXONOX_BIG_ENDIAN
+#cmakedefine ORXONOX_LITTLE_ENDIAN
+
+// Architecture
+#cmakedefine ORXONOX_ARCH_32
+#cmakedefine ORXONOX_ARCH_64
+
+// See if we can use __forceinline or if we need to use __inline instead
+#cmakedefine HAVE_FORCEINLINE
+#ifndef FORCEINLINE
+#  ifdef HAVE_FORCEINLINE
+#    define FORCEINLINE __forceinline
+#  else
+#    define FORCEINLINE __inline
+#  endif
+#endif
+
+// Try to define function information
+#ifndef __FUNCTIONNAME__
+#  ifdef ORXONOX_COMPILER_BORLAND
+#    define __FUNCTIONNAME__ __FUNC__
+#  elif defined(ORXONOX_COMPILER_GCC)
+#    define __FUNCTIONNAME__ __PRETTY_FUNCTION__
+#  elif defined(ORXONOX_COMPILER_MSVC)
+#    define __FUNCTIONNAME__ __FUNCTION__
+#  else
+#    define __FUNCTIONNAME__
+#  endif
+#endif
+
+
+/*---------------------------------
+ * Version information
+ *-------------------------------*/
+#define ORXONOX_VERSION_MAJOR @ORXONOX_VERSION_MAJOR@
+#define ORXONOX_VERSION_MINOR @ORXONOX_VERSION_MINOR@
+#define ORXONOX_VERSION_PATCH @ORXONOX_VERSION_PATCH@
+#define ORXONOX_VERSION_NAME "@ORXONOX_VERSION_NAME@"
+
+//! Defines version info encoded as 0xMMIIPP (M: Major version, I: Minor version, P: Patch version, all as hex)
+#define ORXONOX_VERSION \
+    ((ORXONOX_VERSION_MAJOR << 16) | (ORXONOX_VERSION_MINOR << 8) | ORXONOX_VERSION_PATCH)
+
+
+/*---------------------------------
+ * Unix settings
+ *-------------------------------*/
+#ifdef ORXONOX_PLATFORM_UNIX
+
+// TODO: Check what this actually is and whether we need it or not
+#if 0
+#  ifdef ORXONOX_PLATFORM_APPLE
+#    define ORXONOX_PLATFORM_LIB "OrxonoxPlatform.bundle"
+#  else // ORXONOX_PLATFORM_LINUX
+#    define ORXONOX_PLATFORM_LIB "libOrxonoxPlatform.so"
+#  endif
+#endif
+
+#endif /* Patform Unix */
+
+
+/*---------------------------------
+ * Apple Settings
+ *-------------------------------*/
+
+
+/*---------------------------------
+ * Options
+ *-------------------------------*/
+/**
+@def ORXONOX_RELEASE
+    Enables expensive (build time) optimisations and disables certain features
+*/
+#cmakedefine ORXONOX_RELEASE
+
+
+/*---------------------------------
+ * Includes and Declarations
+ *-------------------------------*/
+// Define the english written operators like and, or, xor
+// This is C++ standard, but the Microsoft compiler doesn't define them.
+#cmakedefine HAVE_ISO646_H
+#ifdef HAVE_ISO646_H
+#  include <iso646.h>
+#endif
+
+#cmakedefine HAVE_STDINT_H
+#ifdef HAVE_STDINT_H
+#  include <stdint.h>
+#elif defined(ORXONOX_COMPILER_MSVC)
+typedef __int8            int8_t;
+typedef __int16           int16_t;
+typedef __int32           int32_t;
+typedef __int64           int64_t;
+typedef unsigned __int8   uint8_t;
+typedef unsigned __int16  uint16_t;
+typedef unsigned __int32  uint32_t;
+typedef unsigned __int64  uint64_t;
+#endif
+
+#cmakedefine HAVE_STDDEF_H
+/* Quite large, do not include unless necessary
+#ifdef HAVE_STDDEF_H
+#  include <stddef.h>
+#endif
+*/
+
+// Always include the memory leak detector for MSVC except for actual releases
+// Note: Although officially supported, VLD does not work with MSVC 9
+#if defined(ORXONOX_COMPILER_MSVC) && _MSC_VER < 1500 && !defined(ORXONOX_RELEASE)
+#  include <vld.h>
+#endif
+
+// Forward declare the everywhere used std::string
+namespace std
+{
+    template<class _Elem> struct char_traits;
+    template<class _Ty>   class  allocator;
+    template<class _Elem, class _Traits, class _Ax> class basic_string;
+    typedef basic_string<char, char_traits<char>, allocator<char> > string;
+}
+
+// Import general purpose smart pointers
+namespace boost
+{
+    template<class T> class scoped_ptr;
+    template<class T> class shared_ptr;
+    template<class T> class weak_ptr;
+    template<class T> class intrusive_ptr;
+    template<class T> class shared_array;
+    template<class T> class scoped_array;
+}
+namespace orxonox
+{
+    using boost::scoped_ptr;
+    using boost::shared_ptr;
+    using boost::weak_ptr;
+    using boost::intrusive_ptr;
+    using boost::shared_array;
+    using boost::scoped_array;
+}
+
+#endif /* _OrxonoxConfig_H__ */
Index: /code/branches/rocket2/src/SpecialConfig.h.in
===================================================================
--- /code/branches/rocket2/src/SpecialConfig.h.in	(revision 6952)
+++ /code/branches/rocket2/src/SpecialConfig.h.in	(revision 6952)
@@ -0,0 +1,134 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Various constants and options that only affect very little code.
+@note
+    This is merely to avoid recompiling everything when only a path changes.
+@remarks
+    @GENERATED_FILE_COMMENT@
+*/
+
+#ifndef _SpecialConfig_H__
+#define _SpecialConfig_H__
+
+#include "OrxonoxConfig.h"
+#include <boost/preprocessor/stringize.hpp>
+
+/**
+@def CEGUILUA_USE_INTERNAL_LIBRARY
+    Set whether we must suffix "ceguilua/" for the CEGUILua.h include
+*/
+#cmakedefine CEGUILUA_USE_INTERNAL_LIBRARY
+
+/**
+@def DEPENDENCY_PACKAGE_ENABLE
+    Defined if a precompiled depdency package was used. We then copy all libraries
+    too when installing.
+*/
+#cmakedefine DEPENDENCY_PACKAGE_ENABLE
+
+/**
+@def INSTALL_COPYABLE
+    Orxonox either gets installed to the system or just into a folder.
+    The latter uses relative paths.
+*/
+#cmakedefine INSTALL_COPYABLE
+
+/**
+@def CMAKE_CONFIGURATION_TYPES
+    Using MSVC or XCode IDE
+*/
+#cmakedefine CMAKE_CONFIGURATION_TYPES
+
+// Handle default ConfigValues
+namespace orxonox { namespace specialConfig
+{
+    // DEFAULT RELATIVE PATHS (might not be used at all)
+    const char defaultRuntimePath[] = "@DEFAULT_RUNTIME_PATH@";
+    const char defaultLibraryPath[] = "@DEFAULT_LIBRARY_PATH@";
+    const char defaultArchivePath[] = "@DEFAULT_ARCHIVE_PATH@";
+    const char defaultModulePath[]  = "@DEFAULT_MODULE_PATH@";
+    const char defaultDocPath[]     = "@DEFAULT_DOC_PATH@";
+    const char defaultDataPath[]    = "@DEFAULT_DATA_PATH@";
+    const char defaultConfigPath[]  = "@DEFAULT_CONFIG_PATH@";
+    const char defaultLogPath[]     = "@DEFAULT_LOG_PATH@";
+
+#ifndef INSTALL_COPYABLE
+    // INSTALLATION PATHS
+    const char dataInstallDirectory[]       = "@DATA_INSTALL_DIRECTORY@";
+    const char moduleInstallDirectory[]     = "@MODULE_INSTALL_DIRECTORY@";
+#endif
+
+    // DEVELOPMENT RUN PATHS
+    const char dataDevDirectory[]           = "@DATA_DIRECTORY@";
+    const char externalDataDevDirectory[]   = "@EXTERNAL_DATA_DIRECTORY@";
+#ifdef CMAKE_CONFIGURATION_TYPES
+    const char moduleDevDirectory[]         = "@CMAKE_MODULE_OUTPUT_DIRECTORY@/" BOOST_PP_STRINGIZE(CMAKE_BUILD_TYPE);
+    const char configDevDirectory[]         = "@CMAKE_CONFIG_OUTPUT_DIRECTORY@/" BOOST_PP_STRINGIZE(CMAKE_BUILD_TYPE);
+    const char logDevDirectory[]            = "@CMAKE_LOG_OUTPUT_DIRECTORY@/"    BOOST_PP_STRINGIZE(CMAKE_BUILD_TYPE);
+#else
+    const char moduleDevDirectory[]         = "@CMAKE_MODULE_OUTPUT_DIRECTORY@";
+    const char configDevDirectory[]         = "@CMAKE_CONFIG_OUTPUT_DIRECTORY@";
+    const char logDevDirectory[]            = "@CMAKE_LOG_OUTPUT_DIRECTORY@";
+#endif
+
+#ifdef DEPENDENCY_PACKAGE_ENABLE
+    const char dependencyLibraryDirectory[] = "@DEP_LIBRARY_DIR@";
+#endif
+
+    // Module extension
+    const char moduleExtension[] = "@ORXONOX_MODULE_EXTENSION@";
+
+    // OGRE PLUGINS
+#ifdef NDEBUG
+    const char ogrePlugins[] = "@OGRE_PLUGINS_RELEASE@";
+#  ifdef DEPENDENCY_PACKAGE_ENABLE
+    const char ogrePluginsDirectory[] = ".";
+#  else
+    const char ogrePluginsDirectory[] = "@OGRE_PLUGINS_FOLDER_RELEASE@";
+#  endif
+#else
+    const char ogrePlugins[] = "@OGRE_PLUGINS_DEBUG@";
+#  ifdef DEPENDENCY_PACKAGE_ENABLE
+    const char ogrePluginsDirectory[] = ".";
+#  else
+    const char ogrePluginsDirectory[] = "@OGRE_PLUGINS_FOLDER_DEBUG@";
+#  endif
+#endif
+} }
+
+/**
+@def ORXONOX_USE_WINMAIN
+    Use main() or WinMain()?
+*/
+#cmakedefine ORXONOX_USE_WINMAIN
+
+#endif /* _SpecialConfig_H__ */
Index: /code/branches/rocket2/src/external/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,38 @@
+ #
+ #             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.
+ #
+
+################ Sub Directories ################
+
+ADD_SUBDIRECTORY(tolua)
+
+# Include CEGUILua if not requested otherwise
+IF(CEGUILUA_USE_INTERNAL_LIBRARY)
+  IF(NOT IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/ceguilua/ceguilua-${CEGUI_VERSION})
+    MESSAGE(FATAL_ERROR "CEGUILua version not found in src folder. Update list of supported versions in LibraryConfig.cmake!")
+  ENDIF()
+
+  ADD_SUBDIRECTORY(ceguilua)
+  SET(CEGUILUA_LIBRARY ${CEGUILUA_LIBRARY} PARENT_SCOPE)
+ENDIF()
+
+ADD_SUBDIRECTORY(bullet)
+ADD_SUBDIRECTORY(cpptcl)
+ADD_SUBDIRECTORY(ogreceguirenderer)
+ADD_SUBDIRECTORY(ois)
+ADD_SUBDIRECTORY(tinyxml)
Index: /code/branches/rocket2/src/external/bullet/AUTHORS
===================================================================
--- /code/branches/rocket2/src/external/bullet/AUTHORS	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/AUTHORS	(revision 6952)
@@ -0,0 +1,22 @@
+
+Bullet Physics Library is an open source project with help from the community at the Physics Forum
+See the forum at http://bulletphysics.com
+
+The project was started by Erwin Coumans
+
+Following people contributed to Bullet
+(random order, please let us know on the forum if your name should be in this list)
+
+Gino van den Bergen: LinearMath classes
+Christer Ericson: parts of the voronoi simplex solver
+Simon Hobbs: 3d axis sweep and prune, Extras/SATCollision, separating axis theorem + SIMD code
+Dirk Gregorius: generic D6 constraint
+Erin Catto: accumulated impulse in sequential impulse
+Nathanael Presson: EPA penetration depth calculation
+Francisco Leon: GIMPACT Concave Concave collision
+Joerg Henrichs: make buildsystem (work in progress)
+Eric Sunshine: jam + msvcgen buildsystem
+Steve Baker: GPU physics and general implementation improvements
+Jay Lee: Double precision support
+KleMiX, aka Vsevolod Klementjev, managed version, rewritten in C# for XNA
+Erwin Coumans: most other source code
Index: /code/branches/rocket2/src/external/bullet/Bullet-C-Api.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/Bullet-C-Api.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/Bullet-C-Api.h	(revision 6952)
@@ -0,0 +1,175 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+	Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's.
+	Work in progress, functionality will be added on demand.
+
+	If possible, use the richer Bullet C++ API, by including "btBulletDynamicsCommon.h"
+*/
+
+#ifndef BULLET_C_API_H
+#define BULLET_C_API_H
+
+#define PL_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
+
+#ifdef BT_USE_DOUBLE_PRECISION
+typedef double	plReal;
+#else
+typedef float	plReal;
+#endif
+
+typedef plReal	plVector3[3];
+typedef plReal	plQuaternion[4];
+
+#ifdef __cplusplus
+extern "C" { 
+#endif
+
+/**	Particular physics SDK (C-API) */
+	PL_DECLARE_HANDLE(plPhysicsSdkHandle);
+
+/** 	Dynamics world, belonging to some physics SDK (C-API)*/
+	PL_DECLARE_HANDLE(plDynamicsWorldHandle);
+
+/** Rigid Body that can be part of a Dynamics World (C-API)*/	
+	PL_DECLARE_HANDLE(plRigidBodyHandle);
+
+/** 	Collision Shape/Geometry, property of a Rigid Body (C-API)*/
+	PL_DECLARE_HANDLE(plCollisionShapeHandle);
+
+/** Constraint for Rigid Bodies (C-API)*/
+	PL_DECLARE_HANDLE(plConstraintHandle);
+
+/** Triangle Mesh interface (C-API)*/
+	PL_DECLARE_HANDLE(plMeshInterfaceHandle);
+
+/** Broadphase Scene/Proxy Handles (C-API)*/
+	PL_DECLARE_HANDLE(plCollisionBroadphaseHandle);
+	PL_DECLARE_HANDLE(plBroadphaseProxyHandle);
+	PL_DECLARE_HANDLE(plCollisionWorldHandle);
+
+/**
+	Create and Delete a Physics SDK	
+*/
+
+	extern	plPhysicsSdkHandle	plNewBulletSdk(); //this could be also another sdk, like ODE, PhysX etc.
+	extern	void		plDeletePhysicsSdk(plPhysicsSdkHandle	physicsSdk);
+
+/** Collision World, not strictly necessary, you can also just create a Dynamics World with Rigid Bodies which internally manages the Collision World with Collision Objects */
+
+	typedef void(*btBroadphaseCallback)(void* clientData, void* object1,void* object2);
+
+	extern plCollisionBroadphaseHandle	plCreateSapBroadphase(btBroadphaseCallback beginCallback,btBroadphaseCallback endCallback);
+
+	extern void	plDestroyBroadphase(plCollisionBroadphaseHandle bp);
+
+	extern 	plBroadphaseProxyHandle plCreateProxy(plCollisionBroadphaseHandle bp, void* clientData, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ);
+
+	extern void plDestroyProxy(plCollisionBroadphaseHandle bp, plBroadphaseProxyHandle proxyHandle);
+
+	extern void plSetBoundingBox(plBroadphaseProxyHandle proxyHandle, plReal minX,plReal minY,plReal minZ, plReal maxX,plReal maxY, plReal maxZ);
+
+/* todo: add pair cache support with queries like add/remove/find pair */
+	
+	extern plCollisionWorldHandle plCreateCollisionWorld(plPhysicsSdkHandle physicsSdk);
+
+/* todo: add/remove objects */
+	
+
+/* Dynamics World */
+
+	extern  plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdk);
+
+	extern  void           plDeleteDynamicsWorld(plDynamicsWorldHandle world);
+
+	extern	void	plStepSimulation(plDynamicsWorldHandle,	plReal	timeStep);
+
+	extern  void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object);
+
+	extern  void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object);
+
+
+/* Rigid Body  */
+
+	extern  plRigidBodyHandle plCreateRigidBody(	void* user_data,  float mass, plCollisionShapeHandle cshape );
+
+	extern  void plDeleteRigidBody(plRigidBodyHandle body);
+
+
+/* Collision Shape definition */
+
+	extern  plCollisionShapeHandle plNewSphereShape(plReal radius);
+	extern  plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z);
+	extern  plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height);	
+	extern  plCollisionShapeHandle plNewConeShape(plReal radius, plReal height);
+	extern  plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height);
+	extern	plCollisionShapeHandle plNewCompoundShape();
+	extern	void	plAddChildShape(plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn);
+
+	extern  void plDeleteShape(plCollisionShapeHandle shape);
+
+	/* Convex Meshes */
+	extern  plCollisionShapeHandle plNewConvexHullShape();
+	extern  void		plAddVertex(plCollisionShapeHandle convexHull, plReal x,plReal y,plReal z);
+/* Concave static triangle meshes */
+	extern  plMeshInterfaceHandle		   plNewMeshInterface();
+	extern  void		plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2);
+	extern  plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle);
+
+	extern  void plSetScaling(plCollisionShapeHandle shape, plVector3 scaling);
+
+/* SOLID has Response Callback/Table/Management */
+/* PhysX has Triggers, User Callbacks and filtering */
+/* ODE has the typedef void dNearCallback (void *data, dGeomID o1, dGeomID o2); */
+
+/*	typedef void plUpdatedPositionCallback(void* userData, plRigidBodyHandle	rbHandle, plVector3 pos); */
+/*	typedef void plUpdatedOrientationCallback(void* userData, plRigidBodyHandle	rbHandle, plQuaternion orientation); */
+
+	/* get world transform */
+	extern void	plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix);
+	extern void	plGetPosition(plRigidBodyHandle object,plVector3 position);
+	extern void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation);
+
+	/* set world transform (position/orientation) */
+	extern  void plSetPosition(plRigidBodyHandle object, const plVector3 position);
+	extern  void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation);
+	extern	void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient);
+
+	typedef struct plRayCastResult {
+		plRigidBodyHandle		m_body;  
+		plCollisionShapeHandle	m_shape; 		
+		plVector3				m_positionWorld; 		
+		plVector3				m_normalWorld;
+	} plRayCastResult;
+
+	extern  int plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plRayCastResult res);
+
+	/* Sweep API */
+
+	/* extern  plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal); */
+
+	/* Continuous Collision Detection API */
+	
+	// needed for source/blender/blenkernel/intern/collision.c
+	double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3]);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //BULLET_C_API_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.cpp	(revision 6952)
@@ -0,0 +1,37 @@
+
+//Bullet Continuous Collision Detection and Physics Library
+//Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+
+//
+// btAxisSweep3
+//
+// Copyright (c) 2006 Simon Hobbs
+//
+// 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 "btAxisSweep3.h"
+
+
+btAxisSweep3::btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache, bool disableRaycastAccelerator)
+:btAxisSweep3Internal<unsigned short int>(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache,disableRaycastAccelerator)
+{
+	// 1 handle is reserved as sentinel
+	btAssert(maxHandles > 1 && maxHandles < 32767);
+
+}
+
+
+bt32BitAxisSweep3::bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache , bool disableRaycastAccelerator)
+:btAxisSweep3Internal<unsigned int>(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache,disableRaycastAccelerator)
+{
+	// 1 handle is reserved as sentinel
+	btAssert(maxHandles > 1 && maxHandles < 2147483647);
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btAxisSweep3.h	(revision 6952)
@@ -0,0 +1,1024 @@
+//Bullet Continuous Collision Detection and Physics Library
+//Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+//
+// btAxisSweep3.h
+//
+// Copyright (c) 2006 Simon Hobbs
+//
+// 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 AXIS_SWEEP_3_H
+#define AXIS_SWEEP_3_H
+
+#include "LinearMath/btVector3.h"
+#include "btOverlappingPairCache.h"
+#include "btBroadphaseInterface.h"
+#include "btBroadphaseProxy.h"
+#include "btOverlappingPairCallback.h"
+#include "btDbvtBroadphase.h"
+
+//#define DEBUG_BROADPHASE 1
+#define USE_OVERLAP_TEST_ON_REMOVES 1
+
+/// The internal templace class btAxisSweep3Internal implements the sweep and prune broadphase.
+/// It uses quantized integers to represent the begin and end points for each of the 3 axis.
+/// Dont use this class directly, use btAxisSweep3 or bt32BitAxisSweep3 instead.
+template <typename BP_FP_INT_TYPE>
+class btAxisSweep3Internal : public btBroadphaseInterface
+{
+protected:
+
+	BP_FP_INT_TYPE	m_bpHandleMask;
+	BP_FP_INT_TYPE	m_handleSentinel;
+
+public:
+	
+ BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	class Edge
+	{
+	public:
+		BP_FP_INT_TYPE m_pos;			// low bit is min/max
+		BP_FP_INT_TYPE m_handle;
+
+		BP_FP_INT_TYPE IsMax() const {return static_cast<BP_FP_INT_TYPE>(m_pos & 1);}
+	};
+
+public:
+	class	Handle : public btBroadphaseProxy
+	{
+	public:
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+	
+		// indexes into the edge arrays
+		BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3];		// 6 * 2 = 12
+//		BP_FP_INT_TYPE m_uniqueId;
+		btBroadphaseProxy*	m_dbvtProxy;//for faster raycast
+		//void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject
+	
+		SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;}
+		SIMD_FORCE_INLINE BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];}
+	};		// 24 bytes + 24 for Edge structures = 44 bytes total per entry
+
+	
+protected:
+	btVector3 m_worldAabbMin;						// overall system bounds
+	btVector3 m_worldAabbMax;						// overall system bounds
+
+	btVector3 m_quantize;						// scaling factor for quantization
+
+	BP_FP_INT_TYPE m_numHandles;						// number of active handles
+	BP_FP_INT_TYPE m_maxHandles;						// max number of handles
+	Handle* m_pHandles;						// handles pool
+	
+	BP_FP_INT_TYPE m_firstFreeHandle;		// free handles list
+
+	Edge* m_pEdges[3];						// edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries)
+	void* m_pEdgesRawPtr[3];
+
+	btOverlappingPairCache* m_pairCache;
+
+	///btOverlappingPairCallback is an additional optional user callback for adding/removing overlapping pairs, similar interface to btOverlappingPairCache.
+	btOverlappingPairCallback* m_userPairCallback;
+	
+	bool	m_ownsPairCache;
+
+	int	m_invalidPair;
+
+	///additional dynamic aabb structure, used to accelerate ray cast queries.
+	///can be disabled using a optional argument in the constructor
+	btDbvtBroadphase*	m_raycastAccelerator;
+	btOverlappingPairCache*	m_nullPairCache;
+
+
+	// allocation/deallocation
+	BP_FP_INT_TYPE allocHandle();
+	void freeHandle(BP_FP_INT_TYPE handle);
+	
+
+	bool testOverlap2D(const Handle* pHandleA, const Handle* pHandleB,int axis0,int axis1);
+
+#ifdef DEBUG_BROADPHASE
+	void debugPrintAxis(int axis,bool checkCardinality=true);
+#endif //DEBUG_BROADPHASE
+
+	//Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
+	//void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB);
+
+	
+
+	void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
+	void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
+	void sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
+	void sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps );
+
+public:
+
+	btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0,bool disableRaycastAccelerator = false);
+
+	virtual	~btAxisSweep3Internal();
+
+	BP_FP_INT_TYPE getNumHandles() const
+	{
+		return m_numHandles;
+	}
+
+	virtual void	calculateOverlappingPairs(btDispatcher* dispatcher);
+	
+	BP_FP_INT_TYPE addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
+	void removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher);
+	void updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
+	SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;}
+
+	virtual void resetPool(btDispatcher* dispatcher);
+
+	void	processAllOverlappingPairs(btOverlapCallback* callback);
+
+	//Broadphase Interface
+	virtual btBroadphaseProxy*	createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy);
+	virtual void	destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+	virtual void	setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher);
+	virtual void  getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+	
+	virtual void	rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0));
+	
+	void quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const;
+	///unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result
+	void unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+	
+	bool	testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
+
+	btOverlappingPairCache*	getOverlappingPairCache()
+	{
+		return m_pairCache;
+	}
+	const btOverlappingPairCache*	getOverlappingPairCache() const
+	{
+		return m_pairCache;
+	}
+
+	void	setOverlappingPairUserCallback(btOverlappingPairCallback* pairCallback)
+	{
+		m_userPairCallback = pairCallback;
+	}
+	const btOverlappingPairCallback*	getOverlappingPairUserCallback() const
+	{
+		return m_userPairCallback;
+	}
+
+	///getAabb returns the axis aligned bounding box in the 'global' coordinate frame
+	///will add some transform later
+	virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
+	{
+		aabbMin = m_worldAabbMin;
+		aabbMax = m_worldAabbMax;
+	}
+
+	virtual void	printStats()
+	{
+/*		printf("btAxisSweep3.h\n");
+		printf("numHandles = %d, maxHandles = %d\n",m_numHandles,m_maxHandles);
+		printf("aabbMin=%f,%f,%f,aabbMax=%f,%f,%f\n",m_worldAabbMin.getX(),m_worldAabbMin.getY(),m_worldAabbMin.getZ(),
+			m_worldAabbMax.getX(),m_worldAabbMax.getY(),m_worldAabbMax.getZ());
+			*/
+
+	}
+
+};
+
+////////////////////////////////////////////////////////////////////
+
+
+
+
+#ifdef DEBUG_BROADPHASE
+#include <stdio.h>
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3<BP_FP_INT_TYPE>::debugPrintAxis(int axis, bool checkCardinality)
+{
+	int numEdges = m_pHandles[0].m_maxEdges[axis];
+	printf("SAP Axis %d, numEdges=%d\n",axis,numEdges);
+
+	int i;
+	for (i=0;i<numEdges+1;i++)
+	{
+		Edge* pEdge = m_pEdges[axis] + i;
+		Handle* pHandlePrev = getHandle(pEdge->m_handle);
+		int handleIndex = pEdge->IsMax()? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis];
+		char beginOrEnd;
+		beginOrEnd=pEdge->IsMax()?'E':'B';
+		printf("	[%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex);
+	}
+
+	if (checkCardinality)
+		btAssert(numEdges == m_numHandles*2+1);
+}
+#endif //DEBUG_BROADPHASE
+
+template <typename BP_FP_INT_TYPE>
+btBroadphaseProxy*	btAxisSweep3Internal<BP_FP_INT_TYPE>::createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy)
+{
+		(void)shapeType;
+		BP_FP_INT_TYPE handleId = addHandle(aabbMin,aabbMax, userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,multiSapProxy);
+		
+		Handle* handle = getHandle(handleId);
+		
+		if (m_raycastAccelerator)
+		{
+			btBroadphaseProxy* rayProxy = m_raycastAccelerator->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,dispatcher,0);
+			handle->m_dbvtProxy = rayProxy;
+		}
+		return handle;
+}
+
+
+
+template <typename BP_FP_INT_TYPE>
+void	btAxisSweep3Internal<BP_FP_INT_TYPE>::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
+{
+	Handle* handle = static_cast<Handle*>(proxy);
+	if (m_raycastAccelerator)
+		m_raycastAccelerator->destroyProxy(handle->m_dbvtProxy,dispatcher);
+	removeHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), dispatcher);
+}
+
+template <typename BP_FP_INT_TYPE>
+void	btAxisSweep3Internal<BP_FP_INT_TYPE>::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher)
+{
+	Handle* handle = static_cast<Handle*>(proxy);
+	handle->m_aabbMin = aabbMin;
+	handle->m_aabbMax = aabbMax;
+	updateHandle(static_cast<BP_FP_INT_TYPE>(handle->m_uniqueId), aabbMin, aabbMax,dispatcher);
+	if (m_raycastAccelerator)
+		m_raycastAccelerator->setAabb(handle->m_dbvtProxy,aabbMin,aabbMax,dispatcher);
+
+}
+
+template <typename BP_FP_INT_TYPE>
+void	btAxisSweep3Internal<BP_FP_INT_TYPE>::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax)
+{
+	if (m_raycastAccelerator)
+	{
+		m_raycastAccelerator->rayTest(rayFrom,rayTo,rayCallback,aabbMin,aabbMax);
+	} 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())
+			{
+				rayCallback.process(getHandle(m_pEdges[axis][i].m_handle));
+			}
+		}
+	}
+}
+
+
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+	Handle* pHandle = static_cast<Handle*>(proxy);
+	aabbMin = pHandle->m_aabbMin;
+	aabbMax = pHandle->m_aabbMax;
+}
+
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+	Handle* pHandle = static_cast<Handle*>(proxy);
+
+	unsigned short vecInMin[3];
+	unsigned short vecInMax[3];
+
+	vecInMin[0] = m_pEdges[0][pHandle->m_minEdges[0]].m_pos ;
+	vecInMax[0] = m_pEdges[0][pHandle->m_maxEdges[0]].m_pos +1 ;
+	vecInMin[1] = m_pEdges[1][pHandle->m_minEdges[1]].m_pos ;
+	vecInMax[1] = m_pEdges[1][pHandle->m_maxEdges[1]].m_pos +1 ;
+	vecInMin[2] = m_pEdges[2][pHandle->m_minEdges[2]].m_pos ;
+	vecInMax[2] = m_pEdges[2][pHandle->m_maxEdges[2]].m_pos +1 ;
+	
+	aabbMin.setValue((btScalar)(vecInMin[0]) / (m_quantize.getX()),(btScalar)(vecInMin[1]) / (m_quantize.getY()),(btScalar)(vecInMin[2]) / (m_quantize.getZ()));
+	aabbMin += m_worldAabbMin;
+	
+	aabbMax.setValue((btScalar)(vecInMax[0]) / (m_quantize.getX()),(btScalar)(vecInMax[1]) / (m_quantize.getY()),(btScalar)(vecInMax[2]) / (m_quantize.getZ()));
+	aabbMax += m_worldAabbMin;
+}
+
+
+
+
+template <typename BP_FP_INT_TYPE>
+btAxisSweep3Internal<BP_FP_INT_TYPE>::btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache , bool disableRaycastAccelerator)
+:m_bpHandleMask(handleMask),
+m_handleSentinel(handleSentinel),
+m_pairCache(pairCache),
+m_userPairCallback(0),
+m_ownsPairCache(false),
+m_invalidPair(0),
+m_raycastAccelerator(0)
+{
+	BP_FP_INT_TYPE maxHandles = static_cast<BP_FP_INT_TYPE>(userMaxHandles+1);//need to add one sentinel handle
+
+	if (!m_pairCache)
+	{
+		void* ptr = btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16);
+		m_pairCache = new(ptr) btHashedOverlappingPairCache();
+		m_ownsPairCache = true;
+	}
+
+	if (!disableRaycastAccelerator)
+	{
+		m_nullPairCache = new (btAlignedAlloc(sizeof(btNullPairCache),16)) btNullPairCache();
+		m_raycastAccelerator = new (btAlignedAlloc(sizeof(btDbvtBroadphase),16)) btDbvtBroadphase(m_nullPairCache);//m_pairCache);
+		m_raycastAccelerator->m_deferedcollide = true;//don't add/remove pairs
+	}
+
+	//btAssert(bounds.HasVolume());
+
+	// init bounds
+	m_worldAabbMin = worldAabbMin;
+	m_worldAabbMax = worldAabbMax;
+
+	btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin;
+
+	BP_FP_INT_TYPE	maxInt = m_handleSentinel;
+
+	m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize;
+
+	// allocate handles buffer, using btAlignedAlloc, and put all handles on free list
+	m_pHandles = new Handle[maxHandles];
+	
+	m_maxHandles = maxHandles;
+	m_numHandles = 0;
+
+	// handle 0 is reserved as the null index, and is also used as the sentinel
+	m_firstFreeHandle = 1;
+	{
+		for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < maxHandles; i++)
+			m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1));
+		m_pHandles[maxHandles - 1].SetNextFree(0);
+	}
+
+	{
+		// allocate edge buffers
+		for (int i = 0; i < 3; i++)
+		{
+			m_pEdgesRawPtr[i] = btAlignedAlloc(sizeof(Edge)*maxHandles*2,16);
+			m_pEdges[i] = new(m_pEdgesRawPtr[i]) Edge[maxHandles * 2];
+		}
+	}
+	//removed overlap management
+
+	// make boundary sentinels
+	
+	m_pHandles[0].m_clientObject = 0;
+
+	for (int axis = 0; axis < 3; axis++)
+	{
+		m_pHandles[0].m_minEdges[axis] = 0;
+		m_pHandles[0].m_maxEdges[axis] = 1;
+
+		m_pEdges[axis][0].m_pos = 0;
+		m_pEdges[axis][0].m_handle = 0;
+		m_pEdges[axis][1].m_pos = m_handleSentinel;
+		m_pEdges[axis][1].m_handle = 0;
+#ifdef DEBUG_BROADPHASE
+		debugPrintAxis(axis);
+#endif //DEBUG_BROADPHASE
+
+	}
+
+}
+
+template <typename BP_FP_INT_TYPE>
+btAxisSweep3Internal<BP_FP_INT_TYPE>::~btAxisSweep3Internal()
+{
+	if (m_raycastAccelerator)
+	{
+		m_nullPairCache->~btOverlappingPairCache();
+		btAlignedFree(m_nullPairCache);
+		m_raycastAccelerator->~btDbvtBroadphase();
+		btAlignedFree (m_raycastAccelerator);
+	}
+
+	for (int i = 2; i >= 0; i--)
+	{
+		btAlignedFree(m_pEdgesRawPtr[i]);
+	}
+	delete [] m_pHandles;
+
+	if (m_ownsPairCache)
+	{
+		m_pairCache->~btOverlappingPairCache();
+		btAlignedFree(m_pairCache);
+	}
+}
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const
+{
+#ifdef OLD_CLAMPING_METHOD
+	///problem with this clamping method is that the floating point during quantization might still go outside the range [(0|isMax) .. (m_handleSentinel&m_bpHandleMask]|isMax]
+	///see http://code.google.com/p/bullet/issues/detail?id=87
+	btVector3 clampedPoint(point);
+	clampedPoint.setMax(m_worldAabbMin);
+	clampedPoint.setMin(m_worldAabbMax);
+	btVector3 v = (clampedPoint - m_worldAabbMin) * m_quantize;
+	out[0] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getX() & m_bpHandleMask) | isMax);
+	out[1] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getY() & m_bpHandleMask) | isMax);
+	out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & m_bpHandleMask) | isMax);
+#else
+	btVector3 v = (point - m_worldAabbMin) * m_quantize;
+	out[0]=(v[0]<=0)?(BP_FP_INT_TYPE)isMax:(v[0]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[0]&m_bpHandleMask)|isMax);
+	out[1]=(v[1]<=0)?(BP_FP_INT_TYPE)isMax:(v[1]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[1]&m_bpHandleMask)|isMax);
+	out[2]=(v[2]<=0)?(BP_FP_INT_TYPE)isMax:(v[2]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[2]&m_bpHandleMask)|isMax);
+#endif //OLD_CLAMPING_METHOD
+}
+
+
+template <typename BP_FP_INT_TYPE>
+BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::allocHandle()
+{
+	btAssert(m_firstFreeHandle);
+
+	BP_FP_INT_TYPE handle = m_firstFreeHandle;
+	m_firstFreeHandle = getHandle(handle)->GetNextFree();
+	m_numHandles++;
+
+	return handle;
+}
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::freeHandle(BP_FP_INT_TYPE handle)
+{
+	btAssert(handle > 0 && handle < m_maxHandles);
+
+	getHandle(handle)->SetNextFree(m_firstFreeHandle);
+	m_firstFreeHandle = handle;
+
+	m_numHandles--;
+}
+
+
+template <typename BP_FP_INT_TYPE>
+BP_FP_INT_TYPE btAxisSweep3Internal<BP_FP_INT_TYPE>::addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner,short int collisionFilterGroup,short int collisionFilterMask,btDispatcher* dispatcher,void* multiSapProxy)
+{
+	// quantize the bounds
+	BP_FP_INT_TYPE min[3], max[3];
+	quantize(min, aabbMin, 0);
+	quantize(max, aabbMax, 1);
+
+	// allocate a handle
+	BP_FP_INT_TYPE handle = allocHandle();
+	
+
+	Handle* pHandle = getHandle(handle);
+	
+	pHandle->m_uniqueId = static_cast<int>(handle);
+	//pHandle->m_pOverlaps = 0;
+	pHandle->m_clientObject = pOwner;
+	pHandle->m_collisionFilterGroup = collisionFilterGroup;
+	pHandle->m_collisionFilterMask = collisionFilterMask;
+	pHandle->m_multiSapParentProxy = multiSapProxy;
+
+	// compute current limit of edge arrays
+	BP_FP_INT_TYPE limit = static_cast<BP_FP_INT_TYPE>(m_numHandles * 2);
+
+	
+	// insert new edges just inside the max boundary edge
+	for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++)
+	{
+
+		m_pHandles[0].m_maxEdges[axis] += 2;
+
+		m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1];
+
+		m_pEdges[axis][limit - 1].m_pos = min[axis];
+		m_pEdges[axis][limit - 1].m_handle = handle;
+
+		m_pEdges[axis][limit].m_pos = max[axis];
+		m_pEdges[axis][limit].m_handle = handle;
+
+		pHandle->m_minEdges[axis] = static_cast<BP_FP_INT_TYPE>(limit - 1);
+		pHandle->m_maxEdges[axis] = limit;
+	}
+
+	// now sort the new edges to their correct position
+	sortMinDown(0, pHandle->m_minEdges[0], dispatcher,false);
+	sortMaxDown(0, pHandle->m_maxEdges[0], dispatcher,false);
+	sortMinDown(1, pHandle->m_minEdges[1], dispatcher,false);
+	sortMaxDown(1, pHandle->m_maxEdges[1], dispatcher,false);
+	sortMinDown(2, pHandle->m_minEdges[2], dispatcher,true);
+	sortMaxDown(2, pHandle->m_maxEdges[2], dispatcher,true);
+
+
+	return handle;
+}
+
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher)
+{
+
+	Handle* pHandle = getHandle(handle);
+
+	//explicitly remove the pairs containing the proxy
+	//we could do it also in the sortMinUp (passing true)
+	///@todo: compare performance
+	if (!m_pairCache->hasDeferredRemoval())
+	{
+		m_pairCache->removeOverlappingPairsContainingProxy(pHandle,dispatcher);
+	}
+
+	// compute current limit of edge arrays
+	int limit = static_cast<int>(m_numHandles * 2);
+	
+	int axis;
+
+	for (axis = 0;axis<3;axis++)
+	{
+		m_pHandles[0].m_maxEdges[axis] -= 2;
+	}
+
+	// remove the edges by sorting them up to the end of the list
+	for ( axis = 0; axis < 3; axis++)
+	{
+		Edge* pEdges = m_pEdges[axis];
+		BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis];
+		pEdges[max].m_pos = m_handleSentinel;
+
+		sortMaxUp(axis,max,dispatcher,false);
+
+
+		BP_FP_INT_TYPE i = pHandle->m_minEdges[axis];
+		pEdges[i].m_pos = m_handleSentinel;
+
+
+		sortMinUp(axis,i,dispatcher,false);
+
+		pEdges[limit-1].m_handle = 0;
+		pEdges[limit-1].m_pos = m_handleSentinel;
+		
+#ifdef DEBUG_BROADPHASE
+			debugPrintAxis(axis,false);
+#endif //DEBUG_BROADPHASE
+
+
+	}
+
+
+	// free the handle
+	freeHandle(handle);
+
+	
+}
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::resetPool(btDispatcher* dispatcher)
+{
+	if (m_numHandles == 0)
+	{
+		m_firstFreeHandle = 1;
+		{
+			for (BP_FP_INT_TYPE i = m_firstFreeHandle; i < m_maxHandles; i++)
+				m_pHandles[i].SetNextFree(static_cast<BP_FP_INT_TYPE>(i + 1));
+			m_pHandles[m_maxHandles - 1].SetNextFree(0);
+		}
+	}
+}       
+
+
+extern int gOverlappingPairs;
+//#include <stdio.h>
+
+template <typename BP_FP_INT_TYPE>
+void	btAxisSweep3Internal<BP_FP_INT_TYPE>::calculateOverlappingPairs(btDispatcher* dispatcher)
+{
+
+	if (m_pairCache->hasDeferredRemoval())
+	{
+	
+		btBroadphasePairArray&	overlappingPairArray = m_pairCache->getOverlappingPairArray();
+
+		//perform a sort, to find duplicates and to sort 'invalid' pairs to the end
+		overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
+
+		overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
+		m_invalidPair = 0;
+
+		
+		int i;
+
+		btBroadphasePair previousPair;
+		previousPair.m_pProxy0 = 0;
+		previousPair.m_pProxy1 = 0;
+		previousPair.m_algorithm = 0;
+		
+		
+		for (i=0;i<overlappingPairArray.size();i++)
+		{
+		
+			btBroadphasePair& pair = overlappingPairArray[i];
+
+			bool isDuplicate = (pair == previousPair);
+
+			previousPair = pair;
+
+			bool needsRemoval = false;
+
+			if (!isDuplicate)
+			{
+				///important to use an AABB test that is consistent with the broadphase
+				bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
+
+				if (hasOverlap)
+				{
+					needsRemoval = false;//callback->processOverlap(pair);
+				} else
+				{
+					needsRemoval = true;
+				}
+			} else
+			{
+				//remove duplicate
+				needsRemoval = true;
+				//should have no algorithm
+				btAssert(!pair.m_algorithm);
+			}
+			
+			if (needsRemoval)
+			{
+				m_pairCache->cleanOverlappingPair(pair,dispatcher);
+
+		//		m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
+		//		m_overlappingPairArray.pop_back();
+				pair.m_pProxy0 = 0;
+				pair.m_pProxy1 = 0;
+				m_invalidPair++;
+				gOverlappingPairs--;
+			} 
+			
+		}
+
+	///if you don't like to skip the invalid pairs in the array, execute following code:
+	#define CLEAN_INVALID_PAIRS 1
+	#ifdef CLEAN_INVALID_PAIRS
+
+		//perform a sort, to sort 'invalid' pairs to the end
+		overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
+
+		overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
+		m_invalidPair = 0;
+	#endif//CLEAN_INVALID_PAIRS
+		
+		//printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size());
+	}
+
+}
+
+
+template <typename BP_FP_INT_TYPE>
+bool btAxisSweep3Internal<BP_FP_INT_TYPE>::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+{
+	const Handle* pHandleA = static_cast<Handle*>(proxy0);
+	const Handle* pHandleB = static_cast<Handle*>(proxy1);
+	
+	//optimization 1: check the array index (memory address), instead of the m_pos
+
+	for (int axis = 0; axis < 3; axis++)
+	{ 
+		if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || 
+			pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) 
+		{ 
+			return false; 
+		} 
+	} 
+	return true;
+}
+
+template <typename BP_FP_INT_TYPE>
+bool btAxisSweep3Internal<BP_FP_INT_TYPE>::testOverlap2D(const Handle* pHandleA, const Handle* pHandleB,int axis0,int axis1)
+{
+	//optimization 1: check the array index (memory address), instead of the m_pos
+
+	if (pHandleA->m_maxEdges[axis0] < pHandleB->m_minEdges[axis0] || 
+		pHandleB->m_maxEdges[axis0] < pHandleA->m_minEdges[axis0] ||
+		pHandleA->m_maxEdges[axis1] < pHandleB->m_minEdges[axis1] ||
+		pHandleB->m_maxEdges[axis1] < pHandleA->m_minEdges[axis1]) 
+	{ 
+		return false; 
+	} 
+	return true;
+}
+
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher)
+{
+//	btAssert(bounds.IsFinite());
+	//btAssert(bounds.HasVolume());
+
+	Handle* pHandle = getHandle(handle);
+
+	// quantize the new bounds
+	BP_FP_INT_TYPE min[3], max[3];
+	quantize(min, aabbMin, 0);
+	quantize(max, aabbMax, 1);
+
+	// update changed edges
+	for (int axis = 0; axis < 3; axis++)
+	{
+		BP_FP_INT_TYPE emin = pHandle->m_minEdges[axis];
+		BP_FP_INT_TYPE emax = pHandle->m_maxEdges[axis];
+
+		int dmin = (int)min[axis] - (int)m_pEdges[axis][emin].m_pos;
+		int dmax = (int)max[axis] - (int)m_pEdges[axis][emax].m_pos;
+
+		m_pEdges[axis][emin].m_pos = min[axis];
+		m_pEdges[axis][emax].m_pos = max[axis];
+
+		// expand (only adds overlaps)
+		if (dmin < 0)
+			sortMinDown(axis, emin,dispatcher,true);
+
+		if (dmax > 0)
+			sortMaxUp(axis, emax,dispatcher,true);
+
+		// shrink (only removes overlaps)
+		if (dmin > 0)
+			sortMinUp(axis, emin,dispatcher,true);
+
+		if (dmax < 0)
+			sortMaxDown(axis, emax,dispatcher,true);
+
+#ifdef DEBUG_BROADPHASE
+	debugPrintAxis(axis);
+#endif //DEBUG_BROADPHASE
+	}
+
+	
+}
+
+
+
+
+// sorting a min edge downwards can only ever *add* overlaps
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* /* dispatcher */, bool updateOverlaps)
+{
+
+	Edge* pEdge = m_pEdges[axis] + edge;
+	Edge* pPrev = pEdge - 1;
+	Handle* pHandleEdge = getHandle(pEdge->m_handle);
+
+	while (pEdge->m_pos < pPrev->m_pos)
+	{
+		Handle* pHandlePrev = getHandle(pPrev->m_handle);
+
+		if (pPrev->IsMax())
+		{
+			// if previous edge is a maximum check the bounds and add an overlap if necessary
+			const int axis1 = (1  << axis) & 3;
+			const int axis2 = (1  << axis1) & 3;
+			if (updateOverlaps && testOverlap2D(pHandleEdge, pHandlePrev,axis1,axis2))
+			{
+				m_pairCache->addOverlappingPair(pHandleEdge,pHandlePrev);
+				if (m_userPairCallback)
+					m_userPairCallback->addOverlappingPair(pHandleEdge,pHandlePrev);
+
+				//AddOverlap(pEdge->m_handle, pPrev->m_handle);
+
+			}
+
+			// update edge reference in other handle
+			pHandlePrev->m_maxEdges[axis]++;
+		}
+		else
+			pHandlePrev->m_minEdges[axis]++;
+
+		pHandleEdge->m_minEdges[axis]--;
+
+		// swap the edges
+		Edge swap = *pEdge;
+		*pEdge = *pPrev;
+		*pPrev = swap;
+
+		// decrement
+		pEdge--;
+		pPrev--;
+	}
+
+#ifdef DEBUG_BROADPHASE
+	debugPrintAxis(axis);
+#endif //DEBUG_BROADPHASE
+
+}
+
+// sorting a min edge upwards can only ever *remove* overlaps
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps)
+{
+	Edge* pEdge = m_pEdges[axis] + edge;
+	Edge* pNext = pEdge + 1;
+	Handle* pHandleEdge = getHandle(pEdge->m_handle);
+
+	while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
+	{
+		Handle* pHandleNext = getHandle(pNext->m_handle);
+
+		if (pNext->IsMax())
+		{
+			Handle* handle0 = getHandle(pEdge->m_handle);
+			Handle* handle1 = getHandle(pNext->m_handle);
+			const int axis1 = (1  << axis) & 3;
+			const int axis2 = (1  << axis1) & 3;
+			
+			// if next edge is maximum remove any overlap between the two handles
+			if (updateOverlaps 
+#ifdef USE_OVERLAP_TEST_ON_REMOVES
+				&& testOverlap2D(handle0,handle1,axis1,axis2)
+#endif //USE_OVERLAP_TEST_ON_REMOVES
+				)
+			{
+				
+
+				m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher);	
+				if (m_userPairCallback)
+					m_userPairCallback->removeOverlappingPair(handle0,handle1,dispatcher);
+				
+			}
+
+
+			// update edge reference in other handle
+			pHandleNext->m_maxEdges[axis]--;
+		}
+		else
+			pHandleNext->m_minEdges[axis]--;
+
+		pHandleEdge->m_minEdges[axis]++;
+
+		// swap the edges
+		Edge swap = *pEdge;
+		*pEdge = *pNext;
+		*pNext = swap;
+
+		// increment
+		pEdge++;
+		pNext++;
+	}
+
+
+}
+
+// sorting a max edge downwards can only ever *remove* overlaps
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps)
+{
+
+	Edge* pEdge = m_pEdges[axis] + edge;
+	Edge* pPrev = pEdge - 1;
+	Handle* pHandleEdge = getHandle(pEdge->m_handle);
+
+	while (pEdge->m_pos < pPrev->m_pos)
+	{
+		Handle* pHandlePrev = getHandle(pPrev->m_handle);
+
+		if (!pPrev->IsMax())
+		{
+			// if previous edge was a minimum remove any overlap between the two handles
+			Handle* handle0 = getHandle(pEdge->m_handle);
+			Handle* handle1 = getHandle(pPrev->m_handle);
+			const int axis1 = (1  << axis) & 3;
+			const int axis2 = (1  << axis1) & 3;
+
+			if (updateOverlaps  
+#ifdef USE_OVERLAP_TEST_ON_REMOVES
+				&& testOverlap2D(handle0,handle1,axis1,axis2)
+#endif //USE_OVERLAP_TEST_ON_REMOVES
+				)
+			{
+				//this is done during the overlappingpairarray iteration/narrowphase collision
+
+				
+				m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher);
+				if (m_userPairCallback)
+					m_userPairCallback->removeOverlappingPair(handle0,handle1,dispatcher);
+			
+
+
+			}
+
+			// update edge reference in other handle
+			pHandlePrev->m_minEdges[axis]++;;
+		}
+		else
+			pHandlePrev->m_maxEdges[axis]++;
+
+		pHandleEdge->m_maxEdges[axis]--;
+
+		// swap the edges
+		Edge swap = *pEdge;
+		*pEdge = *pPrev;
+		*pPrev = swap;
+
+		// decrement
+		pEdge--;
+		pPrev--;
+	}
+
+	
+#ifdef DEBUG_BROADPHASE
+	debugPrintAxis(axis);
+#endif //DEBUG_BROADPHASE
+
+}
+
+// sorting a max edge upwards can only ever *add* overlaps
+template <typename BP_FP_INT_TYPE>
+void btAxisSweep3Internal<BP_FP_INT_TYPE>::sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* /* dispatcher */, bool updateOverlaps)
+{
+	Edge* pEdge = m_pEdges[axis] + edge;
+	Edge* pNext = pEdge + 1;
+	Handle* pHandleEdge = getHandle(pEdge->m_handle);
+
+	while (pNext->m_handle && (pEdge->m_pos >= pNext->m_pos))
+	{
+		Handle* pHandleNext = getHandle(pNext->m_handle);
+
+		const int axis1 = (1  << axis) & 3;
+		const int axis2 = (1  << axis1) & 3;
+
+		if (!pNext->IsMax())
+		{
+			// if next edge is a minimum check the bounds and add an overlap if necessary
+			if (updateOverlaps && testOverlap2D(pHandleEdge, pHandleNext,axis1,axis2))
+			{
+				Handle* handle0 = getHandle(pEdge->m_handle);
+				Handle* handle1 = getHandle(pNext->m_handle);
+				m_pairCache->addOverlappingPair(handle0,handle1);
+				if (m_userPairCallback)
+					m_userPairCallback->addOverlappingPair(handle0,handle1);
+			}
+
+			// update edge reference in other handle
+			pHandleNext->m_minEdges[axis]--;
+		}
+		else
+			pHandleNext->m_maxEdges[axis]--;
+
+		pHandleEdge->m_maxEdges[axis]++;
+
+		// swap the edges
+		Edge swap = *pEdge;
+		*pEdge = *pNext;
+		*pNext = swap;
+
+		// increment
+		pEdge++;
+		pNext++;
+	}
+	
+}
+
+
+
+////////////////////////////////////////////////////////////////////
+
+
+/// The btAxisSweep3 is an efficient implementation of the 3d axis sweep and prune broadphase.
+/// It uses arrays rather then lists for storage of the 3 axis. Also it operates using 16 bit integer coordinates instead of floats.
+/// For large worlds and many objects, use bt32BitAxisSweep3 or btDbvtBroadphase instead. bt32BitAxisSweep3 has higher precision and allows more then 16384 objects at the cost of more memory and bit of performance.
+class btAxisSweep3 : public btAxisSweep3Internal<unsigned short int>
+{
+public:
+
+	btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false);
+
+};
+
+/// The bt32BitAxisSweep3 allows higher precision quantization and more objects compared to the btAxisSweep3 sweep and prune.
+/// This comes at the cost of more memory per handle, and a bit slower performance.
+/// It uses arrays rather then lists for storage of the 3 axis.
+class bt32BitAxisSweep3 : public btAxisSweep3Internal<unsigned int>
+{
+public:
+
+	bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false);
+
+};
+
+#endif
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h	(revision 6952)
@@ -0,0 +1,74 @@
+/*
+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		BROADPHASE_INTERFACE_H
+#define 	BROADPHASE_INTERFACE_H
+
+
+
+struct btDispatcherInfo;
+class btDispatcher;
+#include "btBroadphaseProxy.h"
+
+class btOverlappingPairCache;
+
+
+
+struct	btBroadphaseRayCallback
+{
+	///added some cached data to accelerate ray-AABB tests
+	btVector3		m_rayDirectionInverse;
+	unsigned int	m_signs[3];
+	btScalar		m_lambda_max;
+
+	virtual ~btBroadphaseRayCallback() {}
+	virtual bool	process(const btBroadphaseProxy* proxy) = 0;
+};
+
+#include "LinearMath/btVector3.h"
+
+///The btBroadphaseInterface class provides an interface to detect aabb-overlapping object pairs.
+///Some implementations for this broadphase interface include btAxisSweep3, bt32BitAxisSweep3 and btDbvtBroadphase.
+///The actual overlapping pair management, storage, adding and removing of pairs is dealt by the btOverlappingPairCache class.
+class btBroadphaseInterface
+{
+public:
+	virtual ~btBroadphaseInterface() {}
+
+	virtual btBroadphaseProxy*	createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy) =0;
+	virtual void	destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0;
+	virtual void	setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0;
+	virtual void	getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const =0;
+
+	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;
+
+	///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
+	virtual void	calculateOverlappingPairs(btDispatcher* dispatcher)=0;
+
+	virtual	btOverlappingPairCache*	getOverlappingPairCache()=0;
+	virtual	const btOverlappingPairCache*	getOverlappingPairCache() const =0;
+
+	///getAabb returns the axis aligned bounding box in the 'global' coordinate frame
+	///will add some transform later
+	virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const =0;
+
+	///reset broadphase internal structures, to ensure determinism/reproducability
+	virtual void resetPool(btDispatcher* dispatcher) {};
+
+	virtual void	printStats() = 0;
+
+};
+
+#endif //BROADPHASE_INTERFACE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp	(revision 6952)
@@ -0,0 +1,17 @@
+/*
+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 "btBroadphaseProxy.h"
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h	(revision 6952)
@@ -0,0 +1,251 @@
+/*
+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 BROADPHASE_PROXY_H
+#define BROADPHASE_PROXY_H
+
+#include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btAlignedAllocator.h"
+
+
+/// btDispatcher uses these types
+/// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave
+/// to facilitate type checking
+/// CUSTOM_POLYHEDRAL_SHAPE_TYPE,CUSTOM_CONVEX_SHAPE_TYPE and CUSTOM_CONCAVE_SHAPE_TYPE can be used to extend Bullet without modifying source code
+enum BroadphaseNativeTypes
+{
+	// polyhedral convex shapes
+	BOX_SHAPE_PROXYTYPE,
+	TRIANGLE_SHAPE_PROXYTYPE,
+	TETRAHEDRAL_SHAPE_PROXYTYPE,
+	CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE,
+	CONVEX_HULL_SHAPE_PROXYTYPE,
+	CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE,
+	CUSTOM_POLYHEDRAL_SHAPE_TYPE,
+//implicit convex shapes
+IMPLICIT_CONVEX_SHAPES_START_HERE,
+	SPHERE_SHAPE_PROXYTYPE,
+	MULTI_SPHERE_SHAPE_PROXYTYPE,
+	CAPSULE_SHAPE_PROXYTYPE,
+	CONE_SHAPE_PROXYTYPE,
+	CONVEX_SHAPE_PROXYTYPE,
+	CYLINDER_SHAPE_PROXYTYPE,
+	UNIFORM_SCALING_SHAPE_PROXYTYPE,
+	MINKOWSKI_SUM_SHAPE_PROXYTYPE,
+	MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE,
+	CUSTOM_CONVEX_SHAPE_TYPE,
+//concave shapes
+CONCAVE_SHAPES_START_HERE,
+	//keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
+	TRIANGLE_MESH_SHAPE_PROXYTYPE,
+	SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE,
+	///used for demo integration FAST/Swift collision library and Bullet
+	FAST_CONCAVE_MESH_PROXYTYPE,
+	//terrain
+	TERRAIN_SHAPE_PROXYTYPE,
+///Used for GIMPACT Trimesh integration
+	GIMPACT_SHAPE_PROXYTYPE,
+///Multimaterial mesh
+    MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE,
+	
+	EMPTY_SHAPE_PROXYTYPE,
+	STATIC_PLANE_PROXYTYPE,
+	CUSTOM_CONCAVE_SHAPE_TYPE,
+CONCAVE_SHAPES_END_HERE,
+
+	COMPOUND_SHAPE_PROXYTYPE,
+
+	SOFTBODY_SHAPE_PROXYTYPE,
+	HFFLUID_SHAPE_PROXYTYPE,
+	HFFLUID_BUOYANT_CONVEX_SHAPE_PROXYTYPE,
+	INVALID_SHAPE_PROXYTYPE,
+
+	MAX_BROADPHASE_COLLISION_TYPES
+	
+};
+
+
+///The btBroadphaseProxy is the main class that can be used with the Bullet broadphases. 
+///It stores collision shape type information, collision filter information and a client object, typically a btCollisionObject or btRigidBody.
+ATTRIBUTE_ALIGNED16(struct) btBroadphaseProxy
+{
+
+BT_DECLARE_ALIGNED_ALLOCATOR();
+	
+	///optional filtering to cull potential collisions
+	enum CollisionFilterGroups
+	{
+	        DefaultFilter = 1,
+	        StaticFilter = 2,
+	        KinematicFilter = 4,
+	        DebrisFilter = 8,
+			SensorTrigger = 16,
+			CharacterFilter = 32,
+	        AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger
+	};
+
+	//Usually the client btCollisionObject or Rigidbody class
+	void*	m_clientObject;
+	short int m_collisionFilterGroup;
+	short int m_collisionFilterMask;
+	void*	m_multiSapParentProxy;		
+	int			m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc.
+
+	btVector3	m_aabbMin;
+	btVector3	m_aabbMax;
+
+	SIMD_FORCE_INLINE int getUid() const
+	{
+		return m_uniqueId;
+	}
+
+	//used for memory pools
+	btBroadphaseProxy() :m_clientObject(0),m_multiSapParentProxy(0)
+	{
+	}
+
+	btBroadphaseProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask,void* multiSapParentProxy=0)
+		:m_clientObject(userPtr),
+		m_collisionFilterGroup(collisionFilterGroup),
+		m_collisionFilterMask(collisionFilterMask),
+		m_aabbMin(aabbMin),
+		m_aabbMax(aabbMax)
+	{
+		m_multiSapParentProxy = multiSapParentProxy;
+	}
+
+	
+
+	static SIMD_FORCE_INLINE bool isPolyhedral(int proxyType)
+	{
+		return (proxyType  < IMPLICIT_CONVEX_SHAPES_START_HERE);
+	}
+
+	static SIMD_FORCE_INLINE bool	isConvex(int proxyType)
+	{
+		return (proxyType < CONCAVE_SHAPES_START_HERE);
+	}
+
+	static SIMD_FORCE_INLINE bool	isConcave(int proxyType)
+	{
+		return ((proxyType > CONCAVE_SHAPES_START_HERE) &&
+			(proxyType < CONCAVE_SHAPES_END_HERE));
+	}
+	static SIMD_FORCE_INLINE bool	isCompound(int proxyType)
+	{
+		return (proxyType == COMPOUND_SHAPE_PROXYTYPE);
+	}
+	static SIMD_FORCE_INLINE bool isInfinite(int proxyType)
+	{
+		return (proxyType == STATIC_PLANE_PROXYTYPE);
+	}
+	
+}
+;
+
+class btCollisionAlgorithm;
+
+struct btBroadphaseProxy;
+
+
+
+///The btBroadphasePair class contains a pair of aabb-overlapping objects.
+///A btDispatcher can search a btCollisionAlgorithm that performs exact/narrowphase collision detection on the actual collision shapes.
+ATTRIBUTE_ALIGNED16(struct) btBroadphasePair
+{
+	btBroadphasePair ()
+		:
+	m_pProxy0(0),
+		m_pProxy1(0),
+		m_algorithm(0),
+		m_internalInfo1(0)
+	{
+	}
+
+BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	btBroadphasePair(const btBroadphasePair& other)
+		:		m_pProxy0(other.m_pProxy0),
+				m_pProxy1(other.m_pProxy1),
+				m_algorithm(other.m_algorithm),
+				m_internalInfo1(other.m_internalInfo1)
+	{
+	}
+	btBroadphasePair(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1)
+	{
+
+		//keep them sorted, so the std::set operations work
+		if (proxy0.m_uniqueId < proxy1.m_uniqueId)
+        { 
+            m_pProxy0 = &proxy0; 
+            m_pProxy1 = &proxy1; 
+        }
+        else 
+        { 
+			m_pProxy0 = &proxy1; 
+            m_pProxy1 = &proxy0; 
+        }
+
+		m_algorithm = 0;
+		m_internalInfo1 = 0;
+
+	}
+	
+	btBroadphaseProxy* m_pProxy0;
+	btBroadphaseProxy* m_pProxy1;
+	
+	mutable btCollisionAlgorithm* m_algorithm;
+	union { void* m_internalInfo1; int m_internalTmpValue;};//don't use this data, it will be removed in future version.
+
+};
+
+/*
+//comparison for set operation, see Solid DT_Encounter
+SIMD_FORCE_INLINE bool operator<(const btBroadphasePair& a, const btBroadphasePair& b) 
+{ 
+    return a.m_pProxy0 < b.m_pProxy0 || 
+        (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 < b.m_pProxy1); 
+}
+*/
+
+
+
+class btBroadphasePairSortPredicate
+{
+	public:
+
+		bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b )
+		{
+			const int uidA0 = a.m_pProxy0 ? a.m_pProxy0->m_uniqueId : -1;
+			const int uidB0 = b.m_pProxy0 ? b.m_pProxy0->m_uniqueId : -1;
+			const int uidA1 = a.m_pProxy1 ? a.m_pProxy1->m_uniqueId : -1;
+			const int uidB1 = b.m_pProxy1 ? b.m_pProxy1->m_uniqueId : -1;
+
+			 return uidA0 > uidB0 || 
+				(a.m_pProxy0 == b.m_pProxy0 && uidA1 > uidB1) ||
+				(a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm); 
+		}
+};
+
+
+SIMD_FORCE_INLINE bool operator==(const btBroadphasePair& a, const btBroadphasePair& b) 
+{
+	 return (a.m_pProxy0 == b.m_pProxy0) && (a.m_pProxy1 == b.m_pProxy1);
+}
+
+
+#endif //BROADPHASE_PROXY_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp	(revision 6952)
@@ -0,0 +1,23 @@
+/*
+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 "btCollisionAlgorithm.h"
+#include "btDispatcher.h"
+
+btCollisionAlgorithm::btCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
+{
+	m_dispatcher = ci.m_dispatcher1;
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h	(revision 6952)
@@ -0,0 +1,80 @@
+/*
+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 COLLISION_ALGORITHM_H
+#define COLLISION_ALGORITHM_H
+
+#include "LinearMath/btScalar.h"
+#include "LinearMath/btAlignedObjectArray.h"
+
+struct btBroadphaseProxy;
+class btDispatcher;
+class btManifoldResult;
+class btCollisionObject;
+struct btDispatcherInfo;
+class	btPersistentManifold;
+
+typedef btAlignedObjectArray<btPersistentManifold*>	btManifoldArray;
+
+struct btCollisionAlgorithmConstructionInfo
+{
+	btCollisionAlgorithmConstructionInfo()
+		:m_dispatcher1(0),
+		m_manifold(0)
+	{
+	}
+	btCollisionAlgorithmConstructionInfo(btDispatcher* dispatcher,int temp)
+		:m_dispatcher1(dispatcher)
+	{
+		(void)temp;
+	}
+
+	btDispatcher*	m_dispatcher1;
+	btPersistentManifold*	m_manifold;
+
+	int	getDispatcherId();
+
+};
+
+
+///btCollisionAlgorithm is an collision interface that is compatible with the Broadphase and btDispatcher.
+///It is persistent over frames
+class btCollisionAlgorithm
+{
+
+protected:
+
+	btDispatcher*	m_dispatcher;
+
+protected:
+	int	getDispatcherId();
+	
+public:
+
+	btCollisionAlgorithm() {};
+
+	btCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci);
+
+	virtual ~btCollisionAlgorithm() {};
+
+	virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
+
+	virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0;
+
+	virtual	void	getAllContactManifolds(btManifoldArray&	manifoldArray) = 0;
+};
+
+
+#endif //COLLISION_ALGORITHM_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp	(revision 6952)
@@ -0,0 +1,1295 @@
+/*
+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.
+*/
+///btDbvt implementation by Nathanael Presson
+
+#include "btDbvt.h"
+
+//
+typedef btAlignedObjectArray<btDbvtNode*>			tNodeArray;
+typedef btAlignedObjectArray<const btDbvtNode*>	tConstNodeArray;
+
+//
+struct btDbvtNodeEnumerator : btDbvt::ICollide
+{
+	tConstNodeArray	nodes;
+	void Process(const btDbvtNode* n) { nodes.push_back(n); }
+};
+
+//
+static DBVT_INLINE int			indexof(const btDbvtNode* node)
+{
+	return(node->parent->childs[1]==node);
+}
+
+//
+static DBVT_INLINE btDbvtVolume	merge(	const btDbvtVolume& a,
+									  const btDbvtVolume& b)
+{
+#if (DBVT_MERGE_IMPL==DBVT_IMPL_SSE)
+	ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]);
+	btDbvtVolume&	res=*(btDbvtVolume*)locals;
+#else
+		btDbvtVolume	res;
+#endif
+	Merge(a,b,res);
+	return(res);
+}
+
+// volume+edge lengths
+static DBVT_INLINE btScalar		size(const btDbvtVolume& a)
+{
+	const btVector3	edges=a.Lengths();
+	return(	edges.x()*edges.y()*edges.z()+
+		edges.x()+edges.y()+edges.z());
+}
+
+//
+static void						getmaxdepth(const btDbvtNode* node,int depth,int& maxdepth)
+{
+	if(node->isinternal())
+	{
+		getmaxdepth(node->childs[0],depth+1,maxdepth);
+		getmaxdepth(node->childs[0],depth+1,maxdepth);
+	} else maxdepth=btMax(maxdepth,depth);
+}
+
+//
+static DBVT_INLINE void			deletenode(	btDbvt* pdbvt,
+										   btDbvtNode* node)
+{
+	btAlignedFree(pdbvt->m_free);
+	pdbvt->m_free=node;
+}
+
+//
+static void						recursedeletenode(	btDbvt* pdbvt,
+												  btDbvtNode* node)
+{
+	if(!node->isleaf())
+	{
+		recursedeletenode(pdbvt,node->childs[0]);
+		recursedeletenode(pdbvt,node->childs[1]);
+	}
+	if(node==pdbvt->m_root) pdbvt->m_root=0;
+	deletenode(pdbvt,node);
+}
+
+//
+static DBVT_INLINE btDbvtNode*	createnode(	btDbvt* pdbvt,
+										   btDbvtNode* parent,
+										   void* data)
+{
+	btDbvtNode*	node;
+	if(pdbvt->m_free)
+	{ node=pdbvt->m_free;pdbvt->m_free=0; }
+	else
+	{ node=new(btAlignedAlloc(sizeof(btDbvtNode),16)) btDbvtNode(); }
+	node->parent	=	parent;
+	node->data		=	data;
+	node->childs[1]	=	0;
+	return(node);
+}
+
+//
+static DBVT_INLINE btDbvtNode*	createnode(	btDbvt* pdbvt,
+										   btDbvtNode* parent,
+										   const btDbvtVolume& volume,
+										   void* data)
+{
+	btDbvtNode*	node=createnode(pdbvt,parent,data);
+	node->volume=volume;
+	return(node);
+}
+
+//
+static DBVT_INLINE btDbvtNode*	createnode(	btDbvt* pdbvt,
+										   btDbvtNode* parent,
+										   const btDbvtVolume& volume0,
+										   const btDbvtVolume& volume1,
+										   void* data)
+{
+	btDbvtNode*	node=createnode(pdbvt,parent,data);
+	Merge(volume0,volume1,node->volume);
+	return(node);
+}
+
+//
+static void						insertleaf(	btDbvt* pdbvt,
+										   btDbvtNode* root,
+										   btDbvtNode* leaf)
+{
+	if(!pdbvt->m_root)
+	{
+		pdbvt->m_root	=	leaf;
+		leaf->parent	=	0;
+	}
+	else
+	{
+		if(!root->isleaf())
+		{
+			do	{
+				root=root->childs[Select(	leaf->volume,
+					root->childs[0]->volume,
+					root->childs[1]->volume)];
+			} while(!root->isleaf());
+		}
+		btDbvtNode*	prev=root->parent;
+		btDbvtNode*	node=createnode(pdbvt,prev,leaf->volume,root->volume,0);
+		if(prev)
+		{
+			prev->childs[indexof(root)]	=	node;
+			node->childs[0]				=	root;root->parent=node;
+			node->childs[1]				=	leaf;leaf->parent=node;
+			do	{
+				if(!prev->volume.Contain(node->volume))
+					Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
+				else
+					break;
+				node=prev;
+			} while(0!=(prev=node->parent));
+		}
+		else
+		{
+			node->childs[0]	=	root;root->parent=node;
+			node->childs[1]	=	leaf;leaf->parent=node;
+			pdbvt->m_root	=	node;
+		}
+	}
+}
+
+//
+static btDbvtNode*				removeleaf(	btDbvt* pdbvt,
+										   btDbvtNode* leaf)
+{
+	if(leaf==pdbvt->m_root)
+	{
+		pdbvt->m_root=0;
+		return(0);
+	}
+	else
+	{
+		btDbvtNode*	parent=leaf->parent;
+		btDbvtNode*	prev=parent->parent;
+		btDbvtNode*	sibling=parent->childs[1-indexof(leaf)];			
+		if(prev)
+		{
+			prev->childs[indexof(parent)]=sibling;
+			sibling->parent=prev;
+			deletenode(pdbvt,parent);
+			while(prev)
+			{
+				const btDbvtVolume	pb=prev->volume;
+				Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume);
+				if(NotEqual(pb,prev->volume))
+				{
+					prev=prev->parent;
+				} else break;
+			}
+			return(prev?prev:pdbvt->m_root);
+		}
+		else
+		{								
+			pdbvt->m_root=sibling;
+			sibling->parent=0;
+			deletenode(pdbvt,parent);
+			return(pdbvt->m_root);
+		}			
+	}
+}
+
+//
+static void						fetchleaves(btDbvt* pdbvt,
+											btDbvtNode* root,
+											tNodeArray& leaves,
+											int depth=-1)
+{
+	if(root->isinternal()&&depth)
+	{
+		fetchleaves(pdbvt,root->childs[0],leaves,depth-1);
+		fetchleaves(pdbvt,root->childs[1],leaves,depth-1);
+		deletenode(pdbvt,root);
+	}
+	else
+	{
+		leaves.push_back(root);
+	}
+}
+
+//
+static void						split(	const tNodeArray& leaves,
+									  tNodeArray& left,
+									  tNodeArray& right,
+									  const btVector3& org,
+									  const btVector3& axis)
+{
+	left.resize(0);
+	right.resize(0);
+	for(int i=0,ni=leaves.size();i<ni;++i)
+	{
+		if(dot(axis,leaves[i]->volume.Center()-org)<0)
+			left.push_back(leaves[i]);
+		else
+			right.push_back(leaves[i]);
+	}
+}
+
+//
+static btDbvtVolume				bounds(	const tNodeArray& leaves)
+{
+#if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
+	ATTRIBUTE_ALIGNED16(char	locals[sizeof(btDbvtVolume)]);
+	btDbvtVolume&	volume=*(btDbvtVolume*)locals;
+	volume=leaves[0]->volume;
+#else
+	btDbvtVolume volume=leaves[0]->volume;
+#endif
+	for(int i=1,ni=leaves.size();i<ni;++i)
+	{
+		Merge(volume,leaves[i]->volume,volume);
+	}
+	return(volume);
+}
+
+//
+static void						bottomup(	btDbvt* pdbvt,
+										 tNodeArray& leaves)
+{
+	while(leaves.size()>1)
+	{
+		btScalar	minsize=SIMD_INFINITY;
+		int			minidx[2]={-1,-1};
+		for(int i=0;i<leaves.size();++i)
+		{
+			for(int j=i+1;j<leaves.size();++j)
+			{
+				const btScalar	sz=size(merge(leaves[i]->volume,leaves[j]->volume));
+				if(sz<minsize)
+				{
+					minsize		=	sz;
+					minidx[0]	=	i;
+					minidx[1]	=	j;
+				}
+			}
+		}
+		btDbvtNode*	n[]	=	{leaves[minidx[0]],leaves[minidx[1]]};
+		btDbvtNode*	p	=	createnode(pdbvt,0,n[0]->volume,n[1]->volume,0);
+		p->childs[0]		=	n[0];
+		p->childs[1]		=	n[1];
+		n[0]->parent		=	p;
+		n[1]->parent		=	p;
+		leaves[minidx[0]]	=	p;
+		leaves.swap(minidx[1],leaves.size()-1);
+		leaves.pop_back();
+	}
+}
+
+//
+static btDbvtNode*			topdown(btDbvt* pdbvt,
+									tNodeArray& leaves,
+									int bu_treshold)
+{
+	static const btVector3	axis[]={btVector3(1,0,0),
+		btVector3(0,1,0),
+		btVector3(0,0,1)};
+	if(leaves.size()>1)
+	{
+		if(leaves.size()>bu_treshold)
+		{
+			const btDbvtVolume	vol=bounds(leaves);
+			const btVector3			org=vol.Center();
+			tNodeArray				sets[2];
+			int						bestaxis=-1;
+			int						bestmidp=leaves.size();
+			int						splitcount[3][2]={{0,0},{0,0},{0,0}};
+			int i;
+			for( i=0;i<leaves.size();++i)
+			{
+				const btVector3	x=leaves[i]->volume.Center()-org;
+				for(int j=0;j<3;++j)
+				{
+					++splitcount[j][dot(x,axis[j])>0?1:0];
+				}
+			}
+			for( i=0;i<3;++i)
+			{
+				if((splitcount[i][0]>0)&&(splitcount[i][1]>0))
+				{
+					const int	midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1]));
+					if(midp<bestmidp)
+					{
+						bestaxis=i;
+						bestmidp=midp;
+					}
+				}
+			}
+			if(bestaxis>=0)
+			{
+				sets[0].reserve(splitcount[bestaxis][0]);
+				sets[1].reserve(splitcount[bestaxis][1]);
+				split(leaves,sets[0],sets[1],org,axis[bestaxis]);
+			}
+			else
+			{
+				sets[0].reserve(leaves.size()/2+1);
+				sets[1].reserve(leaves.size()/2);
+				for(int i=0,ni=leaves.size();i<ni;++i)
+				{
+					sets[i&1].push_back(leaves[i]);
+				}
+			}
+			btDbvtNode*	node=createnode(pdbvt,0,vol,0);
+			node->childs[0]=topdown(pdbvt,sets[0],bu_treshold);
+			node->childs[1]=topdown(pdbvt,sets[1],bu_treshold);
+			node->childs[0]->parent=node;
+			node->childs[1]->parent=node;
+			return(node);
+		}
+		else
+		{
+			bottomup(pdbvt,leaves);
+			return(leaves[0]);
+		}
+	}
+	return(leaves[0]);
+}
+
+//
+static DBVT_INLINE btDbvtNode*	sort(btDbvtNode* n,btDbvtNode*& r)
+{
+	btDbvtNode*	p=n->parent;
+	btAssert(n->isinternal());
+	if(p>n)
+	{
+		const int		i=indexof(n);
+		const int		j=1-i;
+		btDbvtNode*	s=p->childs[j];
+		btDbvtNode*	q=p->parent;
+		btAssert(n==p->childs[i]);
+		if(q) q->childs[indexof(p)]=n; else r=n;
+		s->parent=n;
+		p->parent=n;
+		n->parent=q;
+		p->childs[0]=n->childs[0];
+		p->childs[1]=n->childs[1];
+		n->childs[0]->parent=p;
+		n->childs[1]->parent=p;
+		n->childs[i]=p;
+		n->childs[j]=s;
+		btSwap(p->volume,n->volume);
+		return(p);
+	}
+	return(n);
+}
+
+#if 0
+static DBVT_INLINE btDbvtNode*	walkup(btDbvtNode* n,int count)
+{
+	while(n&&(count--)) n=n->parent;
+	return(n);
+}
+#endif
+
+//
+// Api
+//
+
+//
+btDbvt::btDbvt()
+{
+	m_root		=	0;
+	m_free		=	0;
+	m_lkhd		=	-1;
+	m_leaves	=	0;
+	m_opath		=	0;
+}
+
+//
+btDbvt::~btDbvt()
+{
+	clear();
+}
+
+//
+void			btDbvt::clear()
+{
+	if(m_root)	
+		recursedeletenode(this,m_root);
+	btAlignedFree(m_free);
+	m_free=0;
+	m_lkhd		=	-1;
+	m_stkStack.clear();
+	m_opath		=	0;
+	
+}
+
+//
+void			btDbvt::optimizeBottomUp()
+{
+	if(m_root)
+	{
+		tNodeArray leaves;
+		leaves.reserve(m_leaves);
+		fetchleaves(this,m_root,leaves);
+		bottomup(this,leaves);
+		m_root=leaves[0];
+	}
+}
+
+//
+void			btDbvt::optimizeTopDown(int bu_treshold)
+{
+	if(m_root)
+	{
+		tNodeArray	leaves;
+		leaves.reserve(m_leaves);
+		fetchleaves(this,m_root,leaves);
+		m_root=topdown(this,leaves,bu_treshold);
+	}
+}
+
+//
+void			btDbvt::optimizeIncremental(int passes)
+{
+	if(passes<0) passes=m_leaves;
+	if(m_root&&(passes>0))
+	{
+		do	{
+			btDbvtNode*		node=m_root;
+			unsigned	bit=0;
+			while(node->isinternal())
+			{
+				node=sort(node,m_root)->childs[(m_opath>>bit)&1];
+				bit=(bit+1)&(sizeof(unsigned)*8-1);
+			}
+			update(node);
+			++m_opath;
+		} while(--passes);
+	}
+}
+
+//
+btDbvtNode*	btDbvt::insert(const btDbvtVolume& volume,void* data)
+{
+	btDbvtNode*	leaf=createnode(this,0,volume,data);
+	insertleaf(this,m_root,leaf);
+	++m_leaves;
+	return(leaf);
+}
+
+//
+void			btDbvt::update(btDbvtNode* leaf,int lookahead)
+{
+	btDbvtNode*	root=removeleaf(this,leaf);
+	if(root)
+	{
+		if(lookahead>=0)
+		{
+			for(int i=0;(i<lookahead)&&root->parent;++i)
+			{
+				root=root->parent;
+			}
+		} else root=m_root;
+	}
+	insertleaf(this,root,leaf);
+}
+
+//
+void			btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume)
+{
+	btDbvtNode*	root=removeleaf(this,leaf);
+	if(root)
+	{
+		if(m_lkhd>=0)
+		{
+			for(int i=0;(i<m_lkhd)&&root->parent;++i)
+			{
+				root=root->parent;
+			}
+		} else root=m_root;
+	}
+	leaf->volume=volume;
+	insertleaf(this,root,leaf);
+}
+
+//
+bool			btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin)
+{
+	if(leaf->volume.Contain(volume)) return(false);
+	volume.Expand(btVector3(margin,margin,margin));
+	volume.SignedExpand(velocity);
+	update(leaf,volume);
+	return(true);
+}
+
+//
+bool			btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity)
+{
+	if(leaf->volume.Contain(volume)) return(false);
+	volume.SignedExpand(velocity);
+	update(leaf,volume);
+	return(true);
+}
+
+//
+bool			btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin)
+{
+	if(leaf->volume.Contain(volume)) return(false);
+	volume.Expand(btVector3(margin,margin,margin));
+	update(leaf,volume);
+	return(true);
+}
+
+//
+void			btDbvt::remove(btDbvtNode* leaf)
+{
+	removeleaf(this,leaf);
+	deletenode(this,leaf);
+	--m_leaves;
+}
+
+//
+void			btDbvt::write(IWriter* iwriter) const
+{
+	btDbvtNodeEnumerator	nodes;
+	nodes.nodes.reserve(m_leaves*2);
+	enumNodes(m_root,nodes);
+	iwriter->Prepare(m_root,nodes.nodes.size());
+	for(int i=0;i<nodes.nodes.size();++i)
+	{
+		const btDbvtNode* n=nodes.nodes[i];
+		int			p=-1;
+		if(n->parent) p=nodes.nodes.findLinearSearch(n->parent);
+		if(n->isinternal())
+		{
+			const int	c0=nodes.nodes.findLinearSearch(n->childs[0]);
+			const int	c1=nodes.nodes.findLinearSearch(n->childs[1]);
+			iwriter->WriteNode(n,i,p,c0,c1);
+		}
+		else
+		{
+			iwriter->WriteLeaf(n,i,p);
+		}	
+	}
+}
+
+//
+void			btDbvt::clone(btDbvt& dest,IClone* iclone) const
+{
+	dest.clear();
+	if(m_root!=0)
+	{	
+		btAlignedObjectArray<sStkCLN>	stack;
+		stack.reserve(m_leaves);
+		stack.push_back(sStkCLN(m_root,0));
+		do	{
+			const int		i=stack.size()-1;
+			const sStkCLN	e=stack[i];
+			btDbvtNode*			n=createnode(&dest,e.parent,e.node->volume,e.node->data);
+			stack.pop_back();
+			if(e.parent!=0)
+				e.parent->childs[i&1]=n;
+			else
+				dest.m_root=n;
+			if(e.node->isinternal())
+			{
+				stack.push_back(sStkCLN(e.node->childs[0],n));
+				stack.push_back(sStkCLN(e.node->childs[1],n));
+			}
+			else
+			{
+				iclone->CloneLeaf(n);
+			}
+		} while(stack.size()>0);
+	}
+}
+
+//
+int				btDbvt::maxdepth(const btDbvtNode* node)
+{
+	int	depth=0;
+	if(node) getmaxdepth(node,1,depth);
+	return(depth);
+}
+
+//
+int				btDbvt::countLeaves(const btDbvtNode* node)
+{
+	if(node->isinternal())
+		return(countLeaves(node->childs[0])+countLeaves(node->childs[1]));
+	else
+		return(1);
+}
+
+//
+void			btDbvt::extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves)
+{
+	if(node->isinternal())
+	{
+		extractLeaves(node->childs[0],leaves);
+		extractLeaves(node->childs[1],leaves);
+	}
+	else
+	{
+		leaves.push_back(node);
+	}	
+}
+
+//
+#if DBVT_ENABLE_BENCHMARK
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "LinearMath/btQuickProf.h"
+
+/*
+q6600,2.4ghz
+
+/Ox /Ob2 /Oi /Ot /I "." /I "..\.." /I "..\..\src" /D "NDEBUG" /D "_LIB" /D "_WINDOWS" /D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_NONSTDC_NO_DEPRECATE" /D "WIN32"
+/GF /FD /MT /GS- /Gy /arch:SSE2 /Zc:wchar_t- /Fp"..\..\out\release8\build\libbulletcollision\libbulletcollision.pch"
+/Fo"..\..\out\release8\build\libbulletcollision\\"
+/Fd"..\..\out\release8\build\libbulletcollision\bulletcollision.pdb"
+/W3 /nologo /c /Wp64 /Zi /errorReport:prompt
+
+Benchmarking dbvt...
+World scale: 100.000000
+Extents base: 1.000000
+Extents range: 4.000000
+Leaves: 8192
+sizeof(btDbvtVolume): 32 bytes
+sizeof(btDbvtNode):   44 bytes
+[1] btDbvtVolume intersections: 3499 ms (-1%)
+[2] btDbvtVolume merges: 1934 ms (0%)
+[3] btDbvt::collideTT: 5485 ms (-21%)
+[4] btDbvt::collideTT self: 2814 ms (-20%)
+[5] btDbvt::collideTT xform: 7379 ms (-1%)
+[6] btDbvt::collideTT xform,self: 7270 ms (-2%)
+[7] btDbvt::rayTest: 6314 ms (0%),(332143 r/s)
+[8] insert/remove: 2093 ms (0%),(1001983 ir/s)
+[9] updates (teleport): 1879 ms (-3%),(1116100 u/s)
+[10] updates (jitter): 1244 ms (-4%),(1685813 u/s)
+[11] optimize (incremental): 2514 ms (0%),(1668000 o/s)
+[12] btDbvtVolume notequal: 3659 ms (0%)
+[13] culling(OCL+fullsort): 2218 ms (0%),(461 t/s)
+[14] culling(OCL+qsort): 3688 ms (5%),(2221 t/s)
+[15] culling(KDOP+qsort): 1139 ms (-1%),(7192 t/s)
+[16] insert/remove batch(256): 5092 ms (0%),(823704 bir/s)
+[17] btDbvtVolume select: 3419 ms (0%)
+*/
+
+struct btDbvtBenchmark
+{
+	struct NilPolicy : btDbvt::ICollide
+	{
+		NilPolicy() : m_pcount(0),m_depth(-SIMD_INFINITY),m_checksort(true)		{}
+		void	Process(const btDbvtNode*,const btDbvtNode*)				{ ++m_pcount; }
+		void	Process(const btDbvtNode*)									{ ++m_pcount; }
+		void	Process(const btDbvtNode*,btScalar depth)
+		{
+			++m_pcount;
+			if(m_checksort)
+			{ if(depth>=m_depth) m_depth=depth; else printf("wrong depth: %f (should be >= %f)\r\n",depth,m_depth); }
+		}
+		int			m_pcount;
+		btScalar	m_depth;
+		bool		m_checksort;
+	};
+	struct P14 : btDbvt::ICollide
+	{
+		struct Node
+		{
+			const btDbvtNode*	leaf;
+			btScalar			depth;
+		};
+		void Process(const btDbvtNode* leaf,btScalar depth)
+		{
+			Node	n;
+			n.leaf	=	leaf;
+			n.depth	=	depth;
+		}
+		static int sortfnc(const Node& a,const Node& b)
+		{
+			if(a.depth<b.depth) return(+1);
+			if(a.depth>b.depth) return(-1);
+			return(0);
+		}
+		btAlignedObjectArray<Node>		m_nodes;
+	};
+	struct P15 : btDbvt::ICollide
+	{
+		struct Node
+		{
+			const btDbvtNode*	leaf;
+			btScalar			depth;
+		};
+		void Process(const btDbvtNode* leaf)
+		{
+			Node	n;
+			n.leaf	=	leaf;
+			n.depth	=	dot(leaf->volume.Center(),m_axis);
+		}
+		static int sortfnc(const Node& a,const Node& b)
+		{
+			if(a.depth<b.depth) return(+1);
+			if(a.depth>b.depth) return(-1);
+			return(0);
+		}
+		btAlignedObjectArray<Node>		m_nodes;
+		btVector3						m_axis;
+	};
+	static btScalar			RandUnit()
+	{
+		return(rand()/(btScalar)RAND_MAX);
+	}
+	static btVector3		RandVector3()
+	{
+		return(btVector3(RandUnit(),RandUnit(),RandUnit()));
+	}
+	static btVector3		RandVector3(btScalar cs)
+	{
+		return(RandVector3()*cs-btVector3(cs,cs,cs)/2);
+	}
+	static btDbvtVolume	RandVolume(btScalar cs,btScalar eb,btScalar es)
+	{
+		return(btDbvtVolume::FromCE(RandVector3(cs),btVector3(eb,eb,eb)+RandVector3()*es));
+	}
+	static btTransform		RandTransform(btScalar cs)
+	{
+		btTransform	t;
+		t.setOrigin(RandVector3(cs));
+		t.setRotation(btQuaternion(RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2).normalized());
+		return(t);
+	}
+	static void				RandTree(btScalar cs,btScalar eb,btScalar es,int leaves,btDbvt& dbvt)
+	{
+		dbvt.clear();
+		for(int i=0;i<leaves;++i)
+		{
+			dbvt.insert(RandVolume(cs,eb,es),0);
+		}
+	}
+};
+
+void			btDbvt::benchmark()
+{
+	static const btScalar	cfgVolumeCenterScale		=	100;
+	static const btScalar	cfgVolumeExentsBase			=	1;
+	static const btScalar	cfgVolumeExentsScale		=	4;
+	static const int		cfgLeaves					=	8192;
+	static const bool		cfgEnable					=	true;
+
+	//[1] btDbvtVolume intersections
+	bool					cfgBenchmark1_Enable		=	cfgEnable;
+	static const int		cfgBenchmark1_Iterations	=	8;
+	static const int		cfgBenchmark1_Reference		=	3499;
+	//[2] btDbvtVolume merges
+	bool					cfgBenchmark2_Enable		=	cfgEnable;
+	static const int		cfgBenchmark2_Iterations	=	4;
+	static const int		cfgBenchmark2_Reference		=	1945;
+	//[3] btDbvt::collideTT
+	bool					cfgBenchmark3_Enable		=	cfgEnable;
+	static const int		cfgBenchmark3_Iterations	=	512;
+	static const int		cfgBenchmark3_Reference		=	5485;
+	//[4] btDbvt::collideTT self
+	bool					cfgBenchmark4_Enable		=	cfgEnable;
+	static const int		cfgBenchmark4_Iterations	=	512;
+	static const int		cfgBenchmark4_Reference		=	2814;
+	//[5] btDbvt::collideTT xform
+	bool					cfgBenchmark5_Enable		=	cfgEnable;
+	static const int		cfgBenchmark5_Iterations	=	512;
+	static const btScalar	cfgBenchmark5_OffsetScale	=	2;
+	static const int		cfgBenchmark5_Reference		=	7379;
+	//[6] btDbvt::collideTT xform,self
+	bool					cfgBenchmark6_Enable		=	cfgEnable;
+	static const int		cfgBenchmark6_Iterations	=	512;
+	static const btScalar	cfgBenchmark6_OffsetScale	=	2;
+	static const int		cfgBenchmark6_Reference		=	7270;
+	//[7] btDbvt::rayTest
+	bool					cfgBenchmark7_Enable		=	cfgEnable;
+	static const int		cfgBenchmark7_Passes		=	32;
+	static const int		cfgBenchmark7_Iterations	=	65536;
+	static const int		cfgBenchmark7_Reference		=	6307;
+	//[8] insert/remove
+	bool					cfgBenchmark8_Enable		=	cfgEnable;
+	static const int		cfgBenchmark8_Passes		=	32;
+	static const int		cfgBenchmark8_Iterations	=	65536;
+	static const int		cfgBenchmark8_Reference		=	2105;
+	//[9] updates (teleport)
+	bool					cfgBenchmark9_Enable		=	cfgEnable;
+	static const int		cfgBenchmark9_Passes		=	32;
+	static const int		cfgBenchmark9_Iterations	=	65536;
+	static const int		cfgBenchmark9_Reference		=	1879;
+	//[10] updates (jitter)
+	bool					cfgBenchmark10_Enable		=	cfgEnable;
+	static const btScalar	cfgBenchmark10_Scale		=	cfgVolumeCenterScale/10000;
+	static const int		cfgBenchmark10_Passes		=	32;
+	static const int		cfgBenchmark10_Iterations	=	65536;
+	static const int		cfgBenchmark10_Reference	=	1244;
+	//[11] optimize (incremental)
+	bool					cfgBenchmark11_Enable		=	cfgEnable;
+	static const int		cfgBenchmark11_Passes		=	64;
+	static const int		cfgBenchmark11_Iterations	=	65536;
+	static const int		cfgBenchmark11_Reference	=	2510;
+	//[12] btDbvtVolume notequal
+	bool					cfgBenchmark12_Enable		=	cfgEnable;
+	static const int		cfgBenchmark12_Iterations	=	32;
+	static const int		cfgBenchmark12_Reference	=	3677;
+	//[13] culling(OCL+fullsort)
+	bool					cfgBenchmark13_Enable		=	cfgEnable;
+	static const int		cfgBenchmark13_Iterations	=	1024;
+	static const int		cfgBenchmark13_Reference	=	2231;
+	//[14] culling(OCL+qsort)
+	bool					cfgBenchmark14_Enable		=	cfgEnable;
+	static const int		cfgBenchmark14_Iterations	=	8192;
+	static const int		cfgBenchmark14_Reference	=	3500;
+	//[15] culling(KDOP+qsort)
+	bool					cfgBenchmark15_Enable		=	cfgEnable;
+	static const int		cfgBenchmark15_Iterations	=	8192;
+	static const int		cfgBenchmark15_Reference	=	1151;
+	//[16] insert/remove batch
+	bool					cfgBenchmark16_Enable		=	cfgEnable;
+	static const int		cfgBenchmark16_BatchCount	=	256;
+	static const int		cfgBenchmark16_Passes		=	16384;
+	static const int		cfgBenchmark16_Reference	=	5138;
+	//[17] select
+	bool					cfgBenchmark17_Enable		=	cfgEnable;
+	static const int		cfgBenchmark17_Iterations	=	4;
+	static const int		cfgBenchmark17_Reference	=	3390;
+
+	btClock					wallclock;
+	printf("Benchmarking dbvt...\r\n");
+	printf("\tWorld scale: %f\r\n",cfgVolumeCenterScale);
+	printf("\tExtents base: %f\r\n",cfgVolumeExentsBase);
+	printf("\tExtents range: %f\r\n",cfgVolumeExentsScale);
+	printf("\tLeaves: %u\r\n",cfgLeaves);
+	printf("\tsizeof(btDbvtVolume): %u bytes\r\n",sizeof(btDbvtVolume));
+	printf("\tsizeof(btDbvtNode):   %u bytes\r\n",sizeof(btDbvtNode));
+	if(cfgBenchmark1_Enable)
+	{// Benchmark 1	
+		srand(380843);
+		btAlignedObjectArray<btDbvtVolume>	volumes;
+		btAlignedObjectArray<bool>			results;
+		volumes.resize(cfgLeaves);
+		results.resize(cfgLeaves);
+		for(int i=0;i<cfgLeaves;++i)
+		{
+			volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+		}
+		printf("[1] btDbvtVolume intersections: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark1_Iterations;++i)
+		{
+			for(int j=0;j<cfgLeaves;++j)
+			{
+				for(int k=0;k<cfgLeaves;++k)
+				{
+					results[k]=Intersect(volumes[j],volumes[k]);
+				}
+			}
+		}
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark1_Reference)*100/time);
+	}
+	if(cfgBenchmark2_Enable)
+	{// Benchmark 2	
+		srand(380843);
+		btAlignedObjectArray<btDbvtVolume>	volumes;
+		btAlignedObjectArray<btDbvtVolume>	results;
+		volumes.resize(cfgLeaves);
+		results.resize(cfgLeaves);
+		for(int i=0;i<cfgLeaves;++i)
+		{
+			volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+		}
+		printf("[2] btDbvtVolume merges: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark2_Iterations;++i)
+		{
+			for(int j=0;j<cfgLeaves;++j)
+			{
+				for(int k=0;k<cfgLeaves;++k)
+				{
+					Merge(volumes[j],volumes[k],results[k]);
+				}
+			}
+		}
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark2_Reference)*100/time);
+	}
+	if(cfgBenchmark3_Enable)
+	{// Benchmark 3	
+		srand(380843);
+		btDbvt						dbvt[2];
+		btDbvtBenchmark::NilPolicy	policy;
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
+		dbvt[0].optimizeTopDown();
+		dbvt[1].optimizeTopDown();
+		printf("[3] btDbvt::collideTT: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark3_Iterations;++i)
+		{
+			btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,policy);
+		}
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark3_Reference)*100/time);
+	}
+	if(cfgBenchmark4_Enable)
+	{// Benchmark 4
+		srand(380843);
+		btDbvt						dbvt;
+		btDbvtBenchmark::NilPolicy	policy;
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		printf("[4] btDbvt::collideTT self: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark4_Iterations;++i)
+		{
+			btDbvt::collideTT(dbvt.m_root,dbvt.m_root,policy);
+		}
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark4_Reference)*100/time);
+	}
+	if(cfgBenchmark5_Enable)
+	{// Benchmark 5	
+		srand(380843);
+		btDbvt								dbvt[2];
+		btAlignedObjectArray<btTransform>	transforms;
+		btDbvtBenchmark::NilPolicy			policy;
+		transforms.resize(cfgBenchmark5_Iterations);
+		for(int i=0;i<transforms.size();++i)
+		{
+			transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark5_OffsetScale);
+		}
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[0]);
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt[1]);
+		dbvt[0].optimizeTopDown();
+		dbvt[1].optimizeTopDown();
+		printf("[5] btDbvt::collideTT xform: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark5_Iterations;++i)
+		{
+			btDbvt::collideTT(dbvt[0].m_root,dbvt[1].m_root,transforms[i],policy);
+		}
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark5_Reference)*100/time);
+	}
+	if(cfgBenchmark6_Enable)
+	{// Benchmark 6	
+		srand(380843);
+		btDbvt								dbvt;
+		btAlignedObjectArray<btTransform>	transforms;
+		btDbvtBenchmark::NilPolicy			policy;
+		transforms.resize(cfgBenchmark6_Iterations);
+		for(int i=0;i<transforms.size();++i)
+		{
+			transforms[i]=btDbvtBenchmark::RandTransform(cfgVolumeCenterScale*cfgBenchmark6_OffsetScale);
+		}
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		printf("[6] btDbvt::collideTT xform,self: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark6_Iterations;++i)
+		{
+			btDbvt::collideTT(dbvt.m_root,dbvt.m_root,transforms[i],policy);		
+		}
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark6_Reference)*100/time);
+	}
+	if(cfgBenchmark7_Enable)
+	{// Benchmark 7	
+		srand(380843);
+		btDbvt								dbvt;
+		btAlignedObjectArray<btVector3>		rayorg;
+		btAlignedObjectArray<btVector3>		raydir;
+		btDbvtBenchmark::NilPolicy			policy;
+		rayorg.resize(cfgBenchmark7_Iterations);
+		raydir.resize(cfgBenchmark7_Iterations);
+		for(int i=0;i<rayorg.size();++i)
+		{
+			rayorg[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
+			raydir[i]=btDbvtBenchmark::RandVector3(cfgVolumeCenterScale*2);
+		}
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		printf("[7] btDbvt::rayTest: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark7_Passes;++i)
+		{
+			for(int j=0;j<cfgBenchmark7_Iterations;++j)
+			{
+				btDbvt::rayTest(dbvt.m_root,rayorg[j],rayorg[j]+raydir[j],policy);
+			}
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		unsigned	rays=cfgBenchmark7_Passes*cfgBenchmark7_Iterations;
+		printf("%u ms (%i%%),(%u r/s)\r\n",time,(time-cfgBenchmark7_Reference)*100/time,(rays*1000)/time);
+	}
+	if(cfgBenchmark8_Enable)
+	{// Benchmark 8	
+		srand(380843);
+		btDbvt								dbvt;
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		printf("[8] insert/remove: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark8_Passes;++i)
+		{
+			for(int j=0;j<cfgBenchmark8_Iterations;++j)
+			{
+				dbvt.remove(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
+			}
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	ir=cfgBenchmark8_Passes*cfgBenchmark8_Iterations;
+		printf("%u ms (%i%%),(%u ir/s)\r\n",time,(time-cfgBenchmark8_Reference)*100/time,ir*1000/time);
+	}
+	if(cfgBenchmark9_Enable)
+	{// Benchmark 9	
+		srand(380843);
+		btDbvt										dbvt;
+		btAlignedObjectArray<const btDbvtNode*>	leaves;
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		dbvt.extractLeaves(dbvt.m_root,leaves);
+		printf("[9] updates (teleport): ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark9_Passes;++i)
+		{
+			for(int j=0;j<cfgBenchmark9_Iterations;++j)
+			{
+				dbvt.update(const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]),
+					btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale));
+			}
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations;
+		printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time);
+	}
+	if(cfgBenchmark10_Enable)
+	{// Benchmark 10	
+		srand(380843);
+		btDbvt										dbvt;
+		btAlignedObjectArray<const btDbvtNode*>	leaves;
+		btAlignedObjectArray<btVector3>				vectors;
+		vectors.resize(cfgBenchmark10_Iterations);
+		for(int i=0;i<vectors.size();++i)
+		{
+			vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1))*cfgBenchmark10_Scale;
+		}
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		dbvt.extractLeaves(dbvt.m_root,leaves);
+		printf("[10] updates (jitter): ");
+		wallclock.reset();
+
+		for(int i=0;i<cfgBenchmark10_Passes;++i)
+		{
+			for(int j=0;j<cfgBenchmark10_Iterations;++j)
+			{			
+				const btVector3&	d=vectors[j];
+				btDbvtNode*		l=const_cast<btDbvtNode*>(leaves[rand()%cfgLeaves]);
+				btDbvtVolume		v=btDbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d);
+				dbvt.update(l,v);
+			}
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations;
+		printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time);
+	}
+	if(cfgBenchmark11_Enable)
+	{// Benchmark 11	
+		srand(380843);
+		btDbvt										dbvt;
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		printf("[11] optimize (incremental): ");
+		wallclock.reset();	
+		for(int i=0;i<cfgBenchmark11_Passes;++i)
+		{
+			dbvt.optimizeIncremental(cfgBenchmark11_Iterations);
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	op=cfgBenchmark11_Passes*cfgBenchmark11_Iterations;
+		printf("%u ms (%i%%),(%u o/s)\r\n",time,(time-cfgBenchmark11_Reference)*100/time,op/time*1000);
+	}
+	if(cfgBenchmark12_Enable)
+	{// Benchmark 12	
+		srand(380843);
+		btAlignedObjectArray<btDbvtVolume>	volumes;
+		btAlignedObjectArray<bool>				results;
+		volumes.resize(cfgLeaves);
+		results.resize(cfgLeaves);
+		for(int i=0;i<cfgLeaves;++i)
+		{
+			volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+		}
+		printf("[12] btDbvtVolume notequal: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark12_Iterations;++i)
+		{
+			for(int j=0;j<cfgLeaves;++j)
+			{
+				for(int k=0;k<cfgLeaves;++k)
+				{
+					results[k]=NotEqual(volumes[j],volumes[k]);
+				}
+			}
+		}
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark12_Reference)*100/time);
+	}
+	if(cfgBenchmark13_Enable)
+	{// Benchmark 13	
+		srand(380843);
+		btDbvt								dbvt;
+		btAlignedObjectArray<btVector3>		vectors;
+		btDbvtBenchmark::NilPolicy			policy;
+		vectors.resize(cfgBenchmark13_Iterations);
+		for(int i=0;i<vectors.size();++i)
+		{
+			vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
+		}
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		printf("[13] culling(OCL+fullsort): ");
+		wallclock.reset();	
+		for(int i=0;i<cfgBenchmark13_Iterations;++i)
+		{
+			static const btScalar	offset=0;
+			policy.m_depth=-SIMD_INFINITY;
+			dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy);
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	t=cfgBenchmark13_Iterations;
+		printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark13_Reference)*100/time,(t*1000)/time);
+	}
+	if(cfgBenchmark14_Enable)
+	{// Benchmark 14	
+		srand(380843);
+		btDbvt								dbvt;
+		btAlignedObjectArray<btVector3>		vectors;
+		btDbvtBenchmark::P14				policy;
+		vectors.resize(cfgBenchmark14_Iterations);
+		for(int i=0;i<vectors.size();++i)
+		{
+			vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
+		}
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		policy.m_nodes.reserve(cfgLeaves);
+		printf("[14] culling(OCL+qsort): ");
+		wallclock.reset();	
+		for(int i=0;i<cfgBenchmark14_Iterations;++i)
+		{
+			static const btScalar	offset=0;
+			policy.m_nodes.resize(0);
+			dbvt.collideOCL(dbvt.m_root,&vectors[i],&offset,vectors[i],1,policy,false);
+			policy.m_nodes.quickSort(btDbvtBenchmark::P14::sortfnc);
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	t=cfgBenchmark14_Iterations;
+		printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark14_Reference)*100/time,(t*1000)/time);
+	}
+	if(cfgBenchmark15_Enable)
+	{// Benchmark 15	
+		srand(380843);
+		btDbvt								dbvt;
+		btAlignedObjectArray<btVector3>		vectors;
+		btDbvtBenchmark::P15				policy;
+		vectors.resize(cfgBenchmark15_Iterations);
+		for(int i=0;i<vectors.size();++i)
+		{
+			vectors[i]=(btDbvtBenchmark::RandVector3()*2-btVector3(1,1,1)).normalized();
+		}
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		policy.m_nodes.reserve(cfgLeaves);
+		printf("[15] culling(KDOP+qsort): ");
+		wallclock.reset();	
+		for(int i=0;i<cfgBenchmark15_Iterations;++i)
+		{
+			static const btScalar	offset=0;
+			policy.m_nodes.resize(0);
+			policy.m_axis=vectors[i];
+			dbvt.collideKDOP(dbvt.m_root,&vectors[i],&offset,1,policy);
+			policy.m_nodes.quickSort(btDbvtBenchmark::P15::sortfnc);
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	t=cfgBenchmark15_Iterations;
+		printf("%u ms (%i%%),(%u t/s)\r\n",time,(time-cfgBenchmark15_Reference)*100/time,(t*1000)/time);
+	}
+	if(cfgBenchmark16_Enable)
+	{// Benchmark 16	
+		srand(380843);
+		btDbvt								dbvt;
+		btAlignedObjectArray<btDbvtNode*>	batch;
+		btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt);
+		dbvt.optimizeTopDown();
+		batch.reserve(cfgBenchmark16_BatchCount);
+		printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount);
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark16_Passes;++i)
+		{
+			for(int j=0;j<cfgBenchmark16_BatchCount;++j)
+			{
+				batch.push_back(dbvt.insert(btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale),0));
+			}
+			for(int j=0;j<cfgBenchmark16_BatchCount;++j)
+			{
+				dbvt.remove(batch[j]);
+			}
+			batch.resize(0);
+		}
+		const int	time=(int)wallclock.getTimeMilliseconds();
+		const int	ir=cfgBenchmark16_Passes*cfgBenchmark16_BatchCount;
+		printf("%u ms (%i%%),(%u bir/s)\r\n",time,(time-cfgBenchmark16_Reference)*100/time,int(ir*1000.0/time));
+	}
+	if(cfgBenchmark17_Enable)
+	{// Benchmark 17
+		srand(380843);
+		btAlignedObjectArray<btDbvtVolume>	volumes;
+		btAlignedObjectArray<int>			results;
+		btAlignedObjectArray<int>			indices;
+		volumes.resize(cfgLeaves);
+		results.resize(cfgLeaves);
+		indices.resize(cfgLeaves);
+		for(int i=0;i<cfgLeaves;++i)
+		{
+			indices[i]=i;
+			volumes[i]=btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale);
+		}
+		for(int i=0;i<cfgLeaves;++i)
+		{
+			btSwap(indices[i],indices[rand()%cfgLeaves]);
+		}
+		printf("[17] btDbvtVolume select: ");
+		wallclock.reset();
+		for(int i=0;i<cfgBenchmark17_Iterations;++i)
+		{
+			for(int j=0;j<cfgLeaves;++j)
+			{
+				for(int k=0;k<cfgLeaves;++k)
+				{
+					const int idx=indices[k];
+					results[idx]=Select(volumes[idx],volumes[j],volumes[k]);
+				}
+			}
+		}
+		const int time=(int)wallclock.getTimeMilliseconds();
+		printf("%u ms (%i%%)\r\n",time,(time-cfgBenchmark17_Reference)*100/time);
+	}
+	printf("\r\n\r\n");
+}
+#endif
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvt.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvt.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvt.h	(revision 6952)
@@ -0,0 +1,1255 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2007 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.
+*/
+///btDbvt implementation by Nathanael Presson
+
+#ifndef BT_DYNAMIC_BOUNDING_VOLUME_TREE_H
+#define BT_DYNAMIC_BOUNDING_VOLUME_TREE_H
+
+#include "LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btAabbUtil2.h"
+
+//
+// Compile time configuration
+//
+
+
+// Implementation profiles
+#define DBVT_IMPL_GENERIC		0	// Generic implementation	
+#define DBVT_IMPL_SSE			1	// SSE
+
+// Template implementation of ICollide
+#ifdef WIN32
+#if (defined (_MSC_VER) && _MSC_VER >= 1400)
+#define	DBVT_USE_TEMPLATE		1
+#else
+#define	DBVT_USE_TEMPLATE		0
+#endif
+#else
+#define	DBVT_USE_TEMPLATE		0
+#endif
+
+// Use only intrinsics instead of inline asm
+#define DBVT_USE_INTRINSIC_SSE	1
+
+// Using memmov for collideOCL
+#define DBVT_USE_MEMMOVE		1
+
+// Enable benchmarking code
+#define	DBVT_ENABLE_BENCHMARK	0
+
+// Inlining
+#define DBVT_INLINE				SIMD_FORCE_INLINE
+
+// Specific methods implementation
+
+//SSE gives errors on a MSVC 7.1
+#ifdef BT_USE_SSE
+#define DBVT_SELECT_IMPL		DBVT_IMPL_SSE
+#define DBVT_MERGE_IMPL			DBVT_IMPL_SSE
+#define DBVT_INT0_IMPL			DBVT_IMPL_SSE
+#else
+#define DBVT_SELECT_IMPL		DBVT_IMPL_GENERIC
+#define DBVT_MERGE_IMPL			DBVT_IMPL_GENERIC
+#define DBVT_INT0_IMPL			DBVT_IMPL_GENERIC
+#endif
+
+#if	(DBVT_SELECT_IMPL==DBVT_IMPL_SSE)||	\
+	(DBVT_MERGE_IMPL==DBVT_IMPL_SSE)||	\
+	(DBVT_INT0_IMPL==DBVT_IMPL_SSE)
+#include <emmintrin.h>
+#endif
+
+//
+// Auto config and checks
+//
+
+#if DBVT_USE_TEMPLATE
+#define	DBVT_VIRTUAL
+#define DBVT_VIRTUAL_DTOR(a)
+#define DBVT_PREFIX					template <typename T>
+#define DBVT_IPOLICY				T& policy
+#define DBVT_CHECKTYPE				static const ICollide&	typechecker=*(T*)1;(void)typechecker;
+#else
+#define	DBVT_VIRTUAL_DTOR(a)		virtual ~a() {}
+#define DBVT_VIRTUAL				virtual
+#define DBVT_PREFIX
+#define DBVT_IPOLICY				ICollide& policy
+#define DBVT_CHECKTYPE
+#endif
+
+#if DBVT_USE_MEMMOVE
+#ifndef __CELLOS_LV2__
+#include <memory.h>
+#endif
+#include <string.h>
+#endif
+
+#ifndef DBVT_USE_TEMPLATE
+#error "DBVT_USE_TEMPLATE undefined"
+#endif
+
+#ifndef DBVT_USE_MEMMOVE
+#error "DBVT_USE_MEMMOVE undefined"
+#endif
+
+#ifndef DBVT_ENABLE_BENCHMARK
+#error "DBVT_ENABLE_BENCHMARK undefined"
+#endif
+
+#ifndef DBVT_SELECT_IMPL
+#error "DBVT_SELECT_IMPL undefined"
+#endif
+
+#ifndef DBVT_MERGE_IMPL
+#error "DBVT_MERGE_IMPL undefined"
+#endif
+
+#ifndef DBVT_INT0_IMPL
+#error "DBVT_INT0_IMPL undefined"
+#endif
+
+//
+// Defaults volumes
+//
+
+/* btDbvtAabbMm			*/ 
+struct	btDbvtAabbMm
+{
+	DBVT_INLINE btVector3			Center() const	{ return((mi+mx)/2); }
+	DBVT_INLINE btVector3			Lengths() const	{ return(mx-mi); }
+	DBVT_INLINE btVector3			Extents() const	{ return((mx-mi)/2); }
+	DBVT_INLINE const btVector3&	Mins() const	{ return(mi); }
+	DBVT_INLINE const btVector3&	Maxs() const	{ return(mx); }
+	static inline btDbvtAabbMm		FromCE(const btVector3& c,const btVector3& e);
+	static inline btDbvtAabbMm		FromCR(const btVector3& c,btScalar r);
+	static inline btDbvtAabbMm		FromMM(const btVector3& mi,const btVector3& mx);
+	static inline btDbvtAabbMm		FromPoints(const btVector3* pts,int n);
+	static inline btDbvtAabbMm		FromPoints(const btVector3** ppts,int n);
+	DBVT_INLINE void				Expand(const btVector3& e);
+	DBVT_INLINE void				SignedExpand(const btVector3& e);
+	DBVT_INLINE bool				Contain(const btDbvtAabbMm& a) const;
+	DBVT_INLINE int					Classify(const btVector3& n,btScalar o,int s) const;
+	DBVT_INLINE btScalar			ProjectMinimum(const btVector3& v,unsigned signs) const;
+	DBVT_INLINE friend bool			Intersect(	const btDbvtAabbMm& a,
+		const btDbvtAabbMm& b);
+	
+	DBVT_INLINE friend bool			Intersect(	const btDbvtAabbMm& a,
+		const btVector3& b);
+
+	DBVT_INLINE friend btScalar		Proximity(	const btDbvtAabbMm& a,
+		const btDbvtAabbMm& b);
+	DBVT_INLINE friend int			Select(		const btDbvtAabbMm& o,
+		const btDbvtAabbMm& a,
+		const btDbvtAabbMm& b);
+	DBVT_INLINE friend void			Merge(		const btDbvtAabbMm& a,
+		const btDbvtAabbMm& b,
+		btDbvtAabbMm& r);
+	DBVT_INLINE friend bool			NotEqual(	const btDbvtAabbMm& a,
+		const btDbvtAabbMm& b);
+private:
+	DBVT_INLINE void				AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const;
+private:
+	btVector3	mi,mx;
+};
+
+// Types	
+typedef	btDbvtAabbMm	btDbvtVolume;
+
+/* btDbvtNode				*/ 
+struct	btDbvtNode
+{
+	btDbvtVolume	volume;
+	btDbvtNode*		parent;
+	DBVT_INLINE bool	isleaf() const		{ return(childs[1]==0); }
+	DBVT_INLINE bool	isinternal() const	{ return(!isleaf()); }
+	union
+	{
+		btDbvtNode*	childs[2];
+		void*	data;
+		int		dataAsInt;
+	};
+};
+
+///The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree).
+///This btDbvt is used for soft body collision detection and for the btDbvtBroadphase. It has a fast insert, remove and update of nodes.
+///Unlike the btQuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure.
+struct	btDbvt
+{
+	/* Stack element	*/ 
+	struct	sStkNN
+	{
+		const btDbvtNode*	a;
+		const btDbvtNode*	b;
+		sStkNN() {}
+		sStkNN(const btDbvtNode* na,const btDbvtNode* nb) : a(na),b(nb) {}
+	};
+	struct	sStkNP
+	{
+		const btDbvtNode*	node;
+		int			mask;
+		sStkNP(const btDbvtNode* n,unsigned m) : node(n),mask(m) {}
+	};
+	struct	sStkNPS
+	{
+		const btDbvtNode*	node;
+		int			mask;
+		btScalar	value;
+		sStkNPS() {}
+		sStkNPS(const btDbvtNode* n,unsigned m,btScalar v) : node(n),mask(m),value(v) {}
+	};
+	struct	sStkCLN
+	{
+		const btDbvtNode*	node;
+		btDbvtNode*		parent;
+		sStkCLN(const btDbvtNode* n,btDbvtNode* p) : node(n),parent(p) {}
+	};
+	// Policies/Interfaces
+
+	/* ICollide	*/ 
+	struct	ICollide
+	{		
+		DBVT_VIRTUAL_DTOR(ICollide)
+			DBVT_VIRTUAL void	Process(const btDbvtNode*,const btDbvtNode*)		{}
+		DBVT_VIRTUAL void	Process(const btDbvtNode*)					{}
+		DBVT_VIRTUAL void	Process(const btDbvtNode* n,btScalar)			{ Process(n); }
+		DBVT_VIRTUAL bool	Descent(const btDbvtNode*)					{ return(true); }
+		DBVT_VIRTUAL bool	AllLeaves(const btDbvtNode*)					{ return(true); }
+	};
+	/* IWriter	*/ 
+	struct	IWriter
+	{
+		virtual ~IWriter() {}
+		virtual void		Prepare(const btDbvtNode* root,int numnodes)=0;
+		virtual void		WriteNode(const btDbvtNode*,int index,int parent,int child0,int child1)=0;
+		virtual void		WriteLeaf(const btDbvtNode*,int index,int parent)=0;
+	};
+	/* IClone	*/ 
+	struct	IClone
+	{
+		virtual ~IClone()	{}
+		virtual void		CloneLeaf(btDbvtNode*) {}
+	};
+
+	// Constants
+	enum	{
+		SIMPLE_STACKSIZE	=	64,
+		DOUBLE_STACKSIZE	=	SIMPLE_STACKSIZE*2
+	};
+
+	// Fields
+	btDbvtNode*		m_root;
+	btDbvtNode*		m_free;
+	int				m_lkhd;
+	int				m_leaves;
+	unsigned		m_opath;
+
+	
+	btAlignedObjectArray<sStkNN>	m_stkStack;
+
+
+	// Methods
+	btDbvt();
+	~btDbvt();
+	void			clear();
+	bool			empty() const { return(0==m_root); }
+	void			optimizeBottomUp();
+	void			optimizeTopDown(int bu_treshold=128);
+	void			optimizeIncremental(int passes);
+	btDbvtNode*		insert(const btDbvtVolume& box,void* data);
+	void			update(btDbvtNode* leaf,int lookahead=-1);
+	void			update(btDbvtNode* leaf,btDbvtVolume& volume);
+	bool			update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin);
+	bool			update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity);
+	bool			update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin);	
+	void			remove(btDbvtNode* leaf);
+	void			write(IWriter* iwriter) const;
+	void			clone(btDbvt& dest,IClone* iclone=0) const;
+	static int		maxdepth(const btDbvtNode* node);
+	static int		countLeaves(const btDbvtNode* node);
+	static void		extractLeaves(const btDbvtNode* node,btAlignedObjectArray<const btDbvtNode*>& leaves);
+#if DBVT_ENABLE_BENCHMARK
+	static void		benchmark();
+#else
+	static void		benchmark(){}
+#endif
+	// DBVT_IPOLICY must support ICollide policy/interface
+	DBVT_PREFIX
+		static void		enumNodes(	const btDbvtNode* root,
+		DBVT_IPOLICY);
+	DBVT_PREFIX
+		static void		enumLeaves(	const btDbvtNode* root,
+		DBVT_IPOLICY);
+	DBVT_PREFIX
+		void		collideTT(	const btDbvtNode* root0,
+		const btDbvtNode* root1,
+		DBVT_IPOLICY);
+
+	DBVT_PREFIX
+		void		collideTTpersistentStack(	const btDbvtNode* root0,
+		  const btDbvtNode* root1,
+		  DBVT_IPOLICY);
+#if 0
+	DBVT_PREFIX
+		void		collideTT(	const btDbvtNode* root0,
+		const btDbvtNode* root1,
+		const btTransform& xform,
+		DBVT_IPOLICY);
+	DBVT_PREFIX
+		void		collideTT(	const btDbvtNode* root0,
+		const btTransform& xform0,
+		const btDbvtNode* root1,
+		const btTransform& xform1,
+		DBVT_IPOLICY);
+#endif
+
+	DBVT_PREFIX
+		void		collideTV(	const btDbvtNode* root,
+		const btDbvtVolume& volume,
+		DBVT_IPOLICY);
+	///rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thread-safe (uses locking etc)
+	///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time
+	DBVT_PREFIX
+		static void		rayTest(	const btDbvtNode* root,
+		const btVector3& rayFrom,
+		const btVector3& rayTo,
+		DBVT_IPOLICY);
+	///rayTestInternal is faster than rayTest, because it uses a persistent stack (to reduce dynamic memory allocations to a minimum) and it uses precomputed signs/rayInverseDirections
+	///rayTestInternal is used by btDbvtBroadphase to accelerate world ray casts
+	DBVT_PREFIX
+		void		rayTestInternal(	const btDbvtNode* root,
+								const btVector3& rayFrom,
+								const btVector3& rayTo,
+								const btVector3& rayDirectionInverse,
+								unsigned int signs[3],
+								btScalar lambda_max,
+								const btVector3& aabbMin,
+								const btVector3& aabbMax,
+								DBVT_IPOLICY) const;
+
+	DBVT_PREFIX
+		static void		collideKDOP(const btDbvtNode* root,
+		const btVector3* normals,
+		const btScalar* offsets,
+		int count,
+		DBVT_IPOLICY);
+	DBVT_PREFIX
+		static void		collideOCL(	const btDbvtNode* root,
+		const btVector3* normals,
+		const btScalar* offsets,
+		const btVector3& sortaxis,
+		int count,								
+		DBVT_IPOLICY,
+		bool fullsort=true);
+	DBVT_PREFIX
+		static void		collideTU(	const btDbvtNode* root,
+		DBVT_IPOLICY);
+	// Helpers	
+	static DBVT_INLINE int	nearest(const int* i,const btDbvt::sStkNPS* a,btScalar v,int l,int h)
+	{
+		int	m=0;
+		while(l<h)
+		{
+			m=(l+h)>>1;
+			if(a[i[m]].value>=v) l=m+1; else h=m;
+		}
+		return(h);
+	}
+	static DBVT_INLINE int	allocate(	btAlignedObjectArray<int>& ifree,
+		btAlignedObjectArray<sStkNPS>& stock,
+		const sStkNPS& value)
+	{
+		int	i;
+		if(ifree.size()>0)
+		{ i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; }
+		else
+		{ i=stock.size();stock.push_back(value); }
+		return(i); 
+	}
+	//
+private:
+	btDbvt(const btDbvt&)	{}	
+};
+
+//
+// Inline's
+//
+
+//
+inline btDbvtAabbMm			btDbvtAabbMm::FromCE(const btVector3& c,const btVector3& e)
+{
+	btDbvtAabbMm box;
+	box.mi=c-e;box.mx=c+e;
+	return(box);
+}
+
+//
+inline btDbvtAabbMm			btDbvtAabbMm::FromCR(const btVector3& c,btScalar r)
+{
+	return(FromCE(c,btVector3(r,r,r)));
+}
+
+//
+inline btDbvtAabbMm			btDbvtAabbMm::FromMM(const btVector3& mi,const btVector3& mx)
+{
+	btDbvtAabbMm box;
+	box.mi=mi;box.mx=mx;
+	return(box);
+}
+
+//
+inline btDbvtAabbMm			btDbvtAabbMm::FromPoints(const btVector3* pts,int n)
+{
+	btDbvtAabbMm box;
+	box.mi=box.mx=pts[0];
+	for(int i=1;i<n;++i)
+	{
+		box.mi.setMin(pts[i]);
+		box.mx.setMax(pts[i]);
+	}
+	return(box);
+}
+
+//
+inline btDbvtAabbMm			btDbvtAabbMm::FromPoints(const btVector3** ppts,int n)
+{
+	btDbvtAabbMm box;
+	box.mi=box.mx=*ppts[0];
+	for(int i=1;i<n;++i)
+	{
+		box.mi.setMin(*ppts[i]);
+		box.mx.setMax(*ppts[i]);
+	}
+	return(box);
+}
+
+//
+DBVT_INLINE void		btDbvtAabbMm::Expand(const btVector3& e)
+{
+	mi-=e;mx+=e;
+}
+
+//
+DBVT_INLINE void		btDbvtAabbMm::SignedExpand(const btVector3& e)
+{
+	if(e.x()>0) mx.setX(mx.x()+e[0]); else mi.setX(mi.x()+e[0]);
+	if(e.y()>0) mx.setY(mx.y()+e[1]); else mi.setY(mi.y()+e[1]);
+	if(e.z()>0) mx.setZ(mx.z()+e[2]); else mi.setZ(mi.z()+e[2]);
+}
+
+//
+DBVT_INLINE bool		btDbvtAabbMm::Contain(const btDbvtAabbMm& a) const
+{
+	return(	(mi.x()<=a.mi.x())&&
+		(mi.y()<=a.mi.y())&&
+		(mi.z()<=a.mi.z())&&
+		(mx.x()>=a.mx.x())&&
+		(mx.y()>=a.mx.y())&&
+		(mx.z()>=a.mx.z()));
+}
+
+//
+DBVT_INLINE int		btDbvtAabbMm::Classify(const btVector3& n,btScalar o,int s) const
+{
+	btVector3			pi,px;
+	switch(s)
+	{
+	case	(0+0+0):	px=btVector3(mi.x(),mi.y(),mi.z());
+		pi=btVector3(mx.x(),mx.y(),mx.z());break;
+	case	(1+0+0):	px=btVector3(mx.x(),mi.y(),mi.z());
+		pi=btVector3(mi.x(),mx.y(),mx.z());break;
+	case	(0+2+0):	px=btVector3(mi.x(),mx.y(),mi.z());
+		pi=btVector3(mx.x(),mi.y(),mx.z());break;
+	case	(1+2+0):	px=btVector3(mx.x(),mx.y(),mi.z());
+		pi=btVector3(mi.x(),mi.y(),mx.z());break;
+	case	(0+0+4):	px=btVector3(mi.x(),mi.y(),mx.z());
+		pi=btVector3(mx.x(),mx.y(),mi.z());break;
+	case	(1+0+4):	px=btVector3(mx.x(),mi.y(),mx.z());
+		pi=btVector3(mi.x(),mx.y(),mi.z());break;
+	case	(0+2+4):	px=btVector3(mi.x(),mx.y(),mx.z());
+		pi=btVector3(mx.x(),mi.y(),mi.z());break;
+	case	(1+2+4):	px=btVector3(mx.x(),mx.y(),mx.z());
+		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);
+	return(0);
+}
+
+//
+DBVT_INLINE btScalar	btDbvtAabbMm::ProjectMinimum(const btVector3& v,unsigned signs) const
+{
+	const btVector3*	b[]={&mx,&mi};
+	const btVector3		p(	b[(signs>>0)&1]->x(),
+		b[(signs>>1)&1]->y(),
+		b[(signs>>2)&1]->z());
+	return(dot(p,v));
+}
+
+//
+DBVT_INLINE void		btDbvtAabbMm::AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const
+{
+	for(int i=0;i<3;++i)
+	{
+		if(d[i]<0)
+		{ smi+=mx[i]*d[i];smx+=mi[i]*d[i]; }
+		else
+		{ smi+=mi[i]*d[i];smx+=mx[i]*d[i]; }
+	}
+}
+
+//
+DBVT_INLINE bool		Intersect(	const btDbvtAabbMm& a,
+								  const btDbvtAabbMm& b)
+{
+#if	DBVT_INT0_IMPL == DBVT_IMPL_SSE
+	const __m128	rt(_mm_or_ps(	_mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)),
+		_mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi))));
+	const __int32*	pu((const __int32*)&rt);
+	return((pu[0]|pu[1]|pu[2])==0);
+#else
+	return(	(a.mi.x()<=b.mx.x())&&
+		(a.mx.x()>=b.mi.x())&&
+		(a.mi.y()<=b.mx.y())&&
+		(a.mx.y()>=b.mi.y())&&
+		(a.mi.z()<=b.mx.z())&&		
+		(a.mx.z()>=b.mi.z()));
+#endif
+}
+
+
+
+//
+DBVT_INLINE bool		Intersect(	const btDbvtAabbMm& a,
+								  const btVector3& b)
+{
+	return(	(b.x()>=a.mi.x())&&
+		(b.y()>=a.mi.y())&&
+		(b.z()>=a.mi.z())&&
+		(b.x()<=a.mx.x())&&
+		(b.y()<=a.mx.y())&&
+		(b.z()<=a.mx.z()));
+}
+
+
+
+
+
+//////////////////////////////////////
+
+
+//
+DBVT_INLINE btScalar	Proximity(	const btDbvtAabbMm& a,
+								  const btDbvtAabbMm& b)
+{
+	const btVector3	d=(a.mi+a.mx)-(b.mi+b.mx);
+	return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z()));
+}
+
+
+
+//
+DBVT_INLINE int			Select(	const btDbvtAabbMm& o,
+							   const btDbvtAabbMm& a,
+							   const btDbvtAabbMm& b)
+{
+#if	DBVT_SELECT_IMPL == DBVT_IMPL_SSE
+	static ATTRIBUTE_ALIGNED16(const unsigned __int32)	mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff};
+	///@todo: the intrinsic version is 11% slower
+#if DBVT_USE_INTRINSIC_SSE
+
+	union btSSEUnion ///NOTE: if we use more intrinsics, move btSSEUnion into the LinearMath directory
+	{
+	   __m128		ssereg;
+	   float		floats[4];
+	   int			ints[4];
+	};
+
+	__m128	omi(_mm_load_ps(o.mi));
+	omi=_mm_add_ps(omi,_mm_load_ps(o.mx));
+	__m128	ami(_mm_load_ps(a.mi));
+	ami=_mm_add_ps(ami,_mm_load_ps(a.mx));
+	ami=_mm_sub_ps(ami,omi);
+	ami=_mm_and_ps(ami,_mm_load_ps((const float*)mask));
+	__m128	bmi(_mm_load_ps(b.mi));
+	bmi=_mm_add_ps(bmi,_mm_load_ps(b.mx));
+	bmi=_mm_sub_ps(bmi,omi);
+	bmi=_mm_and_ps(bmi,_mm_load_ps((const float*)mask));
+	__m128	t0(_mm_movehl_ps(ami,ami));
+	ami=_mm_add_ps(ami,t0);
+	ami=_mm_add_ss(ami,_mm_shuffle_ps(ami,ami,1));
+	__m128 t1(_mm_movehl_ps(bmi,bmi));
+	bmi=_mm_add_ps(bmi,t1);
+	bmi=_mm_add_ss(bmi,_mm_shuffle_ps(bmi,bmi,1));
+	
+	btSSEUnion tmp;
+	tmp.ssereg = _mm_cmple_ss(bmi,ami);
+	return tmp.ints[0]&1;
+
+#else
+	ATTRIBUTE_ALIGNED16(__int32	r[1]);
+	__asm
+	{
+		mov		eax,o
+			mov		ecx,a
+			mov		edx,b
+			movaps	xmm0,[eax]
+		movaps	xmm5,mask
+			addps	xmm0,[eax+16]	
+		movaps	xmm1,[ecx]
+		movaps	xmm2,[edx]
+		addps	xmm1,[ecx+16]
+		addps	xmm2,[edx+16]
+		subps	xmm1,xmm0
+			subps	xmm2,xmm0
+			andps	xmm1,xmm5
+			andps	xmm2,xmm5
+			movhlps	xmm3,xmm1
+			movhlps	xmm4,xmm2
+			addps	xmm1,xmm3
+			addps	xmm2,xmm4
+			pshufd	xmm3,xmm1,1
+			pshufd	xmm4,xmm2,1
+			addss	xmm1,xmm3
+			addss	xmm2,xmm4
+			cmpless	xmm2,xmm1
+			movss	r,xmm2
+	}
+	return(r[0]&1);
+#endif
+#else
+	return(Proximity(o,a)<Proximity(o,b)?0:1);
+#endif
+}
+
+//
+DBVT_INLINE void		Merge(	const btDbvtAabbMm& a,
+							  const btDbvtAabbMm& b,
+							  btDbvtAabbMm& r)
+{
+#if DBVT_MERGE_IMPL==DBVT_IMPL_SSE
+	__m128	ami(_mm_load_ps(a.mi));
+	__m128	amx(_mm_load_ps(a.mx));
+	__m128	bmi(_mm_load_ps(b.mi));
+	__m128	bmx(_mm_load_ps(b.mx));
+	ami=_mm_min_ps(ami,bmi);
+	amx=_mm_max_ps(amx,bmx);
+	_mm_store_ps(r.mi,ami);
+	_mm_store_ps(r.mx,amx);
+#else
+	for(int i=0;i<3;++i)
+	{
+		if(a.mi[i]<b.mi[i]) r.mi[i]=a.mi[i]; else r.mi[i]=b.mi[i];
+		if(a.mx[i]>b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i];
+	}
+#endif
+}
+
+//
+DBVT_INLINE bool		NotEqual(	const btDbvtAabbMm& a,
+								 const btDbvtAabbMm& b)
+{
+	return(	(a.mi.x()!=b.mi.x())||
+		(a.mi.y()!=b.mi.y())||
+		(a.mi.z()!=b.mi.z())||
+		(a.mx.x()!=b.mx.x())||
+		(a.mx.y()!=b.mx.y())||
+		(a.mx.z()!=b.mx.z()));
+}
+
+//
+// Inline's
+//
+
+//
+DBVT_PREFIX
+inline void		btDbvt::enumNodes(	const btDbvtNode* root,
+								  DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		policy.Process(root);
+	if(root->isinternal())
+	{
+		enumNodes(root->childs[0],policy);
+		enumNodes(root->childs[1],policy);
+	}
+}
+
+//
+DBVT_PREFIX
+inline void		btDbvt::enumLeaves(	const btDbvtNode* root,
+								   DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root->isinternal())
+		{
+			enumLeaves(root->childs[0],policy);
+			enumLeaves(root->childs[1],policy);
+		}
+		else
+		{
+			policy.Process(root);
+		}
+}
+
+//
+DBVT_PREFIX
+inline void		btDbvt::collideTT(	const btDbvtNode* root0,
+								  const btDbvtNode* root1,
+								  DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root0&&root1)
+		{
+			int								depth=1;
+			int								treshold=DOUBLE_STACKSIZE-4;
+			btAlignedObjectArray<sStkNN>	stkStack;
+			stkStack.resize(DOUBLE_STACKSIZE);
+			stkStack[0]=sStkNN(root0,root1);
+			do	{		
+				sStkNN	p=stkStack[--depth];
+				if(depth>treshold)
+				{
+					stkStack.resize(stkStack.size()*2);
+					treshold=stkStack.size()-4;
+				}
+				if(p.a==p.b)
+				{
+					if(p.a->isinternal())
+					{
+						stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
+						stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
+						stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
+					}
+				}
+				else if(Intersect(p.a->volume,p.b->volume))
+				{
+					if(p.a->isinternal())
+					{
+						if(p.b->isinternal())
+						{
+							stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
+							stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
+							stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
+							stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+						}
+						else
+						{
+							stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
+							stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
+						}
+					}
+					else
+					{
+						if(p.b->isinternal())
+						{
+							stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
+							stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
+						}
+						else
+						{
+							policy.Process(p.a,p.b);
+						}
+					}
+				}
+			} while(depth);
+		}
+}
+
+
+
+DBVT_PREFIX
+inline void		btDbvt::collideTTpersistentStack(	const btDbvtNode* root0,
+								  const btDbvtNode* root1,
+								  DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root0&&root1)
+		{
+			int								depth=1;
+			int								treshold=DOUBLE_STACKSIZE-4;
+			
+			m_stkStack.resize(DOUBLE_STACKSIZE);
+			m_stkStack[0]=sStkNN(root0,root1);
+			do	{		
+				sStkNN	p=m_stkStack[--depth];
+				if(depth>treshold)
+				{
+					m_stkStack.resize(m_stkStack.size()*2);
+					treshold=m_stkStack.size()-4;
+				}
+				if(p.a==p.b)
+				{
+					if(p.a->isinternal())
+					{
+						m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]);
+						m_stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]);
+						m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]);
+					}
+				}
+				else if(Intersect(p.a->volume,p.b->volume))
+				{
+					if(p.a->isinternal())
+					{
+						if(p.b->isinternal())
+						{
+							m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
+							m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
+							m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
+							m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+						}
+						else
+						{
+							m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
+							m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
+						}
+					}
+					else
+					{
+						if(p.b->isinternal())
+						{
+							m_stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
+							m_stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
+						}
+						else
+						{
+							policy.Process(p.a,p.b);
+						}
+					}
+				}
+			} while(depth);
+		}
+}
+
+#if 0
+//
+DBVT_PREFIX
+inline void		btDbvt::collideTT(	const btDbvtNode* root0,
+								  const btDbvtNode* root1,
+								  const btTransform& xform,
+								  DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root0&&root1)
+		{
+			int								depth=1;
+			int								treshold=DOUBLE_STACKSIZE-4;
+			btAlignedObjectArray<sStkNN>	stkStack;
+			stkStack.resize(DOUBLE_STACKSIZE);
+			stkStack[0]=sStkNN(root0,root1);
+			do	{
+				sStkNN	p=stkStack[--depth];
+				if(Intersect(p.a->volume,p.b->volume,xform))
+				{
+					if(depth>treshold)
+					{
+						stkStack.resize(stkStack.size()*2);
+						treshold=stkStack.size()-4;
+					}
+					if(p.a->isinternal())
+					{
+						if(p.b->isinternal())
+						{					
+							stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]);
+							stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]);
+							stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]);
+							stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]);
+						}
+						else
+						{
+							stkStack[depth++]=sStkNN(p.a->childs[0],p.b);
+							stkStack[depth++]=sStkNN(p.a->childs[1],p.b);
+						}
+					}
+					else
+					{
+						if(p.b->isinternal())
+						{
+							stkStack[depth++]=sStkNN(p.a,p.b->childs[0]);
+							stkStack[depth++]=sStkNN(p.a,p.b->childs[1]);
+						}
+						else
+						{
+							policy.Process(p.a,p.b);
+						}
+					}
+				}
+			} while(depth);
+		}
+}
+//
+DBVT_PREFIX
+inline void		btDbvt::collideTT(	const btDbvtNode* root0,
+								  const btTransform& xform0,
+								  const btDbvtNode* root1,
+								  const btTransform& xform1,
+								  DBVT_IPOLICY)
+{
+	const btTransform	xform=xform0.inverse()*xform1;
+	collideTT(root0,root1,xform,policy);
+}
+#endif 
+
+//
+DBVT_PREFIX
+inline void		btDbvt::collideTV(	const btDbvtNode* root,
+								  const btDbvtVolume& vol,
+								  DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root)
+		{
+			ATTRIBUTE_ALIGNED16(btDbvtVolume)		volume(vol);
+			btAlignedObjectArray<const btDbvtNode*>	stack;
+			stack.resize(0);
+			stack.reserve(SIMPLE_STACKSIZE);
+			stack.push_back(root);
+			do	{
+				const btDbvtNode*	n=stack[stack.size()-1];
+				stack.pop_back();
+				if(Intersect(n->volume,volume))
+				{
+					if(n->isinternal())
+					{
+						stack.push_back(n->childs[0]);
+						stack.push_back(n->childs[1]);
+					}
+					else
+					{
+						policy.Process(n);
+					}
+				}
+			} while(stack.size()>0);
+		}
+}
+
+DBVT_PREFIX
+inline void		btDbvt::rayTestInternal(	const btDbvtNode* root,
+								const btVector3& rayFrom,
+								const btVector3& rayTo,
+								const btVector3& rayDirectionInverse,
+								unsigned int signs[3],
+								btScalar lambda_max,
+								const btVector3& aabbMin,
+								const btVector3& aabbMax,
+								DBVT_IPOLICY) const
+{
+	DBVT_CHECKTYPE
+	if(root)
+	{
+		btVector3 resultNormal;
+
+		int								depth=1;
+		int								treshold=DOUBLE_STACKSIZE-2;
+		btAlignedObjectArray<const btDbvtNode*>	stack;
+		stack.resize(DOUBLE_STACKSIZE);
+		stack[0]=root;
+		btVector3 bounds[2];
+		do	
+		{
+			const btDbvtNode*	node=stack[--depth];
+			bounds[0] = node->volume.Mins()+aabbMin;
+			bounds[1] = node->volume.Maxs()+aabbMax;
+			btScalar tmin=1.f,lambda_min=0.f;
+			unsigned int result1=false;
+			result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
+			if(result1)
+			{
+				if(node->isinternal())
+				{
+					if(depth>treshold)
+					{
+						stack.resize(stack.size()*2);
+						treshold=stack.size()-2;
+					}
+					stack[depth++]=node->childs[0];
+					stack[depth++]=node->childs[1];
+				}
+				else
+				{
+					policy.Process(node);
+				}
+			}
+		} while(depth);
+	}
+}
+
+//
+DBVT_PREFIX
+inline void		btDbvt::rayTest(	const btDbvtNode* root,
+								const btVector3& rayFrom,
+								const btVector3& rayTo,
+								DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root)
+		{
+			btVector3 rayDir = (rayTo-rayFrom);
+			rayDir.normalize ();
+
+			///what about division by zero? --> just set rayDirection[i] to INF/1e30
+			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];
+			unsigned int signs[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
+
+			btScalar lambda_max = rayDir.dot(rayTo-rayFrom);
+
+			btVector3 resultNormal;
+
+			btAlignedObjectArray<const btDbvtNode*>	stack;
+
+			int								depth=1;
+			int								treshold=DOUBLE_STACKSIZE-2;
+
+			stack.resize(DOUBLE_STACKSIZE);
+			stack[0]=root;
+			btVector3 bounds[2];
+			do	{
+				const btDbvtNode*	node=stack[--depth];
+
+				bounds[0] = node->volume.Mins();
+				bounds[1] = node->volume.Maxs();
+				
+				btScalar tmin=1.f,lambda_min=0.f;
+				unsigned int result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max);
+
+#ifdef COMPARE_BTRAY_AABB2
+				btScalar param=1.f;
+				bool result2 = btRayAabb(rayFrom,rayTo,node->volume.Mins(),node->volume.Maxs(),param,resultNormal);
+				btAssert(result1 == result2);
+#endif //TEST_BTRAY_AABB2
+
+				if(result1)
+				{
+					if(node->isinternal())
+					{
+						if(depth>treshold)
+						{
+							stack.resize(stack.size()*2);
+							treshold=stack.size()-2;
+						}
+						stack[depth++]=node->childs[0];
+						stack[depth++]=node->childs[1];
+					}
+					else
+					{
+						policy.Process(node);
+					}
+				}
+			} while(depth);
+
+		}
+}
+
+//
+DBVT_PREFIX
+inline void		btDbvt::collideKDOP(const btDbvtNode* root,
+									const btVector3* normals,
+									const btScalar* offsets,
+									int count,
+									DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root)
+		{
+			const int						inside=(1<<count)-1;
+			btAlignedObjectArray<sStkNP>	stack;
+			int								signs[sizeof(unsigned)*8];
+			btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
+			for(int i=0;i<count;++i)
+			{
+				signs[i]=	((normals[i].x()>=0)?1:0)+
+					((normals[i].y()>=0)?2:0)+
+					((normals[i].z()>=0)?4:0);
+			}
+			stack.reserve(SIMPLE_STACKSIZE);
+			stack.push_back(sStkNP(root,0));
+			do	{
+				sStkNP	se=stack[stack.size()-1];
+				bool	out=false;
+				stack.pop_back();
+				for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
+				{
+					if(0==(se.mask&j))
+					{
+						const int	side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
+						switch(side)
+						{
+						case	-1:	out=true;break;
+						case	+1:	se.mask|=j;break;
+						}
+					}
+				}
+				if(!out)
+				{
+					if((se.mask!=inside)&&(se.node->isinternal()))
+					{
+						stack.push_back(sStkNP(se.node->childs[0],se.mask));
+						stack.push_back(sStkNP(se.node->childs[1],se.mask));
+					}
+					else
+					{
+						if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy);
+					}
+				}
+			} while(stack.size());
+		}
+}
+
+//
+DBVT_PREFIX
+inline void		btDbvt::collideOCL(	const btDbvtNode* root,
+								   const btVector3* normals,
+								   const btScalar* offsets,
+								   const btVector3& sortaxis,
+								   int count,
+								   DBVT_IPOLICY,
+								   bool fsort)
+{
+	DBVT_CHECKTYPE
+		if(root)
+		{
+			const unsigned					srtsgns=(sortaxis[0]>=0?1:0)+
+				(sortaxis[1]>=0?2:0)+
+				(sortaxis[2]>=0?4:0);
+			const int						inside=(1<<count)-1;
+			btAlignedObjectArray<sStkNPS>	stock;
+			btAlignedObjectArray<int>		ifree;
+			btAlignedObjectArray<int>		stack;
+			int								signs[sizeof(unsigned)*8];
+			btAssert(count<int (sizeof(signs)/sizeof(signs[0])));
+			for(int i=0;i<count;++i)
+			{
+				signs[i]=	((normals[i].x()>=0)?1:0)+
+					((normals[i].y()>=0)?2:0)+
+					((normals[i].z()>=0)?4:0);
+			}
+			stock.reserve(SIMPLE_STACKSIZE);
+			stack.reserve(SIMPLE_STACKSIZE);
+			ifree.reserve(SIMPLE_STACKSIZE);
+			stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns))));
+			do	{
+				const int	id=stack[stack.size()-1];
+				sStkNPS		se=stock[id];
+				stack.pop_back();ifree.push_back(id);
+				if(se.mask!=inside)
+				{
+					bool	out=false;
+					for(int i=0,j=1;(!out)&&(i<count);++i,j<<=1)
+					{
+						if(0==(se.mask&j))
+						{
+							const int	side=se.node->volume.Classify(normals[i],offsets[i],signs[i]);
+							switch(side)
+							{
+							case	-1:	out=true;break;
+							case	+1:	se.mask|=j;break;
+							}
+						}
+					}
+					if(out) continue;
+				}
+				if(policy.Descent(se.node))
+				{
+					if(se.node->isinternal())
+					{
+						const btDbvtNode* pns[]={	se.node->childs[0],se.node->childs[1]};
+						sStkNPS		nes[]={	sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)),
+							sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))};
+						const int	q=nes[0].value<nes[1].value?1:0;				
+						int			j=stack.size();
+						if(fsort&&(j>0))
+						{
+							/* Insert 0	*/ 
+							j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size());
+							stack.push_back(0);
+#if DBVT_USE_MEMMOVE
+							memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
+#else
+							for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
+#endif
+							stack[j]=allocate(ifree,stock,nes[q]);
+							/* Insert 1	*/ 
+							j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size());
+							stack.push_back(0);
+#if DBVT_USE_MEMMOVE
+							memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1));
+#else
+							for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1];
+#endif
+							stack[j]=allocate(ifree,stock,nes[1-q]);
+						}
+						else
+						{
+							stack.push_back(allocate(ifree,stock,nes[q]));
+							stack.push_back(allocate(ifree,stock,nes[1-q]));
+						}
+					}
+					else
+					{
+						policy.Process(se.node,se.value);
+					}
+				}
+			} while(stack.size());
+		}
+}
+
+//
+DBVT_PREFIX
+inline void		btDbvt::collideTU(	const btDbvtNode* root,
+								  DBVT_IPOLICY)
+{
+	DBVT_CHECKTYPE
+		if(root)
+		{
+			btAlignedObjectArray<const btDbvtNode*>	stack;
+			stack.reserve(SIMPLE_STACKSIZE);
+			stack.push_back(root);
+			do	{
+				const btDbvtNode*	n=stack[stack.size()-1];
+				stack.pop_back();
+				if(policy.Descent(n))
+				{
+					if(n->isinternal())
+					{ stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); }
+					else
+					{ policy.Process(n); }
+				}
+			} while(stack.size()>0);
+		}
+}
+
+//
+// PP Cleanup
+//
+
+#undef DBVT_USE_MEMMOVE
+#undef DBVT_USE_TEMPLATE
+#undef DBVT_VIRTUAL_DTOR
+#undef DBVT_VIRTUAL
+#undef DBVT_PREFIX
+#undef DBVT_IPOLICY
+#undef DBVT_CHECKTYPE
+#undef DBVT_IMPL_GENERIC
+#undef DBVT_IMPL_SSE
+#undef DBVT_USE_INTRINSIC_SSE
+#undef DBVT_SELECT_IMPL
+#undef DBVT_MERGE_IMPL
+#undef DBVT_INT0_IMPL
+
+#endif
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp	(revision 6952)
@@ -0,0 +1,727 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2007 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.
+*/
+///btDbvtBroadphase implementation by Nathanael Presson
+
+#include "btDbvtBroadphase.h"
+
+//
+// Profiling
+//
+
+#if DBVT_BP_PROFILE||DBVT_BP_ENABLE_BENCHMARK
+#include <stdio.h>
+#endif
+
+#if DBVT_BP_PROFILE
+struct	ProfileScope
+{
+	__forceinline ProfileScope(btClock& clock,unsigned long& value) :
+	m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds())
+	{
+	}
+	__forceinline ~ProfileScope()
+	{
+		(*m_value)+=m_clock->getTimeMicroseconds()-m_base;
+	}
+	btClock*		m_clock;
+	unsigned long*	m_value;
+	unsigned long	m_base;
+};
+#define	SPC(_value_)	ProfileScope	spc_scope(m_clock,_value_)
+#else
+#define	SPC(_value_)
+#endif
+
+//
+// Helpers
+//
+
+//
+template <typename T>
+static inline void	listappend(T* item,T*& list)
+{
+	item->links[0]=0;
+	item->links[1]=list;
+	if(list) list->links[0]=item;
+	list=item;
+}
+
+//
+template <typename T>
+static inline void	listremove(T* item,T*& list)
+{
+	if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1];
+	if(item->links[1]) item->links[1]->links[0]=item->links[0];
+}
+
+//
+template <typename T>
+static inline int	listcount(T* root)
+{
+	int	n=0;
+	while(root) { ++n;root=root->links[1]; }
+	return(n);
+}
+
+//
+template <typename T>
+static inline void	clear(T& value)
+{
+	static const struct ZeroDummy : T {} zerodummy;
+	value=zerodummy;
+}
+
+//
+// Colliders
+//
+
+/* Tree collider	*/ 
+struct	btDbvtTreeCollider : btDbvt::ICollide
+{
+	btDbvtBroadphase*	pbp;
+	btDbvtProxy*		proxy;
+	btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {}
+	void	Process(const btDbvtNode* na,const btDbvtNode* nb)
+	{
+		if(na!=nb)
+		{
+			btDbvtProxy*	pa=(btDbvtProxy*)na->data;
+			btDbvtProxy*	pb=(btDbvtProxy*)nb->data;
+#if DBVT_BP_SORTPAIRS
+			if(pa->m_uniqueId>pb->m_uniqueId) 
+				btSwap(pa,pb);
+#endif
+			pbp->m_paircache->addOverlappingPair(pa,pb);
+			++pbp->m_newpairs;
+		}
+	}
+	void	Process(const btDbvtNode* n)
+	{
+		Process(n,proxy->leaf);
+	}
+};
+
+//
+// btDbvtBroadphase
+//
+
+//
+btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache)
+{
+	m_deferedcollide	=	false;
+	m_needcleanup		=	true;
+	m_releasepaircache	=	(paircache!=0)?false:true;
+	m_prediction		=	1/(btScalar)2;
+	m_stageCurrent		=	0;
+	m_fixedleft			=	0;
+	m_fupdates			=	1;
+	m_dupdates			=	0;
+	m_cupdates			=	10;
+	m_newpairs			=	1;
+	m_updates_call		=	0;
+	m_updates_done		=	0;
+	m_updates_ratio		=	0;
+	m_paircache			=	paircache? paircache	: new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
+	m_gid				=	0;
+	m_pid				=	0;
+	m_cid				=	0;
+	for(int i=0;i<=STAGECOUNT;++i)
+	{
+		m_stageRoots[i]=0;
+	}
+#if DBVT_BP_PROFILE
+	clear(m_profiling);
+#endif
+}
+
+//
+btDbvtBroadphase::~btDbvtBroadphase()
+{
+	if(m_releasepaircache) 
+	{
+		m_paircache->~btOverlappingPairCache();
+		btAlignedFree(m_paircache);
+	}
+}
+
+//
+btBroadphaseProxy*				btDbvtBroadphase::createProxy(	const btVector3& aabbMin,
+															  const btVector3& aabbMax,
+															  int /*shapeType*/,
+															  void* userPtr,
+															  short int collisionFilterGroup,
+															  short int collisionFilterMask,
+															  btDispatcher* /*dispatcher*/,
+															  void* /*multiSapProxy*/)
+{
+	btDbvtProxy*		proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy(	aabbMin,aabbMax,userPtr,
+		collisionFilterGroup,
+		collisionFilterMask);
+
+	btDbvtAabbMm aabb = btDbvtVolume::FromMM(aabbMin,aabbMax);
+
+	//bproxy->aabb			=	btDbvtVolume::FromMM(aabbMin,aabbMax);
+	proxy->stage		=	m_stageCurrent;
+	proxy->m_uniqueId	=	++m_gid;
+	proxy->leaf			=	m_sets[0].insert(aabb,proxy);
+	listappend(proxy,m_stageRoots[m_stageCurrent]);
+	if(!m_deferedcollide)
+	{
+		btDbvtTreeCollider	collider(this);
+		collider.proxy=proxy;
+		m_sets[0].collideTV(m_sets[0].m_root,aabb,collider);
+		m_sets[1].collideTV(m_sets[1].m_root,aabb,collider);
+	}
+	return(proxy);
+}
+
+//
+void							btDbvtBroadphase::destroyProxy(	btBroadphaseProxy* absproxy,
+															   btDispatcher* dispatcher)
+{
+	btDbvtProxy*	proxy=(btDbvtProxy*)absproxy;
+	if(proxy->stage==STAGECOUNT)
+		m_sets[1].remove(proxy->leaf);
+	else
+		m_sets[0].remove(proxy->leaf);
+	listremove(proxy,m_stageRoots[proxy->stage]);
+	m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher);
+	btAlignedFree(proxy);
+	m_needcleanup=true;
+}
+
+void	btDbvtBroadphase::getAabb(btBroadphaseProxy* absproxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+	btDbvtProxy*						proxy=(btDbvtProxy*)absproxy;
+	aabbMin = proxy->m_aabbMin;
+	aabbMax = proxy->m_aabbMax;
+}
+
+struct	BroadphaseRayTester : btDbvt::ICollide
+{
+	btBroadphaseRayCallback& m_rayCallback;
+	BroadphaseRayTester(btBroadphaseRayCallback& orgCallback)
+		:m_rayCallback(orgCallback)
+	{
+	}
+	void					Process(const btDbvtNode* leaf)
+	{
+		btDbvtProxy*	proxy=(btDbvtProxy*)leaf->data;
+		m_rayCallback.process(proxy);
+	}
+};	
+
+void	btDbvtBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax)
+{
+	BroadphaseRayTester callback(rayCallback);
+
+	m_sets[0].rayTestInternal(	m_sets[0].m_root,
+		rayFrom,
+		rayTo,
+		rayCallback.m_rayDirectionInverse,
+		rayCallback.m_signs,
+		rayCallback.m_lambda_max,
+		aabbMin,
+		aabbMax,
+		callback);
+
+	m_sets[1].rayTestInternal(	m_sets[1].m_root,
+		rayFrom,
+		rayTo,
+		rayCallback.m_rayDirectionInverse,
+		rayCallback.m_signs,
+		rayCallback.m_lambda_max,
+		aabbMin,
+		aabbMax,
+		callback);
+
+}
+
+//
+void							btDbvtBroadphase::setAabb(		btBroadphaseProxy* absproxy,
+														  const btVector3& aabbMin,
+														  const btVector3& aabbMax,
+														  btDispatcher* /*dispatcher*/)
+{
+	btDbvtProxy*						proxy=(btDbvtProxy*)absproxy;
+	ATTRIBUTE_ALIGNED16(btDbvtVolume)	aabb=btDbvtVolume::FromMM(aabbMin,aabbMax);
+#if DBVT_BP_PREVENTFALSEUPDATE
+	if(NotEqual(aabb,proxy->leaf->volume))
+#endif
+	{
+		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;
+			if(Intersect(proxy->leaf->volume,aabb))
+			{/* Moving				*/ 
+
+				const btVector3	delta=aabbMin-proxy->m_aabbMin;
+				btVector3		velocity(((proxy->m_aabbMax-proxy->m_aabbMin)/2)*m_prediction);
+				if(delta[0]<0) velocity[0]=-velocity[0];
+				if(delta[1]<0) velocity[1]=-velocity[1];
+				if(delta[2]<0) velocity[2]=-velocity[2];
+				if	(
+#ifdef DBVT_BP_MARGIN				
+					m_sets[0].update(proxy->leaf,aabb,velocity,DBVT_BP_MARGIN)
+#else
+					m_sets[0].update(proxy->leaf,aabb,velocity)
+#endif
+					)
+				{
+					++m_updates_done;
+					docollide=true;
+				}
+			}
+			else
+			{/* Teleporting			*/ 
+				m_sets[0].update(proxy->leaf,aabb);
+				++m_updates_done;
+				docollide=true;
+			}	
+		}
+		listremove(proxy,m_stageRoots[proxy->stage]);
+		proxy->m_aabbMin = aabbMin;
+		proxy->m_aabbMax = aabbMax;
+		proxy->stage	=	m_stageCurrent;
+		listappend(proxy,m_stageRoots[m_stageCurrent]);
+		if(docollide)
+		{
+			m_needcleanup=true;
+			if(!m_deferedcollide)
+			{
+				btDbvtTreeCollider	collider(this);
+				m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider);
+				m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider);
+			}
+		}	
+	}
+}
+
+//
+void							btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
+{
+	collide(dispatcher);
+#if DBVT_BP_PROFILE
+	if(0==(m_pid%DBVT_BP_PROFILING_RATE))
+	{	
+		printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs());
+		unsigned int	total=m_profiling.m_total;
+		if(total<=0) total=1;
+		printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE);
+		printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE);
+		printf("cleanup:   %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE);
+		printf("total:     %uus\r\n",total/DBVT_BP_PROFILING_RATE);
+		const unsigned long	sum=m_profiling.m_ddcollide+
+			m_profiling.m_fdcollide+
+			m_profiling.m_cleanup;
+		printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE);
+		printf("job counts: %u%%\r\n",(m_profiling.m_jobcount*100)/((m_sets[0].m_leaves+m_sets[1].m_leaves)*DBVT_BP_PROFILING_RATE));
+		clear(m_profiling);
+		m_clock.reset();
+	}
+#endif
+
+	performDeferredRemoval(dispatcher);
+
+}
+
+void btDbvtBroadphase::performDeferredRemoval(btDispatcher* dispatcher)
+{
+
+	if (m_paircache->hasDeferredRemoval())
+	{
+
+		btBroadphasePairArray&	overlappingPairArray = m_paircache->getOverlappingPairArray();
+
+		//perform a sort, to find duplicates and to sort 'invalid' pairs to the end
+		overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
+
+		int invalidPair = 0;
+
+		
+		int i;
+
+		btBroadphasePair previousPair;
+		previousPair.m_pProxy0 = 0;
+		previousPair.m_pProxy1 = 0;
+		previousPair.m_algorithm = 0;
+		
+		
+		for (i=0;i<overlappingPairArray.size();i++)
+		{
+		
+			btBroadphasePair& pair = overlappingPairArray[i];
+
+			bool isDuplicate = (pair == previousPair);
+
+			previousPair = pair;
+
+			bool needsRemoval = false;
+
+			if (!isDuplicate)
+			{
+				//important to perform AABB check that is consistent with the broadphase
+				btDbvtProxy*		pa=(btDbvtProxy*)pair.m_pProxy0;
+				btDbvtProxy*		pb=(btDbvtProxy*)pair.m_pProxy1;
+				bool hasOverlap = Intersect(pa->leaf->volume,pb->leaf->volume);
+
+				if (hasOverlap)
+				{
+					needsRemoval = false;
+				} else
+				{
+					needsRemoval = true;
+				}
+			} else
+			{
+				//remove duplicate
+				needsRemoval = true;
+				//should have no algorithm
+				btAssert(!pair.m_algorithm);
+			}
+			
+			if (needsRemoval)
+			{
+				m_paircache->cleanOverlappingPair(pair,dispatcher);
+
+				pair.m_pProxy0 = 0;
+				pair.m_pProxy1 = 0;
+				invalidPair++;
+			} 
+			
+		}
+
+		//perform a sort, to sort 'invalid' pairs to the end
+		overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
+		overlappingPairArray.resize(overlappingPairArray.size() - invalidPair);
+	}
+}
+
+//
+void							btDbvtBroadphase::collide(btDispatcher* dispatcher)
+{
+	/*printf("---------------------------------------------------------\n");
+	printf("m_sets[0].m_leaves=%d\n",m_sets[0].m_leaves);
+	printf("m_sets[1].m_leaves=%d\n",m_sets[1].m_leaves);
+	printf("numPairs = %d\n",getOverlappingPairCache()->getNumOverlappingPairs());
+	{
+		int i;
+		for (i=0;i<getOverlappingPairCache()->getNumOverlappingPairs();i++)
+		{
+			printf("pair[%d]=(%d,%d),",i,getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy0->getUid(),
+				getOverlappingPairCache()->getOverlappingPairArray()[i].m_pProxy1->getUid());
+		}
+		printf("\n");
+	}
+*/
+
+
+
+	SPC(m_profiling.m_total);
+	/* optimize				*/ 
+	m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100);
+	if(m_fixedleft)
+	{
+		const int count=1+(m_sets[1].m_leaves*m_fupdates)/100;
+		m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100);
+		m_fixedleft=btMax<int>(0,m_fixedleft-count);
+	}
+	/* dynamic -> fixed set	*/ 
+	m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT;
+	btDbvtProxy*	current=m_stageRoots[m_stageCurrent];
+	if(current)
+	{
+		btDbvtTreeCollider	collider(this);
+		do	{
+			btDbvtProxy*	next=current->links[1];
+			listremove(current,m_stageRoots[current->stage]);
+			listappend(current,m_stageRoots[STAGECOUNT]);
+#if DBVT_BP_ACCURATESLEEPING
+			m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher);
+			collider.proxy=current;
+			btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider);
+			btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider);
+#endif
+			m_sets[0].remove(current->leaf);
+			ATTRIBUTE_ALIGNED16(btDbvtVolume)	curAabb=btDbvtVolume::FromMM(current->m_aabbMin,current->m_aabbMax);
+			current->leaf	=	m_sets[1].insert(curAabb,current);
+			current->stage	=	STAGECOUNT;	
+			current			=	next;
+		} while(current);
+		m_fixedleft=m_sets[1].m_leaves;
+		m_needcleanup=true;
+	}
+	/* collide dynamics		*/ 
+	{
+		btDbvtTreeCollider	collider(this);
+		if(m_deferedcollide)
+		{
+			SPC(m_profiling.m_fdcollide);
+			m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[1].m_root,collider);
+		}
+		if(m_deferedcollide)
+		{
+			SPC(m_profiling.m_ddcollide);
+			m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[0].m_root,collider);
+		}
+	}
+	/* clean up				*/ 
+	if(m_needcleanup)
+	{
+		SPC(m_profiling.m_cleanup);
+		btBroadphasePairArray&	pairs=m_paircache->getOverlappingPairArray();
+		if(pairs.size()>0)
+		{
+
+			int			ni=btMin(pairs.size(),btMax<int>(m_newpairs,(pairs.size()*m_cupdates)/100));
+			for(int i=0;i<ni;++i)
+			{
+				btBroadphasePair&	p=pairs[(m_cid+i)%pairs.size()];
+				btDbvtProxy*		pa=(btDbvtProxy*)p.m_pProxy0;
+				btDbvtProxy*		pb=(btDbvtProxy*)p.m_pProxy1;
+				if(!Intersect(pa->leaf->volume,pb->leaf->volume))
+				{
+#if DBVT_BP_SORTPAIRS
+					if(pa->m_uniqueId>pb->m_uniqueId) 
+						btSwap(pa,pb);
+#endif
+					m_paircache->removeOverlappingPair(pa,pb,dispatcher);
+					--ni;--i;
+				}
+			}
+			if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0;
+		}
+	}
+	++m_pid;
+	m_newpairs=1;
+	m_needcleanup=false;
+	if(m_updates_call>0)
+	{ m_updates_ratio=m_updates_done/(btScalar)m_updates_call; }
+	else
+	{ m_updates_ratio=0; }
+	m_updates_done/=2;
+	m_updates_call/=2;
+}
+
+//
+void							btDbvtBroadphase::optimize()
+{
+	m_sets[0].optimizeTopDown();
+	m_sets[1].optimizeTopDown();
+}
+
+//
+btOverlappingPairCache*			btDbvtBroadphase::getOverlappingPairCache()
+{
+	return(m_paircache);
+}
+
+//
+const btOverlappingPairCache*	btDbvtBroadphase::getOverlappingPairCache() const
+{
+	return(m_paircache);
+}
+
+//
+void							btDbvtBroadphase::getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
+{
+
+	ATTRIBUTE_ALIGNED16(btDbvtVolume)	bounds;
+
+	if(!m_sets[0].empty())
+		if(!m_sets[1].empty())	Merge(	m_sets[0].m_root->volume,
+			m_sets[1].m_root->volume,bounds);
+		else
+			bounds=m_sets[0].m_root->volume;
+	else if(!m_sets[1].empty())	bounds=m_sets[1].m_root->volume;
+	else
+		bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0);
+	aabbMin=bounds.Mins();
+	aabbMax=bounds.Maxs();
+}
+
+void btDbvtBroadphase::resetPool(btDispatcher* dispatcher)
+{
+	
+	int totalObjects = m_sets[0].m_leaves + m_sets[1].m_leaves;
+	if (!totalObjects)
+	{
+		//reset internal dynamic tree data structures
+		m_sets[0].clear();
+		m_sets[1].clear();
+		
+		m_deferedcollide	=	false;
+		m_needcleanup		=	true;
+		m_prediction		=	1/(btScalar)2;
+		m_stageCurrent		=	0;
+		m_fixedleft			=	0;
+		m_fupdates			=	1;
+		m_dupdates			=	0;
+		m_cupdates			=	10;
+		m_newpairs			=	1;
+		m_updates_call		=	0;
+		m_updates_done		=	0;
+		m_updates_ratio		=	0;
+		
+		m_gid				=	0;
+		m_pid				=	0;
+		m_cid				=	0;
+		for(int i=0;i<=STAGECOUNT;++i)
+		{
+			m_stageRoots[i]=0;
+		}
+	}
+}
+
+//
+void							btDbvtBroadphase::printStats()
+{}
+
+//
+#if DBVT_BP_ENABLE_BENCHMARK
+
+struct	btBroadphaseBenchmark
+{
+	struct	Experiment
+	{
+		const char*			name;
+		int					object_count;
+		int					update_count;
+		int					spawn_count;
+		int					iterations;
+		btScalar			speed;
+		btScalar			amplitude;
+	};
+	struct	Object
+	{
+		btVector3			center;
+		btVector3			extents;
+		btBroadphaseProxy*	proxy;
+		btScalar			time;
+		void				update(btScalar speed,btScalar amplitude,btBroadphaseInterface* pbi)
+		{
+			time		+=	speed;
+			center[0]	=	btCos(time*(btScalar)2.17)*amplitude+
+				btSin(time)*amplitude/2;
+			center[1]	=	btCos(time*(btScalar)1.38)*amplitude+
+				btSin(time)*amplitude;
+			center[2]	=	btSin(time*(btScalar)0.777)*amplitude;
+			pbi->setAabb(proxy,center-extents,center+extents,0);
+		}
+	};
+	static int		UnsignedRand(int range=RAND_MAX-1)	{ return(rand()%(range+1)); }
+	static btScalar	UnitRand()							{ return(UnsignedRand(16384)/(btScalar)16384); }
+	static void		OutputTime(const char* name,btClock& c,unsigned count=0)
+	{
+		const unsigned long	us=c.getTimeMicroseconds();
+		const unsigned long	ms=(us+500)/1000;
+		const btScalar		sec=us/(btScalar)(1000*1000);
+		if(count>0)
+			printf("%s : %u us (%u ms), %.2f/s\r\n",name,us,ms,count/sec);
+		else
+			printf("%s : %u us (%u ms)\r\n",name,us,ms);
+	}
+};
+
+void							btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi)
+{
+	static const btBroadphaseBenchmark::Experiment		experiments[]=
+	{
+		{"1024o.10%",1024,10,0,8192,(btScalar)0.005,(btScalar)100},
+		/*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100},
+		{"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/
+	};
+	static const int										nexperiments=sizeof(experiments)/sizeof(experiments[0]);
+	btAlignedObjectArray<btBroadphaseBenchmark::Object*>	objects;
+	btClock													wallclock;
+	/* Begin			*/ 
+	for(int iexp=0;iexp<nexperiments;++iexp)
+	{
+		const btBroadphaseBenchmark::Experiment&	experiment=experiments[iexp];
+		const int									object_count=experiment.object_count;
+		const int									update_count=(object_count*experiment.update_count)/100;
+		const int									spawn_count=(object_count*experiment.spawn_count)/100;
+		const btScalar								speed=experiment.speed;	
+		const btScalar								amplitude=experiment.amplitude;
+		printf("Experiment #%u '%s':\r\n",iexp,experiment.name);
+		printf("\tObjects: %u\r\n",object_count);
+		printf("\tUpdate: %u\r\n",update_count);
+		printf("\tSpawn: %u\r\n",spawn_count);
+		printf("\tSpeed: %f\r\n",speed);
+		printf("\tAmplitude: %f\r\n",amplitude);
+		srand(180673);
+		/* Create objects	*/ 
+		wallclock.reset();
+		objects.reserve(object_count);
+		for(int i=0;i<object_count;++i)
+		{
+			btBroadphaseBenchmark::Object*	po=new btBroadphaseBenchmark::Object();
+			po->center[0]=btBroadphaseBenchmark::UnitRand()*50;
+			po->center[1]=btBroadphaseBenchmark::UnitRand()*50;
+			po->center[2]=btBroadphaseBenchmark::UnitRand()*50;
+			po->extents[0]=btBroadphaseBenchmark::UnitRand()*2+2;
+			po->extents[1]=btBroadphaseBenchmark::UnitRand()*2+2;
+			po->extents[2]=btBroadphaseBenchmark::UnitRand()*2+2;
+			po->time=btBroadphaseBenchmark::UnitRand()*2000;
+			po->proxy=pbi->createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0);
+			objects.push_back(po);
+		}
+		btBroadphaseBenchmark::OutputTime("\tInitialization",wallclock);
+		/* First update		*/ 
+		wallclock.reset();
+		for(int i=0;i<objects.size();++i)
+		{
+			objects[i]->update(speed,amplitude,pbi);
+		}
+		btBroadphaseBenchmark::OutputTime("\tFirst update",wallclock);
+		/* Updates			*/ 
+		wallclock.reset();
+		for(int i=0;i<experiment.iterations;++i)
+		{
+			for(int j=0;j<update_count;++j)
+			{				
+				objects[j]->update(speed,amplitude,pbi);
+			}
+			pbi->calculateOverlappingPairs(0);
+		}
+		btBroadphaseBenchmark::OutputTime("\tUpdate",wallclock,experiment.iterations);
+		/* Clean up			*/ 
+		wallclock.reset();
+		for(int i=0;i<objects.size();++i)
+		{
+			pbi->destroyProxy(objects[i]->proxy,0);
+			delete objects[i];
+		}
+		objects.resize(0);
+		btBroadphaseBenchmark::OutputTime("\tRelease",wallclock);
+	}
+
+}
+#else
+void							btDbvtBroadphase::benchmark(btBroadphaseInterface*)
+{}
+#endif
+
+#if DBVT_BP_PROFILE
+#undef	SPC
+#endif
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h	(revision 6952)
@@ -0,0 +1,126 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2007 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.
+*/
+///btDbvtBroadphase implementation by Nathanael Presson
+#ifndef BT_DBVT_BROADPHASE_H
+#define BT_DBVT_BROADPHASE_H
+
+#include "BulletCollision/BroadphaseCollision/btDbvt.h"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
+
+//
+// Compile time config
+//
+
+#define	DBVT_BP_PROFILE					0
+//#define DBVT_BP_SORTPAIRS				1
+#define DBVT_BP_PREVENTFALSEUPDATE		0
+#define DBVT_BP_ACCURATESLEEPING		0
+#define DBVT_BP_ENABLE_BENCHMARK		0
+#define DBVT_BP_MARGIN					(btScalar)0.05
+
+#if DBVT_BP_PROFILE
+#define	DBVT_BP_PROFILING_RATE	256
+#include "LinearMath/btQuickprof.h"
+#endif
+
+//
+// btDbvtProxy
+//
+struct btDbvtProxy : btBroadphaseProxy
+{
+	/* Fields		*/ 
+	//btDbvtAabbMm	aabb;
+	btDbvtNode*		leaf;
+	btDbvtProxy*	links[2];
+	int				stage;
+	/* ctor			*/ 
+	btDbvtProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr,short int collisionFilterGroup, short int collisionFilterMask) :
+	btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask)
+	{
+		links[0]=links[1]=0;
+	}
+};
+
+typedef btAlignedObjectArray<btDbvtProxy*>	btDbvtProxyArray;
+
+///The btDbvtBroadphase implements a broadphase using two dynamic AABB bounding volume hierarchies/trees (see btDbvt).
+///One tree is used for static/non-moving objects, and another tree is used for dynamic objects. Objects can move from one tree to the other.
+///This is a very fast broadphase, especially for very dynamic worlds where many objects are moving. Its insert/add and remove of objects is generally faster than the sweep and prune broadphases btAxisSweep3 and bt32BitAxisSweep3.
+struct	btDbvtBroadphase : btBroadphaseInterface
+{
+	/* Config		*/ 
+	enum	{
+		DYNAMIC_SET			=	0,	/* Dynamic set index	*/ 
+		FIXED_SET			=	1,	/* Fixed set index		*/ 
+		STAGECOUNT			=	2	/* Number of stages		*/ 
+	};
+	/* Fields		*/ 
+	btDbvt					m_sets[2];					// Dbvt sets
+	btDbvtProxy*			m_stageRoots[STAGECOUNT+1];	// Stages list
+	btOverlappingPairCache*	m_paircache;				// Pair cache
+	btScalar				m_prediction;				// Velocity prediction
+	int						m_stageCurrent;				// Current stage
+	int						m_fupdates;					// % of fixed updates per frame
+	int						m_dupdates;					// % of dynamic updates per frame
+	int						m_cupdates;					// % of cleanup updates per frame
+	int						m_newpairs;					// Number of pairs created
+	int						m_fixedleft;				// Fixed optimization left
+	unsigned				m_updates_call;				// Number of updates call
+	unsigned				m_updates_done;				// Number of updates done
+	btScalar				m_updates_ratio;			// m_updates_done/m_updates_call
+	int						m_pid;						// Parse id
+	int						m_cid;						// Cleanup index
+	int						m_gid;						// Gen id
+	bool					m_releasepaircache;			// Release pair cache on delete
+	bool					m_deferedcollide;			// Defere dynamic/static collision to collide call
+	bool					m_needcleanup;				// Need to run cleanup?
+#if DBVT_BP_PROFILE
+	btClock					m_clock;
+	struct	{
+		unsigned long		m_total;
+		unsigned long		m_ddcollide;
+		unsigned long		m_fdcollide;
+		unsigned long		m_cleanup;
+		unsigned long		m_jobcount;
+	}				m_profiling;
+#endif
+	/* Methods		*/ 
+	btDbvtBroadphase(btOverlappingPairCache* paircache=0);
+	~btDbvtBroadphase();
+	void							collide(btDispatcher* dispatcher);
+	void							optimize();
+	/* 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	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*);
+
+
+	void	performDeferredRemoval(btDispatcher* dispatcher);
+
+	///reset broadphase internal structures, to ensure determinism/reproducability
+	virtual void resetPool(btDispatcher* dispatcher);
+
+};
+
+#endif
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDispatcher.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDispatcher.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDispatcher.cpp	(revision 6952)
@@ -0,0 +1,22 @@
+/*
+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 "btDispatcher.h"
+
+btDispatcher::~btDispatcher()
+{
+
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDispatcher.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDispatcher.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btDispatcher.h	(revision 6952)
@@ -0,0 +1,106 @@
+/*
+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 _DISPATCHER_H
+#define _DISPATCHER_H
+
+#include "LinearMath/btScalar.h"
+
+class btCollisionAlgorithm;
+struct btBroadphaseProxy;
+class btRigidBody;
+class	btCollisionObject;
+class btOverlappingPairCache;
+
+
+class btPersistentManifold;
+class btStackAlloc;
+
+struct btDispatcherInfo
+{
+	enum DispatchFunc
+	{
+		DISPATCH_DISCRETE = 1,
+		DISPATCH_CONTINUOUS
+	};
+	btDispatcherInfo()
+		:m_timeStep(btScalar(0.)),
+		m_stepCount(0),
+		m_dispatchFunc(DISPATCH_DISCRETE),
+		m_timeOfImpact(btScalar(1.)),
+		m_useContinuous(false),
+		m_debugDraw(0),
+		m_enableSatConvex(false),
+		m_enableSPU(true),
+		m_useEpa(true),
+		m_allowedCcdPenetration(btScalar(0.04)),
+		m_useConvexConservativeDistanceUtil(true),
+		m_convexConservativeDistanceThreshold(0.0f),
+		m_stackAllocator(0)
+	{
+
+	}
+	btScalar	m_timeStep;
+	int			m_stepCount;
+	int			m_dispatchFunc;
+	mutable btScalar	m_timeOfImpact;
+	bool		m_useContinuous;
+	class btIDebugDraw*	m_debugDraw;
+	bool		m_enableSatConvex;
+	bool		m_enableSPU;
+	bool		m_useEpa;
+	btScalar	m_allowedCcdPenetration;
+	bool		m_useConvexConservativeDistanceUtil;
+	btScalar	m_convexConservativeDistanceThreshold;
+	btStackAlloc*	m_stackAllocator;
+};
+
+///The btDispatcher interface class can be used in combination with broadphase to dispatch calculations for overlapping pairs.
+///For example for pairwise collision detection, calculating contact points stored in btPersistentManifold or user callbacks (game logic).
+class btDispatcher
+{
+
+
+public:
+	virtual ~btDispatcher() ;
+
+	virtual btCollisionAlgorithm* findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold=0) = 0;
+
+	virtual btPersistentManifold*	getNewManifold(void* body0,void* body1)=0;
+
+	virtual void releaseManifold(btPersistentManifold* manifold)=0;
+
+	virtual void clearManifold(btPersistentManifold* manifold)=0;
+
+	virtual bool	needsCollision(btCollisionObject* body0,btCollisionObject* body1) = 0;
+
+	virtual bool	needsResponse(btCollisionObject* body0,btCollisionObject* body1)=0;
+
+	virtual void	dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher)  =0;
+
+	virtual int getNumManifolds() const = 0;
+
+	virtual btPersistentManifold* getManifoldByIndexInternal(int index) = 0;
+
+	virtual	btPersistentManifold**	getInternalManifoldPointer() = 0;
+
+	virtual	void* allocateCollisionAlgorithm(int size)  = 0;
+
+	virtual	void freeCollisionAlgorithm(void* ptr) = 0;
+
+};
+
+
+#endif //_DISPATCHER_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.cpp	(revision 6952)
@@ -0,0 +1,489 @@
+/*
+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 "btMultiSapBroadphase.h"
+
+#include "btSimpleBroadphase.h"
+#include "LinearMath/btAabbUtil2.h"
+#include "btQuantizedBvh.h"
+
+///	btSapBroadphaseArray	m_sapBroadphases;
+
+///	btOverlappingPairCache*	m_overlappingPairs;
+extern int gOverlappingPairs;
+
+/*
+class btMultiSapSortedOverlappingPairCache : public btSortedOverlappingPairCache
+{
+public:
+
+	virtual btBroadphasePair*	addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+	{
+		return btSortedOverlappingPairCache::addOverlappingPair((btBroadphaseProxy*)proxy0->m_multiSapParentProxy,(btBroadphaseProxy*)proxy1->m_multiSapParentProxy);
+	}
+};
+
+*/
+
+btMultiSapBroadphase::btMultiSapBroadphase(int /*maxProxies*/,btOverlappingPairCache* pairCache)
+:m_overlappingPairs(pairCache),
+m_optimizedAabbTree(0),
+m_ownsPairCache(false),
+m_invalidPair(0)
+{
+	if (!m_overlappingPairs)
+	{
+		m_ownsPairCache = true;
+		void* mem = btAlignedAlloc(sizeof(btSortedOverlappingPairCache),16);
+		m_overlappingPairs = new (mem)btSortedOverlappingPairCache();
+	}
+
+	struct btMultiSapOverlapFilterCallback : public btOverlapFilterCallback
+	{
+		virtual ~btMultiSapOverlapFilterCallback()
+		{}
+		// return true when pairs need collision
+		virtual bool	needBroadphaseCollision(btBroadphaseProxy* childProxy0,btBroadphaseProxy* childProxy1) const
+		{
+			btBroadphaseProxy* multiProxy0 = (btBroadphaseProxy*)childProxy0->m_multiSapParentProxy;
+			btBroadphaseProxy* multiProxy1 = (btBroadphaseProxy*)childProxy1->m_multiSapParentProxy;
+			
+			bool collides = (multiProxy0->m_collisionFilterGroup & multiProxy1->m_collisionFilterMask) != 0;
+			collides = collides && (multiProxy1->m_collisionFilterGroup & multiProxy0->m_collisionFilterMask);
+	
+			return collides;
+		}
+	};
+
+	void* mem = btAlignedAlloc(sizeof(btMultiSapOverlapFilterCallback),16);
+	m_filterCallback = new (mem)btMultiSapOverlapFilterCallback();
+
+	m_overlappingPairs->setOverlapFilterCallback(m_filterCallback);
+//	mem = btAlignedAlloc(sizeof(btSimpleBroadphase),16);
+//	m_simpleBroadphase = new (mem) btSimpleBroadphase(maxProxies,m_overlappingPairs);
+}
+
+btMultiSapBroadphase::~btMultiSapBroadphase()
+{
+	if (m_ownsPairCache)
+	{
+		m_overlappingPairs->~btOverlappingPairCache();
+		btAlignedFree(m_overlappingPairs);
+	}
+}
+
+
+void	btMultiSapBroadphase::buildTree(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax)
+{
+	m_optimizedAabbTree = new btQuantizedBvh();
+	m_optimizedAabbTree->setQuantizationValues(bvhAabbMin,bvhAabbMax);
+	QuantizedNodeArray&	nodes = m_optimizedAabbTree->getLeafNodeArray();
+	for (int i=0;i<m_sapBroadphases.size();i++)
+	{
+		btQuantizedBvhNode node;
+		btVector3 aabbMin,aabbMax;
+		m_sapBroadphases[i]->getBroadphaseAabb(aabbMin,aabbMax);
+		m_optimizedAabbTree->quantize(&node.m_quantizedAabbMin[0],aabbMin,0);
+		m_optimizedAabbTree->quantize(&node.m_quantizedAabbMax[0],aabbMax,1);
+		int partId = 0;
+		node.m_escapeIndexOrTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | i;
+		nodes.push_back(node);
+	}
+	m_optimizedAabbTree->buildInternal();
+}
+
+btBroadphaseProxy*	btMultiSapBroadphase::createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* /*ignoreMe*/)
+{
+	//void* ignoreMe -> we could think of recursive multi-sap, if someone is interested
+
+	void* mem = btAlignedAlloc(sizeof(btMultiSapProxy),16);
+	btMultiSapProxy* proxy = new (mem)btMultiSapProxy(aabbMin,  aabbMax,shapeType,userPtr, collisionFilterGroup,collisionFilterMask);
+	m_multiSapProxies.push_back(proxy);
+
+	///this should deal with inserting/removal into child broadphases
+	setAabb(proxy,aabbMin,aabbMax,dispatcher);
+	return proxy;
+}
+
+void	btMultiSapBroadphase::destroyProxy(btBroadphaseProxy* /*proxy*/,btDispatcher* /*dispatcher*/)
+{
+	///not yet
+	btAssert(0);
+
+}
+
+
+void	btMultiSapBroadphase::addToChildBroadphase(btMultiSapProxy* parentMultiSapProxy, btBroadphaseProxy* childProxy, btBroadphaseInterface*	childBroadphase)
+{
+	void* mem = btAlignedAlloc(sizeof(btBridgeProxy),16);
+	btBridgeProxy* bridgeProxyRef = new(mem) btBridgeProxy;
+	bridgeProxyRef->m_childProxy = childProxy;
+	bridgeProxyRef->m_childBroadphase = childBroadphase;
+	parentMultiSapProxy->m_bridgeProxies.push_back(bridgeProxyRef);
+}
+
+
+bool boxIsContainedWithinBox(const btVector3& amin,const btVector3& amax,const btVector3& bmin,const btVector3& bmax);
+bool boxIsContainedWithinBox(const btVector3& amin,const btVector3& amax,const btVector3& bmin,const btVector3& bmax)
+{
+return
+amin.getX() >= bmin.getX() && amax.getX() <= bmax.getX() &&
+amin.getY() >= bmin.getY() && amax.getY() <= bmax.getY() &&
+amin.getZ() >= bmin.getZ() && amax.getZ() <= bmax.getZ();
+}
+
+
+
+
+
+
+void	btMultiSapBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+	btMultiSapProxy* multiProxy = static_cast<btMultiSapProxy*>(proxy);
+	aabbMin = multiProxy->m_aabbMin;
+	aabbMax = multiProxy->m_aabbMax;
+}
+
+void	btMultiSapBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax)
+{
+	for (int i=0;i<m_multiSapProxies.size();i++)
+	{
+		rayCallback.process(m_multiSapProxies[i]);
+	}
+}
+
+
+//#include <stdio.h>
+
+void	btMultiSapBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)
+{
+	btMultiSapProxy* multiProxy = static_cast<btMultiSapProxy*>(proxy);
+	multiProxy->m_aabbMin = aabbMin;
+	multiProxy->m_aabbMax = aabbMax;
+	
+	
+//	bool fullyContained = false;
+//	bool alreadyInSimple = false;
+	
+
+
+	
+	struct MyNodeOverlapCallback : public btNodeOverlapCallback
+	{
+		btMultiSapBroadphase*	m_multiSap;
+		btMultiSapProxy*		m_multiProxy;
+		btDispatcher*			m_dispatcher;
+
+		MyNodeOverlapCallback(btMultiSapBroadphase* multiSap,btMultiSapProxy* multiProxy,btDispatcher* dispatcher)
+			:m_multiSap(multiSap),
+			m_multiProxy(multiProxy),
+			m_dispatcher(dispatcher)
+		{
+
+		}
+
+		virtual void processNode(int /*nodeSubPart*/, int broadphaseIndex)
+		{
+			btBroadphaseInterface* childBroadphase = m_multiSap->getBroadphaseArray()[broadphaseIndex];
+
+			int containingBroadphaseIndex = -1;
+			//already found?
+			for (int i=0;i<m_multiProxy->m_bridgeProxies.size();i++)
+			{
+
+				if (m_multiProxy->m_bridgeProxies[i]->m_childBroadphase == childBroadphase)
+				{
+					containingBroadphaseIndex = i;
+					break;
+				}
+			}
+			if (containingBroadphaseIndex<0)
+			{
+				//add it
+				btBroadphaseProxy* childProxy = childBroadphase->createProxy(m_multiProxy->m_aabbMin,m_multiProxy->m_aabbMax,m_multiProxy->m_shapeType,m_multiProxy->m_clientObject,m_multiProxy->m_collisionFilterGroup,m_multiProxy->m_collisionFilterMask, m_dispatcher,m_multiProxy);
+				m_multiSap->addToChildBroadphase(m_multiProxy,childProxy,childBroadphase);
+
+			}
+		}
+	};
+
+	MyNodeOverlapCallback	myNodeCallback(this,multiProxy,dispatcher);
+
+
+
+	
+	if (m_optimizedAabbTree)
+		m_optimizedAabbTree->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
+
+	int i;
+
+	for ( i=0;i<multiProxy->m_bridgeProxies.size();i++)
+	{
+		btVector3 worldAabbMin,worldAabbMax;
+		multiProxy->m_bridgeProxies[i]->m_childBroadphase->getBroadphaseAabb(worldAabbMin,worldAabbMax);
+		bool overlapsBroadphase = TestAabbAgainstAabb2(worldAabbMin,worldAabbMax,multiProxy->m_aabbMin,multiProxy->m_aabbMax);
+		if (!overlapsBroadphase)
+		{
+			//remove it now
+			btBridgeProxy* bridgeProxy = multiProxy->m_bridgeProxies[i];
+
+			btBroadphaseProxy* childProxy = bridgeProxy->m_childProxy;
+			bridgeProxy->m_childBroadphase->destroyProxy(childProxy,dispatcher);
+			
+			multiProxy->m_bridgeProxies.swap( i,multiProxy->m_bridgeProxies.size()-1);
+			multiProxy->m_bridgeProxies.pop_back();
+
+		}
+	}
+
+
+	/*
+
+	if (1)
+	{
+
+		//find broadphase that contain this multiProxy
+		int numChildBroadphases = getBroadphaseArray().size();
+		for (int i=0;i<numChildBroadphases;i++)
+		{
+			btBroadphaseInterface* childBroadphase = getBroadphaseArray()[i];
+			btVector3 worldAabbMin,worldAabbMax;
+			childBroadphase->getBroadphaseAabb(worldAabbMin,worldAabbMax);
+			bool overlapsBroadphase = TestAabbAgainstAabb2(worldAabbMin,worldAabbMax,multiProxy->m_aabbMin,multiProxy->m_aabbMax);
+			
+		//	fullyContained = fullyContained || boxIsContainedWithinBox(worldAabbMin,worldAabbMax,multiProxy->m_aabbMin,multiProxy->m_aabbMax);
+			int containingBroadphaseIndex = -1;
+			
+			//if already contains this
+			
+			for (int i=0;i<multiProxy->m_bridgeProxies.size();i++)
+			{
+				if (multiProxy->m_bridgeProxies[i]->m_childBroadphase == childBroadphase)
+				{
+					containingBroadphaseIndex = i;
+				}
+				alreadyInSimple = alreadyInSimple || (multiProxy->m_bridgeProxies[i]->m_childBroadphase == m_simpleBroadphase);
+			}
+
+			if (overlapsBroadphase)
+			{
+				if (containingBroadphaseIndex<0)
+				{
+					btBroadphaseProxy* childProxy = childBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher);
+					childProxy->m_multiSapParentProxy = multiProxy;
+					addToChildBroadphase(multiProxy,childProxy,childBroadphase);
+				}
+			} else
+			{
+				if (containingBroadphaseIndex>=0)
+				{
+					//remove
+					btBridgeProxy* bridgeProxy = multiProxy->m_bridgeProxies[containingBroadphaseIndex];
+
+					btBroadphaseProxy* childProxy = bridgeProxy->m_childProxy;
+					bridgeProxy->m_childBroadphase->destroyProxy(childProxy,dispatcher);
+					
+					multiProxy->m_bridgeProxies.swap( containingBroadphaseIndex,multiProxy->m_bridgeProxies.size()-1);
+					multiProxy->m_bridgeProxies.pop_back();
+				}
+			}
+		}
+
+
+		///If we are in no other child broadphase, stick the proxy in the global 'simple' broadphase (brute force)
+		///hopefully we don't end up with many entries here (can assert/provide feedback on stats)
+		if (0)//!multiProxy->m_bridgeProxies.size())
+		{
+			///we don't pass the userPtr but our multisap proxy. We need to patch this, before processing an actual collision
+			///this is needed to be able to calculate the aabb overlap
+			btBroadphaseProxy* childProxy = m_simpleBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher);
+			childProxy->m_multiSapParentProxy = multiProxy;
+			addToChildBroadphase(multiProxy,childProxy,m_simpleBroadphase);
+		}
+	}
+
+	if (!multiProxy->m_bridgeProxies.size())
+	{
+		///we don't pass the userPtr but our multisap proxy. We need to patch this, before processing an actual collision
+		///this is needed to be able to calculate the aabb overlap
+		btBroadphaseProxy* childProxy = m_simpleBroadphase->createProxy(aabbMin,aabbMax,multiProxy->m_shapeType,multiProxy->m_clientObject,multiProxy->m_collisionFilterGroup,multiProxy->m_collisionFilterMask, dispatcher);
+		childProxy->m_multiSapParentProxy = multiProxy;
+		addToChildBroadphase(multiProxy,childProxy,m_simpleBroadphase);
+	}
+*/
+
+
+	//update
+	for ( i=0;i<multiProxy->m_bridgeProxies.size();i++)
+	{
+		btBridgeProxy* bridgeProxyRef = multiProxy->m_bridgeProxies[i];
+		bridgeProxyRef->m_childBroadphase->setAabb(bridgeProxyRef->m_childProxy,aabbMin,aabbMax,dispatcher);
+	}
+
+}
+bool stopUpdating=false;
+
+
+
+class btMultiSapBroadphasePairSortPredicate
+{
+	public:
+
+		bool operator() ( const btBroadphasePair& a1, const btBroadphasePair& b1 )
+		{
+				btMultiSapBroadphase::btMultiSapProxy* aProxy0 = a1.m_pProxy0 ? (btMultiSapBroadphase::btMultiSapProxy*)a1.m_pProxy0->m_multiSapParentProxy : 0;
+				btMultiSapBroadphase::btMultiSapProxy* aProxy1 = a1.m_pProxy1 ? (btMultiSapBroadphase::btMultiSapProxy*)a1.m_pProxy1->m_multiSapParentProxy : 0;
+				btMultiSapBroadphase::btMultiSapProxy* bProxy0 = b1.m_pProxy0 ? (btMultiSapBroadphase::btMultiSapProxy*)b1.m_pProxy0->m_multiSapParentProxy : 0;
+				btMultiSapBroadphase::btMultiSapProxy* bProxy1 = b1.m_pProxy1 ? (btMultiSapBroadphase::btMultiSapProxy*)b1.m_pProxy1->m_multiSapParentProxy : 0;
+
+				 return aProxy0 > bProxy0 || 
+					(aProxy0 == bProxy0 && aProxy1 > bProxy1) ||
+					(aProxy0 == bProxy0 && aProxy1 == bProxy1 && a1.m_algorithm > b1.m_algorithm); 
+		}
+};
+
+
+        ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
+void    btMultiSapBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
+{
+
+//	m_simpleBroadphase->calculateOverlappingPairs(dispatcher);
+
+	if (!stopUpdating && getOverlappingPairCache()->hasDeferredRemoval())
+	{
+	
+		btBroadphasePairArray&	overlappingPairArray = getOverlappingPairCache()->getOverlappingPairArray();
+
+	//	quicksort(overlappingPairArray,0,overlappingPairArray.size());
+
+		overlappingPairArray.quickSort(btMultiSapBroadphasePairSortPredicate());
+
+		//perform a sort, to find duplicates and to sort 'invalid' pairs to the end
+	//	overlappingPairArray.heapSort(btMultiSapBroadphasePairSortPredicate());
+
+		overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
+		m_invalidPair = 0;
+
+		
+		int i;
+
+		btBroadphasePair previousPair;
+		previousPair.m_pProxy0 = 0;
+		previousPair.m_pProxy1 = 0;
+		previousPair.m_algorithm = 0;
+		
+		
+		for (i=0;i<overlappingPairArray.size();i++)
+		{
+		
+			btBroadphasePair& pair = overlappingPairArray[i];
+
+			btMultiSapProxy* aProxy0 = pair.m_pProxy0 ? (btMultiSapProxy*)pair.m_pProxy0->m_multiSapParentProxy : 0;
+			btMultiSapProxy* aProxy1 = pair.m_pProxy1 ? (btMultiSapProxy*)pair.m_pProxy1->m_multiSapParentProxy : 0;
+			btMultiSapProxy* bProxy0 = previousPair.m_pProxy0 ? (btMultiSapProxy*)previousPair.m_pProxy0->m_multiSapParentProxy : 0;
+			btMultiSapProxy* bProxy1 = previousPair.m_pProxy1 ? (btMultiSapProxy*)previousPair.m_pProxy1->m_multiSapParentProxy : 0;
+
+			bool isDuplicate = (aProxy0 == bProxy0) && (aProxy1 == bProxy1);
+			
+			previousPair = pair;
+
+			bool needsRemoval = false;
+
+			if (!isDuplicate)
+			{
+				bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
+
+				if (hasOverlap)
+				{
+					needsRemoval = false;//callback->processOverlap(pair);
+				} else
+				{
+					needsRemoval = true;
+				}
+			} else
+			{
+				//remove duplicate
+				needsRemoval = true;
+				//should have no algorithm
+				btAssert(!pair.m_algorithm);
+			}
+			
+			if (needsRemoval)
+			{
+				getOverlappingPairCache()->cleanOverlappingPair(pair,dispatcher);
+
+		//		m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
+		//		m_overlappingPairArray.pop_back();
+				pair.m_pProxy0 = 0;
+				pair.m_pProxy1 = 0;
+				m_invalidPair++;
+				gOverlappingPairs--;
+			} 
+			
+		}
+
+	///if you don't like to skip the invalid pairs in the array, execute following code:
+	#define CLEAN_INVALID_PAIRS 1
+	#ifdef CLEAN_INVALID_PAIRS
+
+		//perform a sort, to sort 'invalid' pairs to the end
+		//overlappingPairArray.heapSort(btMultiSapBroadphasePairSortPredicate());
+		overlappingPairArray.quickSort(btMultiSapBroadphasePairSortPredicate());
+
+		overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
+		m_invalidPair = 0;
+	#endif//CLEAN_INVALID_PAIRS
+		
+		//printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size());
+	}
+
+
+}
+
+
+bool	btMultiSapBroadphase::testAabbOverlap(btBroadphaseProxy* childProxy0,btBroadphaseProxy* childProxy1)
+{
+	btMultiSapProxy* multiSapProxy0 = (btMultiSapProxy*)childProxy0->m_multiSapParentProxy;
+		btMultiSapProxy* multiSapProxy1 = (btMultiSapProxy*)childProxy1->m_multiSapParentProxy;
+
+		return	TestAabbAgainstAabb2(multiSapProxy0->m_aabbMin,multiSapProxy0->m_aabbMax,
+			multiSapProxy1->m_aabbMin,multiSapProxy1->m_aabbMax);
+		
+}
+
+
+void	btMultiSapBroadphase::printStats()
+{
+/*	printf("---------------------------------\n");
+	
+		printf("btMultiSapBroadphase.h\n");
+		printf("numHandles = %d\n",m_multiSapProxies.size());
+			//find broadphase that contain this multiProxy
+		int numChildBroadphases = getBroadphaseArray().size();
+		for (int i=0;i<numChildBroadphases;i++)
+		{
+
+			btBroadphaseInterface* childBroadphase = getBroadphaseArray()[i];
+			childBroadphase->printStats();
+
+		}
+		*/
+
+}
+
+void btMultiSapBroadphase::resetPool(btDispatcher* dispatcher)
+{
+	// not yet
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h	(revision 6952)
@@ -0,0 +1,151 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+#ifndef BT_MULTI_SAP_BROADPHASE
+#define BT_MULTI_SAP_BROADPHASE
+
+#include "btBroadphaseInterface.h"
+#include "LinearMath/btAlignedObjectArray.h"
+#include "btOverlappingPairCache.h"
+
+
+class btBroadphaseInterface;
+class btSimpleBroadphase;
+
+
+typedef btAlignedObjectArray<btBroadphaseInterface*> btSapBroadphaseArray;
+
+///The btMultiSapBroadphase is a research project, not recommended to use in production. Use btAxisSweep3 or btDbvtBroadphase instead.
+///The btMultiSapBroadphase is a broadphase that contains multiple SAP broadphases.
+///The user can add SAP broadphases that cover the world. A btBroadphaseProxy can be in multiple child broadphases at the same time.
+///A btQuantizedBvh acceleration structures finds overlapping SAPs for each btBroadphaseProxy.
+///See http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=328
+///and http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1329
+class btMultiSapBroadphase :public btBroadphaseInterface
+{
+	btSapBroadphaseArray	m_sapBroadphases;
+	
+	btSimpleBroadphase*		m_simpleBroadphase;
+
+	btOverlappingPairCache*	m_overlappingPairs;
+
+	class btQuantizedBvh*			m_optimizedAabbTree;
+
+
+	bool					m_ownsPairCache;
+	
+	btOverlapFilterCallback*	m_filterCallback;
+
+	int			m_invalidPair;
+
+	struct	btBridgeProxy
+	{
+		btBroadphaseProxy*		m_childProxy;
+		btBroadphaseInterface*	m_childBroadphase;
+	};
+
+
+public:
+
+	struct	btMultiSapProxy	: public btBroadphaseProxy
+	{
+
+		///array with all the entries that this proxy belongs to
+		btAlignedObjectArray<btBridgeProxy*> m_bridgeProxies;
+		btVector3	m_aabbMin;
+		btVector3	m_aabbMax;
+
+		int	m_shapeType;
+
+/*		void*	m_userPtr;
+		short int	m_collisionFilterGroup;
+		short int	m_collisionFilterMask;
+*/
+		btMultiSapProxy(const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask)
+			:btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask),
+			m_aabbMin(aabbMin),
+			m_aabbMax(aabbMax),
+			m_shapeType(shapeType)
+		{
+			m_multiSapParentProxy =this;
+		}
+
+		
+	};
+
+protected:
+
+
+	btAlignedObjectArray<btMultiSapProxy*> m_multiSapProxies;
+
+public:
+
+	btMultiSapBroadphase(int maxProxies = 16384,btOverlappingPairCache* pairCache=0);
+
+
+	btSapBroadphaseArray&	getBroadphaseArray()
+	{
+		return m_sapBroadphases;
+	}
+
+	const btSapBroadphaseArray&	getBroadphaseArray() const
+	{
+		return m_sapBroadphases;
+	}
+
+	virtual ~btMultiSapBroadphase();
+
+	virtual btBroadphaseProxy*	createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr, short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy);
+	virtual void	destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+	virtual void	setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher);
+	virtual void	getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+
+	virtual void	rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0));
+
+	void	addToChildBroadphase(btMultiSapProxy* parentMultiSapProxy, btBroadphaseProxy* childProxy, btBroadphaseInterface*	childBroadphase);
+
+	///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb
+	virtual void	calculateOverlappingPairs(btDispatcher* dispatcher);
+
+	bool	testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
+
+	virtual	btOverlappingPairCache*	getOverlappingPairCache()
+	{
+		return m_overlappingPairs;
+	}
+	virtual	const btOverlappingPairCache*	getOverlappingPairCache() const
+	{
+		return m_overlappingPairs;
+	}
+
+	///getAabb returns the axis aligned bounding box in the 'global' coordinate frame
+	///will add some transform later
+	virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
+	{
+		aabbMin.setValue(-1e30f,-1e30f,-1e30f);
+		aabbMax.setValue(1e30f,1e30f,1e30f);
+	}
+
+	void	buildTree(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax);
+
+	virtual void	printStats();
+
+	void quicksort (btBroadphasePairArray& a, int lo, int hi);
+
+	///reset broadphase internal structures, to ensure determinism/reproducability
+	virtual void resetPool(btDispatcher* dispatcher);
+
+};
+
+#endif //BT_MULTI_SAP_BROADPHASE
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp	(revision 6952)
@@ -0,0 +1,633 @@
+/*
+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 "btOverlappingPairCache.h"
+
+#include "btDispatcher.h"
+#include "btCollisionAlgorithm.h"
+#include "LinearMath/btAabbUtil2.h"
+
+#include <stdio.h>
+
+int	gOverlappingPairs = 0;
+
+int gRemovePairs =0;
+int gAddedPairs =0;
+int gFindPairs =0;
+
+
+
+
+btHashedOverlappingPairCache::btHashedOverlappingPairCache():
+	m_overlapFilterCallback(0),
+	m_blockedForChanges(false),
+	m_ghostPairCallback(0)
+{
+	int initialAllocatedSize= 2;
+	m_overlappingPairArray.reserve(initialAllocatedSize);
+	growTables();
+}
+
+
+
+
+btHashedOverlappingPairCache::~btHashedOverlappingPairCache()
+{
+}
+
+
+
+void	btHashedOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher)
+{
+	if (pair.m_algorithm)
+	{
+		{
+			pair.m_algorithm->~btCollisionAlgorithm();
+			dispatcher->freeCollisionAlgorithm(pair.m_algorithm);
+			pair.m_algorithm=0;
+		}
+	}
+}
+
+
+
+
+void	btHashedOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
+{
+
+	class	CleanPairCallback : public btOverlapCallback
+	{
+		btBroadphaseProxy* m_cleanProxy;
+		btOverlappingPairCache*	m_pairCache;
+		btDispatcher* m_dispatcher;
+
+	public:
+		CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache,btDispatcher* dispatcher)
+			:m_cleanProxy(cleanProxy),
+			m_pairCache(pairCache),
+			m_dispatcher(dispatcher)
+		{
+		}
+		virtual	bool	processOverlap(btBroadphasePair& pair)
+		{
+			if ((pair.m_pProxy0 == m_cleanProxy) ||
+				(pair.m_pProxy1 == m_cleanProxy))
+			{
+				m_pairCache->cleanOverlappingPair(pair,m_dispatcher);
+			}
+			return false;
+		}
+		
+	};
+
+	CleanPairCallback cleanPairs(proxy,this,dispatcher);
+
+	processAllOverlappingPairs(&cleanPairs,dispatcher);
+
+}
+
+
+
+
+void	btHashedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
+{
+
+	class	RemovePairCallback : public btOverlapCallback
+	{
+		btBroadphaseProxy* m_obsoleteProxy;
+
+	public:
+		RemovePairCallback(btBroadphaseProxy* obsoleteProxy)
+			:m_obsoleteProxy(obsoleteProxy)
+		{
+		}
+		virtual	bool	processOverlap(btBroadphasePair& pair)
+		{
+			return ((pair.m_pProxy0 == m_obsoleteProxy) ||
+				(pair.m_pProxy1 == m_obsoleteProxy));
+		}
+		
+	};
+
+
+	RemovePairCallback removeCallback(proxy);
+
+	processAllOverlappingPairs(&removeCallback,dispatcher);
+}
+
+
+
+
+
+btBroadphasePair* btHashedOverlappingPairCache::findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
+{
+	gFindPairs++;
+	if(proxy0->m_uniqueId>proxy1->m_uniqueId) 
+		btSwap(proxy0,proxy1);
+	int proxyId1 = proxy0->getUid();
+	int proxyId2 = proxy1->getUid();
+
+	/*if (proxyId1 > proxyId2) 
+		btSwap(proxyId1, proxyId2);*/
+
+	int hash = static_cast<int>(getHash(static_cast<unsigned int>(proxyId1), static_cast<unsigned int>(proxyId2)) & (m_overlappingPairArray.capacity()-1));
+
+	if (hash >= m_hashTable.size())
+	{
+		return NULL;
+	}
+
+	int index = m_hashTable[hash];
+	while (index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false)
+	{
+		index = m_next[index];
+	}
+
+	if (index == BT_NULL_PAIR)
+	{
+		return NULL;
+	}
+
+	btAssert(index < m_overlappingPairArray.size());
+
+	return &m_overlappingPairArray[index];
+}
+
+//#include <stdio.h>
+
+void	btHashedOverlappingPairCache::growTables()
+{
+
+	int newCapacity = m_overlappingPairArray.capacity();
+
+	if (m_hashTable.size() < newCapacity)
+	{
+		//grow hashtable and next table
+		int curHashtableSize = m_hashTable.size();
+
+		m_hashTable.resize(newCapacity);
+		m_next.resize(newCapacity);
+
+
+		int i;
+
+		for (i= 0; i < newCapacity; ++i)
+		{
+			m_hashTable[i] = BT_NULL_PAIR;
+		}
+		for (i = 0; i < newCapacity; ++i)
+		{
+			m_next[i] = BT_NULL_PAIR;
+		}
+
+		for(i=0;i<curHashtableSize;i++)
+		{
+	
+			const btBroadphasePair& pair = m_overlappingPairArray[i];
+			int proxyId1 = pair.m_pProxy0->getUid();
+			int proxyId2 = pair.m_pProxy1->getUid();
+			/*if (proxyId1 > proxyId2) 
+				btSwap(proxyId1, proxyId2);*/
+			int	hashValue = static_cast<int>(getHash(static_cast<unsigned int>(proxyId1),static_cast<unsigned int>(proxyId2)) & (m_overlappingPairArray.capacity()-1));	// New hash value with new mask
+			m_next[i] = m_hashTable[hashValue];
+			m_hashTable[hashValue] = i;
+		}
+
+
+	}
+}
+
+btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1)
+{
+	if(proxy0->m_uniqueId>proxy1->m_uniqueId) 
+		btSwap(proxy0,proxy1);
+	int proxyId1 = proxy0->getUid();
+	int proxyId2 = proxy1->getUid();
+
+	/*if (proxyId1 > proxyId2) 
+		btSwap(proxyId1, proxyId2);*/
+
+	int	hash = static_cast<int>(getHash(static_cast<unsigned int>(proxyId1),static_cast<unsigned int>(proxyId2)) & (m_overlappingPairArray.capacity()-1));	// New hash value with new mask
+
+
+	btBroadphasePair* pair = internalFindPair(proxy0, proxy1, hash);
+	if (pair != NULL)
+	{
+		return pair;
+	}
+	/*for(int i=0;i<m_overlappingPairArray.size();++i)
+		{
+		if(	(m_overlappingPairArray[i].m_pProxy0==proxy0)&&
+			(m_overlappingPairArray[i].m_pProxy1==proxy1))
+			{
+			printf("Adding duplicated %u<>%u\r\n",proxyId1,proxyId2);
+			internalFindPair(proxy0, proxy1, hash);
+			}
+		}*/
+	int count = m_overlappingPairArray.size();
+	int oldCapacity = m_overlappingPairArray.capacity();
+	void* mem = &m_overlappingPairArray.expand();
+
+	//this is where we add an actual pair, so also call the 'ghost'
+	if (m_ghostPairCallback)
+		m_ghostPairCallback->addOverlappingPair(proxy0,proxy1);
+
+	int newCapacity = m_overlappingPairArray.capacity();
+
+	if (oldCapacity < newCapacity)
+	{
+		growTables();
+		//hash with new capacity
+		hash = static_cast<int>(getHash(static_cast<unsigned int>(proxyId1),static_cast<unsigned int>(proxyId2)) & (m_overlappingPairArray.capacity()-1));
+	}
+	
+	pair = new (mem) btBroadphasePair(*proxy0,*proxy1);
+//	pair->m_pProxy0 = proxy0;
+//	pair->m_pProxy1 = proxy1;
+	pair->m_algorithm = 0;
+	pair->m_internalTmpValue = 0;
+	
+
+	m_next[count] = m_hashTable[hash];
+	m_hashTable[hash] = count;
+
+	return pair;
+}
+
+
+
+void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* dispatcher)
+{
+	gRemovePairs++;
+	if(proxy0->m_uniqueId>proxy1->m_uniqueId) 
+		btSwap(proxy0,proxy1);
+	int proxyId1 = proxy0->getUid();
+	int proxyId2 = proxy1->getUid();
+
+	/*if (proxyId1 > proxyId2) 
+		btSwap(proxyId1, proxyId2);*/
+
+	int	hash = static_cast<int>(getHash(static_cast<unsigned int>(proxyId1),static_cast<unsigned int>(proxyId2)) & (m_overlappingPairArray.capacity()-1));
+
+	btBroadphasePair* pair = internalFindPair(proxy0, proxy1, hash);
+	if (pair == NULL)
+	{
+		return 0;
+	}
+
+	cleanOverlappingPair(*pair,dispatcher);
+
+	void* userData = pair->m_internalInfo1;
+
+	btAssert(pair->m_pProxy0->getUid() == proxyId1);
+	btAssert(pair->m_pProxy1->getUid() == proxyId2);
+
+	int pairIndex = int(pair - &m_overlappingPairArray[0]);
+	btAssert(pairIndex < m_overlappingPairArray.size());
+
+	// Remove the pair from the hash table.
+	int index = m_hashTable[hash];
+	btAssert(index != BT_NULL_PAIR);
+
+	int previous = BT_NULL_PAIR;
+	while (index != pairIndex)
+	{
+		previous = index;
+		index = m_next[index];
+	}
+
+	if (previous != BT_NULL_PAIR)
+	{
+		btAssert(m_next[previous] == pairIndex);
+		m_next[previous] = m_next[pairIndex];
+	}
+	else
+	{
+		m_hashTable[hash] = m_next[pairIndex];
+	}
+
+	// We now move the last pair into spot of the
+	// pair being removed. We need to fix the hash
+	// table indices to support the move.
+
+	int lastPairIndex = m_overlappingPairArray.size() - 1;
+
+	if (m_ghostPairCallback)
+		m_ghostPairCallback->removeOverlappingPair(proxy0, proxy1,dispatcher);
+
+	// If the removed pair is the last pair, we are done.
+	if (lastPairIndex == pairIndex)
+	{
+		m_overlappingPairArray.pop_back();
+		return userData;
+	}
+
+	// Remove the last pair from the hash table.
+	const btBroadphasePair* last = &m_overlappingPairArray[lastPairIndex];
+		/* missing swap here too, Nat. */ 
+	int lastHash = static_cast<int>(getHash(static_cast<unsigned int>(last->m_pProxy0->getUid()), static_cast<unsigned int>(last->m_pProxy1->getUid())) & (m_overlappingPairArray.capacity()-1));
+
+	index = m_hashTable[lastHash];
+	btAssert(index != BT_NULL_PAIR);
+
+	previous = BT_NULL_PAIR;
+	while (index != lastPairIndex)
+	{
+		previous = index;
+		index = m_next[index];
+	}
+
+	if (previous != BT_NULL_PAIR)
+	{
+		btAssert(m_next[previous] == lastPairIndex);
+		m_next[previous] = m_next[lastPairIndex];
+	}
+	else
+	{
+		m_hashTable[lastHash] = m_next[lastPairIndex];
+	}
+
+	// Copy the last pair into the remove pair's spot.
+	m_overlappingPairArray[pairIndex] = m_overlappingPairArray[lastPairIndex];
+
+	// Insert the last pair into the hash table
+	m_next[pairIndex] = m_hashTable[lastHash];
+	m_hashTable[lastHash] = pairIndex;
+
+	m_overlappingPairArray.pop_back();
+
+	return userData;
+}
+//#include <stdio.h>
+
+void	btHashedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher)
+{
+
+	int i;
+
+//	printf("m_overlappingPairArray.size()=%d\n",m_overlappingPairArray.size());
+	for (i=0;i<m_overlappingPairArray.size();)
+	{
+	
+		btBroadphasePair* pair = &m_overlappingPairArray[i];
+		if (callback->processOverlap(*pair))
+		{
+			removeOverlappingPair(pair->m_pProxy0,pair->m_pProxy1,dispatcher);
+
+			gOverlappingPairs--;
+		} else
+		{
+			i++;
+		}
+	}
+}
+
+void	btHashedOverlappingPairCache::sortOverlappingPairs(btDispatcher* dispatcher)
+{
+	///need to keep hashmap in sync with pair address, so rebuild all
+	btBroadphasePairArray tmpPairs;
+	int i;
+	for (i=0;i<m_overlappingPairArray.size();i++)
+	{
+		tmpPairs.push_back(m_overlappingPairArray[i]);
+	}
+
+	for (i=0;i<tmpPairs.size();i++)
+	{
+		removeOverlappingPair(tmpPairs[i].m_pProxy0,tmpPairs[i].m_pProxy1,dispatcher);
+	}
+	
+	for (i = 0; i < m_next.size(); i++)
+	{
+		m_next[i] = BT_NULL_PAIR;
+	}
+
+	tmpPairs.quickSort(btBroadphasePairSortPredicate());
+
+	for (i=0;i<tmpPairs.size();i++)
+	{
+		addOverlappingPair(tmpPairs[i].m_pProxy0,tmpPairs[i].m_pProxy1);
+	}
+
+	
+}
+
+
+void*	btSortedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1, btDispatcher* dispatcher )
+{
+	if (!hasDeferredRemoval())
+	{
+		btBroadphasePair findPair(*proxy0,*proxy1);
+
+		int findIndex = m_overlappingPairArray.findLinearSearch(findPair);
+		if (findIndex < m_overlappingPairArray.size())
+		{
+			gOverlappingPairs--;
+			btBroadphasePair& pair = m_overlappingPairArray[findIndex];
+			void* userData = pair.m_internalInfo1;
+			cleanOverlappingPair(pair,dispatcher);
+			if (m_ghostPairCallback)
+				m_ghostPairCallback->removeOverlappingPair(proxy0, proxy1,dispatcher);
+			
+			m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.capacity()-1);
+			m_overlappingPairArray.pop_back();
+			return userData;
+		}
+	}
+
+	return 0;
+}
+
+
+
+
+
+
+
+
+btBroadphasePair*	btSortedOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+{
+	//don't add overlap with own
+	btAssert(proxy0 != proxy1);
+
+	if (!needsBroadphaseCollision(proxy0,proxy1))
+		return 0;
+	
+	void* mem = &m_overlappingPairArray.expand();
+	btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1);
+	
+	gOverlappingPairs++;
+	gAddedPairs++;
+	
+	if (m_ghostPairCallback)
+		m_ghostPairCallback->addOverlappingPair(proxy0, proxy1);
+	return pair;
+	
+}
+
+///this findPair becomes really slow. Either sort the list to speedup the query, or
+///use a different solution. It is mainly used for Removing overlapping pairs. Removal could be delayed.
+///we could keep a linked list in each proxy, and store pair in one of the proxies (with lowest memory address)
+///Also we can use a 2D bitmap, which can be useful for a future GPU implementation
+ btBroadphasePair*	btSortedOverlappingPairCache::findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+{
+	if (!needsBroadphaseCollision(proxy0,proxy1))
+		return 0;
+
+	btBroadphasePair tmpPair(*proxy0,*proxy1);
+	int findIndex = m_overlappingPairArray.findLinearSearch(tmpPair);
+
+	if (findIndex < m_overlappingPairArray.size())
+	{
+		//btAssert(it != m_overlappingPairSet.end());
+		 btBroadphasePair* pair = &m_overlappingPairArray[findIndex];
+		return pair;
+	}
+	return 0;
+}
+
+
+
+
+
+
+
+
+
+
+//#include <stdio.h>
+
+void	btSortedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher)
+{
+
+	int i;
+
+	for (i=0;i<m_overlappingPairArray.size();)
+	{
+	
+		btBroadphasePair* pair = &m_overlappingPairArray[i];
+		if (callback->processOverlap(*pair))
+		{
+			cleanOverlappingPair(*pair,dispatcher);
+			pair->m_pProxy0 = 0;
+			pair->m_pProxy1 = 0;
+			m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
+			m_overlappingPairArray.pop_back();
+			gOverlappingPairs--;
+		} else
+		{
+			i++;
+		}
+	}
+}
+
+
+
+
+btSortedOverlappingPairCache::btSortedOverlappingPairCache():
+	m_blockedForChanges(false),
+	m_hasDeferredRemoval(true),
+	m_overlapFilterCallback(0),
+	m_ghostPairCallback(0)
+{
+	int initialAllocatedSize= 2;
+	m_overlappingPairArray.reserve(initialAllocatedSize);
+}
+
+btSortedOverlappingPairCache::~btSortedOverlappingPairCache()
+{
+}
+
+void	btSortedOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher)
+{
+	if (pair.m_algorithm)
+	{
+		{
+			pair.m_algorithm->~btCollisionAlgorithm();
+			dispatcher->freeCollisionAlgorithm(pair.m_algorithm);
+			pair.m_algorithm=0;
+			gRemovePairs--;
+		}
+	}
+}
+
+
+void	btSortedOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
+{
+
+	class	CleanPairCallback : public btOverlapCallback
+	{
+		btBroadphaseProxy* m_cleanProxy;
+		btOverlappingPairCache*	m_pairCache;
+		btDispatcher* m_dispatcher;
+
+	public:
+		CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache,btDispatcher* dispatcher)
+			:m_cleanProxy(cleanProxy),
+			m_pairCache(pairCache),
+			m_dispatcher(dispatcher)
+		{
+		}
+		virtual	bool	processOverlap(btBroadphasePair& pair)
+		{
+			if ((pair.m_pProxy0 == m_cleanProxy) ||
+				(pair.m_pProxy1 == m_cleanProxy))
+			{
+				m_pairCache->cleanOverlappingPair(pair,m_dispatcher);
+			}
+			return false;
+		}
+		
+	};
+
+	CleanPairCallback cleanPairs(proxy,this,dispatcher);
+
+	processAllOverlappingPairs(&cleanPairs,dispatcher);
+
+}
+
+
+void	btSortedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)
+{
+
+	class	RemovePairCallback : public btOverlapCallback
+	{
+		btBroadphaseProxy* m_obsoleteProxy;
+
+	public:
+		RemovePairCallback(btBroadphaseProxy* obsoleteProxy)
+			:m_obsoleteProxy(obsoleteProxy)
+		{
+		}
+		virtual	bool	processOverlap(btBroadphasePair& pair)
+		{
+			return ((pair.m_pProxy0 == m_obsoleteProxy) ||
+				(pair.m_pProxy1 == m_obsoleteProxy));
+		}
+		
+	};
+
+	RemovePairCallback removeCallback(proxy);
+
+	processAllOverlappingPairs(&removeCallback,dispatcher);
+}
+
+void	btSortedOverlappingPairCache::sortOverlappingPairs(btDispatcher* dispatcher)
+{
+	//should already be sorted
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h	(revision 6952)
@@ -0,0 +1,468 @@
+/*
+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 OVERLAPPING_PAIR_CACHE_H
+#define OVERLAPPING_PAIR_CACHE_H
+
+
+#include "btBroadphaseInterface.h"
+#include "btBroadphaseProxy.h"
+#include "btOverlappingPairCallback.h"
+
+#include "LinearMath/btAlignedObjectArray.h"
+class btDispatcher;
+
+typedef btAlignedObjectArray<btBroadphasePair>	btBroadphasePairArray;
+
+struct	btOverlapCallback
+{
+	virtual ~btOverlapCallback()
+	{}
+	//return true for deletion of the pair
+	virtual bool	processOverlap(btBroadphasePair& pair) = 0;
+
+};
+
+struct btOverlapFilterCallback
+{
+	virtual ~btOverlapFilterCallback()
+	{}
+	// return true when pairs need collision
+	virtual bool	needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0;
+};
+
+
+
+
+
+
+
+extern int gRemovePairs;
+extern int gAddedPairs;
+extern int gFindPairs;
+
+const int BT_NULL_PAIR=0xffffffff;
+
+///The btOverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the btBroadphaseInterface broadphases.
+///The btHashedOverlappingPairCache and btSortedOverlappingPairCache classes are two implementations.
+class btOverlappingPairCache : public btOverlappingPairCallback
+{
+public:
+	virtual ~btOverlappingPairCache() {} // this is needed so we can get to the derived class destructor
+
+	virtual btBroadphasePair*	getOverlappingPairArrayPtr() = 0;
+	
+	virtual const btBroadphasePair*	getOverlappingPairArrayPtr() const = 0;
+
+	virtual btBroadphasePairArray&	getOverlappingPairArray() = 0;
+
+	virtual	void	cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher) = 0;
+
+	virtual int getNumOverlappingPairs() const = 0;
+
+	virtual void	cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher) = 0;
+
+	virtual	void setOverlapFilterCallback(btOverlapFilterCallback* callback) = 0;
+
+	virtual void	processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher) = 0;
+
+	virtual btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) = 0;
+
+	virtual bool	hasDeferredRemoval() = 0;
+
+	virtual	void	setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)=0;
+
+	virtual void	sortOverlappingPairs(btDispatcher* dispatcher) = 0;
+
+
+};
+
+/// Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman, Codercorner, http://codercorner.com
+class btHashedOverlappingPairCache : public btOverlappingPairCache
+{
+	btBroadphasePairArray	m_overlappingPairArray;
+	btOverlapFilterCallback* m_overlapFilterCallback;
+	bool		m_blockedForChanges;
+
+
+public:
+	btHashedOverlappingPairCache();
+	virtual ~btHashedOverlappingPairCache();
+
+	
+	void	removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+
+	virtual void*	removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher);
+	
+	SIMD_FORCE_INLINE bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
+	{
+		if (m_overlapFilterCallback)
+			return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
+
+		bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
+		collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
+		
+		return collides;
+	}
+
+	// Add a pair and return the new pair. If the pair already exists,
+	// no new pair is created and the old one is returned.
+	virtual btBroadphasePair* 	addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+	{
+		gAddedPairs++;
+
+		if (!needsBroadphaseCollision(proxy0,proxy1))
+			return 0;
+
+		return internalAddPair(proxy0,proxy1);
+	}
+
+	
+
+	void	cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+
+	
+	virtual void	processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher);
+
+	virtual btBroadphasePair*	getOverlappingPairArrayPtr()
+	{
+		return &m_overlappingPairArray[0];
+	}
+
+	const btBroadphasePair*	getOverlappingPairArrayPtr() const
+	{
+		return &m_overlappingPairArray[0];
+	}
+
+	btBroadphasePairArray&	getOverlappingPairArray()
+	{
+		return m_overlappingPairArray;
+	}
+
+	const btBroadphasePairArray&	getOverlappingPairArray() const
+	{
+		return m_overlappingPairArray;
+	}
+
+	void	cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher);
+
+
+
+	btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1);
+
+	int GetCount() const { return m_overlappingPairArray.size(); }
+//	btBroadphasePair* GetPairs() { return m_pairs; }
+
+	btOverlapFilterCallback* getOverlapFilterCallback()
+	{
+		return m_overlapFilterCallback;
+	}
+
+	void setOverlapFilterCallback(btOverlapFilterCallback* callback)
+	{
+		m_overlapFilterCallback = callback;
+	}
+
+	int	getNumOverlappingPairs() const
+	{
+		return m_overlappingPairArray.size();
+	}
+private:
+	
+	btBroadphasePair* 	internalAddPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
+
+	void	growTables();
+
+	SIMD_FORCE_INLINE bool equalsPair(const btBroadphasePair& pair, int proxyId1, int proxyId2)
+	{	
+		return pair.m_pProxy0->getUid() == proxyId1 && pair.m_pProxy1->getUid() == proxyId2;
+	}
+
+	/*
+	// Thomas Wang's hash, see: http://www.concentric.net/~Ttwang/tech/inthash.htm
+	// This assumes proxyId1 and proxyId2 are 16-bit.
+	SIMD_FORCE_INLINE int getHash(int proxyId1, int proxyId2)
+	{
+		int key = (proxyId2 << 16) | proxyId1;
+		key = ~key + (key << 15);
+		key = key ^ (key >> 12);
+		key = key + (key << 2);
+		key = key ^ (key >> 4);
+		key = key * 2057;
+		key = key ^ (key >> 16);
+		return key;
+	}
+	*/
+
+
+	
+	SIMD_FORCE_INLINE	unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2)
+	{
+		int key = static_cast<int>(((unsigned int)proxyId1) | (((unsigned int)proxyId2) <<16));
+		// Thomas Wang's hash
+
+		key += ~(key << 15);
+		key ^=  (key >> 10);
+		key +=  (key << 3);
+		key ^=  (key >> 6);
+		key += ~(key << 11);
+		key ^=  (key >> 16);
+		return static_cast<unsigned int>(key);
+	}
+	
+
+
+
+
+	SIMD_FORCE_INLINE btBroadphasePair* internalFindPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, int hash)
+	{
+		int proxyId1 = proxy0->getUid();
+		int proxyId2 = proxy1->getUid();
+		#if 0 // wrong, 'equalsPair' use unsorted uids, copy-past devil striked again. Nat.
+		if (proxyId1 > proxyId2) 
+			btSwap(proxyId1, proxyId2);
+		#endif
+
+		int index = m_hashTable[hash];
+		
+		while( index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false)
+		{
+			index = m_next[index];
+		}
+
+		if ( index == BT_NULL_PAIR )
+		{
+			return NULL;
+		}
+
+		btAssert(index < m_overlappingPairArray.size());
+
+		return &m_overlappingPairArray[index];
+	}
+
+	virtual bool	hasDeferredRemoval()
+	{
+		return false;
+	}
+
+	virtual	void	setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)
+	{
+		m_ghostPairCallback = ghostPairCallback;
+	}
+
+	virtual void	sortOverlappingPairs(btDispatcher* dispatcher);
+	
+
+protected:
+	
+	btAlignedObjectArray<int>	m_hashTable;
+	btAlignedObjectArray<int>	m_next;
+	btOverlappingPairCallback*	m_ghostPairCallback;
+	
+};
+
+
+
+
+///btSortedOverlappingPairCache maintains the objects with overlapping AABB
+///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase
+class	btSortedOverlappingPairCache : public btOverlappingPairCache
+{
+	protected:
+		//avoid brute-force finding all the time
+		btBroadphasePairArray	m_overlappingPairArray;
+
+		//during the dispatch, check that user doesn't destroy/create proxy
+		bool		m_blockedForChanges;
+
+		///by default, do the removal during the pair traversal
+		bool		m_hasDeferredRemoval;
+		
+		//if set, use the callback instead of the built in filter in needBroadphaseCollision
+		btOverlapFilterCallback* m_overlapFilterCallback;
+
+		btOverlappingPairCallback*	m_ghostPairCallback;
+
+	public:
+			
+		btSortedOverlappingPairCache();	
+		virtual ~btSortedOverlappingPairCache();
+
+		virtual void	processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher);
+
+		void*	removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher);
+
+		void	cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher);
+		
+		btBroadphasePair*	addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
+
+		btBroadphasePair*	findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
+			
+		
+		void	cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+
+		void	removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+
+
+		inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const
+		{
+			if (m_overlapFilterCallback)
+				return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1);
+
+			bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0;
+			collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask);
+			
+			return collides;
+		}
+		
+		btBroadphasePairArray&	getOverlappingPairArray()
+		{
+			return m_overlappingPairArray;
+		}
+
+		const btBroadphasePairArray&	getOverlappingPairArray() const
+		{
+			return m_overlappingPairArray;
+		}
+
+		
+
+
+		btBroadphasePair*	getOverlappingPairArrayPtr()
+		{
+			return &m_overlappingPairArray[0];
+		}
+
+		const btBroadphasePair*	getOverlappingPairArrayPtr() const
+		{
+			return &m_overlappingPairArray[0];
+		}
+
+		int	getNumOverlappingPairs() const
+		{
+			return m_overlappingPairArray.size();
+		}
+		
+		btOverlapFilterCallback* getOverlapFilterCallback()
+		{
+			return m_overlapFilterCallback;
+		}
+
+		void setOverlapFilterCallback(btOverlapFilterCallback* callback)
+		{
+			m_overlapFilterCallback = callback;
+		}
+
+		virtual bool	hasDeferredRemoval()
+		{
+			return m_hasDeferredRemoval;
+		}
+
+		virtual	void	setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)
+		{
+			m_ghostPairCallback = ghostPairCallback;
+		}
+
+		virtual void	sortOverlappingPairs(btDispatcher* dispatcher);
+		
+
+};
+
+
+
+///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing.
+class btNullPairCache : public btOverlappingPairCache
+{
+
+	btBroadphasePairArray	m_overlappingPairArray;
+
+public:
+
+	virtual btBroadphasePair*	getOverlappingPairArrayPtr()
+	{
+		return &m_overlappingPairArray[0];
+	}
+	const btBroadphasePair*	getOverlappingPairArrayPtr() const
+	{
+		return &m_overlappingPairArray[0];
+	}
+	btBroadphasePairArray&	getOverlappingPairArray()
+	{
+		return m_overlappingPairArray;
+	}
+	
+	virtual	void	cleanOverlappingPair(btBroadphasePair& /*pair*/,btDispatcher* /*dispatcher*/)
+	{
+
+	}
+
+	virtual int getNumOverlappingPairs() const
+	{
+		return 0;
+	}
+
+	virtual void	cleanProxyFromPairs(btBroadphaseProxy* /*proxy*/,btDispatcher* /*dispatcher*/)
+	{
+
+	}
+
+	virtual	void setOverlapFilterCallback(btOverlapFilterCallback* /*callback*/)
+	{
+	}
+
+	virtual void	processAllOverlappingPairs(btOverlapCallback*,btDispatcher* /*dispatcher*/)
+	{
+	}
+
+	virtual btBroadphasePair* findPair(btBroadphaseProxy* /*proxy0*/, btBroadphaseProxy* /*proxy1*/)
+	{
+		return 0;
+	}
+
+	virtual bool	hasDeferredRemoval()
+	{
+		return true;
+	}
+
+	virtual	void	setInternalGhostPairCallback(btOverlappingPairCallback* /* ghostPairCallback */)
+	{
+
+	}
+
+	virtual btBroadphasePair*	addOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/)
+	{
+		return 0;
+	}
+
+	virtual void*	removeOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/,btDispatcher* /*dispatcher*/)
+	{
+		return 0;
+	}
+
+	virtual void	removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/)
+	{
+	}
+	
+	virtual void	sortOverlappingPairs(btDispatcher* dispatcher)
+	{
+	}
+
+
+};
+
+
+#endif //OVERLAPPING_PAIR_CACHE_H
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h	(revision 6952)
@@ -0,0 +1,40 @@
+
+/*
+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 OVERLAPPING_PAIR_CALLBACK_H
+#define OVERLAPPING_PAIR_CALLBACK_H
+
+class btDispatcher;
+struct  btBroadphasePair;
+
+///The btOverlappingPairCallback class is an additional optional broadphase user callback for adding/removing overlapping pairs, similar interface to btOverlappingPairCache.
+class btOverlappingPairCallback
+{
+public:
+	virtual ~btOverlappingPairCallback()
+	{
+
+	}
+	
+	virtual btBroadphasePair*	addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) = 0;
+
+	virtual void*	removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher) = 0;
+
+	virtual void	removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0,btDispatcher* dispatcher) = 0;
+
+};
+
+#endif //OVERLAPPING_PAIR_CALLBACK_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp	(revision 6952)
@@ -0,0 +1,1148 @@
+/*
+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 "btQuantizedBvh.h"
+
+#include "LinearMath/btAabbUtil2.h"
+#include "LinearMath/btIDebugDraw.h"
+
+#define RAYAABB2
+
+btQuantizedBvh::btQuantizedBvh() : 
+					m_bulletVersion(BT_BULLET_VERSION),
+					m_useQuantization(false), 
+					//m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY)
+					m_traversalMode(TRAVERSAL_STACKLESS)
+					//m_traversalMode(TRAVERSAL_RECURSIVE)
+					,m_subtreeHeaderCount(0) //PCK: add this line
+{
+	m_bvhAabbMin.setValue(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY);
+	m_bvhAabbMax.setValue(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY);
+}
+
+
+
+
+
+void btQuantizedBvh::buildInternal()
+{
+	///assumes that caller filled in the m_quantizedLeafNodes
+	m_useQuantization = true;
+	int numLeafNodes = 0;
+	
+	if (m_useQuantization)
+	{
+		//now we have an array of leafnodes in m_leafNodes
+		numLeafNodes = m_quantizedLeafNodes.size();
+
+		m_quantizedContiguousNodes.resize(2*numLeafNodes);
+
+	}
+
+	m_curNodeIndex = 0;
+
+	buildTree(0,numLeafNodes);
+
+	///if the entire tree is small then subtree size, we need to create a header info for the tree
+	if(m_useQuantization && !m_SubtreeHeaders.size())
+	{
+		btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
+		subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]);
+		subtree.m_rootNodeIndex = 0;
+		subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex();
+	}
+
+	//PCK: update the copy of the size
+	m_subtreeHeaderCount = m_SubtreeHeaders.size();
+
+	//PCK: clear m_quantizedLeafNodes and m_leafNodes, they are temporary
+	m_quantizedLeafNodes.clear();
+	m_leafNodes.clear();
+}
+
+
+
+///just for debugging, to visualize the individual patches/subtrees
+#ifdef DEBUG_PATCH_COLORS
+btVector3 color[4]=
+{
+	btVector3(255,0,0),
+	btVector3(0,255,0),
+	btVector3(0,0,255),
+	btVector3(0,255,255)
+};
+#endif //DEBUG_PATCH_COLORS
+
+
+
+void	btQuantizedBvh::setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin)
+{
+	//enlarge the AABB to avoid division by zero when initializing the quantization values
+	btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin);
+	m_bvhAabbMin = bvhAabbMin - clampValue;
+	m_bvhAabbMax = bvhAabbMax + clampValue;
+	btVector3 aabbSize = m_bvhAabbMax - m_bvhAabbMin;
+	m_bvhQuantization = btVector3(btScalar(65533.0),btScalar(65533.0),btScalar(65533.0)) / aabbSize;
+	m_useQuantization = true;
+}
+
+
+
+
+btQuantizedBvh::~btQuantizedBvh()
+{
+}
+
+#ifdef DEBUG_TREE_BUILDING
+int gStackDepth = 0;
+int gMaxStackDepth = 0;
+#endif //DEBUG_TREE_BUILDING
+
+void	btQuantizedBvh::buildTree	(int startIndex,int endIndex)
+{
+#ifdef DEBUG_TREE_BUILDING
+	gStackDepth++;
+	if (gStackDepth > gMaxStackDepth)
+		gMaxStackDepth = gStackDepth;
+#endif //DEBUG_TREE_BUILDING
+
+
+	int splitAxis, splitIndex, i;
+	int numIndices =endIndex-startIndex;
+	int curIndex = m_curNodeIndex;
+
+	btAssert(numIndices>0);
+
+	if (numIndices==1)
+	{
+#ifdef DEBUG_TREE_BUILDING
+		gStackDepth--;
+#endif //DEBUG_TREE_BUILDING
+		
+		assignInternalNodeFromLeafNode(m_curNodeIndex,startIndex);
+
+		m_curNodeIndex++;
+		return;	
+	}
+	//calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
+	
+	splitAxis = calcSplittingAxis(startIndex,endIndex);
+
+	splitIndex = sortAndCalcSplittingIndex(startIndex,endIndex,splitAxis);
+
+	int internalNodeIndex = m_curNodeIndex;
+	
+	//set the min aabb to 'inf' or a max value, and set the max aabb to a -inf/minimum value.
+	//the aabb will be expanded during buildTree/mergeInternalNodeAabb with actual node values
+	setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);//can't use btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY)) because of quantization
+	setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);//can't use btVector3(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY)) because of quantization
+	
+	
+	for (i=startIndex;i<endIndex;i++)
+	{
+		mergeInternalNodeAabb(m_curNodeIndex,getAabbMin(i),getAabbMax(i));
+	}
+
+	m_curNodeIndex++;
+	
+
+	//internalNode->m_escapeIndex;
+	
+	int leftChildNodexIndex = m_curNodeIndex;
+
+	//build left child tree
+	buildTree(startIndex,splitIndex);
+
+	int rightChildNodexIndex = m_curNodeIndex;
+	//build right child tree
+	buildTree(splitIndex,endIndex);
+
+#ifdef DEBUG_TREE_BUILDING
+	gStackDepth--;
+#endif //DEBUG_TREE_BUILDING
+
+	int escapeIndex = m_curNodeIndex - curIndex;
+
+	if (m_useQuantization)
+	{
+		//escapeIndex is the number of nodes of this subtree
+		const int sizeQuantizedNode =sizeof(btQuantizedBvhNode);
+		const int treeSizeInBytes = escapeIndex * sizeQuantizedNode;
+		if (treeSizeInBytes > MAX_SUBTREE_SIZE_IN_BYTES)
+		{
+			updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex);
+		}
+	} else
+	{
+
+	}
+
+	setInternalNodeEscapeIndex(internalNodeIndex,escapeIndex);
+
+}
+
+void	btQuantizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex)
+{
+	btAssert(m_useQuantization);
+
+	btQuantizedBvhNode& leftChildNode = m_quantizedContiguousNodes[leftChildNodexIndex];
+	int leftSubTreeSize = leftChildNode.isLeafNode() ? 1 : leftChildNode.getEscapeIndex();
+	int leftSubTreeSizeInBytes =  leftSubTreeSize * static_cast<int>(sizeof(btQuantizedBvhNode));
+	
+	btQuantizedBvhNode& rightChildNode = m_quantizedContiguousNodes[rightChildNodexIndex];
+	int rightSubTreeSize = rightChildNode.isLeafNode() ? 1 : rightChildNode.getEscapeIndex();
+	int rightSubTreeSizeInBytes =  rightSubTreeSize *  static_cast<int>(sizeof(btQuantizedBvhNode));
+
+	if(leftSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES)
+	{
+		btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
+		subtree.setAabbFromQuantizeNode(leftChildNode);
+		subtree.m_rootNodeIndex = leftChildNodexIndex;
+		subtree.m_subtreeSize = leftSubTreeSize;
+	}
+
+	if(rightSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES)
+	{
+		btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
+		subtree.setAabbFromQuantizeNode(rightChildNode);
+		subtree.m_rootNodeIndex = rightChildNodexIndex;
+		subtree.m_subtreeSize = rightSubTreeSize;
+	}
+
+	//PCK: update the copy of the size
+	m_subtreeHeaderCount = m_SubtreeHeaders.size();
+}
+
+
+int	btQuantizedBvh::sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis)
+{
+	int i;
+	int splitIndex =startIndex;
+	int numIndices = endIndex - startIndex;
+	btScalar splitValue;
+
+	btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
+		means+=center;
+	}
+	means *= (btScalar(1.)/(btScalar)numIndices);
+	
+	splitValue = means[splitAxis];
+	
+	//sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
+		if (center[splitAxis] > splitValue)
+		{
+			//swap
+			swapLeafNodes(i,splitIndex);
+			splitIndex++;
+		}
+	}
+
+	//if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex
+	//otherwise the tree-building might fail due to stack-overflows in certain cases.
+	//unbalanced1 is unsafe: it can cause stack overflows
+	//bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1)));
+
+	//unbalanced2 should work too: always use center (perfect balanced trees)	
+	//bool unbalanced2 = true;
+
+	//this should be safe too:
+	int rangeBalancedIndices = numIndices/3;
+	bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices)));
+	
+	if (unbalanced)
+	{
+		splitIndex = startIndex+ (numIndices>>1);
+	}
+
+	bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex));
+	(void)unbal;
+	btAssert(!unbal);
+
+	return splitIndex;
+}
+
+
+int	btQuantizedBvh::calcSplittingAxis(int startIndex,int endIndex)
+{
+	int i;
+
+	btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
+	btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.));
+	int numIndices = endIndex-startIndex;
+
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
+		means+=center;
+	}
+	means *= (btScalar(1.)/(btScalar)numIndices);
+		
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btVector3 center = btScalar(0.5)*(getAabbMax(i)+getAabbMin(i));
+		btVector3 diff2 = center-means;
+		diff2 = diff2 * diff2;
+		variance += diff2;
+	}
+	variance *= (btScalar(1.)/	((btScalar)numIndices-1)	);
+	
+	return variance.maxAxis();
+}
+
+
+
+void	btQuantizedBvh::reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+	//either choose recursive traversal (walkTree) or stackless (walkStacklessTree)
+
+	if (m_useQuantization)
+	{
+		///quantize query AABB
+		unsigned short int quantizedQueryAabbMin[3];
+		unsigned short int quantizedQueryAabbMax[3];
+		quantizeWithClamp(quantizedQueryAabbMin,aabbMin,0);
+		quantizeWithClamp(quantizedQueryAabbMax,aabbMax,1);
+
+		switch (m_traversalMode)
+		{
+		case TRAVERSAL_STACKLESS:
+				walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,0,m_curNodeIndex);
+			break;
+		case TRAVERSAL_STACKLESS_CACHE_FRIENDLY:
+				walkStacklessQuantizedTreeCacheFriendly(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
+			break;
+		case TRAVERSAL_RECURSIVE:
+			{
+				const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[0];
+				walkRecursiveQuantizedTreeAgainstQueryAabb(rootNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
+			}
+			break;
+		default:
+			//unsupported
+			btAssert(0);
+		}
+	} else
+	{
+		walkStacklessTree(nodeCallback,aabbMin,aabbMax);
+	}
+}
+
+
+int maxIterations = 0;
+
+
+void	btQuantizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+	btAssert(!m_useQuantization);
+
+	const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
+	int escapeIndex, curIndex = 0;
+	int walkIterations = 0;
+	bool isLeafNode;
+	//PCK: unsigned instead of bool
+	unsigned aabbOverlap;
+
+	while (curIndex < m_curNodeIndex)
+	{
+		//catch bugs in tree data
+		btAssert (walkIterations < m_curNodeIndex);
+
+		walkIterations++;
+		aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
+		isLeafNode = rootNode->m_escapeIndex == -1;
+		
+		//PCK: unsigned instead of bool
+		if (isLeafNode && (aabbOverlap != 0))
+		{
+			nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
+		} 
+		
+		//PCK: unsigned instead of bool
+		if ((aabbOverlap != 0) || isLeafNode)
+		{
+			rootNode++;
+			curIndex++;
+		} else
+		{
+			escapeIndex = rootNode->m_escapeIndex;
+			rootNode += escapeIndex;
+			curIndex += escapeIndex;
+		}
+	}
+	if (maxIterations < walkIterations)
+		maxIterations = walkIterations;
+
+}
+
+/*
+///this was the original recursive traversal, before we optimized towards stackless traversal
+void	btQuantizedBvh::walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+	bool isLeafNode, aabbOverlap = TestAabbAgainstAabb2(aabbMin,aabbMax,rootNode->m_aabbMin,rootNode->m_aabbMax);
+	if (aabbOverlap)
+	{
+		isLeafNode = (!rootNode->m_leftChild && !rootNode->m_rightChild);
+		if (isLeafNode)
+		{
+			nodeCallback->processNode(rootNode);
+		} else
+		{
+			walkTree(rootNode->m_leftChild,nodeCallback,aabbMin,aabbMax);
+			walkTree(rootNode->m_rightChild,nodeCallback,aabbMin,aabbMax);
+		}
+	}
+
+}
+*/
+
+void btQuantizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const
+{
+	btAssert(m_useQuantization);
+	
+	bool isLeafNode;
+	//PCK: unsigned instead of bool
+	unsigned aabbOverlap;
+
+	//PCK: unsigned instead of bool
+	aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,currentNode->m_quantizedAabbMin,currentNode->m_quantizedAabbMax);
+	isLeafNode = currentNode->isLeafNode();
+		
+	//PCK: unsigned instead of bool
+	if (aabbOverlap != 0)
+	{
+		if (isLeafNode)
+		{
+			nodeCallback->processNode(currentNode->getPartId(),currentNode->getTriangleIndex());
+		} else
+		{
+			//process left and right children
+			const btQuantizedBvhNode* leftChildNode = currentNode+1;
+			walkRecursiveQuantizedTreeAgainstQueryAabb(leftChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
+
+			const btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? leftChildNode+1:leftChildNode+leftChildNode->getEscapeIndex();
+			walkRecursiveQuantizedTreeAgainstQueryAabb(rightChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax);
+		}
+	}		
+}
+
+
+
+void	btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const
+{
+	btAssert(!m_useQuantization);
+
+	const btOptimizedBvhNode* rootNode = &m_contiguousNodes[0];
+	int escapeIndex, curIndex = 0;
+	int walkIterations = 0;
+	bool isLeafNode;
+	//PCK: unsigned instead of bool
+	unsigned aabbOverlap=0;
+	unsigned rayBoxOverlap=0;
+	btScalar lambda_max = 1.0;
+	
+		/* Quick pruning by quantized box */
+	btVector3 rayAabbMin = raySource;
+	btVector3 rayAabbMax = raySource;
+	rayAabbMin.setMin(rayTarget);
+	rayAabbMax.setMax(rayTarget);
+
+	/* Add box cast extents to bounding box */
+	rayAabbMin += aabbMin;
+	rayAabbMax += aabbMax;
+
+#ifdef RAYAABB2
+	btVector3 rayDir = (rayTarget-raySource);
+	rayDir.normalize ();
+	lambda_max = rayDir.dot(rayTarget-raySource);
+	///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];
+	unsigned int sign[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0};
+#endif
+
+	btVector3 bounds[2];
+
+	while (curIndex < m_curNodeIndex)
+	{
+		btScalar param = 1.0;
+		//catch bugs in tree data
+		btAssert (walkIterations < m_curNodeIndex);
+
+		walkIterations++;
+
+		bounds[0] = rootNode->m_aabbMinOrg;
+		bounds[1] = rootNode->m_aabbMaxOrg;
+		/* Add box cast extents */
+		bounds[0] += aabbMin;
+		bounds[1] += aabbMax;
+
+		aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg);
+		//perhaps profile if it is worth doing the aabbOverlap test first
+
+#ifdef RAYAABB2
+			///careful with this check: need to check division by zero (above) and fix the unQuantize method
+			///thanks Joerg/hiker for the reproduction case!
+			///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858
+		rayBoxOverlap = aabbOverlap ? btRayAabb2 (raySource, rayDirectionInverse, sign, bounds, param, 0.0f, lambda_max) : false;
+
+#else
+		btVector3 normal;
+		rayBoxOverlap = btRayAabb(raySource, rayTarget,bounds[0],bounds[1],param, normal);
+#endif
+
+		isLeafNode = rootNode->m_escapeIndex == -1;
+		
+		//PCK: unsigned instead of bool
+		if (isLeafNode && (rayBoxOverlap != 0))
+		{
+			nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex);
+		} 
+		
+		//PCK: unsigned instead of bool
+		if ((rayBoxOverlap != 0) || isLeafNode)
+		{
+			rootNode++;
+			curIndex++;
+		} else
+		{
+			escapeIndex = rootNode->m_escapeIndex;
+			rootNode += escapeIndex;
+			curIndex += escapeIndex;
+		}
+	}
+	if (maxIterations < walkIterations)
+		maxIterations = walkIterations;
+
+}
+
+
+
+void	btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const
+{
+	btAssert(m_useQuantization);
+	
+	int curIndex = startNodeIndex;
+	int walkIterations = 0;
+	int subTreeSize = endNodeIndex - startNodeIndex;
+	(void)subTreeSize;
+
+	const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex];
+	int escapeIndex;
+	
+	bool isLeafNode;
+	//PCK: unsigned instead of bool
+	unsigned boxBoxOverlap = 0;
+	unsigned rayBoxOverlap = 0;
+
+	btScalar lambda_max = 1.0;
+
+#ifdef RAYAABB2
+	btVector3 rayDirection = (rayTarget-raySource);
+	rayDirection.normalize ();
+	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];
+	unsigned int sign[3] = { rayDirection[0] < 0.0, rayDirection[1] < 0.0, rayDirection[2] < 0.0};
+#endif
+
+	/* Quick pruning by quantized box */
+	btVector3 rayAabbMin = raySource;
+	btVector3 rayAabbMax = raySource;
+	rayAabbMin.setMin(rayTarget);
+	rayAabbMax.setMax(rayTarget);
+
+	/* Add box cast extents to bounding box */
+	rayAabbMin += aabbMin;
+	rayAabbMax += aabbMax;
+
+	unsigned short int quantizedQueryAabbMin[3];
+	unsigned short int quantizedQueryAabbMax[3];
+	quantizeWithClamp(quantizedQueryAabbMin,rayAabbMin,0);
+	quantizeWithClamp(quantizedQueryAabbMax,rayAabbMax,1);
+
+	while (curIndex < endNodeIndex)
+	{
+
+//#define VISUALLY_ANALYZE_BVH 1
+#ifdef VISUALLY_ANALYZE_BVH
+		//some code snippet to debugDraw aabb, to visually analyze bvh structure
+		static int drawPatch = 0;
+		//need some global access to a debugDrawer
+		extern btIDebugDraw* debugDrawerPtr;
+		if (curIndex==drawPatch)
+		{
+			btVector3 aabbMin,aabbMax;
+			aabbMin = unQuantize(rootNode->m_quantizedAabbMin);
+			aabbMax = unQuantize(rootNode->m_quantizedAabbMax);
+			btVector3	color(1,0,0);
+			debugDrawerPtr->drawAabb(aabbMin,aabbMax,color);
+		}
+#endif//VISUALLY_ANALYZE_BVH
+
+		//catch bugs in tree data
+		btAssert (walkIterations < subTreeSize);
+
+		walkIterations++;
+		//PCK: unsigned instead of bool
+		// only interested if this is closer than any previous hit
+		btScalar param = 1.0;
+		rayBoxOverlap = 0;
+		boxBoxOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
+		isLeafNode = rootNode->isLeafNode();
+		if (boxBoxOverlap)
+		{
+			btVector3 bounds[2];
+			bounds[0] = unQuantize(rootNode->m_quantizedAabbMin);
+			bounds[1] = unQuantize(rootNode->m_quantizedAabbMax);
+			/* Add box cast extents */
+			bounds[0] += aabbMin;
+			bounds[1] += aabbMax;
+			btVector3 normal;
+#if 0
+			bool ra2 = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0, lambda_max);
+			bool ra = btRayAabb (raySource, rayTarget, bounds[0], bounds[1], param, normal);
+			if (ra2 != ra)
+			{
+				printf("functions don't match\n");
+			}
+#endif
+#ifdef RAYAABB2
+			///careful with this check: need to check division by zero (above) and fix the unQuantize method
+			///thanks Joerg/hiker for the reproduction case!
+			///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858
+
+			//BT_PROFILE("btRayAabb2");
+			rayBoxOverlap = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max);
+			
+#else
+			rayBoxOverlap = true;//btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal);
+#endif
+		}
+		
+		if (isLeafNode && rayBoxOverlap)
+		{
+			nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex());
+		}
+		
+		//PCK: unsigned instead of bool
+		if ((rayBoxOverlap != 0) || isLeafNode)
+		{
+			rootNode++;
+			curIndex++;
+		} else
+		{
+			escapeIndex = rootNode->getEscapeIndex();
+			rootNode += escapeIndex;
+			curIndex += escapeIndex;
+		}
+	}
+	if (maxIterations < walkIterations)
+		maxIterations = walkIterations;
+
+}
+
+void	btQuantizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const
+{
+	btAssert(m_useQuantization);
+	
+	int curIndex = startNodeIndex;
+	int walkIterations = 0;
+	int subTreeSize = endNodeIndex - startNodeIndex;
+	(void)subTreeSize;
+
+	const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex];
+	int escapeIndex;
+	
+	bool isLeafNode;
+	//PCK: unsigned instead of bool
+	unsigned aabbOverlap;
+
+	while (curIndex < endNodeIndex)
+	{
+
+//#define VISUALLY_ANALYZE_BVH 1
+#ifdef VISUALLY_ANALYZE_BVH
+		//some code snippet to debugDraw aabb, to visually analyze bvh structure
+		static int drawPatch = 0;
+		//need some global access to a debugDrawer
+		extern btIDebugDraw* debugDrawerPtr;
+		if (curIndex==drawPatch)
+		{
+			btVector3 aabbMin,aabbMax;
+			aabbMin = unQuantize(rootNode->m_quantizedAabbMin);
+			aabbMax = unQuantize(rootNode->m_quantizedAabbMax);
+			btVector3	color(1,0,0);
+			debugDrawerPtr->drawAabb(aabbMin,aabbMax,color);
+		}
+#endif//VISUALLY_ANALYZE_BVH
+
+		//catch bugs in tree data
+		btAssert (walkIterations < subTreeSize);
+
+		walkIterations++;
+		//PCK: unsigned instead of bool
+		aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax);
+		isLeafNode = rootNode->isLeafNode();
+		
+		if (isLeafNode && aabbOverlap)
+		{
+			nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex());
+		} 
+		
+		//PCK: unsigned instead of bool
+		if ((aabbOverlap != 0) || isLeafNode)
+		{
+			rootNode++;
+			curIndex++;
+		} else
+		{
+			escapeIndex = rootNode->getEscapeIndex();
+			rootNode += escapeIndex;
+			curIndex += escapeIndex;
+		}
+	}
+	if (maxIterations < walkIterations)
+		maxIterations = walkIterations;
+
+}
+
+//This traversal can be called from Playstation 3 SPU
+void	btQuantizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const
+{
+	btAssert(m_useQuantization);
+
+	int i;
+
+
+	for (i=0;i<this->m_SubtreeHeaders.size();i++)
+	{
+		const btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
+
+		//PCK: unsigned instead of bool
+		unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
+		if (overlap != 0)
+		{
+			walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax,
+				subtree.m_rootNodeIndex,
+				subtree.m_rootNodeIndex+subtree.m_subtreeSize);
+		}
+	}
+}
+
+
+void	btQuantizedBvh::reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const
+{
+	reportBoxCastOverlappingNodex(nodeCallback,raySource,rayTarget,btVector3(0,0,0),btVector3(0,0,0));
+}
+
+
+void	btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+	//always use stackless
+
+	if (m_useQuantization)
+	{
+		walkStacklessQuantizedTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
+	}
+	else
+	{
+		walkStacklessTreeAgainstRay(nodeCallback, raySource, rayTarget, aabbMin, aabbMax, 0, m_curNodeIndex);
+	}
+	/*
+	{
+		//recursive traversal
+		btVector3 qaabbMin = raySource;
+		btVector3 qaabbMax = raySource;
+		qaabbMin.setMin(rayTarget);
+		qaabbMax.setMax(rayTarget);
+		qaabbMin += aabbMin;
+		qaabbMax += aabbMax;
+		reportAabbOverlappingNodex(nodeCallback,qaabbMin,qaabbMax);
+	}
+	*/
+
+}
+
+
+void	btQuantizedBvh::swapLeafNodes(int i,int splitIndex)
+{
+	if (m_useQuantization)
+	{
+			btQuantizedBvhNode tmp = m_quantizedLeafNodes[i];
+			m_quantizedLeafNodes[i] = m_quantizedLeafNodes[splitIndex];
+			m_quantizedLeafNodes[splitIndex] = tmp;
+	} else
+	{
+			btOptimizedBvhNode tmp = m_leafNodes[i];
+			m_leafNodes[i] = m_leafNodes[splitIndex];
+			m_leafNodes[splitIndex] = tmp;
+	}
+}
+
+void	btQuantizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex)
+{
+	if (m_useQuantization)
+	{
+		m_quantizedContiguousNodes[internalNode] = m_quantizedLeafNodes[leafNodeIndex];
+	} else
+	{
+		m_contiguousNodes[internalNode] = m_leafNodes[leafNodeIndex];
+	}
+}
+
+//PCK: include
+#include <new>
+
+#if 0
+//PCK: consts
+static const unsigned BVH_ALIGNMENT = 16;
+static const unsigned BVH_ALIGNMENT_MASK = BVH_ALIGNMENT-1;
+
+static const unsigned BVH_ALIGNMENT_BLOCKS = 2;
+#endif
+
+
+unsigned int btQuantizedBvh::getAlignmentSerializationPadding()
+{
+	// I changed this to 0 since the extra padding is not needed or used.
+	return 0;//BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT;
+}
+
+unsigned btQuantizedBvh::calculateSerializeBufferSize()
+{
+	unsigned baseSize = sizeof(btQuantizedBvh) + getAlignmentSerializationPadding();
+	baseSize += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
+	if (m_useQuantization)
+	{
+		return baseSize + m_curNodeIndex * sizeof(btQuantizedBvhNode);
+	}
+	return baseSize + m_curNodeIndex * sizeof(btOptimizedBvhNode);
+}
+
+bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian)
+{
+	btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size());
+	m_subtreeHeaderCount = m_SubtreeHeaders.size();
+
+/*	if (i_dataBufferSize < calculateSerializeBufferSize() || o_alignedDataBuffer == NULL || (((unsigned)o_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0))
+	{
+		///check alignedment for buffer?
+		btAssert(0);
+		return false;
+	}
+*/
+
+	btQuantizedBvh *targetBvh = (btQuantizedBvh *)o_alignedDataBuffer;
+
+	// construct the class so the virtual function table, etc will be set up
+	// Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor
+	new (targetBvh) btQuantizedBvh;
+
+	if (i_swapEndian)
+	{
+		targetBvh->m_curNodeIndex = static_cast<int>(btSwapEndian(m_curNodeIndex));
+
+
+		btSwapVector3Endian(m_bvhAabbMin,targetBvh->m_bvhAabbMin);
+		btSwapVector3Endian(m_bvhAabbMax,targetBvh->m_bvhAabbMax);
+		btSwapVector3Endian(m_bvhQuantization,targetBvh->m_bvhQuantization);
+
+		targetBvh->m_traversalMode = (btTraversalMode)btSwapEndian(m_traversalMode);
+		targetBvh->m_subtreeHeaderCount = static_cast<int>(btSwapEndian(m_subtreeHeaderCount));
+	}
+	else
+	{
+		targetBvh->m_curNodeIndex = m_curNodeIndex;
+		targetBvh->m_bvhAabbMin = m_bvhAabbMin;
+		targetBvh->m_bvhAabbMax = m_bvhAabbMax;
+		targetBvh->m_bvhQuantization = m_bvhQuantization;
+		targetBvh->m_traversalMode = m_traversalMode;
+		targetBvh->m_subtreeHeaderCount = m_subtreeHeaderCount;
+	}
+
+	targetBvh->m_useQuantization = m_useQuantization;
+
+	unsigned char *nodeData = (unsigned char *)targetBvh;
+	nodeData += sizeof(btQuantizedBvh);
+	
+	unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
+	nodeData += sizeToAdd;
+	
+	int nodeCount = m_curNodeIndex;
+
+	if (m_useQuantization)
+	{
+		targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
+
+		if (i_swapEndian)
+		{
+			for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
+			{
+				targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]);
+				targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]);
+				targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]);
+
+				targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]);
+				targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]);
+				targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]);
+
+				targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = static_cast<int>(btSwapEndian(m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex));
+			}
+		}
+		else
+		{
+			for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
+			{
+	
+				targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0];
+				targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1];
+				targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2];
+
+				targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0];
+				targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1];
+				targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2];
+
+				targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex;
+
+
+			}
+		}
+		nodeData += sizeof(btQuantizedBvhNode) * nodeCount;
+
+		// this clears the pointer in the member variable it doesn't really do anything to the data
+		// it does call the destructor on the contained objects, but they are all classes with no destructor defined
+		// so the memory (which is not freed) is left alone
+		targetBvh->m_quantizedContiguousNodes.initializeFromBuffer(NULL, 0, 0);
+	}
+	else
+	{
+		targetBvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
+
+		if (i_swapEndian)
+		{
+			for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
+			{
+				btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMinOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg);
+				btSwapVector3Endian(m_contiguousNodes[nodeIndex].m_aabbMaxOrg, targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg);
+
+				targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = static_cast<int>(btSwapEndian(m_contiguousNodes[nodeIndex].m_escapeIndex));
+				targetBvh->m_contiguousNodes[nodeIndex].m_subPart = static_cast<int>(btSwapEndian(m_contiguousNodes[nodeIndex].m_subPart));
+				targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = static_cast<int>(btSwapEndian(m_contiguousNodes[nodeIndex].m_triangleIndex));
+			}
+		}
+		else
+		{
+			for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
+			{
+				targetBvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg = m_contiguousNodes[nodeIndex].m_aabbMinOrg;
+				targetBvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg = m_contiguousNodes[nodeIndex].m_aabbMaxOrg;
+
+				targetBvh->m_contiguousNodes[nodeIndex].m_escapeIndex = m_contiguousNodes[nodeIndex].m_escapeIndex;
+				targetBvh->m_contiguousNodes[nodeIndex].m_subPart = m_contiguousNodes[nodeIndex].m_subPart;
+				targetBvh->m_contiguousNodes[nodeIndex].m_triangleIndex = m_contiguousNodes[nodeIndex].m_triangleIndex;
+			}
+		}
+		nodeData += sizeof(btOptimizedBvhNode) * nodeCount;
+
+		// this clears the pointer in the member variable it doesn't really do anything to the data
+		// it does call the destructor on the contained objects, but they are all classes with no destructor defined
+		// so the memory (which is not freed) is left alone
+		targetBvh->m_contiguousNodes.initializeFromBuffer(NULL, 0, 0);
+	}
+
+	sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
+	nodeData += sizeToAdd;
+
+	// Now serialize the subtree headers
+	targetBvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, m_subtreeHeaderCount, m_subtreeHeaderCount);
+	if (i_swapEndian)
+	{
+		for (int i = 0; i < m_subtreeHeaderCount; i++)
+		{
+			targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
+			targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
+			targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
+
+			targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
+			targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
+			targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
+
+			targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = static_cast<int>(btSwapEndian(m_SubtreeHeaders[i].m_rootNodeIndex));
+			targetBvh->m_SubtreeHeaders[i].m_subtreeSize = static_cast<int>(btSwapEndian(m_SubtreeHeaders[i].m_subtreeSize));
+		}
+	}
+	else
+	{
+		for (int i = 0; i < m_subtreeHeaderCount; i++)
+		{
+			targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = (m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
+			targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = (m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
+			targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = (m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
+
+			targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = (m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
+			targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = (m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
+			targetBvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = (m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
+
+			targetBvh->m_SubtreeHeaders[i].m_rootNodeIndex = (m_SubtreeHeaders[i].m_rootNodeIndex);
+			targetBvh->m_SubtreeHeaders[i].m_subtreeSize = (m_SubtreeHeaders[i].m_subtreeSize);
+
+			// need to clear padding in destination buffer
+			targetBvh->m_SubtreeHeaders[i].m_padding[0] = 0;
+			targetBvh->m_SubtreeHeaders[i].m_padding[1] = 0;
+			targetBvh->m_SubtreeHeaders[i].m_padding[2] = 0;
+		}
+	}
+	nodeData += sizeof(btBvhSubtreeInfo) * m_subtreeHeaderCount;
+
+	// this clears the pointer in the member variable it doesn't really do anything to the data
+	// it does call the destructor on the contained objects, but they are all classes with no destructor defined
+	// so the memory (which is not freed) is left alone
+	targetBvh->m_SubtreeHeaders.initializeFromBuffer(NULL, 0, 0);
+
+	// this wipes the virtual function table pointer at the start of the buffer for the class
+	*((void**)o_alignedDataBuffer) = NULL;
+
+	return true;
+}
+
+btQuantizedBvh *btQuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian)
+{
+
+	if (i_alignedDataBuffer == NULL)// || (((unsigned)i_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0))
+	{
+		return NULL;
+	}
+	btQuantizedBvh *bvh = (btQuantizedBvh *)i_alignedDataBuffer;
+
+	if (i_swapEndian)
+	{
+		bvh->m_curNodeIndex = static_cast<int>(btSwapEndian(bvh->m_curNodeIndex));
+
+		btUnSwapVector3Endian(bvh->m_bvhAabbMin);
+		btUnSwapVector3Endian(bvh->m_bvhAabbMax);
+		btUnSwapVector3Endian(bvh->m_bvhQuantization);
+
+		bvh->m_traversalMode = (btTraversalMode)btSwapEndian(bvh->m_traversalMode);
+		bvh->m_subtreeHeaderCount = static_cast<int>(btSwapEndian(bvh->m_subtreeHeaderCount));
+	}
+
+	unsigned int calculatedBufSize = bvh->calculateSerializeBufferSize();
+	btAssert(calculatedBufSize <= i_dataBufferSize);
+
+	if (calculatedBufSize > i_dataBufferSize)
+	{
+		return NULL;
+	}
+
+	unsigned char *nodeData = (unsigned char *)bvh;
+	nodeData += sizeof(btQuantizedBvh);
+	
+	unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
+	nodeData += sizeToAdd;
+	
+	int nodeCount = bvh->m_curNodeIndex;
+
+	// Must call placement new to fill in virtual function table, etc, but we don't want to overwrite most data, so call a special version of the constructor
+	// Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor
+	new (bvh) btQuantizedBvh(*bvh, false);
+
+	if (bvh->m_useQuantization)
+	{
+		bvh->m_quantizedContiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
+
+		if (i_swapEndian)
+		{
+			for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
+			{
+				bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]);
+				bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]);
+				bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]);
+
+				bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0]);
+				bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[1]);
+				bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]);
+
+				bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = static_cast<int>(btSwapEndian(bvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex));
+			}
+		}
+		nodeData += sizeof(btQuantizedBvhNode) * nodeCount;
+	}
+	else
+	{
+		bvh->m_contiguousNodes.initializeFromBuffer(nodeData, nodeCount, nodeCount);
+
+		if (i_swapEndian)
+		{
+			for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++)
+			{
+				btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg);
+				btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg);
+				
+				bvh->m_contiguousNodes[nodeIndex].m_escapeIndex = static_cast<int>(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_escapeIndex));
+				bvh->m_contiguousNodes[nodeIndex].m_subPart = static_cast<int>(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_subPart));
+				bvh->m_contiguousNodes[nodeIndex].m_triangleIndex = static_cast<int>(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_triangleIndex));
+			}
+		}
+		nodeData += sizeof(btOptimizedBvhNode) * nodeCount;
+	}
+
+	sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK;
+	nodeData += sizeToAdd;
+
+	// Now serialize the subtree headers
+	bvh->m_SubtreeHeaders.initializeFromBuffer(nodeData, bvh->m_subtreeHeaderCount, bvh->m_subtreeHeaderCount);
+	if (i_swapEndian)
+	{
+		for (int i = 0; i < bvh->m_subtreeHeaderCount; i++)
+		{
+			bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[0]);
+			bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[1]);
+			bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMin[2]);
+
+			bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[0]);
+			bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[1]);
+			bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2] = btSwapEndian(bvh->m_SubtreeHeaders[i].m_quantizedAabbMax[2]);
+
+			bvh->m_SubtreeHeaders[i].m_rootNodeIndex = static_cast<int>(btSwapEndian(bvh->m_SubtreeHeaders[i].m_rootNodeIndex));
+			bvh->m_SubtreeHeaders[i].m_subtreeSize = static_cast<int>(btSwapEndian(bvh->m_SubtreeHeaders[i].m_subtreeSize));
+		}
+	}
+
+	return bvh;
+}
+
+// Constructor that prevents btVector3's default constructor from being called
+btQuantizedBvh::btQuantizedBvh(btQuantizedBvh &self, bool /* ownsMemory */) :
+m_bvhAabbMin(self.m_bvhAabbMin),
+m_bvhAabbMax(self.m_bvhAabbMax),
+m_bvhQuantization(self.m_bvhQuantization),
+m_bulletVersion(BT_BULLET_VERSION)
+{
+
+}
+
+
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btQuantizedBvh.h	(revision 6952)
@@ -0,0 +1,473 @@
+/*
+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 QUANTIZED_BVH_H
+#define QUANTIZED_BVH_H
+
+//#define DEBUG_CHECK_DEQUANTIZATION 1
+#ifdef DEBUG_CHECK_DEQUANTIZATION
+#ifdef __SPU__
+#define printf spu_printf
+#endif //__SPU__
+
+#include <stdio.h>
+#include <stdlib.h>
+#endif //DEBUG_CHECK_DEQUANTIZATION
+
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btAlignedAllocator.h"
+
+
+//http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf__m128.asp
+
+
+//Note: currently we have 16 bytes per quantized node
+#define MAX_SUBTREE_SIZE_IN_BYTES  2048
+
+// 10 gives the potential for 1024 parts, with at most 2^21 (2097152) (minus one
+// actually) triangles each (since the sign bit is reserved
+#define MAX_NUM_PARTS_IN_BITS 10
+
+///btQuantizedBvhNode is a compressed aabb node, 16 bytes.
+///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range).
+ATTRIBUTE_ALIGNED16	(struct) btQuantizedBvhNode
+{
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	//12 bytes
+	unsigned short int	m_quantizedAabbMin[3];
+	unsigned short int	m_quantizedAabbMax[3];
+	//4 bytes
+	int	m_escapeIndexOrTriangleIndex;
+
+	bool isLeafNode() const
+	{
+		//skipindex is negative (internal node), triangleindex >=0 (leafnode)
+		return (m_escapeIndexOrTriangleIndex >= 0);
+	}
+	int getEscapeIndex() const
+	{
+		btAssert(!isLeafNode());
+		return -m_escapeIndexOrTriangleIndex;
+	}
+	int	getTriangleIndex() const
+	{
+		btAssert(isLeafNode());
+		// Get only the lower bits where the triangle index is stored
+		return (m_escapeIndexOrTriangleIndex&~((~0)<<(31-MAX_NUM_PARTS_IN_BITS)));
+	}
+	int	getPartId() const
+	{
+		btAssert(isLeafNode());
+		// Get only the highest bits where the part index is stored
+		return (m_escapeIndexOrTriangleIndex>>(31-MAX_NUM_PARTS_IN_BITS));
+	}
+}
+;
+
+/// btOptimizedBvhNode contains both internal and leaf node information.
+/// Total node size is 44 bytes / node. You can use the compressed version of 16 bytes.
+ATTRIBUTE_ALIGNED16 (struct) btOptimizedBvhNode
+{
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	//32 bytes
+	btVector3	m_aabbMinOrg;
+	btVector3	m_aabbMaxOrg;
+
+	//4
+	int	m_escapeIndex;
+
+	//8
+	//for child nodes
+	int	m_subPart;
+	int	m_triangleIndex;
+	int	m_padding[5];//bad, due to alignment
+
+
+};
+
+
+///btBvhSubtreeInfo provides info to gather a subtree of limited size
+ATTRIBUTE_ALIGNED16(class) btBvhSubtreeInfo
+{
+public:
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	//12 bytes
+	unsigned short int	m_quantizedAabbMin[3];
+	unsigned short int	m_quantizedAabbMax[3];
+	//4 bytes, points to the root of the subtree
+	int			m_rootNodeIndex;
+	//4 bytes
+	int			m_subtreeSize;
+	int			m_padding[3];
+
+	btBvhSubtreeInfo()
+	{
+		//memset(&m_padding[0], 0, sizeof(m_padding));
+	}
+
+
+	void	setAabbFromQuantizeNode(const btQuantizedBvhNode& quantizedNode)
+	{
+		m_quantizedAabbMin[0] = quantizedNode.m_quantizedAabbMin[0];
+		m_quantizedAabbMin[1] = quantizedNode.m_quantizedAabbMin[1];
+		m_quantizedAabbMin[2] = quantizedNode.m_quantizedAabbMin[2];
+		m_quantizedAabbMax[0] = quantizedNode.m_quantizedAabbMax[0];
+		m_quantizedAabbMax[1] = quantizedNode.m_quantizedAabbMax[1];
+		m_quantizedAabbMax[2] = quantizedNode.m_quantizedAabbMax[2];
+	}
+}
+;
+
+
+class btNodeOverlapCallback
+{
+public:
+	virtual ~btNodeOverlapCallback() {};
+
+	virtual void processNode(int subPart, int triangleIndex) = 0;
+};
+
+#include "LinearMath/btAlignedAllocator.h"
+#include "LinearMath/btAlignedObjectArray.h"
+
+
+
+///for code readability:
+typedef btAlignedObjectArray<btOptimizedBvhNode>	NodeArray;
+typedef btAlignedObjectArray<btQuantizedBvhNode>	QuantizedNodeArray;
+typedef btAlignedObjectArray<btBvhSubtreeInfo>		BvhSubtreeInfoArray;
+
+
+///The btQuantizedBvh class stores an AABB tree that can be quickly traversed on CPU and Cell SPU.
+///It is used by the btBvhTriangleMeshShape as midphase, and by the btMultiSapBroadphase.
+///It is recommended to use quantization for better performance and lower memory requirements.
+ATTRIBUTE_ALIGNED16(class) btQuantizedBvh
+{
+public:
+	enum btTraversalMode
+	{
+		TRAVERSAL_STACKLESS = 0,
+		TRAVERSAL_STACKLESS_CACHE_FRIENDLY,
+		TRAVERSAL_RECURSIVE
+	};
+
+protected:
+
+
+	btVector3			m_bvhAabbMin;
+	btVector3			m_bvhAabbMax;
+	btVector3			m_bvhQuantization;
+
+	int					m_bulletVersion;	//for serialization versioning. It could also be used to detect endianess.
+
+	int					m_curNodeIndex;
+	//quantization data
+	bool				m_useQuantization;
+
+
+
+	NodeArray			m_leafNodes;
+	NodeArray			m_contiguousNodes;
+	QuantizedNodeArray	m_quantizedLeafNodes;
+	QuantizedNodeArray	m_quantizedContiguousNodes;
+	
+	btTraversalMode	m_traversalMode;
+	BvhSubtreeInfoArray		m_SubtreeHeaders;
+
+	//This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray
+	int m_subtreeHeaderCount;
+
+	
+
+
+
+	///two versions, one for quantized and normal nodes. This allows code-reuse while maintaining readability (no template/macro!)
+	///this might be refactored into a virtual, it is usually not calculated at run-time
+	void	setInternalNodeAabbMin(int nodeIndex, const btVector3& aabbMin)
+	{
+		if (m_useQuantization)
+		{
+			quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] ,aabbMin,0);
+		} else
+		{
+			m_contiguousNodes[nodeIndex].m_aabbMinOrg = aabbMin;
+
+		}
+	}
+	void	setInternalNodeAabbMax(int nodeIndex,const btVector3& aabbMax)
+	{
+		if (m_useQuantization)
+		{
+			quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0],aabbMax,1);
+		} else
+		{
+			m_contiguousNodes[nodeIndex].m_aabbMaxOrg = aabbMax;
+		}
+	}
+
+	btVector3 getAabbMin(int nodeIndex) const
+	{
+		if (m_useQuantization)
+		{
+			return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMin[0]);
+		}
+		//non-quantized
+		return m_leafNodes[nodeIndex].m_aabbMinOrg;
+
+	}
+	btVector3 getAabbMax(int nodeIndex) const
+	{
+		if (m_useQuantization)
+		{
+			return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMax[0]);
+		} 
+		//non-quantized
+		return m_leafNodes[nodeIndex].m_aabbMaxOrg;
+		
+	}
+
+	
+	void	setInternalNodeEscapeIndex(int nodeIndex, int escapeIndex)
+	{
+		if (m_useQuantization)
+		{
+			m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = -escapeIndex;
+		} 
+		else
+		{
+			m_contiguousNodes[nodeIndex].m_escapeIndex = escapeIndex;
+		}
+
+	}
+
+	void mergeInternalNodeAabb(int nodeIndex,const btVector3& newAabbMin,const btVector3& newAabbMax) 
+	{
+		if (m_useQuantization)
+		{
+			unsigned short int quantizedAabbMin[3];
+			unsigned short int quantizedAabbMax[3];
+			quantize(quantizedAabbMin,newAabbMin,0);
+			quantize(quantizedAabbMax,newAabbMax,1);
+			for (int i=0;i<3;i++)
+			{
+				if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] > quantizedAabbMin[i])
+					m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] = quantizedAabbMin[i];
+
+				if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] < quantizedAabbMax[i])
+					m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] = quantizedAabbMax[i];
+
+			}
+		} else
+		{
+			//non-quantized
+			m_contiguousNodes[nodeIndex].m_aabbMinOrg.setMin(newAabbMin);
+			m_contiguousNodes[nodeIndex].m_aabbMaxOrg.setMax(newAabbMax);		
+		}
+	}
+
+	void	swapLeafNodes(int firstIndex,int secondIndex);
+
+	void	assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex);
+
+protected:
+
+	
+
+	void	buildTree	(int startIndex,int endIndex);
+
+	int	calcSplittingAxis(int startIndex,int endIndex);
+
+	int	sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis);
+	
+	void	walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+
+	void	walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const;
+	void	walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const;
+	void	walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const;
+
+	///tree traversal designed for small-memory processors like PS3 SPU
+	void	walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const;
+
+	///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal
+	void	walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const;
+
+	///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal
+	void	walkRecursiveQuantizedTreeAgainstQuantizedTree(const btQuantizedBvhNode* treeNodeA,const btQuantizedBvhNode* treeNodeB,btNodeOverlapCallback* nodeCallback) const;
+	
+
+
+
+	void	updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex);
+
+public:
+	
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	btQuantizedBvh();
+
+	virtual ~btQuantizedBvh();
+
+	
+	///***************************************** expert/internal use only *************************
+	void	setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin=btScalar(1.0));
+	QuantizedNodeArray&	getLeafNodeArray() {			return	m_quantizedLeafNodes;	}
+	///buildInternal is expert use only: assumes that setQuantizationValues and LeafNodeArray are initialized
+	void	buildInternal();
+	///***************************************** expert/internal use only *************************
+
+	void	reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+	void	reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const;
+	void	reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const;
+
+		SIMD_FORCE_INLINE void quantize(unsigned short* out, const btVector3& point,int isMax) const
+	{
+
+		btAssert(m_useQuantization);
+
+		btAssert(point.getX() <= m_bvhAabbMax.getX());
+		btAssert(point.getY() <= m_bvhAabbMax.getY());
+		btAssert(point.getZ() <= m_bvhAabbMax.getZ());
+
+		btAssert(point.getX() >= m_bvhAabbMin.getX());
+		btAssert(point.getY() >= m_bvhAabbMin.getY());
+		btAssert(point.getZ() >= m_bvhAabbMin.getZ());
+
+		btVector3 v = (point - m_bvhAabbMin) * m_bvhQuantization;
+		///Make sure rounding is done in a way that unQuantize(quantizeWithClamp(...)) is conservative
+		///end-points always set the first bit, so that they are sorted properly (so that neighbouring AABBs overlap properly)
+		///@todo: double-check this
+		if (isMax)
+		{
+			out[0] = (unsigned short) (((unsigned short)(v.getX()+btScalar(1.)) | 1));
+			out[1] = (unsigned short) (((unsigned short)(v.getY()+btScalar(1.)) | 1));
+			out[2] = (unsigned short) (((unsigned short)(v.getZ()+btScalar(1.)) | 1));
+		} else
+		{
+			out[0] = (unsigned short) (((unsigned short)(v.getX()) & 0xfffe));
+			out[1] = (unsigned short) (((unsigned short)(v.getY()) & 0xfffe));
+			out[2] = (unsigned short) (((unsigned short)(v.getZ()) & 0xfffe));
+		}
+
+
+#ifdef DEBUG_CHECK_DEQUANTIZATION
+		btVector3 newPoint = unQuantize(out);
+		if (isMax)
+		{
+			if (newPoint.getX() < point.getX())
+			{
+				printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n",newPoint.getX()-point.getX(), newPoint.getX(),point.getX());
+			}
+			if (newPoint.getY() < point.getY())
+			{
+				printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n",newPoint.getY()-point.getY(), newPoint.getY(),point.getY());
+			}
+			if (newPoint.getZ() < point.getZ())
+			{
+
+				printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n",newPoint.getZ()-point.getZ(), newPoint.getZ(),point.getZ());
+			}
+		} else
+		{
+			if (newPoint.getX() > point.getX())
+			{
+				printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n",newPoint.getX()-point.getX(), newPoint.getX(),point.getX());
+			}
+			if (newPoint.getY() > point.getY())
+			{
+				printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n",newPoint.getY()-point.getY(), newPoint.getY(),point.getY());
+			}
+			if (newPoint.getZ() > point.getZ())
+			{
+				printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n",newPoint.getZ()-point.getZ(), newPoint.getZ(),point.getZ());
+			}
+		}
+#endif //DEBUG_CHECK_DEQUANTIZATION
+
+	}
+
+
+	SIMD_FORCE_INLINE void quantizeWithClamp(unsigned short* out, const btVector3& point2,int isMax) const
+	{
+
+		btAssert(m_useQuantization);
+
+		btVector3 clampedPoint(point2);
+		clampedPoint.setMax(m_bvhAabbMin);
+		clampedPoint.setMin(m_bvhAabbMax);
+
+		quantize(out,clampedPoint,isMax);
+
+	}
+	
+	SIMD_FORCE_INLINE btVector3	unQuantize(const unsigned short* vecIn) const
+	{
+			btVector3	vecOut;
+			vecOut.setValue(
+			(btScalar)(vecIn[0]) / (m_bvhQuantization.getX()),
+			(btScalar)(vecIn[1]) / (m_bvhQuantization.getY()),
+			(btScalar)(vecIn[2]) / (m_bvhQuantization.getZ()));
+			vecOut += m_bvhAabbMin;
+			return vecOut;
+	}
+
+	///setTraversalMode let's you choose between stackless, recursive or stackless cache friendly tree traversal. Note this is only implemented for quantized trees.
+	void	setTraversalMode(btTraversalMode	traversalMode)
+	{
+		m_traversalMode = traversalMode;
+	}
+
+
+	SIMD_FORCE_INLINE QuantizedNodeArray&	getQuantizedNodeArray()
+	{	
+		return	m_quantizedContiguousNodes;
+	}
+
+
+	SIMD_FORCE_INLINE BvhSubtreeInfoArray&	getSubtreeInfoArray()
+	{
+		return m_SubtreeHeaders;
+	}
+
+
+	/////Calculate space needed to store BVH for serialization
+	unsigned calculateSerializeBufferSize();
+
+	/// Data buffer MUST be 16 byte aligned
+	virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian);
+
+	///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place'
+	static btQuantizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian);
+
+	static unsigned int getAlignmentSerializationPadding();
+
+	SIMD_FORCE_INLINE bool isQuantized()
+	{
+		return m_useQuantization;
+	}
+
+private:
+	// Special "copy" constructor that allows for in-place deserialization
+	// Prevents btVector3's default constructor from being called, but doesn't inialize much else
+	// ownsMemory should most likely be false if deserializing, and if you are not, don't call this (it also changes the function signature, which we need)
+	btQuantizedBvh(btQuantizedBvh &other, bool ownsMemory);
+
+}
+;
+
+
+#endif //QUANTIZED_BVH_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp	(revision 6952)
@@ -0,0 +1,330 @@
+/*
+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 "btSimpleBroadphase.h"
+#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btMatrix3x3.h"
+#include <new>
+
+extern int gOverlappingPairs;
+
+void	btSimpleBroadphase::validate()
+{
+	for (int i=0;i<m_numHandles;i++)
+	{
+		for (int j=i+1;j<m_numHandles;j++)
+		{
+			btAssert(&m_pHandles[i] != &m_pHandles[j]);
+		}
+	}
+	
+}
+
+btSimpleBroadphase::btSimpleBroadphase(int maxProxies, btOverlappingPairCache* overlappingPairCache)
+	:m_pairCache(overlappingPairCache),
+	m_ownsPairCache(false),
+	m_invalidPair(0)
+{
+
+	if (!overlappingPairCache)
+	{
+		void* mem = btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16);
+		m_pairCache = new (mem)btHashedOverlappingPairCache();
+		m_ownsPairCache = true;
+	}
+
+	// allocate handles buffer and put all handles on free list
+	m_pHandlesRawPtr = btAlignedAlloc(sizeof(btSimpleBroadphaseProxy)*maxProxies,16);
+	m_pHandles = new(m_pHandlesRawPtr) btSimpleBroadphaseProxy[maxProxies];
+	m_maxHandles = maxProxies;
+	m_numHandles = 0;
+	m_firstFreeHandle = 0;
+	m_LastHandleIndex = -1;
+	
+
+	{
+		for (int i = m_firstFreeHandle; i < maxProxies; i++)
+		{
+			m_pHandles[i].SetNextFree(i + 1);
+			m_pHandles[i].m_uniqueId = i+2;//any UID will do, we just avoid too trivial values (0,1) for debugging purposes
+		}
+		m_pHandles[maxProxies - 1].SetNextFree(0);
+	
+	}
+
+}
+
+btSimpleBroadphase::~btSimpleBroadphase()
+{
+	btAlignedFree(m_pHandlesRawPtr);
+
+	if (m_ownsPairCache)
+	{
+		m_pairCache->~btOverlappingPairCache();
+		btAlignedFree(m_pairCache);
+	}
+}
+
+
+btBroadphaseProxy*	btSimpleBroadphase::createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* /*dispatcher*/,void* multiSapProxy)
+{
+	if (m_numHandles >= m_maxHandles)
+	{
+		btAssert(0);
+		return 0; //should never happen, but don't let the game crash ;-)
+	}
+	btAssert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]);
+
+	int newHandleIndex = allocHandle();
+	btSimpleBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex])btSimpleBroadphaseProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy);
+
+	return proxy;
+}
+
+class	RemovingOverlapCallback : public btOverlapCallback
+{
+protected:
+	virtual bool	processOverlap(btBroadphasePair& pair)
+	{
+		(void)pair;
+		btAssert(0);
+		return false;
+	}
+};
+
+class RemovePairContainingProxy
+{
+
+	btBroadphaseProxy*	m_targetProxy;
+	public:
+	virtual ~RemovePairContainingProxy()
+	{
+	}
+protected:
+	virtual bool processOverlap(btBroadphasePair& pair)
+	{
+		btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy0);
+		btSimpleBroadphaseProxy* proxy1 = static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy1);
+
+		return ((m_targetProxy == proxy0 || m_targetProxy == proxy1));
+	};
+};
+
+void	btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg,btDispatcher* dispatcher)
+{
+		
+		btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxyOrg);
+		freeHandle(proxy0);
+
+		m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg,dispatcher);
+
+		//validate();
+		
+}
+
+void	btSimpleBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const
+{
+	const btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
+	aabbMin = sbp->m_aabbMin;
+	aabbMax = sbp->m_aabbMax;
+}
+
+void	btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* /*dispatcher*/)
+{
+	btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy);
+	sbp->m_aabbMin = aabbMin;
+	sbp->m_aabbMax = aabbMax;
+}
+
+void	btSimpleBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax)
+{
+	for (int i=0; i <= m_LastHandleIndex; i++)
+	{
+		btSimpleBroadphaseProxy* proxy = &m_pHandles[i];
+		if(!proxy->m_clientObject)
+		{
+			continue;
+		}
+		rayCallback.process(proxy);
+	}
+}
+
+
+
+	
+
+
+
+bool	btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1)
+{
+	return proxy0->m_aabbMin[0] <= proxy1->m_aabbMax[0] && proxy1->m_aabbMin[0] <= proxy0->m_aabbMax[0] && 
+		   proxy0->m_aabbMin[1] <= proxy1->m_aabbMax[1] && proxy1->m_aabbMin[1] <= proxy0->m_aabbMax[1] &&
+		   proxy0->m_aabbMin[2] <= proxy1->m_aabbMax[2] && proxy1->m_aabbMin[2] <= proxy0->m_aabbMax[2];
+
+}
+
+
+
+//then remove non-overlapping ones
+class CheckOverlapCallback : public btOverlapCallback
+{
+public:
+	virtual bool processOverlap(btBroadphasePair& pair)
+	{
+		return (!btSimpleBroadphase::aabbOverlap(static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy0),static_cast<btSimpleBroadphaseProxy*>(pair.m_pProxy1)));
+	}
+};
+
+void	btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher)
+{
+	//first check for new overlapping pairs
+	int i,j;
+	if (m_numHandles >= 0)
+	{
+		int new_largest_index = -1;
+		for (i=0; i <= m_LastHandleIndex; i++)
+		{
+			btSimpleBroadphaseProxy* proxy0 = &m_pHandles[i];
+			if(!proxy0->m_clientObject)
+			{
+				continue;
+			}
+			new_largest_index = i;
+			for (j=i+1; j <= m_LastHandleIndex; j++)
+			{
+				btSimpleBroadphaseProxy* proxy1 = &m_pHandles[j];
+				btAssert(proxy0 != proxy1);
+				if(!proxy1->m_clientObject)
+				{
+					continue;
+				}
+
+				btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
+				btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1);
+
+				if (aabbOverlap(p0,p1))
+				{
+					if ( !m_pairCache->findPair(proxy0,proxy1))
+					{
+						m_pairCache->addOverlappingPair(proxy0,proxy1);
+					}
+				} else
+				{
+					if (!m_pairCache->hasDeferredRemoval())
+					{
+						if ( m_pairCache->findPair(proxy0,proxy1))
+						{
+							m_pairCache->removeOverlappingPair(proxy0,proxy1,dispatcher);
+						}
+					}
+				}
+			}
+		}
+
+		m_LastHandleIndex = new_largest_index;
+
+		if (m_ownsPairCache && m_pairCache->hasDeferredRemoval())
+		{
+
+			btBroadphasePairArray&	overlappingPairArray = m_pairCache->getOverlappingPairArray();
+
+			//perform a sort, to find duplicates and to sort 'invalid' pairs to the end
+			overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
+
+			overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
+			m_invalidPair = 0;
+
+
+			btBroadphasePair previousPair;
+			previousPair.m_pProxy0 = 0;
+			previousPair.m_pProxy1 = 0;
+			previousPair.m_algorithm = 0;
+
+
+			for (i=0;i<overlappingPairArray.size();i++)
+			{
+
+				btBroadphasePair& pair = overlappingPairArray[i];
+
+				bool isDuplicate = (pair == previousPair);
+
+				previousPair = pair;
+
+				bool needsRemoval = false;
+
+				if (!isDuplicate)
+				{
+					bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1);
+
+					if (hasOverlap)
+					{
+						needsRemoval = false;//callback->processOverlap(pair);
+					} else
+					{
+						needsRemoval = true;
+					}
+				} else
+				{
+					//remove duplicate
+					needsRemoval = true;
+					//should have no algorithm
+					btAssert(!pair.m_algorithm);
+				}
+
+				if (needsRemoval)
+				{
+					m_pairCache->cleanOverlappingPair(pair,dispatcher);
+
+					//		m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1);
+					//		m_overlappingPairArray.pop_back();
+					pair.m_pProxy0 = 0;
+					pair.m_pProxy1 = 0;
+					m_invalidPair++;
+					gOverlappingPairs--;
+				} 
+
+			}
+
+			///if you don't like to skip the invalid pairs in the array, execute following code:
+#define CLEAN_INVALID_PAIRS 1
+#ifdef CLEAN_INVALID_PAIRS
+
+			//perform a sort, to sort 'invalid' pairs to the end
+			overlappingPairArray.quickSort(btBroadphasePairSortPredicate());
+
+			overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair);
+			m_invalidPair = 0;
+#endif//CLEAN_INVALID_PAIRS
+
+		}
+	}
+}
+
+
+bool btSimpleBroadphase::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+{
+	btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0);
+	btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1);
+	return aabbOverlap(p0,p1);
+}
+
+void	btSimpleBroadphase::resetPool(btDispatcher* dispatcher)
+{
+	//not yet
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h	(revision 6952)
@@ -0,0 +1,170 @@
+/*
+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 SIMPLE_BROADPHASE_H
+#define SIMPLE_BROADPHASE_H
+
+
+#include "btOverlappingPairCache.h"
+
+
+struct btSimpleBroadphaseProxy : public btBroadphaseProxy
+{
+	int			m_nextFree;
+	
+//	int			m_handleId;
+
+	
+	btSimpleBroadphaseProxy() {};
+
+	btSimpleBroadphaseProxy(const btVector3& minpt,const btVector3& maxpt,int shapeType,void* userPtr,short int collisionFilterGroup,short int collisionFilterMask,void* multiSapProxy)
+	:btBroadphaseProxy(minpt,maxpt,userPtr,collisionFilterGroup,collisionFilterMask,multiSapProxy)
+	{
+		(void)shapeType;
+	}
+	
+	
+	SIMD_FORCE_INLINE void SetNextFree(int next) {m_nextFree = next;}
+	SIMD_FORCE_INLINE int GetNextFree() const {return m_nextFree;}
+
+	
+
+
+};
+
+///The SimpleBroadphase is just a unit-test for btAxisSweep3, bt32BitAxisSweep3, or btDbvtBroadphase, so use those classes instead.
+///It is a brute force aabb culling broadphase based on O(n^2) aabb checks
+class btSimpleBroadphase : public btBroadphaseInterface
+{
+
+protected:
+
+	int		m_numHandles;						// number of active handles
+	int		m_maxHandles;						// max number of handles
+	int		m_LastHandleIndex;							
+	
+	btSimpleBroadphaseProxy* m_pHandles;						// handles pool
+
+	void* m_pHandlesRawPtr;
+	int		m_firstFreeHandle;		// free handles list
+	
+	int allocHandle()
+	{
+		btAssert(m_numHandles < m_maxHandles);
+		int freeHandle = m_firstFreeHandle;
+		m_firstFreeHandle = m_pHandles[freeHandle].GetNextFree();
+		m_numHandles++;
+		if(freeHandle > m_LastHandleIndex)
+		{
+			m_LastHandleIndex = freeHandle;
+		}
+		return freeHandle;
+	}
+
+	void freeHandle(btSimpleBroadphaseProxy* proxy)
+	{
+		int handle = int(proxy-m_pHandles);
+		btAssert(handle >= 0 && handle < m_maxHandles);
+		if(handle == m_LastHandleIndex)
+		{
+			m_LastHandleIndex--;
+		}
+		proxy->SetNextFree(m_firstFreeHandle);
+		m_firstFreeHandle = handle;
+
+		proxy->m_clientObject = 0;
+
+		m_numHandles--;
+	}
+
+	btOverlappingPairCache*	m_pairCache;
+	bool	m_ownsPairCache;
+
+	int	m_invalidPair;
+
+	
+	
+	inline btSimpleBroadphaseProxy*	getSimpleProxyFromProxy(btBroadphaseProxy* proxy)
+	{
+		btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxy);
+		return proxy0;
+	}
+
+	inline const btSimpleBroadphaseProxy*	getSimpleProxyFromProxy(btBroadphaseProxy* proxy) const
+	{
+		const btSimpleBroadphaseProxy* proxy0 = static_cast<const btSimpleBroadphaseProxy*>(proxy);
+		return proxy0;
+	}
+
+	///reset broadphase internal structures, to ensure determinism/reproducability
+	virtual void resetPool(btDispatcher* dispatcher);
+
+
+	void	validate();
+
+protected:
+
+
+	
+
+public:
+	btSimpleBroadphase(int maxProxies=16384,btOverlappingPairCache* overlappingPairCache=0);
+	virtual ~btSimpleBroadphase();
+
+
+		static bool	aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1);
+
+
+	virtual btBroadphaseProxy*	createProxy(  const btVector3& aabbMin,  const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy);
+
+	virtual void	calculateOverlappingPairs(btDispatcher* dispatcher);
+
+	virtual void	destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
+	virtual void	setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher);
+	virtual void	getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const;
+
+	virtual void	rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0));
+		
+	btOverlappingPairCache*	getOverlappingPairCache()
+	{
+		return m_pairCache;
+	}
+	const btOverlappingPairCache*	getOverlappingPairCache() const
+	{
+		return m_pairCache;
+	}
+
+	bool	testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1);
+
+
+	///getAabb returns the axis aligned bounding box in the 'global' coordinate frame
+	///will add some transform later
+	virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const
+	{
+		aabbMin.setValue(-1e30f,-1e30f,-1e30f);
+		aabbMax.setValue(1e30f,1e30f,1e30f);
+	}
+
+	virtual void	printStats()
+	{
+//		printf("btSimpleBroadphase.h\n");
+//		printf("numHandles = %d, maxHandles = %d\n",m_numHandles,m_maxHandles);
+	}
+};
+
+
+
+#endif //SIMPLE_BROADPHASE_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,200 @@
+ADD_SOURCE_FILES(BULLET_FILES
+
+COMPILATION_BEGIN BulletCollisionCompilation.cpp
+
+	BroadphaseCollision/btAxisSweep3.cpp
+	BroadphaseCollision/btBroadphaseProxy.cpp
+	BroadphaseCollision/btCollisionAlgorithm.cpp
+	BroadphaseCollision/btDispatcher.cpp
+	BroadphaseCollision/btDbvtBroadphase.cpp
+	BroadphaseCollision/btDbvt.cpp
+	BroadphaseCollision/btMultiSapBroadphase.cpp
+	BroadphaseCollision/btOverlappingPairCache.cpp
+	BroadphaseCollision/btQuantizedBvh.cpp
+	BroadphaseCollision/btSimpleBroadphase.cpp
+
+	CollisionDispatch/btActivatingCollisionAlgorithm.cpp
+	CollisionDispatch/btCollisionDispatcher.cpp
+	CollisionDispatch/btCollisionObject.cpp
+	CollisionDispatch/btCollisionWorld.cpp
+	CollisionDispatch/btCompoundCollisionAlgorithm.cpp
+	CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
+	CollisionDispatch/btDefaultCollisionConfiguration.cpp
+	CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
+	CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
+	CollisionDispatch/btBoxBoxDetector.cpp
+	CollisionDispatch/btGhostObject.cpp
+	CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
+	CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
+	CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
+	CollisionDispatch/btConvexConvexAlgorithm.cpp
+	CollisionDispatch/btEmptyCollisionAlgorithm.cpp
+	CollisionDispatch/btManifoldResult.cpp
+	CollisionDispatch/btSimulationIslandManager.cpp
+	CollisionDispatch/btUnionFind.cpp
+	CollisionDispatch/SphereTriangleDetector.cpp
+
+	CollisionShapes/btBoxShape.cpp
+	CollisionShapes/btBvhTriangleMeshShape.cpp
+	CollisionShapes/btCapsuleShape.cpp
+	CollisionShapes/btCollisionShape.cpp
+	CollisionShapes/btCompoundShape.cpp
+	CollisionShapes/btConcaveShape.cpp
+	CollisionShapes/btConeShape.cpp
+	CollisionShapes/btConvexHullShape.cpp
+	CollisionShapes/btConvexPointCloudShape.cpp
+	CollisionShapes/btConvexShape.cpp
+	CollisionShapes/btConvexInternalShape.cpp
+	CollisionShapes/btConvexTriangleMeshShape.cpp
+	CollisionShapes/btCylinderShape.cpp
+	CollisionShapes/btEmptyShape.cpp
+	CollisionShapes/btHeightfieldTerrainShape.cpp
+	CollisionShapes/btMinkowskiSumShape.cpp
+	CollisionShapes/btMultimaterialTriangleMeshShape.cpp
+	CollisionShapes/btMultiSphereShape.cpp
+	CollisionShapes/btOptimizedBvh.cpp
+	CollisionShapes/btPolyhedralConvexShape.cpp
+	CollisionShapes/btScaledBvhTriangleMeshShape.cpp
+	CollisionShapes/btTetrahedronShape.cpp
+	CollisionShapes/btSphereShape.cpp
+	CollisionShapes/btShapeHull.cpp
+	CollisionShapes/btStaticPlaneShape.cpp
+	CollisionShapes/btStridingMeshInterface.cpp
+	CollisionShapes/btTriangleCallback.cpp
+	CollisionShapes/btTriangleBuffer.cpp
+	CollisionShapes/btTriangleIndexVertexArray.cpp
+	CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
+	CollisionShapes/btTriangleMesh.cpp
+	CollisionShapes/btTriangleMeshShape.cpp
+	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/btGjkEpa2.cpp
+	NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
+	NarrowPhaseCollision/btConvexCast.cpp
+	NarrowPhaseCollision/btGjkConvexCast.cpp
+	NarrowPhaseCollision/btGjkPairDetector.cpp
+	NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
+	NarrowPhaseCollision/btPersistentManifold.cpp
+	NarrowPhaseCollision/btRaycastCallback.cpp
+	NarrowPhaseCollision/btSubSimplexConvexCast.cpp
+	NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
+
+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
+	BroadphaseCollision/btBroadphaseInterface.h
+	BroadphaseCollision/btBroadphaseProxy.h
+	BroadphaseCollision/btCollisionAlgorithm.h
+	BroadphaseCollision/btDispatcher.h
+	BroadphaseCollision/btDbvtBroadphase.h
+	BroadphaseCollision/btDbvt.h
+	BroadphaseCollision/btMultiSapBroadphase.h
+	BroadphaseCollision/btOverlappingPairCache.h
+	BroadphaseCollision/btOverlappingPairCallback.h
+	BroadphaseCollision/btQuantizedBvh.h
+	BroadphaseCollision/btSimpleBroadphase.h
+
+	CollisionDispatch/btActivatingCollisionAlgorithm.h
+	CollisionDispatch/btCollisionConfiguration.h
+	CollisionDispatch/btCollisionCreateFunc.h
+	CollisionDispatch/btCollisionDispatcher.h
+	CollisionDispatch/btCollisionObject.h
+	CollisionDispatch/btCollisionWorld.h
+	CollisionDispatch/btCompoundCollisionAlgorithm.h
+	CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
+	CollisionDispatch/btDefaultCollisionConfiguration.h
+	CollisionDispatch/btSphereSphereCollisionAlgorithm.h
+	CollisionDispatch/btBoxBoxCollisionAlgorithm.h
+	CollisionDispatch/btBoxBoxDetector.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/btUnionFind.h
+	CollisionDispatch/SphereTriangleDetector.h
+
+	CollisionShapes/btBoxShape.h
+	CollisionShapes/btBvhTriangleMeshShape.h
+	CollisionShapes/btCapsuleShape.h
+	CollisionShapes/btCollisionMargin
+	CollisionShapes/btCollisionShape.h
+	CollisionShapes/btCompoundShape.h
+	CollisionShapes/btConcaveShape.h
+	CollisionShapes/btConeShape.h
+	CollisionShapes/btConvexHullShape.h
+	CollisionShapes/btConvexPointCloudShape.h
+	CollisionShapes/btConvexShape.h
+	CollisionShapes/btConvexInternalShape.h
+	CollisionShapes/btConvexTriangleMeshShape.h
+	CollisionShapes/btCylinderShape.h
+	CollisionShapes/btEmptyShape.h
+	CollisionShapes/btHeightfieldTerrainShape.h
+	CollisionShapes/btMinkowskiSumShape.h
+	CollisionShapes/btMaterial.h
+	CollisionShapes/btMultimaterialTriangleMeshShape.h
+	CollisionShapes/btMultiSphereShape.h
+	CollisionShapes/btOptimizedBvh.h
+	CollisionShapes/btPolyhedralConvexShape.h
+	CollisionShapes/btScaledBvhTriangleMeshShape.h
+	CollisionShapes/btTetrahedronShape.h
+	CollisionShapes/btSphereShape.h
+	CollisionShapes/btShapeHull.h
+	CollisionShapes/btStaticPlaneShape.h
+	CollisionShapes/btStridingMeshInterface.h
+	CollisionShapes/btTriangleCallback.h
+	CollisionShapes/btTriangleBuffer.h
+	CollisionShapes/btTriangleIndexVertexArray.h
+	CollisionShapes/btTriangleIndexVertexMaterialArray.h
+	CollisionShapes/btTriangleMesh.h
+	CollisionShapes/btTriangleMeshShape.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
+	NarrowPhaseCollision/btConvexCast.h
+	NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
+	NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
+	NarrowPhaseCollision/btGjkConvexCast.h
+	NarrowPhaseCollision/btGjkEpa2.h
+	NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
+	NarrowPhaseCollision/btGjkPairDetector.h
+	NarrowPhaseCollision/btManifoldPoint.h
+	NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
+	NarrowPhaseCollision/btPersistentManifold.h
+	NarrowPhaseCollision/btPointCollector.h
+	NarrowPhaseCollision/btRaycastCallback.h
+	NarrowPhaseCollision/btSimplexSolverInterface.h
+	NarrowPhaseCollision/btSubSimplexConvexCast.h
+	NarrowPhaseCollision/btVoronoiSimplexSolver.h
+)
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp	(revision 6952)
@@ -0,0 +1,209 @@
+/*
+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 "LinearMath/btScalar.h"
+#include "SphereTriangleDetector.h"
+#include "BulletCollision/CollisionShapes/btTriangleShape.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
+
+
+SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle,btScalar contactBreakingThreshold)
+:m_sphere(sphere),
+m_triangle(triangle),
+m_contactBreakingThreshold(contactBreakingThreshold)
+{
+
+}
+
+void	SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults)
+{
+
+	(void)debugDraw;
+	const btTransform& transformA = input.m_transformA;
+	const btTransform& transformB = input.m_transformB;
+
+	btVector3 point,normal;
+	btScalar timeOfImpact = btScalar(1.);
+	btScalar depth = btScalar(0.);
+//	output.m_distance = btScalar(1e30);
+	//move sphere into triangle space
+	btTransform	sphereInTr = transformB.inverseTimes(transformA);
+
+	if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact,m_contactBreakingThreshold))
+	{
+		if (swapResults)
+		{
+			btVector3 normalOnB = transformB.getBasis()*normal;
+			btVector3 normalOnA = -normalOnB;
+			btVector3 pointOnA = transformB*point+normalOnB*depth;
+			output.addContactPoint(normalOnA,pointOnA,depth);
+		} else
+		{
+			output.addContactPoint(transformB.getBasis()*normal,transformB*point,depth);
+		}
+	}
+
+}
+
+#define MAX_OVERLAP btScalar(0.)
+
+
+
+// See also geometrictools.com
+// Basic idea: D = |p - (lo + t0*lv)| where t0 = lv . (p - lo) / lv . lv
+btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest);
+
+btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest) {
+	btVector3 diff = p - from;
+	btVector3 v = to - from;
+	btScalar t = v.dot(diff);
+	
+	if (t > 0) {
+		btScalar dotVV = v.dot(v);
+		if (t < dotVV) {
+			t /= dotVV;
+			diff -= t*v;
+		} else {
+			t = 1;
+			diff -= v;
+		}
+	} else
+		t = 0;
+
+	nearest = from + t*v;
+	return diff.dot(diff);	
+}
+
+bool SphereTriangleDetector::facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal)  {
+	btVector3 lp(p);
+	btVector3 lnormal(normal);
+	
+	return pointInTriangle(vertices, lnormal, &lp);
+}
+
+///combined discrete/continuous sphere-triangle
+bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold)
+{
+
+	const btVector3* vertices = &m_triangle->getVertexPtr(0);
+	const btVector3& c = sphereCenter;
+	btScalar r = m_sphere->getRadius();
+
+	btVector3 delta (0,0,0);
+
+	btVector3 normal = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]);
+	normal.normalize();
+	btVector3 p1ToCentre = c - vertices[0];
+	btScalar distanceFromPlane = p1ToCentre.dot(normal);
+
+	if (distanceFromPlane < btScalar(0.))
+	{
+		//triangle facing the other way
+	
+		distanceFromPlane *= btScalar(-1.);
+		normal *= btScalar(-1.);
+	}
+
+	btScalar contactMargin = contactBreakingThreshold;
+	bool isInsideContactPlane = distanceFromPlane < r + contactMargin;
+	bool isInsideShellPlane = distanceFromPlane < r;
+	
+	btScalar deltaDotNormal = delta.dot(normal);
+	if (!isInsideShellPlane && deltaDotNormal >= btScalar(0.0))
+		return false;
+
+	// Check for contact / intersection
+	bool hasContact = false;
+	btVector3 contactPoint;
+	if (isInsideContactPlane) {
+		if (facecontains(c,vertices,normal)) {
+			// Inside the contact wedge - touches a point on the shell plane
+			hasContact = true;
+			contactPoint = c - normal*distanceFromPlane;
+		} else {
+			// Could be inside one of the contact capsules
+			btScalar contactCapsuleRadiusSqr = (r + contactMargin) * (r + contactMargin);
+			btVector3 nearestOnEdge;
+			for (int i = 0; i < m_triangle->getNumEdges(); i++) {
+				
+				btVector3 pa;
+				btVector3 pb;
+				
+				m_triangle->getEdge(i,pa,pb);
+
+				btScalar distanceSqr = SegmentSqrDistance(pa,pb,c, nearestOnEdge);
+				if (distanceSqr < contactCapsuleRadiusSqr) {
+					// Yep, we're inside a capsule
+					hasContact = true;
+					contactPoint = nearestOnEdge;
+				}
+				
+			}
+		}
+	}
+
+	if (hasContact) {
+		btVector3 contactToCentre = c - contactPoint;
+		btScalar distanceSqr = contactToCentre.length2();
+		if (distanceSqr < (r - MAX_OVERLAP)*(r - MAX_OVERLAP)) {
+			btScalar distance = btSqrt(distanceSqr);
+			resultNormal = contactToCentre;
+			resultNormal.normalize();
+			point = contactPoint;
+			depth = -(r-distance);
+			return true;
+		}
+
+		if (delta.dot(contactToCentre) >= btScalar(0.0)) 
+			return false;
+		
+		// Moving towards the contact point -> collision
+		point = contactPoint;
+		timeOfImpact = btScalar(0.0);
+		return true;
+	}
+	
+	return false;
+}
+
+
+bool SphereTriangleDetector::pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p )
+{
+	const btVector3* p1 = &vertices[0];
+	const btVector3* p2 = &vertices[1];
+	const btVector3* p3 = &vertices[2];
+
+	btVector3 edge1( *p2 - *p1 );
+	btVector3 edge2( *p3 - *p2 );
+	btVector3 edge3( *p1 - *p3 );
+
+	btVector3 p1_to_p( *p - *p1 );
+	btVector3 p2_to_p( *p - *p2 );
+	btVector3 p3_to_p( *p - *p3 );
+
+	btVector3 edge1_normal( edge1.cross(normal));
+	btVector3 edge2_normal( edge2.cross(normal));
+	btVector3 edge3_normal( edge3.cross(normal));
+	
+	btScalar r1, r2, r3;
+	r1 = edge1_normal.dot( p1_to_p );
+	r2 = edge2_normal.dot( p2_to_p );
+	r3 = edge3_normal.dot( p3_to_p );
+	if ( ( r1 > 0 && r2 > 0 && r3 > 0 ) ||
+	     ( r1 <= 0 && r2 <= 0 && r3 <= 0 ) )
+		return true;
+	return false;
+
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/SphereTriangleDetector.h	(revision 6952)
@@ -0,0 +1,49 @@
+/*
+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 SPHERE_TRIANGLE_DETECTOR_H
+#define SPHERE_TRIANGLE_DETECTOR_H
+
+#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
+
+
+
+class btSphereShape;
+class btTriangleShape;
+
+
+
+/// sphere-triangle to match the btDiscreteCollisionDetectorInterface
+struct SphereTriangleDetector : public btDiscreteCollisionDetectorInterface
+{
+	virtual void	getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false);
+
+	SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle, btScalar contactBreakingThreshold);
+
+	virtual ~SphereTriangleDetector() {};
+
+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);
+
+	btSphereShape* m_sphere;
+	btTriangleShape* m_triangle;
+	btScalar	m_contactBreakingThreshold;
+	
+};
+#endif //SPHERE_TRIANGLE_DETECTOR_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp	(revision 6952)
@@ -0,0 +1,47 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.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 "btActivatingCollisionAlgorithm.h"
+#include "btCollisionDispatcher.h"
+#include "btCollisionObject.h"
+
+btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci)
+:btCollisionAlgorithm(ci)
+//,
+//m_colObj0(0),
+//m_colObj1(0)
+{
+}
+btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* colObj0,btCollisionObject* colObj1)
+:btCollisionAlgorithm(ci)
+//,
+//m_colObj0(0),
+//m_colObj1(0)
+{
+//	if (ci.m_dispatcher1->needsCollision(colObj0,colObj1))
+//	{
+//		m_colObj0 = colObj0;
+//		m_colObj1 = colObj1;
+//		
+//		m_colObj0->activate();
+//		m_colObj1->activate();
+//	}
+}
+
+btActivatingCollisionAlgorithm::~btActivatingCollisionAlgorithm()
+{
+//		m_colObj0->activate();
+//		m_colObj1->activate();
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h	(revision 6952)
@@ -0,0 +1,36 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.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 __BT_ACTIVATING_COLLISION_ALGORITHM_H
+#define __BT_ACTIVATING_COLLISION_ALGORITHM_H
+
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+
+///This class is not enabled yet (work-in-progress) to more aggressively activate objects.
+class btActivatingCollisionAlgorithm : public btCollisionAlgorithm
+{
+//	btCollisionObject* m_colObj0;
+//	btCollisionObject* m_colObj1;
+
+public:
+
+	btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci);
+
+	btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* colObj0,btCollisionObject* colObj1);
+
+	virtual ~btActivatingCollisionAlgorithm();
+
+};
+#endif //__BT_ACTIVATING_COLLISION_ALGORITHM_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp	(revision 6952)
@@ -0,0 +1,85 @@
+/*
+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 "btBoxBoxCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/CollisionShapes/btBoxShape.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "btBoxBoxDetector.h"
+
+#define USE_PERSISTENT_CONTACTS 1
+
+btBoxBoxCollisionAlgorithm::btBoxBoxCollisionAlgorithm(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;
+	}
+}
+
+btBoxBoxCollisionAlgorithm::~btBoxBoxCollisionAlgorithm()
+{
+	if (m_ownManifold)
+	{
+		if (m_manifoldPtr)
+			m_dispatcher->releaseManifold(m_manifoldPtr);
+	}
+}
+
+void btBoxBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	if (!m_manifoldPtr)
+		return;
+
+	btCollisionObject*	col0 = body0;
+	btCollisionObject*	col1 = body1;
+	btBoxShape* box0 = (btBoxShape*)col0->getCollisionShape();
+	btBoxShape* box1 = (btBoxShape*)col1->getCollisionShape();
+
+
+
+	/// report a contact. internally this will be kept persistent, and contact reduction is done
+	resultOut->setPersistentManifold(m_manifoldPtr);
+#ifndef USE_PERSISTENT_CONTACTS	
+	m_manifoldPtr->clearManifold();
+#endif //USE_PERSISTENT_CONTACTS
+
+	btDiscreteCollisionDetectorInterface::ClosestPointInput input;
+	input.m_maximumDistanceSquared = 1e30f;
+	input.m_transformA = body0->getWorldTransform();
+	input.m_transformB = body1->getWorldTransform();
+
+	btBoxBoxDetector detector(box0,box1);
+	detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw);
+
+#ifdef USE_PERSISTENT_CONTACTS
+	//  refreshContactPoints is only necessary when using persistent contact points. otherwise all points are newly added
+	if (m_ownManifold)
+	{
+		resultOut->refreshContactPoints();
+	}
+#endif //USE_PERSISTENT_CONTACTS
+
+}
+
+btScalar btBoxBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/,btCollisionObject* /*body1*/,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/)
+{
+	//not yet
+	return 1.f;
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h	(revision 6952)
@@ -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_BOX__COLLISION_ALGORITHM_H
+#define BOX_BOX__COLLISION_ALGORITHM_H
+
+#include "btActivatingCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
+#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
+
+class btPersistentManifold;
+
+///box-box collision detection
+class btBoxBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm
+{
+	bool	m_ownManifold;
+	btPersistentManifold*	m_manifoldPtr;
+	
+public:
+	btBoxBoxCollisionAlgorithm(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);
+
+	btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
+
+	virtual ~btBoxBoxCollisionAlgorithm();
+
+	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(btBoxBoxCollisionAlgorithm);
+			void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize);
+			return new(ptr) btBoxBoxCollisionAlgorithm(0,ci,body0,body1);
+		}
+	};
+
+};
+
+#endif //BOX_BOX__COLLISION_ALGORITHM_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp	(revision 6952)
@@ -0,0 +1,689 @@
+
+/*
+ * Box-Box collision detection re-distributed under the ZLib license with permission from Russell L. Smith
+ * Original version is from Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org
+ Bullet Continuous Collision Detection and Physics Library
+ Bullet is 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.
+*/
+
+///ODE box-box collision detection is adapted to work with Bullet
+
+#include "btBoxBoxDetector.h"
+#include "BulletCollision/CollisionShapes/btBoxShape.h"
+
+#include <float.h>
+#include <string.h>
+
+btBoxBoxDetector::btBoxBoxDetector(btBoxShape* box1,btBoxShape* box2)
+: m_box1(box1),
+m_box2(box2)
+{
+
+}
+
+
+// given two boxes (p1,R1,side1) and (p2,R2,side2), collide them together and
+// generate contact points. this returns 0 if there is no contact otherwise
+// it returns the number of contacts generated.
+// `normal' returns the contact normal.
+// `depth' returns the maximum penetration depth along that normal.
+// `return_code' returns a number indicating the type of contact that was
+// detected:
+//        1,2,3 = box 2 intersects with a face of box 1
+//        4,5,6 = box 1 intersects with a face of box 2
+//        7..15 = edge-edge contact
+// `maxc' is the maximum number of contacts allowed to be generated, i.e.
+// the size of the `contact' array.
+// `contact' and `skip' are the contact array information provided to the
+// collision functions. this function only fills in the position and depth
+// fields.
+struct dContactGeom;
+#define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(q)])
+#define dInfinity FLT_MAX
+
+
+/*PURE_INLINE btScalar dDOT   (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,1); }
+PURE_INLINE btScalar dDOT13 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,3); }
+PURE_INLINE btScalar dDOT31 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,3,1); }
+PURE_INLINE btScalar dDOT33 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,3,3); }
+*/
+static btScalar dDOT   (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,1); }
+static btScalar dDOT44 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,4,4); }
+static btScalar dDOT41 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,4,1); }
+static btScalar dDOT14 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,4); }
+#define dMULTIPLYOP1_331(A,op,B,C) \
+{\
+  (A)[0] op dDOT41((B),(C)); \
+  (A)[1] op dDOT41((B+1),(C)); \
+  (A)[2] op dDOT41((B+2),(C)); \
+}
+
+#define dMULTIPLYOP0_331(A,op,B,C) \
+{ \
+  (A)[0] op dDOT((B),(C)); \
+  (A)[1] op dDOT((B+4),(C)); \
+  (A)[2] op dDOT((B+8),(C)); \
+} 
+
+#define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C)
+#define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C)
+
+typedef btScalar dMatrix3[4*3];
+
+void dLineClosestApproach (const btVector3& pa, const btVector3& ua,
+			   const btVector3& pb, const btVector3& ub,
+			   btScalar *alpha, btScalar *beta);
+void dLineClosestApproach (const btVector3& pa, const btVector3& ua,
+			   const btVector3& pb, const btVector3& ub,
+			   btScalar *alpha, btScalar *beta)
+{
+  btVector3 p;
+  p[0] = pb[0] - pa[0];
+  p[1] = pb[1] - pa[1];
+  p[2] = pb[2] - pa[2];
+  btScalar uaub = dDOT(ua,ub);
+  btScalar q1 =  dDOT(ua,p);
+  btScalar q2 = -dDOT(ub,p);
+  btScalar d = 1-uaub*uaub;
+  if (d <= btScalar(0.0001f)) {
+    // @@@ this needs to be made more robust
+    *alpha = 0;
+    *beta  = 0;
+  }
+  else {
+    d = 1.f/d;
+    *alpha = (q1 + uaub*q2)*d;
+    *beta  = (uaub*q1 + q2)*d;
+  }
+}
+
+
+
+// find all the intersection points between the 2D rectangle with vertices
+// at (+/-h[0],+/-h[1]) and the 2D quadrilateral with vertices (p[0],p[1]),
+// (p[2],p[3]),(p[4],p[5]),(p[6],p[7]).
+//
+// the intersection points are returned as x,y pairs in the 'ret' array.
+// the number of intersection points is returned by the function (this will
+// be in the range 0 to 8).
+
+static int intersectRectQuad2 (btScalar h[2], btScalar p[8], btScalar ret[16])
+{
+  // q (and r) contain nq (and nr) coordinate points for the current (and
+  // chopped) polygons
+  int nq=4,nr=0;
+  btScalar buffer[16];
+  btScalar *q = p;
+  btScalar *r = ret;
+  for (int dir=0; dir <= 1; dir++) {
+    // direction notation: xy[0] = x axis, xy[1] = y axis
+    for (int sign=-1; sign <= 1; sign += 2) {
+      // chop q along the line xy[dir] = sign*h[dir]
+      btScalar *pq = q;
+      btScalar *pr = r;
+      nr = 0;
+      for (int i=nq; i > 0; i--) {
+	// go through all points in q and all lines between adjacent points
+	if (sign*pq[dir] < h[dir]) {
+	  // this point is inside the chopping line
+	  pr[0] = pq[0];
+	  pr[1] = pq[1];
+	  pr += 2;
+	  nr++;
+	  if (nr & 8) {
+	    q = r;
+	    goto done;
+	  }
+	}
+	btScalar *nextq = (i > 1) ? pq+2 : q;
+	if ((sign*pq[dir] < h[dir]) ^ (sign*nextq[dir] < h[dir])) {
+	  // this line crosses the chopping line
+	  pr[1-dir] = pq[1-dir] + (nextq[1-dir]-pq[1-dir]) /
+	    (nextq[dir]-pq[dir]) * (sign*h[dir]-pq[dir]);
+	  pr[dir] = sign*h[dir];
+	  pr += 2;
+	  nr++;
+	  if (nr & 8) {
+	    q = r;
+	    goto done;
+	  }
+	}
+	pq += 2;
+      }
+      q = r;
+      r = (q==ret) ? buffer : ret;
+      nq = nr;
+    }
+  }
+ done:
+  if (q != ret) memcpy (ret,q,nr*2*sizeof(btScalar));
+  return nr;
+}
+
+
+#define M__PI 3.14159265f
+
+// given n points in the plane (array p, of size 2*n), generate m points that
+// best represent the whole set. the definition of 'best' here is not
+// predetermined - the idea is to select points that give good box-box
+// collision detection behavior. the chosen point indexes are returned in the
+// array iret (of size m). 'i0' is always the first entry in the array.
+// n must be in the range [1..8]. m must be in the range [1..n]. i0 must be
+// in the range [0..n-1].
+
+void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[]);
+void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[])
+{
+  // compute the centroid of the polygon in cx,cy
+  int i,j;
+  btScalar a,cx,cy,q;
+  if (n==1) {
+    cx = p[0];
+    cy = p[1];
+  }
+  else if (n==2) {
+    cx = btScalar(0.5)*(p[0] + p[2]);
+    cy = btScalar(0.5)*(p[1] + p[3]);
+  }
+  else {
+    a = 0;
+    cx = 0;
+    cy = 0;
+    for (i=0; i<(n-1); i++) {
+      q = p[i*2]*p[i*2+3] - p[i*2+2]*p[i*2+1];
+      a += q;
+      cx += q*(p[i*2]+p[i*2+2]);
+      cy += q*(p[i*2+1]+p[i*2+3]);
+    }
+    q = p[n*2-2]*p[1] - p[0]*p[n*2-1];
+	if (btFabs(a+q) > SIMD_EPSILON)
+	{
+		a = 1.f/(btScalar(3.0)*(a+q));
+	} else
+	{
+		a=1e30f;
+	}
+    cx = a*(cx + q*(p[n*2-2]+p[0]));
+    cy = a*(cy + q*(p[n*2-1]+p[1]));
+  }
+
+  // compute the angle of each point w.r.t. the centroid
+  btScalar A[8];
+  for (i=0; i<n; i++) A[i] = btAtan2(p[i*2+1]-cy,p[i*2]-cx);
+
+  // search for points that have angles closest to A[i0] + i*(2*pi/m).
+  int avail[8];
+  for (i=0; i<n; i++) avail[i] = 1;
+  avail[i0] = 0;
+  iret[0] = i0;
+  iret++;
+  for (j=1; j<m; j++) {
+    a = btScalar(j)*(2*M__PI/m) + A[i0];
+    if (a > M__PI) a -= 2*M__PI;
+    btScalar maxdiff=1e9,diff;
+
+    *iret = i0;			// iret is not allowed to keep this value, but it sometimes does, when diff=#QNAN0
+
+    for (i=0; i<n; i++) {
+      if (avail[i]) {
+	diff = btFabs (A[i]-a);
+	if (diff > M__PI) diff = 2*M__PI - diff;
+	if (diff < maxdiff) {
+	  maxdiff = diff;
+	  *iret = i;
+	}
+      }
+    }
+#if defined(DEBUG) || defined (_DEBUG)
+    btAssert (*iret != i0);	// ensure iret got set
+#endif
+    avail[*iret] = 0;
+    iret++;
+  }
+}
+
+
+
+int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
+	     const btVector3& side1, const btVector3& p2,
+	     const dMatrix3 R2, const btVector3& side2,
+	     btVector3& normal, btScalar *depth, int *return_code,
+		 int maxc, dContactGeom * /*contact*/, int /*skip*/,btDiscreteCollisionDetectorInterface::Result& output);
+int dBoxBox2 (const btVector3& p1, const dMatrix3 R1,
+	     const btVector3& side1, const btVector3& p2,
+	     const dMatrix3 R2, const btVector3& side2,
+	     btVector3& normal, btScalar *depth, int *return_code,
+		 int maxc, dContactGeom * /*contact*/, int /*skip*/,btDiscreteCollisionDetectorInterface::Result& output)
+{
+  const btScalar fudge_factor = btScalar(1.05);
+  btVector3 p,pp,normalC;
+  const btScalar *normalR = 0;
+  btScalar A[3],B[3],R11,R12,R13,R21,R22,R23,R31,R32,R33,
+    Q11,Q12,Q13,Q21,Q22,Q23,Q31,Q32,Q33,s,s2,l;
+  int i,j,invert_normal,code;
+
+  // get vector from centers of box 1 to box 2, relative to box 1
+  p = p2 - p1;
+  dMULTIPLY1_331 (pp,R1,p);		// get pp = p relative to body 1
+
+  // get side lengths / 2
+  A[0] = side1[0]*btScalar(0.5);
+  A[1] = side1[1]*btScalar(0.5);
+  A[2] = side1[2]*btScalar(0.5);
+  B[0] = side2[0]*btScalar(0.5);
+  B[1] = side2[1]*btScalar(0.5);
+  B[2] = side2[2]*btScalar(0.5);
+
+  // Rij is R1'*R2, i.e. the relative rotation between R1 and R2
+  R11 = dDOT44(R1+0,R2+0); R12 = dDOT44(R1+0,R2+1); R13 = dDOT44(R1+0,R2+2);
+  R21 = dDOT44(R1+1,R2+0); R22 = dDOT44(R1+1,R2+1); R23 = dDOT44(R1+1,R2+2);
+  R31 = dDOT44(R1+2,R2+0); R32 = dDOT44(R1+2,R2+1); R33 = dDOT44(R1+2,R2+2);
+
+  Q11 = btFabs(R11); Q12 = btFabs(R12); Q13 = btFabs(R13);
+  Q21 = btFabs(R21); Q22 = btFabs(R22); Q23 = btFabs(R23);
+  Q31 = btFabs(R31); Q32 = btFabs(R32); Q33 = btFabs(R33);
+
+  // for all 15 possible separating axes:
+  //   * see if the axis separates the boxes. if so, return 0.
+  //   * find the depth of the penetration along the separating axis (s2)
+  //   * if this is the largest depth so far, record it.
+  // the normal vector will be set to the separating axis with the smallest
+  // depth. note: normalR is set to point to a column of R1 or R2 if that is
+  // the smallest depth normal so far. otherwise normalR is 0 and normalC is
+  // set to a vector relative to body 1. invert_normal is 1 if the sign of
+  // the normal should be flipped.
+
+#define TST(expr1,expr2,norm,cc) \
+  s2 = btFabs(expr1) - (expr2); \
+  if (s2 > 0) return 0; \
+  if (s2 > s) { \
+    s = s2; \
+    normalR = norm; \
+    invert_normal = ((expr1) < 0); \
+    code = (cc); \
+  }
+
+  s = -dInfinity;
+  invert_normal = 0;
+  code = 0;
+
+  // separating axis = u1,u2,u3
+  TST (pp[0],(A[0] + B[0]*Q11 + B[1]*Q12 + B[2]*Q13),R1+0,1);
+  TST (pp[1],(A[1] + B[0]*Q21 + B[1]*Q22 + B[2]*Q23),R1+1,2);
+  TST (pp[2],(A[2] + B[0]*Q31 + B[1]*Q32 + B[2]*Q33),R1+2,3);
+
+  // separating axis = v1,v2,v3
+  TST (dDOT41(R2+0,p),(A[0]*Q11 + A[1]*Q21 + A[2]*Q31 + B[0]),R2+0,4);
+  TST (dDOT41(R2+1,p),(A[0]*Q12 + A[1]*Q22 + A[2]*Q32 + B[1]),R2+1,5);
+  TST (dDOT41(R2+2,p),(A[0]*Q13 + A[1]*Q23 + A[2]*Q33 + B[2]),R2+2,6);
+
+  // note: cross product axes need to be scaled when s is computed.
+  // normal (n1,n2,n3) is relative to box 1.
+#undef TST
+#define TST(expr1,expr2,n1,n2,n3,cc) \
+  s2 = btFabs(expr1) - (expr2); \
+  if (s2 > 0) return 0; \
+  l = btSqrt((n1)*(n1) + (n2)*(n2) + (n3)*(n3)); \
+  if (l > 0) { \
+    s2 /= l; \
+    if (s2*fudge_factor > s) { \
+      s = s2; \
+      normalR = 0; \
+      normalC[0] = (n1)/l; normalC[1] = (n2)/l; normalC[2] = (n3)/l; \
+      invert_normal = ((expr1) < 0); \
+      code = (cc); \
+    } \
+  }
+
+  // separating axis = u1 x (v1,v2,v3)
+  TST(pp[2]*R21-pp[1]*R31,(A[1]*Q31+A[2]*Q21+B[1]*Q13+B[2]*Q12),0,-R31,R21,7);
+  TST(pp[2]*R22-pp[1]*R32,(A[1]*Q32+A[2]*Q22+B[0]*Q13+B[2]*Q11),0,-R32,R22,8);
+  TST(pp[2]*R23-pp[1]*R33,(A[1]*Q33+A[2]*Q23+B[0]*Q12+B[1]*Q11),0,-R33,R23,9);
+
+  // separating axis = u2 x (v1,v2,v3)
+  TST(pp[0]*R31-pp[2]*R11,(A[0]*Q31+A[2]*Q11+B[1]*Q23+B[2]*Q22),R31,0,-R11,10);
+  TST(pp[0]*R32-pp[2]*R12,(A[0]*Q32+A[2]*Q12+B[0]*Q23+B[2]*Q21),R32,0,-R12,11);
+  TST(pp[0]*R33-pp[2]*R13,(A[0]*Q33+A[2]*Q13+B[0]*Q22+B[1]*Q21),R33,0,-R13,12);
+
+  // separating axis = u3 x (v1,v2,v3)
+  TST(pp[1]*R11-pp[0]*R21,(A[0]*Q21+A[1]*Q11+B[1]*Q33+B[2]*Q32),-R21,R11,0,13);
+  TST(pp[1]*R12-pp[0]*R22,(A[0]*Q22+A[1]*Q12+B[0]*Q33+B[2]*Q31),-R22,R12,0,14);
+  TST(pp[1]*R13-pp[0]*R23,(A[0]*Q23+A[1]*Q13+B[0]*Q32+B[1]*Q31),-R23,R13,0,15);
+
+#undef TST
+
+  if (!code) return 0;
+
+  // if we get to this point, the boxes interpenetrate. compute the normal
+  // in global coordinates.
+  if (normalR) {
+    normal[0] = normalR[0];
+    normal[1] = normalR[4];
+    normal[2] = normalR[8];
+  }
+  else {
+    dMULTIPLY0_331 (normal,R1,normalC);
+  }
+  if (invert_normal) {
+    normal[0] = -normal[0];
+    normal[1] = -normal[1];
+    normal[2] = -normal[2];
+  }
+  *depth = -s;
+
+  // compute contact point(s)
+
+  if (code > 6) {
+    // an edge from box 1 touches an edge from box 2.
+    // find a point pa on the intersecting edge of box 1
+    btVector3 pa;
+    btScalar sign;
+    for (i=0; i<3; i++) pa[i] = p1[i];
+    for (j=0; j<3; j++) {
+      sign = (dDOT14(normal,R1+j) > 0) ? btScalar(1.0) : btScalar(-1.0);
+      for (i=0; i<3; i++) pa[i] += sign * A[j] * R1[i*4+j];
+    }
+
+    // find a point pb on the intersecting edge of box 2
+    btVector3 pb;
+    for (i=0; i<3; i++) pb[i] = p2[i];
+    for (j=0; j<3; j++) {
+      sign = (dDOT14(normal,R2+j) > 0) ? btScalar(-1.0) : btScalar(1.0);
+      for (i=0; i<3; i++) pb[i] += sign * B[j] * R2[i*4+j];
+    }
+
+    btScalar alpha,beta;
+    btVector3 ua,ub;
+    for (i=0; i<3; i++) ua[i] = R1[((code)-7)/3 + i*4];
+    for (i=0; i<3; i++) ub[i] = R2[((code)-7)%3 + i*4];
+
+    dLineClosestApproach (pa,ua,pb,ub,&alpha,&beta);
+    for (i=0; i<3; i++) pa[i] += ua[i]*alpha;
+    for (i=0; i<3; i++) pb[i] += ub[i]*beta;
+
+	{
+		
+		//contact[0].pos[i] = btScalar(0.5)*(pa[i]+pb[i]);
+		//contact[0].depth = *depth;
+		btVector3 pointInWorld;
+
+#ifdef USE_CENTER_POINT
+	    for (i=0; i<3; i++) 
+			pointInWorld[i] = (pa[i]+pb[i])*btScalar(0.5);
+		output.addContactPoint(-normal,pointInWorld,-*depth);
+#else
+		output.addContactPoint(-normal,pb,-*depth);
+#endif //
+		*return_code = code;
+	}
+    return 1;
+  }
+
+  // okay, we have a face-something intersection (because the separating
+  // axis is perpendicular to a face). define face 'a' to be the reference
+  // face (i.e. the normal vector is perpendicular to this) and face 'b' to be
+  // the incident face (the closest face of the other box).
+
+  const btScalar *Ra,*Rb,*pa,*pb,*Sa,*Sb;
+  if (code <= 3) {
+    Ra = R1;
+    Rb = R2;
+    pa = p1;
+    pb = p2;
+    Sa = A;
+    Sb = B;
+  }
+  else {
+    Ra = R2;
+    Rb = R1;
+    pa = p2;
+    pb = p1;
+    Sa = B;
+    Sb = A;
+  }
+
+  // nr = normal vector of reference face dotted with axes of incident box.
+  // anr = absolute values of nr.
+  btVector3 normal2,nr,anr;
+  if (code <= 3) {
+    normal2[0] = normal[0];
+    normal2[1] = normal[1];
+    normal2[2] = normal[2];
+  }
+  else {
+    normal2[0] = -normal[0];
+    normal2[1] = -normal[1];
+    normal2[2] = -normal[2];
+  }
+  dMULTIPLY1_331 (nr,Rb,normal2);
+  anr[0] = btFabs (nr[0]);
+  anr[1] = btFabs (nr[1]);
+  anr[2] = btFabs (nr[2]);
+
+  // find the largest compontent of anr: this corresponds to the normal
+  // for the indident face. the other axis numbers of the indicent face
+  // are stored in a1,a2.
+  int lanr,a1,a2;
+  if (anr[1] > anr[0]) {
+    if (anr[1] > anr[2]) {
+      a1 = 0;
+      lanr = 1;
+      a2 = 2;
+    }
+    else {
+      a1 = 0;
+      a2 = 1;
+      lanr = 2;
+    }
+  }
+  else {
+    if (anr[0] > anr[2]) {
+      lanr = 0;
+      a1 = 1;
+      a2 = 2;
+    }
+    else {
+      a1 = 0;
+      a2 = 1;
+      lanr = 2;
+    }
+  }
+
+  // compute center point of incident face, in reference-face coordinates
+  btVector3 center;
+  if (nr[lanr] < 0) {
+    for (i=0; i<3; i++) center[i] = pb[i] - pa[i] + Sb[lanr] * Rb[i*4+lanr];
+  }
+  else {
+    for (i=0; i<3; i++) center[i] = pb[i] - pa[i] - Sb[lanr] * Rb[i*4+lanr];
+  }
+
+  // find the normal and non-normal axis numbers of the reference box
+  int codeN,code1,code2;
+  if (code <= 3) codeN = code-1; else codeN = code-4;
+  if (codeN==0) {
+    code1 = 1;
+    code2 = 2;
+  }
+  else if (codeN==1) {
+    code1 = 0;
+    code2 = 2;
+  }
+  else {
+    code1 = 0;
+    code2 = 1;
+  }
+
+  // find the four corners of the incident face, in reference-face coordinates
+  btScalar quad[8];	// 2D coordinate of incident face (x,y pairs)
+  btScalar c1,c2,m11,m12,m21,m22;
+  c1 = dDOT14 (center,Ra+code1);
+  c2 = dDOT14 (center,Ra+code2);
+  // optimize this? - we have already computed this data above, but it is not
+  // stored in an easy-to-index format. for now it's quicker just to recompute
+  // the four dot products.
+  m11 = dDOT44 (Ra+code1,Rb+a1);
+  m12 = dDOT44 (Ra+code1,Rb+a2);
+  m21 = dDOT44 (Ra+code2,Rb+a1);
+  m22 = dDOT44 (Ra+code2,Rb+a2);
+  {
+    btScalar k1 = m11*Sb[a1];
+    btScalar k2 = m21*Sb[a1];
+    btScalar k3 = m12*Sb[a2];
+    btScalar k4 = m22*Sb[a2];
+    quad[0] = c1 - k1 - k3;
+    quad[1] = c2 - k2 - k4;
+    quad[2] = c1 - k1 + k3;
+    quad[3] = c2 - k2 + k4;
+    quad[4] = c1 + k1 + k3;
+    quad[5] = c2 + k2 + k4;
+    quad[6] = c1 + k1 - k3;
+    quad[7] = c2 + k2 - k4;
+  }
+
+  // find the size of the reference face
+  btScalar rect[2];
+  rect[0] = Sa[code1];
+  rect[1] = Sa[code2];
+
+  // intersect the incident and reference faces
+  btScalar ret[16];
+  int n = intersectRectQuad2 (rect,quad,ret);
+  if (n < 1) return 0;		// this should never happen
+
+  // convert the intersection points into reference-face coordinates,
+  // and compute the contact position and depth for each point. only keep
+  // those points that have a positive (penetrating) depth. delete points in
+  // the 'ret' array as necessary so that 'point' and 'ret' correspond.
+  btScalar point[3*8];		// penetrating contact points
+  btScalar dep[8];			// depths for those points
+  btScalar det1 = 1.f/(m11*m22 - m12*m21);
+  m11 *= det1;
+  m12 *= det1;
+  m21 *= det1;
+  m22 *= det1;
+  int cnum = 0;			// number of penetrating contact points found
+  for (j=0; j < n; j++) {
+    btScalar k1 =  m22*(ret[j*2]-c1) - m12*(ret[j*2+1]-c2);
+    btScalar k2 = -m21*(ret[j*2]-c1) + m11*(ret[j*2+1]-c2);
+    for (i=0; i<3; i++) point[cnum*3+i] =
+			  center[i] + k1*Rb[i*4+a1] + k2*Rb[i*4+a2];
+    dep[cnum] = Sa[codeN] - dDOT(normal2,point+cnum*3);
+    if (dep[cnum] >= 0) {
+      ret[cnum*2] = ret[j*2];
+      ret[cnum*2+1] = ret[j*2+1];
+      cnum++;
+    }
+  }
+  if (cnum < 1) return 0;	// this should never happen
+
+  // we can't generate more contacts than we actually have
+  if (maxc > cnum) maxc = cnum;
+  if (maxc < 1) maxc = 1;
+
+  if (cnum <= maxc) {
+    // 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];
+
+		btVector3 pointInWorld;
+		for (i=0; i<3; i++) 
+			pointInWorld[i] = point[j*3+i] + pa[i];
+		output.addContactPoint(-normal,pointInWorld,-dep[j]);
+
+    }
+  }
+  else {
+    // we have more contacts than are wanted, some of them must be culled.
+    // find the deepest point, it is always the first contact.
+    int i1 = 0;
+    btScalar maxdepth = dep[0];
+    for (i=1; i<cnum; i++) {
+      if (dep[i] > maxdepth) {
+	maxdepth = dep[i];
+	i1 = i;
+      }
+    }
+
+    int iret[8];
+    cullPoints2 (cnum,ret,maxc,i1,iret);
+
+    for (j=0; j < maxc; j++) {
+//      dContactGeom *con = CONTACT(contact,skip*j);
+  //    for (i=0; i<3; i++) con->pos[i] = point[iret[j]*3+i] + pa[i];
+    //  con->depth = dep[iret[j]];
+
+		btVector3 posInWorld;
+		for (i=0; i<3; i++) 
+			posInWorld[i] = point[iret[j]*3+i] + pa[i];
+		output.addContactPoint(-normal,posInWorld,-dep[iret[j]]);
+    }
+    cnum = maxc;
+  }
+
+  *return_code = code;
+  return cnum;
+}
+
+void	btBoxBoxDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* /*debugDraw*/,bool /*swapResults*/)
+{
+	
+	const btTransform& transformA = input.m_transformA;
+	const btTransform& transformB = input.m_transformB;
+	
+	int skip = 0;
+	dContactGeom *contact = 0;
+
+	dMatrix3 R1;
+	dMatrix3 R2;
+
+	for (int j=0;j<3;j++)
+	{
+		R1[0+4*j] = transformA.getBasis()[j].x();
+		R2[0+4*j] = transformB.getBasis()[j].x();
+
+		R1[1+4*j] = transformA.getBasis()[j].y();
+		R2[1+4*j] = transformB.getBasis()[j].y();
+
+
+		R1[2+4*j] = transformA.getBasis()[j].z();
+		R2[2+4*j] = transformB.getBasis()[j].z();
+
+	}
+
+	
+
+	btVector3 normal;
+	btScalar depth;
+	int return_code;
+	int maxc = 4;
+
+
+	dBoxBox2 (transformA.getOrigin(), 
+	R1,
+	2.f*m_box1->getHalfExtentsWithMargin(),
+	transformB.getOrigin(),
+	R2, 
+	2.f*m_box2->getHalfExtentsWithMargin(),
+	normal, &depth, &return_code,
+	maxc, contact, skip,
+	output
+	);
+
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxDetector.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxDetector.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btBoxBoxDetector.h	(revision 6952)
@@ -0,0 +1,44 @@
+/*
+ * Box-Box collision detection re-distributed under the ZLib license with permission from Russell L. Smith
+ * Original version is from Open Dynamics Engine, Copyright (C) 2001,2002 Russell L. Smith.
+ * All rights reserved.  Email: russ@q12.org   Web: www.q12.org
+
+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_BOX_DETECTOR_H
+#define BOX_BOX_DETECTOR_H
+
+
+class btBoxShape;
+#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
+
+
+/// btBoxBoxDetector wraps the ODE box-box collision detector
+/// re-distributed under the Zlib license with permission from Russell L. Smith
+struct btBoxBoxDetector : public btDiscreteCollisionDetectorInterface
+{
+	btBoxShape* m_box1;
+	btBoxShape* m_box2;
+
+public:
+
+	btBoxBoxDetector(btBoxShape* box1,btBoxShape* box2);
+
+	virtual ~btBoxBoxDetector() {};
+
+	virtual void	getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false);
+
+};
+
+#endif //BT_BOX_BOX_DETECTOR_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionConfiguration.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionConfiguration.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionConfiguration.h	(revision 6952)
@@ -0,0 +1,47 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_COLLISION_CONFIGURATION
+#define BT_COLLISION_CONFIGURATION
+struct btCollisionAlgorithmCreateFunc;
+
+class btStackAlloc;
+class btPoolAllocator;
+
+///btCollisionConfiguration allows to configure Bullet collision detection
+///stack allocator size, default collision algorithms and persistent manifold pool size
+///@todo: describe the meaning
+class	btCollisionConfiguration
+{
+
+public:
+
+	virtual ~btCollisionConfiguration()
+	{
+	}
+
+	///memory pools
+	virtual btPoolAllocator* getPersistentManifoldPool() = 0;
+
+	virtual btPoolAllocator* getCollisionAlgorithmPool() = 0;
+
+	virtual btStackAlloc*	getStackAllocator() = 0;
+
+	virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) =0;
+
+};
+
+#endif //BT_COLLISION_CONFIGURATION
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h	(revision 6952)
@@ -0,0 +1,45 @@
+/*
+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 COLLISION_CREATE_FUNC
+#define COLLISION_CREATE_FUNC
+
+#include "LinearMath/btAlignedObjectArray.h"
+class btCollisionAlgorithm;
+class btCollisionObject;
+
+struct btCollisionAlgorithmConstructionInfo;
+
+///Used by the btCollisionDispatcher to register and create instances for btCollisionAlgorithm
+struct btCollisionAlgorithmCreateFunc
+{
+	bool m_swapped;
+	
+	btCollisionAlgorithmCreateFunc()
+		:m_swapped(false)
+	{
+	}
+	virtual ~btCollisionAlgorithmCreateFunc(){};
+
+	virtual	btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& , btCollisionObject* body0,btCollisionObject* body1)
+	{
+		
+		(void)body0;
+		(void)body1;
+		return 0;
+	}
+};
+#endif //COLLISION_CREATE_FUNC
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp	(revision 6952)
@@ -0,0 +1,303 @@
+/*
+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 "btCollisionDispatcher.h"
+
+
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+
+#include "BulletCollision/CollisionShapes/btCollisionShape.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
+#include "LinearMath/btPoolAllocator.h"
+#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
+
+int gNumManifold = 0;
+
+#ifdef BT_DEBUG
+#include <stdio.h>
+#endif
+
+
+btCollisionDispatcher::btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration): 
+	m_count(0),
+	m_useIslands(true),
+	m_staticWarningReported(false),
+	m_collisionConfiguration(collisionConfiguration)
+{
+	int i;
+
+	setNearCallback(defaultNearCallback);
+	
+	m_collisionAlgorithmPoolAllocator = collisionConfiguration->getCollisionAlgorithmPool();
+
+	m_persistentManifoldPoolAllocator = collisionConfiguration->getPersistentManifoldPool();
+
+	for (i=0;i<MAX_BROADPHASE_COLLISION_TYPES;i++)
+	{
+		for (int j=0;j<MAX_BROADPHASE_COLLISION_TYPES;j++)
+		{
+			m_doubleDispatch[i][j] = m_collisionConfiguration->getCollisionAlgorithmCreateFunc(i,j);
+			btAssert(m_doubleDispatch[i][j]);
+		}
+	}
+	
+	
+}
+
+
+void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc)
+{
+	m_doubleDispatch[proxyType0][proxyType1] = createFunc;
+}
+
+btCollisionDispatcher::~btCollisionDispatcher()
+{
+}
+
+btPersistentManifold*	btCollisionDispatcher::getNewManifold(void* b0,void* b1) 
+{ 
+	gNumManifold++;
+	
+	//btAssert(gNumManifold < 65535);
+	
+
+	btCollisionObject* body0 = (btCollisionObject*)b0;
+	btCollisionObject* body1 = (btCollisionObject*)b1;
+
+	//test for Bullet 2.74: use a relative contact breaking threshold without clamping against 'gContactBreakingThreshold'
+	//btScalar contactBreakingThreshold = btMin(gContactBreakingThreshold,btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold()));
+	btScalar contactBreakingThreshold = btMin(body0->getCollisionShape()->getContactBreakingThreshold(),body1->getCollisionShape()->getContactBreakingThreshold());
+
+	btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(),body1->getContactProcessingThreshold());
+		
+	void* mem = 0;
+	
+	if (m_persistentManifoldPoolAllocator->getFreeCount())
+	{
+		mem = m_persistentManifoldPoolAllocator->allocate(sizeof(btPersistentManifold));
+	} else
+	{
+		mem = btAlignedAlloc(sizeof(btPersistentManifold),16);
+
+	}
+	btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0,contactBreakingThreshold,contactProcessingThreshold);
+	manifold->m_index1a = m_manifoldsPtr.size();
+	m_manifoldsPtr.push_back(manifold);
+
+	return manifold;
+}
+
+void btCollisionDispatcher::clearManifold(btPersistentManifold* manifold)
+{
+	manifold->clearManifold();
+}
+
+	
+void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold)
+{
+	
+	gNumManifold--;
+
+	//printf("releaseManifold: gNumManifold %d\n",gNumManifold);
+	clearManifold(manifold);
+
+	int findIndex = manifold->m_index1a;
+	btAssert(findIndex < m_manifoldsPtr.size());
+	m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1);
+	m_manifoldsPtr[findIndex]->m_index1a = findIndex;
+	m_manifoldsPtr.pop_back();
+
+	manifold->~btPersistentManifold();
+	if (m_persistentManifoldPoolAllocator->validPtr(manifold))
+	{
+		m_persistentManifoldPoolAllocator->freeMemory(manifold);
+	} else
+	{
+		btAlignedFree(manifold);
+	}
+	
+}
+
+	
+
+btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold)
+{
+	
+	btCollisionAlgorithmConstructionInfo ci;
+
+	ci.m_dispatcher1 = this;
+	ci.m_manifold = sharedManifold;
+	btCollisionAlgorithm* algo = m_doubleDispatch[body0->getCollisionShape()->getShapeType()][body1->getCollisionShape()->getShapeType()]->CreateCollisionAlgorithm(ci,body0,body1);
+
+	return algo;
+}
+
+
+
+
+bool	btCollisionDispatcher::needsResponse(btCollisionObject* body0,btCollisionObject* body1)
+{
+	//here you can do filtering
+	bool hasResponse = 
+		(body0->hasContactResponse() && body1->hasContactResponse());
+	//no response between two static/kinematic bodies:
+	hasResponse = hasResponse &&
+		((!body0->isStaticOrKinematicObject()) ||(! body1->isStaticOrKinematicObject()));
+	return hasResponse;
+}
+
+bool	btCollisionDispatcher::needsCollision(btCollisionObject* body0,btCollisionObject* body1)
+{
+	btAssert(body0);
+	btAssert(body1);
+
+	bool needsCollision = true;
+
+#ifdef BT_DEBUG
+	if (!m_staticWarningReported)
+	{
+		//broadphase filtering already deals with this
+		if ((body0->isStaticObject() || body0->isKinematicObject()) &&
+			(body1->isStaticObject() || body1->isKinematicObject()))
+		{
+			m_staticWarningReported = true;
+			printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
+		}
+	}
+#endif //BT_DEBUG
+
+	if ((!body0->isActive()) && (!body1->isActive()))
+		needsCollision = false;
+	else if (!body0->checkCollideWith(body1))
+		needsCollision = false;
+	
+	return needsCollision ;
+
+}
+
+
+
+///interface for iterating all overlapping collision pairs, no matter how those pairs are stored (array, set, map etc)
+///this is useful for the collision dispatcher.
+class btCollisionPairCallback : public btOverlapCallback
+{
+	const btDispatcherInfo& m_dispatchInfo;
+	btCollisionDispatcher*	m_dispatcher;
+
+public:
+
+	btCollisionPairCallback(const btDispatcherInfo& dispatchInfo,btCollisionDispatcher*	dispatcher)
+	:m_dispatchInfo(dispatchInfo),
+	m_dispatcher(dispatcher)
+	{
+	}
+
+	/*btCollisionPairCallback& operator=(btCollisionPairCallback& other)
+	{
+		m_dispatchInfo = other.m_dispatchInfo;
+		m_dispatcher = other.m_dispatcher;
+		return *this;
+	}
+	*/
+
+
+	virtual ~btCollisionPairCallback() {}
+
+
+	virtual bool	processOverlap(btBroadphasePair& pair)
+	{
+		(*m_dispatcher->getNearCallback())(pair,*m_dispatcher,m_dispatchInfo);
+
+		return false;
+	}
+};
+
+
+
+void	btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) 
+{
+	//m_blockedForChanges = true;
+
+	btCollisionPairCallback	collisionCallback(dispatchInfo,this);
+
+	pairCache->processAllOverlappingPairs(&collisionCallback,dispatcher);
+
+	//m_blockedForChanges = false;
+
+}
+
+
+
+
+//by default, Bullet will use this near callback
+void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo)
+{
+		btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
+		btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
+
+		if (dispatcher.needsCollision(colObj0,colObj1))
+		{
+			//dispatcher will keep algorithms persistent in the collision pair
+			if (!collisionPair.m_algorithm)
+			{
+				collisionPair.m_algorithm = dispatcher.findAlgorithm(colObj0,colObj1);
+			}
+
+			if (collisionPair.m_algorithm)
+			{
+				btManifoldResult contactPointResult(colObj0,colObj1);
+				
+				if (dispatchInfo.m_dispatchFunc == 		btDispatcherInfo::DISPATCH_DISCRETE)
+				{
+					//discrete collision detection query
+					collisionPair.m_algorithm->processCollision(colObj0,colObj1,dispatchInfo,&contactPointResult);
+				} else
+				{
+					//continuous collision detection query, time of impact (toi)
+					btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult);
+					if (dispatchInfo.m_timeOfImpact > toi)
+						dispatchInfo.m_timeOfImpact = toi;
+
+				}
+			}
+		}
+
+}
+
+
+void* btCollisionDispatcher::allocateCollisionAlgorithm(int size)
+{
+	if (m_collisionAlgorithmPoolAllocator->getFreeCount())
+	{
+		return m_collisionAlgorithmPoolAllocator->allocate(size);
+	}
+	
+	//warn user for overflow?
+	return	btAlignedAlloc(static_cast<size_t>(size), 16);
+}
+
+void btCollisionDispatcher::freeCollisionAlgorithm(void* ptr)
+{
+	if (m_collisionAlgorithmPoolAllocator->validPtr(ptr))
+	{
+		m_collisionAlgorithmPoolAllocator->freeMemory(ptr);
+	} else
+	{
+		btAlignedFree(ptr);
+	}
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionDispatcher.h	(revision 6952)
@@ -0,0 +1,147 @@
+/*
+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 COLLISION__DISPATCHER_H
+#define COLLISION__DISPATCHER_H
+
+#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+
+#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
+
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "LinearMath/btAlignedObjectArray.h"
+
+class btIDebugDraw;
+class btOverlappingPairCache;
+class btPoolAllocator;
+class btCollisionConfiguration;
+
+#include "btCollisionCreateFunc.h"
+
+#define USE_DISPATCH_REGISTRY_ARRAY 1
+
+class btCollisionDispatcher;
+///user can override this nearcallback for collision filtering and more finegrained control over collision detection
+typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo);
+
+
+///btCollisionDispatcher supports algorithms that handle ConvexConvex and ConvexConcave collision pairs.
+///Time of Impact, Closest Points and Penetration Depth.
+class btCollisionDispatcher : public btDispatcher
+{
+	int m_count;
+	
+	btAlignedObjectArray<btPersistentManifold*>	m_manifoldsPtr;
+
+	bool m_useIslands;
+
+	bool	m_staticWarningReported;
+	
+	btManifoldResult	m_defaultManifoldResult;
+
+	btNearCallback		m_nearCallback;
+	
+	btPoolAllocator*	m_collisionAlgorithmPoolAllocator;
+
+	btPoolAllocator*	m_persistentManifoldPoolAllocator;
+
+	btCollisionAlgorithmCreateFunc* m_doubleDispatch[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES];
+	
+
+	btCollisionConfiguration*	m_collisionConfiguration;
+
+
+public:
+
+	///registerCollisionCreateFunc allows registration of custom/alternative collision create functions
+	void	registerCollisionCreateFunc(int proxyType0,int proxyType1, btCollisionAlgorithmCreateFunc* createFunc);
+
+	int	getNumManifolds() const
+	{ 
+		return int( m_manifoldsPtr.size());
+	}
+
+	btPersistentManifold**	getInternalManifoldPointer()
+	{
+		return &m_manifoldsPtr[0];
+	}
+
+	 btPersistentManifold* getManifoldByIndexInternal(int index)
+	{
+		return m_manifoldsPtr[index];
+	}
+
+	 const btPersistentManifold* getManifoldByIndexInternal(int index) const
+	{
+		return m_manifoldsPtr[index];
+	}
+
+	btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration);
+
+	virtual ~btCollisionDispatcher();
+
+	virtual btPersistentManifold*	getNewManifold(void* b0,void* b1);
+	
+	virtual void releaseManifold(btPersistentManifold* manifold);
+
+
+	virtual void clearManifold(btPersistentManifold* manifold);
+
+			
+	btCollisionAlgorithm* findAlgorithm(btCollisionObject* body0,btCollisionObject* body1,btPersistentManifold* sharedManifold = 0);
+		
+	virtual bool	needsCollision(btCollisionObject* body0,btCollisionObject* body1);
+	
+	virtual bool	needsResponse(btCollisionObject* body0,btCollisionObject* body1);
+	
+	virtual void	dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) ;
+
+	void	setNearCallback(btNearCallback	nearCallback)
+	{
+		m_nearCallback = nearCallback; 
+	}
+
+	btNearCallback	getNearCallback() const
+	{
+		return m_nearCallback;
+	}
+
+	//by default, Bullet will use this near callback
+	static void  defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo);
+
+	virtual	void* allocateCollisionAlgorithm(int size);
+
+	virtual	void freeCollisionAlgorithm(void* ptr);
+
+	btCollisionConfiguration*	getCollisionConfiguration()
+	{
+		return m_collisionConfiguration;
+	}
+
+	const btCollisionConfiguration*	getCollisionConfiguration() const
+	{
+		return m_collisionConfiguration;
+	}
+
+	void	setCollisionConfiguration(btCollisionConfiguration* config)
+	{
+		m_collisionConfiguration = config;
+	}
+
+};
+
+#endif //COLLISION__DISPATCHER_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionObject.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionObject.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionObject.cpp	(revision 6952)
@@ -0,0 +1,68 @@
+/*
+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 "btCollisionObject.h"
+
+btCollisionObject::btCollisionObject()
+	:	m_anisotropicFriction(1.f,1.f,1.f),
+	m_hasAnisotropicFriction(false),
+	m_contactProcessingThreshold(1e30f),
+		m_broadphaseHandle(0),
+		m_collisionShape(0),
+		m_rootCollisionShape(0),
+		m_collisionFlags(btCollisionObject::CF_STATIC_OBJECT),
+		m_islandTag1(-1),
+		m_companionId(-1),
+		m_activationState1(1),
+		m_deactivationTime(btScalar(0.)),
+		m_friction(btScalar(0.5)),
+		m_restitution(btScalar(0.)),
+		m_userObjectPointer(0),
+		m_internalType(CO_COLLISION_OBJECT),
+		m_hitFraction(btScalar(1.)),
+		m_ccdSweptSphereRadius(btScalar(0.)),
+		m_ccdMotionThreshold(btScalar(0.)),
+		m_checkCollideWith(false)
+{
+	
+}
+
+btCollisionObject::~btCollisionObject()
+{
+}
+
+void btCollisionObject::setActivationState(int newState) 
+{ 
+	if ( (m_activationState1 != DISABLE_DEACTIVATION) && (m_activationState1 != DISABLE_SIMULATION))
+		m_activationState1 = newState;
+}
+
+void btCollisionObject::forceActivationState(int newState)
+{
+	m_activationState1 = newState;
+}
+
+void btCollisionObject::activate(bool forceActivation)
+{
+	if (forceActivation || !(m_collisionFlags & (CF_STATIC_OBJECT|CF_KINEMATIC_OBJECT)))
+	{
+		setActivationState(ACTIVE_TAG);
+		m_deactivationTime = btScalar(0.);
+	}
+}
+
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h	(revision 6952)
@@ -0,0 +1,421 @@
+/*
+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 COLLISION_OBJECT_H
+#define COLLISION_OBJECT_H
+
+#include "LinearMath/btTransform.h"
+
+//island management, m_activationState1
+#define ACTIVE_TAG 1
+#define ISLAND_SLEEPING 2
+#define WANTS_DEACTIVATION 3
+#define DISABLE_DEACTIVATION 4
+#define DISABLE_SIMULATION 5
+
+struct	btBroadphaseProxy;
+class	btCollisionShape;
+#include "LinearMath/btMotionState.h"
+#include "LinearMath/btAlignedAllocator.h"
+#include "LinearMath/btAlignedObjectArray.h"
+
+
+typedef btAlignedObjectArray<class btCollisionObject*> btCollisionObjectArray;
+
+
+/// btCollisionObject can be used to manage collision detection objects. 
+/// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy.
+/// They can be added to the btCollisionWorld.
+ATTRIBUTE_ALIGNED16(class)	btCollisionObject
+{
+
+protected:
+
+	btTransform	m_worldTransform;
+
+	///m_interpolationWorldTransform is used for CCD and interpolation
+	///it can be either previous or future (predicted) transform
+	btTransform	m_interpolationWorldTransform;
+	//those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities) 
+	//without destroying the continuous interpolated motion (which uses this interpolation velocities)
+	btVector3	m_interpolationLinearVelocity;
+	btVector3	m_interpolationAngularVelocity;
+	
+	btVector3		m_anisotropicFriction;
+	bool				m_hasAnisotropicFriction;
+	btScalar		m_contactProcessingThreshold;	
+
+	btBroadphaseProxy*		m_broadphaseHandle;
+	btCollisionShape*		m_collisionShape;
+	
+	///m_rootCollisionShape is temporarily used to store the original collision shape
+	///The m_collisionShape might be temporarily replaced by a child collision shape during collision detection purposes
+	///If it is NULL, the m_collisionShape is not temporarily replaced.
+	btCollisionShape*		m_rootCollisionShape;
+
+	int				m_collisionFlags;
+
+	int				m_islandTag1;
+	int				m_companionId;
+
+	int				m_activationState1;
+	btScalar			m_deactivationTime;
+
+	btScalar		m_friction;
+	btScalar		m_restitution;
+
+	///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer
+	void*			m_userObjectPointer;
+
+	///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;
+
+	///time of impact calculation
+	btScalar		m_hitFraction; 
+	
+	///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
+	btScalar		m_ccdSweptSphereRadius;
+
+	/// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
+	btScalar		m_ccdMotionThreshold;
+	
+	/// If some object should have elaborate collision filtering by sub-classes
+	bool			m_checkCollideWith;
+
+	char	m_pad[7];
+
+	virtual bool	checkCollideWithOverride(btCollisionObject* /* co */)
+	{
+		return true;
+	}
+
+public:
+
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	enum CollisionFlags
+	{
+		CF_STATIC_OBJECT= 1,
+		CF_KINEMATIC_OBJECT= 2,
+		CF_NO_CONTACT_RESPONSE = 4,
+		CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution)
+		CF_CHARACTER_OBJECT = 16
+	};
+
+	enum	CollisionObjectTypes
+	{
+		CO_COLLISION_OBJECT =1,
+		CO_RIGID_BODY,
+		///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
+	};
+
+	SIMD_FORCE_INLINE bool mergesSimulationIslands() const
+	{
+		///static objects, kinematic and object without contact response don't merge islands
+		return  ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE) )==0);
+	}
+
+	const btVector3& getAnisotropicFriction() const
+	{
+		return m_anisotropicFriction;
+	}
+	void	setAnisotropicFriction(const btVector3& anisotropicFriction)
+	{
+		m_anisotropicFriction = anisotropicFriction;
+		m_hasAnisotropicFriction = (anisotropicFriction[0]!=1.f) || (anisotropicFriction[1]!=1.f) || (anisotropicFriction[2]!=1.f);
+	}
+	bool	hasAnisotropicFriction() const
+	{
+		return m_hasAnisotropicFriction;
+	}
+
+	///the constraint solver can discard solving contacts, if the distance is above this threshold. 0 by default.
+	///Note that using contacts with positive distance can improve stability. It increases, however, the chance of colliding with degerate contacts, such as 'interior' triangle edges
+	void	setContactProcessingThreshold( btScalar contactProcessingThreshold)
+	{
+		m_contactProcessingThreshold = contactProcessingThreshold;
+	}
+	btScalar	getContactProcessingThreshold() const
+	{
+		return m_contactProcessingThreshold;
+	}
+
+	SIMD_FORCE_INLINE bool		isStaticObject() const {
+		return (m_collisionFlags & CF_STATIC_OBJECT) != 0;
+	}
+
+	SIMD_FORCE_INLINE bool		isKinematicObject() const
+	{
+		return (m_collisionFlags & CF_KINEMATIC_OBJECT) != 0;
+	}
+
+	SIMD_FORCE_INLINE bool		isStaticOrKinematicObject() const
+	{
+		return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0 ;
+	}
+
+	SIMD_FORCE_INLINE bool		hasContactResponse() const {
+		return (m_collisionFlags & CF_NO_CONTACT_RESPONSE)==0;
+	}
+
+	
+	btCollisionObject();
+
+	virtual ~btCollisionObject();
+
+	virtual void	setCollisionShape(btCollisionShape* collisionShape)
+	{
+		m_collisionShape = collisionShape;
+		m_rootCollisionShape = collisionShape;
+	}
+
+	SIMD_FORCE_INLINE const btCollisionShape*	getCollisionShape() const
+	{
+		return m_collisionShape;
+	}
+
+	SIMD_FORCE_INLINE btCollisionShape*	getCollisionShape()
+	{
+		return m_collisionShape;
+	}
+
+	SIMD_FORCE_INLINE const btCollisionShape*	getRootCollisionShape() const
+	{
+		return m_rootCollisionShape;
+	}
+
+	SIMD_FORCE_INLINE btCollisionShape*	getRootCollisionShape()
+	{
+		return m_rootCollisionShape;
+	}
+
+	///Avoid using this internal API call
+	///internalSetTemporaryCollisionShape is used to temporary replace the actual collision shape by a child collision shape.
+	void	internalSetTemporaryCollisionShape(btCollisionShape* collisionShape)
+	{
+		m_collisionShape = collisionShape;
+	}
+
+	SIMD_FORCE_INLINE	int	getActivationState() const { return m_activationState1;}
+	
+	void setActivationState(int newState);
+
+	void	setDeactivationTime(btScalar time)
+	{
+		m_deactivationTime = time;
+	}
+	btScalar	getDeactivationTime() const
+	{
+		return m_deactivationTime;
+	}
+
+	void forceActivationState(int newState);
+
+	void	activate(bool forceActivation = false);
+
+	SIMD_FORCE_INLINE bool isActive() const
+	{
+		return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION));
+	}
+
+	void	setRestitution(btScalar rest)
+	{
+		m_restitution = rest;
+	}
+	btScalar	getRestitution() const
+	{
+		return m_restitution;
+	}
+	void	setFriction(btScalar frict)
+	{
+		m_friction = frict;
+	}
+	btScalar	getFriction() const
+	{
+		return m_friction;
+	}
+
+	///reserved for Bullet internal usage
+	int	getInternalType() const
+	{
+		return m_internalType;
+	}
+
+	btTransform&	getWorldTransform()
+	{
+		return m_worldTransform;
+	}
+
+	const btTransform&	getWorldTransform() const
+	{
+		return m_worldTransform;
+	}
+
+	void	setWorldTransform(const btTransform& worldTrans)
+	{
+		m_worldTransform = worldTrans;
+	}
+
+
+	SIMD_FORCE_INLINE btBroadphaseProxy*	getBroadphaseHandle()
+	{
+		return m_broadphaseHandle;
+	}
+
+	SIMD_FORCE_INLINE const btBroadphaseProxy*	getBroadphaseHandle() const
+	{
+		return m_broadphaseHandle;
+	}
+
+	void	setBroadphaseHandle(btBroadphaseProxy* handle)
+	{
+		m_broadphaseHandle = handle;
+	}
+
+
+	const btTransform&	getInterpolationWorldTransform() const
+	{
+		return m_interpolationWorldTransform;
+	}
+
+	btTransform&	getInterpolationWorldTransform()
+	{
+		return m_interpolationWorldTransform;
+	}
+
+	void	setInterpolationWorldTransform(const btTransform&	trans)
+	{
+		m_interpolationWorldTransform = trans;
+	}
+
+	void	setInterpolationLinearVelocity(const btVector3& linvel)
+	{
+		m_interpolationLinearVelocity = linvel;
+	}
+
+	void	setInterpolationAngularVelocity(const btVector3& angvel)
+	{
+		m_interpolationAngularVelocity = angvel;
+	}
+
+	const btVector3&	getInterpolationLinearVelocity() const
+	{
+		return m_interpolationLinearVelocity;
+	}
+
+	const btVector3&	getInterpolationAngularVelocity() const
+	{
+		return m_interpolationAngularVelocity;
+	}
+
+	SIMD_FORCE_INLINE int getIslandTag() const
+	{
+		return	m_islandTag1;
+	}
+
+	void	setIslandTag(int tag)
+	{
+		m_islandTag1 = tag;
+	}
+
+	SIMD_FORCE_INLINE int getCompanionId() const
+	{
+		return	m_companionId;
+	}
+
+	void	setCompanionId(int id)
+	{
+		m_companionId = id;
+	}
+
+	SIMD_FORCE_INLINE btScalar			getHitFraction() const
+	{
+		return m_hitFraction; 
+	}
+
+	void	setHitFraction(btScalar hitFraction)
+	{
+		m_hitFraction = hitFraction;
+	}
+
+	
+	SIMD_FORCE_INLINE int	getCollisionFlags() const
+	{
+		return m_collisionFlags;
+	}
+
+	void	setCollisionFlags(int flags)
+	{
+		m_collisionFlags = flags;
+	}
+	
+	///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
+	btScalar			getCcdSweptSphereRadius() const
+	{
+		return m_ccdSweptSphereRadius;
+	}
+
+	///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
+	void	setCcdSweptSphereRadius(btScalar radius)
+	{
+		m_ccdSweptSphereRadius = radius;
+	}
+
+	btScalar 	getCcdMotionThreshold() const
+	{
+		return m_ccdMotionThreshold;
+	}
+
+	btScalar 	getCcdSquareMotionThreshold() const
+	{
+		return m_ccdMotionThreshold*m_ccdMotionThreshold;
+	}
+
+
+
+	/// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold
+	void	setCcdMotionThreshold(btScalar ccdMotionThreshold)
+	{
+		m_ccdMotionThreshold = ccdMotionThreshold*ccdMotionThreshold;
+	}
+
+	///users can point to their objects, userPointer is not used by Bullet
+	void*	getUserPointer() const
+	{
+		return m_userObjectPointer;
+	}
+	
+	///users can point to their objects, userPointer is not used by Bullet
+	void	setUserPointer(void* userPointer)
+	{
+		m_userObjectPointer = userPointer;
+	}
+
+
+	inline bool checkCollideWith(btCollisionObject* co)
+	{
+		if (m_checkCollideWith)
+			return checkCollideWithOverride(co);
+
+		return true;
+	}
+};
+
+#endif //COLLISION_OBJECT_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp	(revision 6952)
@@ -0,0 +1,835 @@
+/*
+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 "btCollisionWorld.h"
+#include "btCollisionDispatcher.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/CollisionShapes/btCollisionShape.h"
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h" //for raycasting
+#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" //for raycasting
+#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
+#include "BulletCollision/CollisionShapes/btCompoundShape.h"
+#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
+#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
+
+#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
+#include "LinearMath/btAabbUtil2.h"
+#include "LinearMath/btQuickprof.h"
+#include "LinearMath/btStackAlloc.h"
+
+//#define USE_BRUTEFORCE_RAYBROADPHASE 1
+//RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation'  or 'updateAabbs' before using a rayTest
+//#define RECALCULATE_AABB_RAYCAST 1
+
+//When the user doesn't provide dispatcher or broadphase, create basic versions (and delete them in destructor)
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
+#include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h"
+
+
+btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, btCollisionConfiguration* collisionConfiguration)
+:m_dispatcher1(dispatcher),
+m_broadphasePairCache(pairCache),
+m_debugDrawer(0)
+{
+	m_stackAlloc = collisionConfiguration->getStackAllocator();
+	m_dispatchInfo.m_stackAllocator = m_stackAlloc;
+}
+
+
+btCollisionWorld::~btCollisionWorld()
+{
+
+	//clean up remaining objects
+	int i;
+	for (i=0;i<m_collisionObjects.size();i++)
+	{
+		btCollisionObject* collisionObject= m_collisionObjects[i];
+
+		btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
+		if (bp)
+		{
+			//
+			// only clear the cached algorithms
+			//
+			getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
+			getBroadphase()->destroyProxy(bp,m_dispatcher1);
+			collisionObject->setBroadphaseHandle(0);
+		}
+	}
+
+
+}
+
+
+
+
+
+
+
+
+
+
+void	btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup,short int collisionFilterMask)
+{
+
+	//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
+			))	;
+
+
+
+
+
+}
+
+
+
+void	btCollisionWorld::updateSingleAabb(btCollisionObject* colObj)
+{
+	btVector3 minAabb,maxAabb;
+	colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
+	//need to increase the aabb for contact thresholds
+	btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold);
+	minAabb -= contactThreshold;
+	maxAabb += contactThreshold;
+
+	btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache;
+
+	//moving objects should be moderately sized, probably something wrong if not
+	if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12)))
+	{
+		bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
+	} else
+	{
+		//something went wrong, investigate
+		//this assert is unwanted in 3D modelers (danger of loosing work)
+		colObj->setActivationState(DISABLE_SIMULATION);
+
+		static bool reportMe = true;
+		if (reportMe && m_debugDrawer)
+		{
+			reportMe = false;
+			m_debugDrawer->reportErrorWarning("Overflow in AABB, object removed from simulation");
+			m_debugDrawer->reportErrorWarning("If you can reproduce this, please email bugs@continuousphysics.com\n");
+			m_debugDrawer->reportErrorWarning("Please include above information, your Platform, version of OS.\n");
+			m_debugDrawer->reportErrorWarning("Thanks.\n");
+		}
+	}
+}
+
+void	btCollisionWorld::updateAabbs()
+{
+	BT_PROFILE("updateAabbs");
+
+	btTransform predictedTrans;
+	for ( int i=0;i<m_collisionObjects.size();i++)
+	{
+		btCollisionObject* colObj = m_collisionObjects[i];
+
+		//only update aabb of active objects
+		if (colObj->isActive())
+		{
+			updateSingleAabb(colObj);
+		}
+	}
+}
+
+
+
+void	btCollisionWorld::performDiscreteCollisionDetection()
+{
+	BT_PROFILE("performDiscreteCollisionDetection");
+
+	btDispatcherInfo& dispatchInfo = getDispatchInfo();
+
+	updateAabbs();
+
+	{
+		BT_PROFILE("calculateOverlappingPairs");
+		m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1);
+	}
+
+
+	btDispatcher* dispatcher = getDispatcher();
+	{
+		BT_PROFILE("dispatchAllCollisionPairs");
+		if (dispatcher)
+			dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1);
+	}
+
+}
+
+
+
+void	btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject)
+{
+
+
+	//bool removeFromBroadphase = false;
+
+	{
+
+		btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle();
+		if (bp)
+		{
+			//
+			// only clear the cached algorithms
+			//
+			getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1);
+			getBroadphase()->destroyProxy(bp,m_dispatcher1);
+			collisionObject->setBroadphaseHandle(0);
+		}
+	}
+
+
+	//swapremove
+	m_collisionObjects.remove(collisionObject);
+
+}
+
+
+
+void	btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
+					  btCollisionObject* collisionObject,
+					  const btCollisionShape* collisionShape,
+					  const btTransform& colObjWorldTransform,
+					  RayResultCallback& resultCallback)
+{
+	btSphereShape pointShape(btScalar(0.0));
+	pointShape.setMargin(0.f);
+	const btConvexShape* castShape = &pointShape;
+
+	if (collisionShape->isConvex())
+	{
+//		BT_PROFILE("rayTestConvex");
+		btConvexCast::CastResult castResult;
+		castResult.m_fraction = resultCallback.m_closestHitFraction;
+
+		btConvexShape* convexShape = (btConvexShape*) collisionShape;
+		btVoronoiSimplexSolver	simplexSolver;
+#define USE_SUBSIMPLEX_CONVEX_CAST 1
+#ifdef USE_SUBSIMPLEX_CONVEX_CAST
+		btSubsimplexConvexCast convexCaster(castShape,convexShape,&simplexSolver);
+#else
+		//btGjkConvexCast	convexCaster(castShape,convexShape,&simplexSolver);
+		//btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);
+#endif //#USE_SUBSIMPLEX_CONVEX_CAST
+
+		if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
+		{
+			//add hit
+			if (castResult.m_normal.length2() > btScalar(0.0001))
+			{
+				if (castResult.m_fraction < resultCallback.m_closestHitFraction)
+				{
+#ifdef USE_SUBSIMPLEX_CONVEX_CAST
+					//rotate normal into worldspace
+					castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal;
+#endif //USE_SUBSIMPLEX_CONVEX_CAST
+
+					castResult.m_normal.normalize();
+					btCollisionWorld::LocalRayResult localRayResult
+						(
+							collisionObject,
+							0,
+							castResult.m_normal,
+							castResult.m_fraction
+						);
+
+					bool normalInWorldSpace = true;
+					resultCallback.addSingleResult(localRayResult, normalInWorldSpace);
+
+				}
+			}
+		}
+	} else {
+		if (collisionShape->isConcave())
+		{
+//			BT_PROFILE("rayTestConcave");
+			if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
+			{
+				///optimized version for btBvhTriangleMeshShape
+				btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
+				btTransform worldTocollisionObject = colObjWorldTransform.inverse();
+				btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
+				btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
+
+				//ConvexCast::CastResult
+				struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
+				{
+					btCollisionWorld::RayResultCallback* m_resultCallback;
+					btCollisionObject*	m_collisionObject;
+					btTriangleMeshShape*	m_triangleMesh;
+
+					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)
+						{
+						}
+
+
+					virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
+					{
+						btCollisionWorld::LocalShapeInfo	shapeInfo;
+						shapeInfo.m_shapePart = partId;
+						shapeInfo.m_triangleIndex = triangleIndex;
+
+						btCollisionWorld::LocalRayResult rayResult
+						(m_collisionObject,
+							&shapeInfo,
+							hitNormalLocal,
+							hitFraction);
+
+						bool	normalInWorldSpace = false;
+						return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
+					}
+
+				};
+
+				BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,triangleMesh);
+				rcb.m_hitFraction = resultCallback.m_closestHitFraction;
+				triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal);
+			} else
+			{
+				//generic (slower) case
+				btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
+
+				btTransform worldTocollisionObject = colObjWorldTransform.inverse();
+
+				btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
+				btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
+
+				//ConvexCast::CastResult
+
+				struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback
+				{
+					btCollisionWorld::RayResultCallback* m_resultCallback;
+					btCollisionObject*	m_collisionObject;
+					btConcaveShape*	m_triangleMesh;
+
+					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)
+						{
+						}
+
+
+					virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex )
+					{
+						btCollisionWorld::LocalShapeInfo	shapeInfo;
+						shapeInfo.m_shapePart = partId;
+						shapeInfo.m_triangleIndex = triangleIndex;
+
+						btCollisionWorld::LocalRayResult rayResult
+						(m_collisionObject,
+							&shapeInfo,
+							hitNormalLocal,
+							hitFraction);
+
+						bool	normalInWorldSpace = false;
+						return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace);
+
+
+					}
+
+				};
+
+
+				BridgeTriangleRaycastCallback	rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObject,concaveShape);
+				rcb.m_hitFraction = resultCallback.m_closestHitFraction;
+
+				btVector3 rayAabbMinLocal = rayFromLocal;
+				rayAabbMinLocal.setMin(rayToLocal);
+				btVector3 rayAabbMaxLocal = rayFromLocal;
+				rayAabbMaxLocal.setMax(rayToLocal);
+
+				concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal);
+			}
+		} else {
+//			BT_PROFILE("rayTestCompound");
+			///@todo: use AABB tree or other BVH acceleration structure, see btDbvt
+			if (collisionShape->isCompound())
+			{
+				const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
+				int i=0;
+				for (i=0;i<compoundShape->getNumChildShapes();i++)
+				{
+					btTransform childTrans = compoundShape->getChildTransform(i);
+					const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
+					btTransform childWorldTrans = colObjWorldTransform * childTrans;
+					// replace collision shape so that callback can determine the triangle
+					btCollisionShape* saveCollisionShape = collisionObject->getCollisionShape();
+					collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
+					rayTestSingle(rayFromTrans,rayToTrans,
+						collisionObject,
+						childCollisionShape,
+						childWorldTrans,
+						resultCallback);
+					// restore
+					collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
+				}
+			}
+		}
+	}
+}
+
+void	btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans,
+					  btCollisionObject* collisionObject,
+					  const btCollisionShape* collisionShape,
+					  const btTransform& colObjWorldTransform,
+					  ConvexResultCallback& resultCallback, btScalar allowedPenetration)
+{
+	if (collisionShape->isConvex())
+	{
+		//BT_PROFILE("convexSweepConvex");
+		btConvexCast::CastResult castResult;
+		castResult.m_allowedPenetration = allowedPenetration;
+		castResult.m_fraction = resultCallback.m_closestHitFraction;//btScalar(1.);//??
+
+		btConvexShape* convexShape = (btConvexShape*) collisionShape;
+		btVoronoiSimplexSolver	simplexSolver;
+		btGjkEpaPenetrationDepthSolver	gjkEpaPenetrationSolver;
+		
+		btContinuousConvexCollision convexCaster1(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver);
+		//btGjkConvexCast convexCaster2(castShape,convexShape,&simplexSolver);
+		//btSubsimplexConvexCast convexCaster3(castShape,convexShape,&simplexSolver);
+
+		btConvexCast* castPtr = &convexCaster1;
+	
+	
+		
+		if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult))
+		{
+			//add hit
+			if (castResult.m_normal.length2() > btScalar(0.0001))
+			{
+				if (castResult.m_fraction < resultCallback.m_closestHitFraction)
+				{
+					castResult.m_normal.normalize();
+					btCollisionWorld::LocalConvexResult localConvexResult
+								(
+									collisionObject,
+									0,
+									castResult.m_normal,
+									castResult.m_hitPoint,
+									castResult.m_fraction
+								);
+
+					bool normalInWorldSpace = true;
+					resultCallback.addSingleResult(localConvexResult, normalInWorldSpace);
+
+				}
+			}
+		}
+	} else {
+		if (collisionShape->isConcave())
+		{
+			if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE)
+			{
+				//BT_PROFILE("convexSweepbtBvhTriangleMesh");
+				btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape;
+				btTransform worldTocollisionObject = colObjWorldTransform.inverse();
+				btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
+				btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
+				// rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
+				btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
+
+				//ConvexCast::CastResult
+				struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
+				{
+					btCollisionWorld::ConvexResultCallback* m_resultCallback;
+					btCollisionObject*	m_collisionObject;
+					btTriangleMeshShape*	m_triangleMesh;
+
+					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)
+						{
+						}
+
+
+					virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
+					{
+						btCollisionWorld::LocalShapeInfo	shapeInfo;
+						shapeInfo.m_shapePart = partId;
+						shapeInfo.m_triangleIndex = triangleIndex;
+						if (hitFraction <= m_resultCallback->m_closestHitFraction)
+						{
+
+							btCollisionWorld::LocalConvexResult convexResult
+							(m_collisionObject,
+								&shapeInfo,
+								hitNormalLocal,
+								hitPointLocal,
+								hitFraction);
+
+							bool	normalInWorldSpace = true;
+
+
+							return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
+						}
+						return hitFraction;
+					}
+
+				};
+
+				BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,triangleMesh, colObjWorldTransform);
+				tccb.m_hitFraction = resultCallback.m_closestHitFraction;
+				btVector3 boxMinLocal, boxMaxLocal;
+				castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
+				triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal);
+			} else
+			{
+				//BT_PROFILE("convexSweepConcave");
+				btConcaveShape* concaveShape = (btConcaveShape*)collisionShape;
+				btTransform worldTocollisionObject = colObjWorldTransform.inverse();
+				btVector3 convexFromLocal = worldTocollisionObject * convexFromTrans.getOrigin();
+				btVector3 convexToLocal = worldTocollisionObject * convexToTrans.getOrigin();
+				// rotation of box in local mesh space = MeshRotation^-1 * ConvexToRotation
+				btTransform rotationXform = btTransform(worldTocollisionObject.getBasis() * convexToTrans.getBasis());
+
+				//ConvexCast::CastResult
+				struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback
+				{
+					btCollisionWorld::ConvexResultCallback* m_resultCallback;
+					btCollisionObject*	m_collisionObject;
+					btConcaveShape*	m_triangleMesh;
+
+					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)
+						{
+						}
+
+
+					virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex )
+					{
+						btCollisionWorld::LocalShapeInfo	shapeInfo;
+						shapeInfo.m_shapePart = partId;
+						shapeInfo.m_triangleIndex = triangleIndex;
+						if (hitFraction <= m_resultCallback->m_closestHitFraction)
+						{
+
+							btCollisionWorld::LocalConvexResult convexResult
+							(m_collisionObject,
+								&shapeInfo,
+								hitNormalLocal,
+								hitPointLocal,
+								hitFraction);
+
+							bool	normalInWorldSpace = false;
+
+							return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace);
+						}
+						return hitFraction;
+					}
+
+				};
+
+				BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,collisionObject,concaveShape, colObjWorldTransform);
+				tccb.m_hitFraction = resultCallback.m_closestHitFraction;
+				btVector3 boxMinLocal, boxMaxLocal;
+				castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal);
+
+				btVector3 rayAabbMinLocal = convexFromLocal;
+				rayAabbMinLocal.setMin(convexToLocal);
+				btVector3 rayAabbMaxLocal = convexFromLocal;
+				rayAabbMaxLocal.setMax(convexToLocal);
+				rayAabbMinLocal += boxMinLocal;
+				rayAabbMaxLocal += boxMaxLocal;
+				concaveShape->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal);
+			}
+		} else {
+			///@todo : use AABB tree or other BVH acceleration structure!
+			if (collisionShape->isCompound())
+			{
+				BT_PROFILE("convexSweepCompound");
+				const btCompoundShape* compoundShape = static_cast<const btCompoundShape*>(collisionShape);
+				int i=0;
+				for (i=0;i<compoundShape->getNumChildShapes();i++)
+				{
+					btTransform childTrans = compoundShape->getChildTransform(i);
+					const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i);
+					btTransform childWorldTrans = colObjWorldTransform * childTrans;
+					// replace collision shape so that callback can determine the triangle
+					btCollisionShape* saveCollisionShape = collisionObject->getCollisionShape();
+					collisionObject->internalSetTemporaryCollisionShape((btCollisionShape*)childCollisionShape);
+					objectQuerySingle(castShape, convexFromTrans,convexToTrans,
+						collisionObject,
+						childCollisionShape,
+						childWorldTrans,
+						resultCallback, allowedPenetration);
+					// restore
+					collisionObject->internalSetTemporaryCollisionShape(saveCollisionShape);
+				}
+			}
+		}
+	}
+}
+
+
+struct btSingleRayCallback : public btBroadphaseRayCallback
+{
+
+	btVector3	m_rayFromWorld;
+	btVector3	m_rayToWorld;
+	btTransform	m_rayFromTrans;
+	btTransform	m_rayToTrans;
+	btVector3	m_hitNormal;
+
+	const btCollisionWorld*	m_world;
+	btCollisionWorld::RayResultCallback&	m_resultCallback;
+
+	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_rayFromTrans.setIdentity();
+		m_rayFromTrans.setOrigin(m_rayFromWorld);
+		m_rayToTrans.setIdentity();
+		m_rayToTrans.setOrigin(m_rayToWorld);
+
+		btVector3 rayDir = (rayToWorld-rayFromWorld);
+
+		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];
+		m_signs[0] = m_rayDirectionInverse[0] < 0.0;
+		m_signs[1] = m_rayDirectionInverse[1] < 0.0;
+		m_signs[2] = m_rayDirectionInverse[2] < 0.0;
+
+		m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld);
+
+	}
+
+	
+
+	virtual bool	process(const btBroadphaseProxy* proxy)
+	{
+		///terminate further ray tests, once the closestHitFraction reached zero
+		if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
+			return false;
+
+		btCollisionObject*	collisionObject = (btCollisionObject*)proxy->m_clientObject;
+
+		//only perform raycast if filterMask matches
+		if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 
+		{
+			//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
+			//btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
+#if 0
+#ifdef RECALCULATE_AABB
+			btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
+			collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
+#else
+			//getBroadphase()->getAabb(collisionObject->getBroadphaseHandle(),collisionObjectAabbMin,collisionObjectAabbMax);
+			const btVector3& collisionObjectAabbMin = collisionObject->getBroadphaseHandle()->m_aabbMin;
+			const btVector3& collisionObjectAabbMax = collisionObject->getBroadphaseHandle()->m_aabbMax;
+#endif
+#endif
+			//btScalar hitLambda = m_resultCallback.m_closestHitFraction;
+			//culling already done by broadphase
+			//if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal))
+			{
+				m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans,
+					collisionObject,
+						collisionObject->getCollisionShape(),
+						collisionObject->getWorldTransform(),
+						m_resultCallback);
+			}
+		}
+		return true;
+	}
+};
+
+void	btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const
+{
+	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
+	btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback);
+
+#ifndef USE_BRUTEFORCE_RAYBROADPHASE
+	m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB);
+#else
+	for (int i=0;i<this->getNumCollisionObjects();i++)
+	{
+		rayCB.process(m_collisionObjects[i]->getBroadphaseHandle());
+	}	
+#endif //USE_BRUTEFORCE_RAYBROADPHASE
+
+}
+
+
+struct btSingleSweepCallback : public btBroadphaseRayCallback
+{
+
+	btTransform	m_convexFromTrans;
+	btTransform	m_convexToTrans;
+	btVector3	m_hitNormal;
+	const btCollisionWorld*	m_world;
+	btCollisionWorld::ConvexResultCallback&	m_resultCallback;
+	btScalar	m_allowedCcdPenetration;
+	const btConvexShape* m_castShape;
+
+
+	btSingleSweepCallback(const btConvexShape* castShape, const btTransform& convexFromTrans,const btTransform& convexToTrans,const btCollisionWorld* world,btCollisionWorld::ConvexResultCallback& resultCallback,btScalar allowedPenetration)
+		:m_convexFromTrans(convexFromTrans),
+		m_convexToTrans(convexToTrans),
+		m_world(world),
+		m_resultCallback(resultCallback),
+		m_allowedCcdPenetration(allowedPenetration),
+		m_castShape(castShape)
+	{
+		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];
+		m_signs[0] = m_rayDirectionInverse[0] < 0.0;
+		m_signs[1] = m_rayDirectionInverse[1] < 0.0;
+		m_signs[2] = m_rayDirectionInverse[2] < 0.0;
+
+		m_lambda_max = rayDir.dot(unnormalizedRayDir);
+
+	}
+
+	virtual bool	process(const btBroadphaseProxy* proxy)
+	{
+		///terminate further convex sweep tests, once the closestHitFraction reached zero
+		if (m_resultCallback.m_closestHitFraction == btScalar(0.f))
+			return false;
+
+		btCollisionObject*	collisionObject = (btCollisionObject*)proxy->m_clientObject;
+
+		//only perform raycast if filterMask matches
+		if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
+			//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
+			m_world->objectQuerySingle(m_castShape, m_convexFromTrans,m_convexToTrans,
+					collisionObject,
+						collisionObject->getCollisionShape(),
+						collisionObject->getWorldTransform(),
+						m_resultCallback,
+						m_allowedCcdPenetration);
+		}
+		
+		return true;
+	}
+};
+
+
+
+void	btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
+{
+
+	BT_PROFILE("convexSweepTest");
+	/// 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
+	/// unfortunately the implementation for rayTest and convexSweepTest duplicated, albeit practically identical
+
+	
+
+	btTransform	convexFromTrans,convexToTrans;
+	convexFromTrans = convexFromWorld;
+	convexToTrans = convexToWorld;
+	btVector3 castShapeAabbMin, castShapeAabbMax;
+	/* Compute AABB that encompasses angular movement */
+	{
+		btVector3 linVel, angVel;
+		btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
+		btVector3 zeroLinVel;
+		zeroLinVel.setValue(0,0,0);
+		btTransform R;
+		R.setIdentity ();
+		R.setRotation (convexFromTrans.getRotation());
+		castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
+	}
+
+#ifndef USE_BRUTEFORCE_RAYBROADPHASE
+
+	btSingleSweepCallback	convexCB(castShape,convexFromWorld,convexToWorld,this,resultCallback,allowedCcdPenetration);
+
+	m_broadphasePairCache->rayTest(convexFromTrans.getOrigin(),convexToTrans.getOrigin(),convexCB,castShapeAabbMin,castShapeAabbMax);
+
+#else
+	/// go over all objects, and if the ray intersects their aabb + cast shape aabb,
+	// do a ray-shape query using convexCaster (CCD)
+	int i;
+	for (i=0;i<m_collisionObjects.size();i++)
+	{
+		btCollisionObject*	collisionObject= m_collisionObjects[i];
+		//only perform raycast if filterMask matches
+		if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
+			//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
+			btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
+			collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
+			AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
+			btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
+			btVector3 hitNormal;
+			if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
+			{
+				objectQuerySingle(castShape, convexFromTrans,convexToTrans,
+					collisionObject,
+						collisionObject->getCollisionShape(),
+						collisionObject->getWorldTransform(),
+						resultCallback,
+						allowedCcdPenetration);
+			}
+		}
+	}
+#endif //USE_BRUTEFORCE_RAYBROADPHASE
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.h	(revision 6952)
@@ -0,0 +1,424 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://bulletphysics.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.
+*/
+
+
+/**
+ * @mainpage Bullet Documentation
+ *
+ * @section intro_sec Introduction
+ * Bullet Collision Detection & Physics SDK
+ *
+ * Bullet is a Collision Detection and Rigid Body Dynamics Library. The Library is Open Source and free for commercial use, under the ZLib license ( http://opensource.org/licenses/zlib-license.php ).
+ *
+ * There is the Physics Forum for feedback and general Collision Detection and Physics discussions.
+ * Please visit http://www.bulletphysics.com
+ *
+ * @section install_sec Installation
+ *
+ * @subsection step1 Step 1: Download
+ * You can download the Bullet Physics Library from the Google Code repository: http://code.google.com/p/bullet/downloads/list
+ * @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
+ * 
+ * @subsection step3 Step 3: Testing demos
+ * Try to run and experiment with BasicDemo executable as a starting point.
+ * Bullet can be used in several ways, as Full Rigid Body simulation, as Collision Detector Library or Low Level / Snippets like the GJK Closest Point calculation.
+ * The Dependencies can be seen in this documentation under Directories
+ * 
+ * @subsection step4 Step 4: Integrating in your application, full Rigid Body and Soft Body simulation
+ * Check out BasicDemo how to create a btDynamicsWorld, btRigidBody and btCollisionShape, Stepping the simulation and synchronizing your graphics object transform.
+ * Check out SoftDemo how to use soft body dynamics, using btSoftRigidDynamicsWorld.
+ * @subsection step5 Step 5 : Integrate the Collision Detection Library (without Dynamics and other Extras)
+ * Bullet Collision Detection can also be used without the Dynamics/Extras.
+ * Check out btCollisionWorld and btCollisionObject, and the CollisionInterfaceDemo.
+ * @subsection step6 Step 6 : Use Snippets like the GJK Closest Point calculation.
+ * Bullet has been designed in a modular way keeping dependencies to a minimum. The ConvexHullDistance demo demonstrates direct use of btGjkPairDetector.
+ *
+ * @section copyright Copyright
+ * Copyright (C) 2005-2008 Erwin Coumans, some contributions Copyright Gino van den Bergen, Christer Ericson, Simon Hobbs, Ricardo Padrela, F Richter(res), Stephane Redon
+ * Special thanks to all visitors of the Bullet Physics forum, and in particular above contributors, John McCutchan, Nathanael Presson, Dave Eberle, Dirk Gregorius, Erin Catto, Dave Eberle, Adam Moravanszky,
+ * Pierre Terdiman, Kenny Erleben, Russell Smith, Oliver Strunk, Jan Paul van Waveren, Marten Svanfeldt.
+ * 
+ */
+
+
+ 
+ 
+
+#ifndef COLLISION_WORLD_H
+#define COLLISION_WORLD_H
+
+class btStackAlloc;
+class btCollisionShape;
+class btConvexShape;
+class btBroadphaseInterface;
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btTransform.h"
+#include "btCollisionObject.h"
+#include "btCollisionDispatcher.h"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
+#include "LinearMath/btAlignedObjectArray.h"
+
+///CollisionWorld is interface and container for the collision detection
+class btCollisionWorld
+{
+
+
+	
+protected:
+
+	btAlignedObjectArray<btCollisionObject*>	m_collisionObjects;
+
+	
+	btDispatcher*	m_dispatcher1;
+
+	btDispatcherInfo	m_dispatchInfo;
+
+	btStackAlloc*	m_stackAlloc;
+
+	btBroadphaseInterface*	m_broadphasePairCache;
+
+	btIDebugDraw*	m_debugDrawer;
+
+
+	
+public:
+
+	//this constructor doesn't own the dispatcher and paircache/broadphase
+	btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphasePairCache, btCollisionConfiguration* collisionConfiguration);
+
+	virtual ~btCollisionWorld();
+
+	void	setBroadphase(btBroadphaseInterface*	pairCache)
+	{
+		m_broadphasePairCache = pairCache;
+	}
+
+	const btBroadphaseInterface*	getBroadphase() const
+	{
+		return m_broadphasePairCache;
+	}
+
+	btBroadphaseInterface*	getBroadphase()
+	{
+		return m_broadphasePairCache;
+	}
+
+	btOverlappingPairCache*	getPairCache()
+	{
+		return m_broadphasePairCache->getOverlappingPairCache();
+	}
+
+
+	btDispatcher*	getDispatcher()
+	{
+		return m_dispatcher1;
+	}
+
+	const btDispatcher*	getDispatcher() const
+	{
+		return m_dispatcher1;
+	}
+
+	void	updateSingleAabb(btCollisionObject* colObj);
+
+	virtual void	updateAabbs();
+
+	
+	virtual void	setDebugDrawer(btIDebugDraw*	debugDrawer)
+	{
+			m_debugDrawer = debugDrawer;
+	}
+
+	virtual btIDebugDraw*	getDebugDrawer()
+	{
+		return m_debugDrawer;
+	}
+
+
+	///LocalShapeInfo gives extra information for complex shapes
+	///Currently, only btTriangleMeshShape is available, so it just contains triangleIndex and subpart
+	struct	LocalShapeInfo
+	{
+		int	m_shapePart;
+		int	m_triangleIndex;
+
+		
+		//const btCollisionShape*	m_shapeTemp;
+		//const btTransform*	m_shapeLocalTransform;
+	};
+
+	struct	LocalRayResult
+	{
+		LocalRayResult(btCollisionObject*	collisionObject, 
+			LocalShapeInfo*	localShapeInfo,
+			const btVector3&		hitNormalLocal,
+			btScalar hitFraction)
+		:m_collisionObject(collisionObject),
+		m_localShapeInfo(localShapeInfo),
+		m_hitNormalLocal(hitNormalLocal),
+		m_hitFraction(hitFraction)
+		{
+		}
+
+		btCollisionObject*		m_collisionObject;
+		LocalShapeInfo*			m_localShapeInfo;
+		btVector3				m_hitNormalLocal;
+		btScalar				m_hitFraction;
+
+	};
+
+	///RayResultCallback is used to report new raycast results
+	struct	RayResultCallback
+	{
+		btScalar	m_closestHitFraction;
+		btCollisionObject*		m_collisionObject;
+		short int	m_collisionFilterGroup;
+		short int	m_collisionFilterMask;
+      //@BP Mod - Custom flags, currently used to enable backface culling on tri-meshes, see btRaycastCallback
+      unsigned int m_flags;
+
+		virtual ~RayResultCallback()
+		{
+		}
+		bool	hasHit() const
+		{
+			return (m_collisionObject != 0);
+		}
+
+		RayResultCallback()
+			:m_closestHitFraction(btScalar(1.)),
+			m_collisionObject(0),
+			m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
+			m_collisionFilterMask(btBroadphaseProxy::AllFilter),
+         //@BP Mod
+         m_flags(0)
+		{
+		}
+
+		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(LocalRayResult& rayResult,bool normalInWorldSpace) = 0;
+	};
+
+	struct	ClosestRayResultCallback : public RayResultCallback
+	{
+		ClosestRayResultCallback(const btVector3&	rayFromWorld,const btVector3&	rayToWorld)
+		:m_rayFromWorld(rayFromWorld),
+		m_rayToWorld(rayToWorld)
+		{
+		}
+
+		btVector3	m_rayFromWorld;//used to calculate hitPointWorld from hitFraction
+		btVector3	m_rayToWorld;
+
+		btVector3	m_hitNormalWorld;
+		btVector3	m_hitPointWorld;
+
+			
+		virtual	btScalar	addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace)
+		{
+			//caller already does the filter on the m_closestHitFraction
+			btAssert(rayResult.m_hitFraction <= m_closestHitFraction);
+
+			
+			m_closestHitFraction = rayResult.m_hitFraction;
+			m_collisionObject = rayResult.m_collisionObject;
+			if (normalInWorldSpace)
+			{
+				m_hitNormalWorld = rayResult.m_hitNormalLocal;
+			} else
+			{
+				///need to transform normal into worldspace
+				m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal;
+			}
+			m_hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction);
+			return rayResult.m_hitFraction;
+		}
+	};
+
+
+	struct LocalConvexResult
+	{
+		LocalConvexResult(btCollisionObject*	hitCollisionObject, 
+			LocalShapeInfo*	localShapeInfo,
+			const btVector3&		hitNormalLocal,
+			const btVector3&		hitPointLocal,
+			btScalar hitFraction
+			)
+		:m_hitCollisionObject(hitCollisionObject),
+		m_localShapeInfo(localShapeInfo),
+		m_hitNormalLocal(hitNormalLocal),
+		m_hitPointLocal(hitPointLocal),
+		m_hitFraction(hitFraction)
+		{
+		}
+
+		btCollisionObject*		m_hitCollisionObject;
+		LocalShapeInfo*			m_localShapeInfo;
+		btVector3				m_hitNormalLocal;
+		btVector3				m_hitPointLocal;
+		btScalar				m_hitFraction;
+	};
+
+	///RayResultCallback is used to report new raycast results
+	struct	ConvexResultCallback
+	{
+		btScalar	m_closestHitFraction;
+		short int	m_collisionFilterGroup;
+		short int	m_collisionFilterMask;
+
+		
+		ConvexResultCallback()
+			:m_closestHitFraction(btScalar(1.)),
+			m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter),
+			m_collisionFilterMask(btBroadphaseProxy::AllFilter)
+		{
+		}
+
+		virtual ~ConvexResultCallback()
+		{
+		}
+
+		
+		bool	hasHit() const
+		{
+			return (m_closestHitFraction < btScalar(1.));
+		}
+
+
+		
+
+		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(LocalConvexResult& convexResult,bool normalInWorldSpace) = 0;
+	};
+
+	struct	ClosestConvexResultCallback : public ConvexResultCallback
+	{
+		ClosestConvexResultCallback(const btVector3&	convexFromWorld,const btVector3&	convexToWorld)
+		:m_convexFromWorld(convexFromWorld),
+		m_convexToWorld(convexToWorld),
+		m_hitCollisionObject(0)
+		{
+		}
+
+		btVector3	m_convexFromWorld;//used to calculate hitPointWorld from hitFraction
+		btVector3	m_convexToWorld;
+
+		btVector3	m_hitNormalWorld;
+		btVector3	m_hitPointWorld;
+		btCollisionObject*	m_hitCollisionObject;
+
+		
+		virtual	btScalar	addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace)
+		{
+//caller already does the filter on the m_closestHitFraction
+			btAssert(convexResult.m_hitFraction <= m_closestHitFraction);
+
+						
+			m_closestHitFraction = convexResult.m_hitFraction;
+			m_hitCollisionObject = convexResult.m_hitCollisionObject;
+			if (normalInWorldSpace)
+			{
+				m_hitNormalWorld = convexResult.m_hitNormalLocal;
+			} else
+			{
+				///need to transform normal into worldspace
+				m_hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal;
+			}
+			m_hitPointWorld = convexResult.m_hitPointLocal;
+			return convexResult.m_hitFraction;
+		}
+	};
+
+	int	getNumCollisionObjects() const
+	{
+		return int(m_collisionObjects.size());
+	}
+
+	/// 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.
+	void    convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback,  btScalar allowedCcdPenetration = btScalar(0.)) const;
+
+
+	/// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
+	/// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape.
+	/// This allows more customization.
+	static void	rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans,
+					  btCollisionObject* collisionObject,
+					  const btCollisionShape* collisionShape,
+					  const btTransform& colObjWorldTransform,
+					  RayResultCallback& resultCallback);
+
+	/// objectQuerySingle performs a collision detection query and calls the resultCallback. It is used internally by rayTest.
+	static void	objectQuerySingle(const btConvexShape* castShape, const btTransform& rayFromTrans,const btTransform& rayToTrans,
+					  btCollisionObject* collisionObject,
+					  const btCollisionShape* collisionShape,
+					  const btTransform& colObjWorldTransform,
+					  ConvexResultCallback& resultCallback, btScalar	allowedPenetration);
+
+	void	addCollisionObject(btCollisionObject* collisionObject,short int collisionFilterGroup=btBroadphaseProxy::DefaultFilter,short int collisionFilterMask=btBroadphaseProxy::AllFilter);
+
+	btCollisionObjectArray& getCollisionObjectArray()
+	{
+		return m_collisionObjects;
+	}
+
+	const btCollisionObjectArray& getCollisionObjectArray() const
+	{
+		return m_collisionObjects;
+	}
+
+
+	void	removeCollisionObject(btCollisionObject* collisionObject);
+
+	virtual void	performDiscreteCollisionDetection();
+
+	btDispatcherInfo& getDispatchInfo()
+	{
+		return m_dispatchInfo;
+	}
+
+	const btDispatcherInfo& getDispatchInfo() const
+	{
+		return m_dispatchInfo;
+	}
+
+};
+
+
+#endif //COLLISION_WORLD_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp	(revision 6952)
@@ -0,0 +1,342 @@
+/*
+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 "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/CollisionShapes/btCompoundShape.h"
+#include "BulletCollision/BroadphaseCollision/btDbvt.h"
+#include "LinearMath/btIDebugDraw.h"
+#include "LinearMath/btAabbUtil2.h"
+#include "btManifoldResult.h"
+
+btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
+:btActivatingCollisionAlgorithm(ci,body0,body1),
+m_isSwapped(isSwapped),
+m_sharedManifold(ci.m_manifold)
+{
+	m_ownsManifold = false;
+
+	btCollisionObject* colObj = m_isSwapped? body1 : body0;
+	btAssert (colObj->getCollisionShape()->isCompound());
+	
+	btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
+	m_compoundShapeRevision = compoundShape->getUpdateRevision();
+	
+	preallocateChildAlgorithms(body0,body1);
+}
+
+void	btCompoundCollisionAlgorithm::preallocateChildAlgorithms(btCollisionObject* body0,btCollisionObject* body1)
+{
+	btCollisionObject* colObj = m_isSwapped? body1 : body0;
+	btCollisionObject* otherObj = m_isSwapped? body0 : body1;
+	btAssert (colObj->getCollisionShape()->isCompound());
+	
+	btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
+
+	int numChildren = compoundShape->getNumChildShapes();
+	int i;
+	
+	m_childCollisionAlgorithms.resize(numChildren);
+	for (i=0;i<numChildren;i++)
+	{
+		if (compoundShape->getDynamicAabbTree())
+		{
+			m_childCollisionAlgorithms[i] = 0;
+		} else
+		{
+			btCollisionShape* tmpShape = colObj->getCollisionShape();
+			btCollisionShape* childShape = compoundShape->getChildShape(i);
+			colObj->internalSetTemporaryCollisionShape( childShape );
+			m_childCollisionAlgorithms[i] = m_dispatcher->findAlgorithm(colObj,otherObj,m_sharedManifold);
+			colObj->internalSetTemporaryCollisionShape( tmpShape );
+		}
+	}
+}
+
+void	btCompoundCollisionAlgorithm::removeChildAlgorithms()
+{
+	int numChildren = m_childCollisionAlgorithms.size();
+	int i;
+	for (i=0;i<numChildren;i++)
+	{
+		if (m_childCollisionAlgorithms[i])
+		{
+			m_childCollisionAlgorithms[i]->~btCollisionAlgorithm();
+			m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]);
+		}
+	}
+}
+
+btCompoundCollisionAlgorithm::~btCompoundCollisionAlgorithm()
+{
+	removeChildAlgorithms();
+}
+
+
+
+
+struct	btCompoundLeafCallback : btDbvt::ICollide
+{
+
+public:
+
+	btCollisionObject* m_compoundColObj;
+	btCollisionObject* m_otherObj;
+	btDispatcher* m_dispatcher;
+	const btDispatcherInfo& m_dispatchInfo;
+	btManifoldResult*	m_resultOut;
+	btCollisionAlgorithm**	m_childCollisionAlgorithms;
+	btPersistentManifold*	m_sharedManifold;
+
+
+
+
+	btCompoundLeafCallback (btCollisionObject* compoundObj,btCollisionObject* otherObj,btDispatcher* dispatcher,const btDispatcherInfo& dispatchInfo,btManifoldResult*	resultOut,btCollisionAlgorithm**	childCollisionAlgorithms,btPersistentManifold*	sharedManifold)
+		:m_compoundColObj(compoundObj),m_otherObj(otherObj),m_dispatcher(dispatcher),m_dispatchInfo(dispatchInfo),m_resultOut(resultOut),
+		m_childCollisionAlgorithms(childCollisionAlgorithms),
+		m_sharedManifold(sharedManifold)
+	{
+
+	}
+
+
+	void	ProcessChildShape(btCollisionShape* childShape,int index)
+	{
+		
+		btCompoundShape* compoundShape = static_cast<btCompoundShape*>(m_compoundColObj->getCollisionShape());
+
+
+		//backup
+		btTransform	orgTrans = m_compoundColObj->getWorldTransform();
+		btTransform	orgInterpolationTrans = m_compoundColObj->getInterpolationWorldTransform();
+		const btTransform& childTrans = compoundShape->getChildTransform(index);
+		btTransform	newChildWorldTrans = orgTrans*childTrans ;
+
+		//perform an AABB check first
+		btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1;
+		childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0);
+		m_otherObj->getCollisionShape()->getAabb(m_otherObj->getWorldTransform(),aabbMin1,aabbMax1);
+
+		if (TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
+		{
+
+			m_compoundColObj->setWorldTransform( newChildWorldTrans);
+			m_compoundColObj->setInterpolationWorldTransform(newChildWorldTrans);
+
+			//the contactpoint is still projected back using the original inverted worldtrans
+			btCollisionShape* tmpShape = m_compoundColObj->getCollisionShape();
+			m_compoundColObj->internalSetTemporaryCollisionShape( childShape );
+
+			if (!m_childCollisionAlgorithms[index])
+				m_childCollisionAlgorithms[index] = m_dispatcher->findAlgorithm(m_compoundColObj,m_otherObj,m_sharedManifold);
+
+			m_childCollisionAlgorithms[index]->processCollision(m_compoundColObj,m_otherObj,m_dispatchInfo,m_resultOut);
+			if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
+			{
+				btVector3 worldAabbMin,worldAabbMax;
+				m_dispatchInfo.m_debugDraw->drawAabb(aabbMin0,aabbMax0,btVector3(1,1,1));
+				m_dispatchInfo.m_debugDraw->drawAabb(aabbMin1,aabbMax1,btVector3(1,1,1));
+			}
+			
+			//revert back transform
+			m_compoundColObj->internalSetTemporaryCollisionShape( tmpShape);
+			m_compoundColObj->setWorldTransform(  orgTrans );
+			m_compoundColObj->setInterpolationWorldTransform(orgInterpolationTrans);
+		}
+	}
+	void		Process(const btDbvtNode* leaf)
+	{
+		int index = leaf->dataAsInt;
+
+		btCompoundShape* compoundShape = static_cast<btCompoundShape*>(m_compoundColObj->getCollisionShape());
+		btCollisionShape* childShape = compoundShape->getChildShape(index);
+		if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb))
+		{
+			btVector3 worldAabbMin,worldAabbMax;
+			btTransform	orgTrans = m_compoundColObj->getWorldTransform();
+			btTransformAabb(leaf->volume.Mins(),leaf->volume.Maxs(),0.,orgTrans,worldAabbMin,worldAabbMax);
+			m_dispatchInfo.m_debugDraw->drawAabb(worldAabbMin,worldAabbMax,btVector3(1,0,0));
+		}
+		ProcessChildShape(childShape,index);
+
+	}
+};
+
+
+
+
+
+
+void btCompoundCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	btCollisionObject* colObj = m_isSwapped? body1 : body0;
+	btCollisionObject* otherObj = m_isSwapped? body0 : body1;
+
+	
+
+	btAssert (colObj->getCollisionShape()->isCompound());
+	btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
+
+	///btCompoundShape might have changed:
+	////make sure the internal child collision algorithm caches are still valid
+	if (compoundShape->getUpdateRevision() != m_compoundShapeRevision)
+	{
+		///clear and update all
+		removeChildAlgorithms();
+		
+		preallocateChildAlgorithms(body0,body1);
+	}
+
+
+	btDbvt* tree = compoundShape->getDynamicAabbTree();
+	//use a dynamic aabb tree to cull potential child-overlaps
+	btCompoundLeafCallback  callback(colObj,otherObj,m_dispatcher,dispatchInfo,resultOut,&m_childCollisionAlgorithms[0],m_sharedManifold);
+
+	///we need to refresh all contact manifolds
+	///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep
+	///so we should add a 'refreshManifolds' in the btCollisionAlgorithm
+	{
+		int i;
+		btManifoldArray manifoldArray;
+		for (i=0;i<m_childCollisionAlgorithms.size();i++)
+		{
+			if (m_childCollisionAlgorithms[i])
+			{
+				m_childCollisionAlgorithms[i]->getAllContactManifolds(manifoldArray);
+				for (int m=0;m<manifoldArray.size();m++)
+				{
+					if (manifoldArray[m]->getNumContacts())
+					{
+						resultOut->setPersistentManifold(manifoldArray[m]);
+						resultOut->refreshContactPoints();
+						resultOut->setPersistentManifold(0);//??necessary?
+					}
+				}
+				manifoldArray.clear();
+			}
+		}
+	}
+
+	if (tree)
+	{
+
+		btVector3 localAabbMin,localAabbMax;
+		btTransform otherInCompoundSpace;
+		otherInCompoundSpace = colObj->getWorldTransform().inverse() * otherObj->getWorldTransform();
+		otherObj->getCollisionShape()->getAabb(otherInCompoundSpace,localAabbMin,localAabbMax);
+
+		const ATTRIBUTE_ALIGNED16(btDbvtVolume)	bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
+		//process all children, that overlap with  the given AABB bounds
+		tree->collideTV(tree->m_root,bounds,callback);
+
+	} else
+	{
+		//iterate over all children, perform an AABB check inside ProcessChildShape
+		int numChildren = m_childCollisionAlgorithms.size();
+		int i;
+		for (i=0;i<numChildren;i++)
+		{
+			callback.ProcessChildShape(compoundShape->getChildShape(i),i);
+		}
+	}
+
+	{
+				//iterate over all children, perform an AABB check inside ProcessChildShape
+		int numChildren = m_childCollisionAlgorithms.size();
+		int i;
+		btManifoldArray	manifoldArray;
+
+		for (i=0;i<numChildren;i++)
+		{
+			if (m_childCollisionAlgorithms[i])
+			{
+				btCollisionShape* childShape = compoundShape->getChildShape(i);
+			//if not longer overlapping, remove the algorithm
+				btTransform	orgTrans = colObj->getWorldTransform();
+				btTransform	orgInterpolationTrans = colObj->getInterpolationWorldTransform();
+				const btTransform& childTrans = compoundShape->getChildTransform(i);
+				btTransform	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);
+
+				if (!TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1))
+				{
+					m_childCollisionAlgorithms[i]->~btCollisionAlgorithm();
+					m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]);
+					m_childCollisionAlgorithms[i] = 0;
+				}
+
+			}
+			
+		}
+
+		
+
+	}
+}
+
+btScalar	btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+
+	btCollisionObject* colObj = m_isSwapped? body1 : body0;
+	btCollisionObject* otherObj = m_isSwapped? body0 : body1;
+
+	btAssert (colObj->getCollisionShape()->isCompound());
+	
+	btCompoundShape* compoundShape = static_cast<btCompoundShape*>(colObj->getCollisionShape());
+
+	//We will use the OptimizedBVH, AABB tree to cull potential child-overlaps
+	//If both proxies are Compound, we will deal with that directly, by performing sequential/parallel tree traversals
+	//given Proxy0 and Proxy1, if both have a tree, Tree0 and Tree1, this means:
+	//determine overlapping nodes of Proxy1 using Proxy0 AABB against Tree1
+	//then use each overlapping node AABB against Tree0
+	//and vise versa.
+
+	btScalar hitFraction = btScalar(1.);
+
+	int numChildren = m_childCollisionAlgorithms.size();
+	int i;
+	for (i=0;i<numChildren;i++)
+	{
+		//temporarily exchange parent btCollisionShape with childShape, and recurse
+		btCollisionShape* childShape = compoundShape->getChildShape(i);
+
+		//backup
+		btTransform	orgTrans = colObj->getWorldTransform();
+	
+		const btTransform& childTrans = compoundShape->getChildTransform(i);
+		//btTransform	newChildWorldTrans = orgTrans*childTrans ;
+		colObj->setWorldTransform( orgTrans*childTrans );
+
+		btCollisionShape* tmpShape = colObj->getCollisionShape();
+		colObj->internalSetTemporaryCollisionShape( childShape );
+		btScalar frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut);
+		if (frac<hitFraction)
+		{
+			hitFraction = frac;
+		}
+		//revert back
+		colObj->internalSetTemporaryCollisionShape( tmpShape);
+		colObj->setWorldTransform( orgTrans);
+	}
+	return hitFraction;
+
+}
+
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h	(revision 6952)
@@ -0,0 +1,86 @@
+/*
+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 COMPOUND_COLLISION_ALGORITHM_H
+#define COMPOUND_COLLISION_ALGORITHM_H
+
+#include "btActivatingCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
+
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+class btDispatcher;
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "btCollisionCreateFunc.h"
+#include "LinearMath/btAlignedObjectArray.h"
+class btDispatcher;
+class btCollisionObject;
+
+/// btCompoundCollisionAlgorithm  supports collision between CompoundCollisionShapes and other collision shapes
+class btCompoundCollisionAlgorithm  : public btActivatingCollisionAlgorithm
+{
+	btAlignedObjectArray<btCollisionAlgorithm*> m_childCollisionAlgorithms;
+	bool m_isSwapped;
+
+	class btPersistentManifold*	m_sharedManifold;
+	bool					m_ownsManifold;
+
+	int	m_compoundShapeRevision;//to keep track of changes, so that childAlgorithm array can be updated
+	
+	void	removeChildAlgorithms();
+	
+	void	preallocateChildAlgorithms(btCollisionObject* body0,btCollisionObject* body1);
+
+public:
+
+	btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
+
+	virtual ~btCompoundCollisionAlgorithm();
+
+	virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+	btScalar	calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+	virtual	void	getAllContactManifolds(btManifoldArray&	manifoldArray)
+	{
+		int i;
+		for (i=0;i<m_childCollisionAlgorithms.size();i++)
+		{
+			if (m_childCollisionAlgorithms[i])
+				m_childCollisionAlgorithms[i]->getAllContactManifolds(manifoldArray);
+		}
+	}
+
+	struct CreateFunc :public 	btCollisionAlgorithmCreateFunc
+	{
+		virtual	btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+		{
+			void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm));
+			return new(mem) btCompoundCollisionAlgorithm(ci,body0,body1,false);
+		}
+	};
+
+	struct SwappedCreateFunc :public 	btCollisionAlgorithmCreateFunc
+	{
+		virtual	btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+		{
+			void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm));
+			return new(mem) btCompoundCollisionAlgorithm(ci,body0,body1,true);
+		}
+	};
+
+};
+
+#endif //COMPOUND_COLLISION_ALGORITHM_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp	(revision 6952)
@@ -0,0 +1,317 @@
+/*
+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 "btConvexConcaveCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/CollisionShapes/btConcaveShape.h"
+#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
+#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
+#include "BulletCollision/CollisionShapes/btTriangleShape.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
+#include "LinearMath/btIDebugDraw.h"
+#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
+
+btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1,bool isSwapped)
+: btActivatingCollisionAlgorithm(ci,body0,body1),
+m_isSwapped(isSwapped),
+m_btConvexTriangleCallback(ci.m_dispatcher1,body0,body1,isSwapped)
+{
+}
+
+btConvexConcaveCollisionAlgorithm::~btConvexConcaveCollisionAlgorithm()
+{
+}
+
+void	btConvexConcaveCollisionAlgorithm::getAllContactManifolds(btManifoldArray&	manifoldArray)
+{
+	if (m_btConvexTriangleCallback.m_manifoldPtr)
+	{
+		manifoldArray.push_back(m_btConvexTriangleCallback.m_manifoldPtr);
+	}
+}
+
+
+btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher*  dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped):
+	  m_dispatcher(dispatcher),
+	m_dispatchInfoPtr(0)
+{
+	m_convexBody = isSwapped? body1:body0;
+	m_triBody = isSwapped? body0:body1;
+	
+	  //
+	  // create the manifold from the dispatcher 'manifold pool'
+	  //
+	  m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBody,m_triBody);
+
+  	  clearCache();
+}
+
+btConvexTriangleCallback::~btConvexTriangleCallback()
+{
+	clearCache();
+	m_dispatcher->releaseManifold( m_manifoldPtr );
+  
+}
+  
+
+void	btConvexTriangleCallback::clearCache()
+{
+	m_dispatcher->clearManifold(m_manifoldPtr);
+}
+
+
+
+void btConvexTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex)
+{
+ 
+	//just for debugging purposes
+	//printf("triangle %d",m_triangleCount++);
+
+
+	//aabb filter is already applied!	
+
+	btCollisionAlgorithmConstructionInfo ci;
+	ci.m_dispatcher1 = m_dispatcher;
+
+	btCollisionObject* ob = static_cast<btCollisionObject*>(m_triBody);
+
+
+	
+	///debug drawing of the overlapping triangles
+	if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe ))
+	{
+		btVector3 color(255,255,0);
+		btTransform& tr = ob->getWorldTransform();
+		m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color);
+		m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color);
+		m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color);
+
+		//btVector3 center = triangle[0] + triangle[1]+triangle[2];
+		//center *= btScalar(0.333333);
+		//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(center),color);
+		//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(center),color);
+		//m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(center),color);
+
+	}
+
+
+	//btCollisionObject* colObj = static_cast<btCollisionObject*>(m_convexProxy->m_clientObject);
+	
+	if (m_convexBody->getCollisionShape()->isConvex())
+	{
+		btTriangleShape tm(triangle[0],triangle[1],triangle[2]);	
+		tm.setMargin(m_collisionMarginTriangle);
+		
+		btCollisionShape* tmpShape = ob->getCollisionShape();
+		ob->internalSetTemporaryCollisionShape( &tm );
+		
+		btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBody,m_triBody,m_manifoldPtr);
+		///this should use the btDispatcher, so the actual registered algorithm is used
+		//		btConvexConvexAlgorithm cvxcvxalgo(m_manifoldPtr,ci,m_convexBody,m_triBody);
+
+		m_resultOut->setShapeIdentifiers(-1,-1,partId,triangleIndex);
+	//	cvxcvxalgo.setShapeIdentifiers(-1,-1,partId,triangleIndex);
+//		cvxcvxalgo.processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
+		colAlgo->processCollision(m_convexBody,m_triBody,*m_dispatchInfoPtr,m_resultOut);
+		colAlgo->~btCollisionAlgorithm();
+		ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo);
+		ob->internalSetTemporaryCollisionShape( tmpShape);
+	}
+
+
+}
+
+
+
+void	btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	m_dispatchInfoPtr = &dispatchInfo;
+	m_collisionMarginTriangle = collisionMarginTriangle;
+	m_resultOut = resultOut;
+
+	//recalc aabbs
+	btTransform convexInTriangleSpace;
+	convexInTriangleSpace = m_triBody->getWorldTransform().inverse() * m_convexBody->getWorldTransform();
+	btCollisionShape* convexShape = static_cast<btCollisionShape*>(m_convexBody->getCollisionShape());
+	//CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
+	convexShape->getAabb(convexInTriangleSpace,m_aabbMin,m_aabbMax);
+	btScalar extraMargin = collisionMarginTriangle;
+	btVector3 extra(extraMargin,extraMargin,extraMargin);
+
+	m_aabbMax += extra;
+	m_aabbMin -= extra;
+	
+}
+
+void btConvexConcaveCollisionAlgorithm::clearCache()
+{
+	m_btConvexTriangleCallback.clearCache();
+
+}
+
+void btConvexConcaveCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	
+	
+	btCollisionObject* convexBody = m_isSwapped ? body1 : body0;
+	btCollisionObject* triBody = m_isSwapped ? body0 : body1;
+
+	if (triBody->getCollisionShape()->isConcave())
+	{
+
+
+		btCollisionObject*	triOb = triBody;
+		btConcaveShape* concaveShape = static_cast<btConcaveShape*>( triOb->getCollisionShape());
+		
+		if (convexBody->getCollisionShape()->isConvex())
+		{
+			btScalar collisionMarginTriangle = concaveShape->getMargin();
+					
+			resultOut->setPersistentManifold(m_btConvexTriangleCallback.m_manifoldPtr);
+			m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,resultOut);
+
+			//Disable persistency. previously, some older algorithm calculated all contacts in one go, so you can clear it here.
+			//m_dispatcher->clearManifold(m_btConvexTriangleCallback.m_manifoldPtr);
+
+			m_btConvexTriangleCallback.m_manifoldPtr->setBodies(convexBody,triBody);
+
+			concaveShape->processAllTriangles( &m_btConvexTriangleCallback,m_btConvexTriangleCallback.getAabbMin(),m_btConvexTriangleCallback.getAabbMax());
+			
+			resultOut->refreshContactPoints();
+	
+		}
+	
+	}
+
+}
+
+
+btScalar btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	(void)resultOut;
+	(void)dispatchInfo;
+	btCollisionObject* convexbody = m_isSwapped ? body1 : body0;
+	btCollisionObject* triBody = m_isSwapped ? body0 : body1;
+
+
+	//quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast)
+
+	//only perform CCD above a certain threshold, this prevents blocking on the long run
+	//because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame...
+	btScalar squareMot0 = (convexbody->getInterpolationWorldTransform().getOrigin() - convexbody->getWorldTransform().getOrigin()).length2();
+	if (squareMot0 < convexbody->getCcdSquareMotionThreshold())
+	{
+		return btScalar(1.);
+	}
+
+	//const btVector3& from = convexbody->m_worldTransform.getOrigin();
+	//btVector3 to = convexbody->m_interpolationWorldTransform.getOrigin();
+	//todo: only do if the motion exceeds the 'radius'
+
+	btTransform triInv = triBody->getWorldTransform().inverse();
+	btTransform convexFromLocal = triInv * convexbody->getWorldTransform();
+	btTransform convexToLocal = triInv * convexbody->getInterpolationWorldTransform();
+
+	struct LocalTriangleSphereCastCallback	: public btTriangleCallback
+	{
+		btTransform m_ccdSphereFromTrans;
+		btTransform m_ccdSphereToTrans;
+		btTransform	m_meshTransform;
+
+		btScalar	m_ccdSphereRadius;
+		btScalar	m_hitFraction;
+	
+
+		LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction)
+			:m_ccdSphereFromTrans(from),
+			m_ccdSphereToTrans(to),
+			m_ccdSphereRadius(ccdSphereRadius),
+			m_hitFraction(hitFraction)
+		{			
+		}
+		
+		
+		virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
+		{
+			(void)partId;
+			(void)triangleIndex;
+			//do a swept sphere for now
+			btTransform ident;
+			ident.setIdentity();
+			btConvexCast::CastResult castResult;
+			castResult.m_fraction = m_hitFraction;
+			btSphereShape	pointShape(m_ccdSphereRadius);
+			btTriangleShape	triShape(triangle[0],triangle[1],triangle[2]);
+			btVoronoiSimplexSolver	simplexSolver;
+			btSubsimplexConvexCast convexCaster(&pointShape,&triShape,&simplexSolver);
+			//GjkConvexCast	convexCaster(&pointShape,convexShape,&simplexSolver);
+			//ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
+			//local space?
+
+			if (convexCaster.calcTimeOfImpact(m_ccdSphereFromTrans,m_ccdSphereToTrans,
+				ident,ident,castResult))
+			{
+				if (m_hitFraction > castResult.m_fraction)
+					m_hitFraction = castResult.m_fraction;
+			}
+
+		}
+
+	};
+
+
+	
+
+	
+	if (triBody->getCollisionShape()->isConcave())
+	{
+		btVector3 rayAabbMin = convexFromLocal.getOrigin();
+		rayAabbMin.setMin(convexToLocal.getOrigin());
+		btVector3 rayAabbMax = convexFromLocal.getOrigin();
+		rayAabbMax.setMax(convexToLocal.getOrigin());
+		btScalar ccdRadius0 = convexbody->getCcdSweptSphereRadius();
+		rayAabbMin -= btVector3(ccdRadius0,ccdRadius0,ccdRadius0);
+		rayAabbMax += btVector3(ccdRadius0,ccdRadius0,ccdRadius0);
+
+		btScalar curHitFraction = btScalar(1.); //is this available?
+		LocalTriangleSphereCastCallback raycastCallback(convexFromLocal,convexToLocal,
+			convexbody->getCcdSweptSphereRadius(),curHitFraction);
+
+		raycastCallback.m_hitFraction = convexbody->getHitFraction();
+
+		btCollisionObject* concavebody = triBody;
+
+		btConcaveShape* triangleMesh = (btConcaveShape*) concavebody->getCollisionShape();
+		
+		if (triangleMesh)
+		{
+			triangleMesh->processAllTriangles(&raycastCallback,rayAabbMin,rayAabbMax);
+		}
+	
+
+
+		if (raycastCallback.m_hitFraction < convexbody->getHitFraction())
+		{
+			convexbody->setHitFraction( raycastCallback.m_hitFraction);
+			return raycastCallback.m_hitFraction;
+		}
+	}
+
+	return btScalar(1.);
+
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h	(revision 6952)
@@ -0,0 +1,116 @@
+/*
+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_CONCAVE_COLLISION_ALGORITHM_H
+#define CONVEX_CONCAVE_COLLISION_ALGORITHM_H
+
+#include "btActivatingCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
+#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+class btDispatcher;
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "btCollisionCreateFunc.h"
+
+///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called.
+class btConvexTriangleCallback : public btTriangleCallback
+{
+	btCollisionObject* m_convexBody;
+	btCollisionObject* m_triBody;
+
+	btVector3	m_aabbMin;
+	btVector3	m_aabbMax ;
+
+
+	btManifoldResult* m_resultOut;
+	btDispatcher*	m_dispatcher;
+	const btDispatcherInfo* m_dispatchInfoPtr;
+	btScalar m_collisionMarginTriangle;
+	
+public:
+int	m_triangleCount;
+	
+	btPersistentManifold*	m_manifoldPtr;
+
+	btConvexTriangleCallback(btDispatcher* dispatcher,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
+
+	void	setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+	virtual ~btConvexTriangleCallback();
+
+	virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex);
+	
+	void clearCache();
+
+	SIMD_FORCE_INLINE const btVector3& getAabbMin() const
+	{
+		return m_aabbMin;
+	}
+	SIMD_FORCE_INLINE const btVector3& getAabbMax() const
+	{
+		return m_aabbMax;
+	}
+
+};
+
+
+
+
+/// btConvexConcaveCollisionAlgorithm  supports collision between convex shapes and (concave) trianges meshes.
+class btConvexConcaveCollisionAlgorithm  : public btActivatingCollisionAlgorithm
+{
+
+	bool	m_isSwapped;
+
+	btConvexTriangleCallback m_btConvexTriangleCallback;
+
+
+
+public:
+
+	btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool isSwapped);
+
+	virtual ~btConvexConcaveCollisionAlgorithm();
+
+	virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+	btScalar	calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+	virtual	void	getAllContactManifolds(btManifoldArray&	manifoldArray);
+	
+	void	clearCache();
+
+	struct CreateFunc :public 	btCollisionAlgorithmCreateFunc
+	{
+		virtual	btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+		{
+			void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm));
+			return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0,body1,false);
+		}
+	};
+
+	struct SwappedCreateFunc :public 	btCollisionAlgorithmCreateFunc
+	{
+		virtual	btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+		{
+			void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm));
+			return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0,body1,true);
+		}
+	};
+
+};
+
+#endif //CONVEX_CONCAVE_COLLISION_ALGORITHM_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp	(revision 6952)
@@ -0,0 +1,396 @@
+/*
+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 "btConvexConvexAlgorithm.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/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"
+
+
+
+
+
+
+
+
+
+btConvexConvexAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface*			simplexSolver, btConvexPenetrationDepthSolver* pdSolver)
+{
+	m_numPerturbationIterations = 0;
+	m_minimumPointsPerturbationThreshold = 3;
+	m_simplexSolver = simplexSolver;
+	m_pdSolver = pdSolver;
+}
+
+btConvexConvexAlgorithm::CreateFunc::~CreateFunc() 
+{ 
+}
+
+btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold)
+: btActivatingCollisionAlgorithm(ci,body0,body1),
+m_simplexSolver(simplexSolver),
+m_pdSolver(pdSolver),
+m_ownManifold (false),
+m_manifoldPtr(mf),
+m_lowLevelOfDetail(false),
+#ifdef USE_SEPDISTANCE_UTIL2
+,m_sepDistance((static_cast<btConvexShape*>(body0->getCollisionShape()))->getAngularMotionDisc(),
+			  (static_cast<btConvexShape*>(body1->getCollisionShape()))->getAngularMotionDisc()),
+#endif
+m_numPerturbationIterations(numPerturbationIterations),
+m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
+{
+	(void)body0;
+	(void)body1;
+}
+
+
+
+
+btConvexConvexAlgorithm::~btConvexConvexAlgorithm()
+{
+	if (m_ownManifold)
+	{
+		if (m_manifoldPtr)
+			m_dispatcher->releaseManifold(m_manifoldPtr);
+	}
+}
+
+void	btConvexConvexAlgorithm ::setLowLevelOfDetail(bool useLowLevel)
+{
+	m_lowLevelOfDetail = useLowLevel;
+}
+
+
+struct btPerturbedContactResult : public btManifoldResult
+{
+	btManifoldResult* m_originalManifoldResult;
+	btTransform m_transformA;
+	btTransform m_transformB;
+	btTransform	m_unPerturbedTransform;
+	bool	m_perturbA;
+	btIDebugDraw*	m_debugDrawer;
+
+
+	btPerturbedContactResult(btManifoldResult* originalResult,const btTransform& transformA,const btTransform& transformB,const btTransform& unPerturbedTransform,bool perturbA,btIDebugDraw* debugDrawer)
+		:m_originalManifoldResult(originalResult),
+		m_transformA(transformA),
+		m_transformB(transformB),
+		m_perturbA(perturbA),
+		m_unPerturbedTransform(unPerturbedTransform),
+		m_debugDrawer(debugDrawer)
+	{
+	}
+	virtual ~ btPerturbedContactResult()
+	{
+	}
+
+	virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar orgDepth)
+	{
+		btVector3 endPt,startPt;
+		btScalar newDepth;
+		btVector3 newNormal;
+
+		if (m_perturbA)
+		{
+			btVector3 endPtOrg = pointInWorld + normalOnBInWorld*orgDepth;
+			endPt = (m_unPerturbedTransform*m_transformA.inverse())(endPtOrg);
+			newDepth = (endPt -  pointInWorld).dot(normalOnBInWorld);
+			startPt = endPt+normalOnBInWorld*newDepth;
+		} else
+		{
+			endPt = pointInWorld + normalOnBInWorld*orgDepth;
+			startPt = (m_unPerturbedTransform*m_transformB.inverse())(pointInWorld);
+			newDepth = (endPt -  startPt).dot(normalOnBInWorld);
+			
+		}
+
+//#define DEBUG_CONTACTS 1
+#ifdef DEBUG_CONTACTS
+		m_debugDrawer->drawLine(startPt,endPt,btVector3(1,0,0));
+		m_debugDrawer->drawSphere(startPt,0.05,btVector3(0,1,0));
+		m_debugDrawer->drawSphere(endPt,0.05,btVector3(0,0,1));
+#endif //DEBUG_CONTACTS
+
+		
+		m_originalManifoldResult->addContactPoint(normalOnBInWorld,startPt,newDepth);
+	}
+
+};
+
+extern btScalar gContactBreakingThreshold;
+
+//
+// Convex-Convex collision algorithm
+//
+void btConvexConvexAlgorithm ::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());
+
+#ifdef USE_SEPDISTANCE_UTIL2
+	m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform());
+	if (!dispatchInfo.m_useConvexConservativeDistanceUtil || m_sepDistance.getConservativeSeparatingDistance()<=0.f)
+#endif //USE_SEPDISTANCE_UTIL2
+
+	{
+
+	
+	btGjkPairDetector::ClosestPointInput input;
+
+	btGjkPairDetector	gjkPairDetector(min0,min1,m_simplexSolver,m_pdSolver);
+	//TODO: if (dispatchInfo.m_useContinuous)
+	gjkPairDetector.setMinkowskiA(min0);
+	gjkPairDetector.setMinkowskiB(min1);
+
+#ifdef USE_SEPDISTANCE_UTIL2
+	if (dispatchInfo.m_useConvexConservativeDistanceUtil)
+	{
+		input.m_maximumDistanceSquared = 1e30f;
+	} else
+#endif //USE_SEPDISTANCE_UTIL2
+	{
+		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);
+	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);
+	//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)
+	{
+		
+		int i;
+
+		bool perturbeA = true;
+		const btScalar angleLimit = 0.125f * SIMD_PI;
+		btScalar perturbeAngle;
+		btScalar radiusA = min0->getAngularMotionDisc();
+		btScalar radiusB = min1->getAngularMotionDisc();
+		if (radiusA < radiusB)
+		{
+			perturbeAngle = gContactBreakingThreshold /radiusA;
+			perturbeA = true;
+		} else
+		{
+			perturbeAngle = gContactBreakingThreshold / radiusB;
+			perturbeA = false;
+		}
+		if ( perturbeAngle > angleLimit ) 
+				perturbeAngle = angleLimit;
+
+		btTransform unPerturbedTransform;
+		if (perturbeA)
+		{
+			unPerturbedTransform = input.m_transformA;
+		} else
+		{
+			unPerturbedTransform = input.m_transformB;
+		}
+		
+		for ( i=0;i<m_numPerturbationIterations;i++)
+		{
+			btQuaternion perturbeRot(v0,perturbeAngle);
+			btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
+			btQuaternion rotq(sepNormalWorldSpace,iterationAngle);
+			
+			
+			if (perturbeA)
+			{
+				input.m_transformA.setBasis(  btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0->getWorldTransform().getBasis());
+				input.m_transformB = body1->getWorldTransform();
+#ifdef DEBUG_CONTACTS
+				dispatchInfo.m_debugDraw->drawTransform(input.m_transformA,10.0);
+#endif //DEBUG_CONTACTS
+			} else
+			{
+				input.m_transformA = body0->getWorldTransform();
+				input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1->getWorldTransform().getBasis());
+#ifdef DEBUG_CONTACTS
+				dispatchInfo.m_debugDraw->drawTransform(input.m_transformB,10.0);
+#endif
+			}
+			
+			btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw);
+			gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw);
+			
+			
+		}
+	}
+
+	
+
+#ifdef USE_SEPDISTANCE_UTIL2
+	if (dispatchInfo.m_useConvexConservativeDistanceUtil)
+	{
+		m_sepDistance.initSeparatingDistance(gjkPairDetector.getCachedSeparatingAxis(),sepDist,body0->getWorldTransform(),body1->getWorldTransform());
+	}
+#endif //USE_SEPDISTANCE_UTIL2
+
+
+	}
+
+	if (m_ownManifold)
+	{
+		resultOut->refreshContactPoints();
+	}
+
+}
+
+
+
+bool disableCcd = false;
+btScalar	btConvexConvexAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	(void)resultOut;
+	(void)dispatchInfo;
+	///Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold
+    
+	///Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold
+	///col0->m_worldTransform,
+	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;
+
+	if (disableCcd)
+		return btScalar(1.);
+
+
+	//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/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h	(revision 6952)
@@ -0,0 +1,108 @@
+/*
+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_CONVEX_ALGORITHM_H
+#define CONVEX_CONVEX_ALGORITHM_H
+
+#include "btActivatingCollisionAlgorithm.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+#include "btCollisionCreateFunc.h"
+#include "btCollisionDispatcher.h"
+#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil
+
+class btConvexPenetrationDepthSolver;
+
+///Enabling USE_SEPDISTANCE_UTIL2 requires 100% reliable distance computation. However, when using large size ratios GJK can be imprecise
+///so the distance is not conservative. In that case, enabling this USE_SEPDISTANCE_UTIL2 would result in failing/missing collisions.
+///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
+
+///The convexConvexAlgorithm collision algorithm implements time of impact, convex closest points and penetration depth calculations between two convex objects.
+///Multiple contact points are calculated by perturbing the orientation of the smallest object orthogonal to the separating normal.
+///This idea was described by Gino van den Bergen in this forum topic http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=4&t=288&p=888#p888
+class btConvexConvexAlgorithm : public btActivatingCollisionAlgorithm
+{
+#ifdef USE_SEPDISTANCE_UTIL2
+	btConvexSeparatingDistanceUtil	m_sepDistance;
+#endif
+	btSimplexSolverInterface*		m_simplexSolver;
+	btConvexPenetrationDepthSolver* m_pdSolver;
+
+	
+	bool	m_ownManifold;
+	btPersistentManifold*	m_manifoldPtr;
+	bool			m_lowLevelOfDetail;
+	
+	int m_numPerturbationIterations;
+	int m_minimumPointsPerturbationThreshold;
+
+
+	///cache separating vector to speedup collision detection
+	
+
+public:
+
+	btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold);
+
+
+	virtual ~btConvexConvexAlgorithm();
+
+	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(btConvexConvexAlgorithm));
+			return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0,body1,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
+		}
+	};
+
+
+};
+
+#endif //CONVEX_CONVEX_ALGORITHM_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp	(revision 6952)
@@ -0,0 +1,155 @@
+/*
+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 "btConvexPlaneCollisionAlgorithm.h"
+
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
+
+//#include <stdio.h>
+
+btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold)
+: btCollisionAlgorithm(ci),
+m_ownManifold(false),
+m_manifoldPtr(mf),
+m_isSwapped(isSwapped),
+m_numPerturbationIterations(numPerturbationIterations),
+m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold)
+{
+	btCollisionObject* convexObj = m_isSwapped? col1 : col0;
+	btCollisionObject* planeObj = m_isSwapped? col0 : col1;
+
+	if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObj,planeObj))
+	{
+		m_manifoldPtr = m_dispatcher->getNewManifold(convexObj,planeObj);
+		m_ownManifold = true;
+	}
+}
+
+
+btConvexPlaneCollisionAlgorithm::~btConvexPlaneCollisionAlgorithm()
+{
+	if (m_ownManifold)
+	{
+		if (m_manifoldPtr)
+			m_dispatcher->releaseManifold(m_manifoldPtr);
+	}
+}
+
+void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion& perturbeRot, btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+    btCollisionObject* convexObj = m_isSwapped? body1 : body0;
+	btCollisionObject* planeObj = m_isSwapped? body0: body1;
+
+	btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
+	btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
+
+    bool hasCollision = false;
+	const btVector3& planeNormal = planeShape->getPlaneNormal();
+	const btScalar& planeConstant = planeShape->getPlaneConstant();
+	
+	btTransform convexWorldTransform = convexObj->getWorldTransform();
+	btTransform convexInPlaneTrans;
+	convexInPlaneTrans= planeObj->getWorldTransform().inverse() * convexWorldTransform;
+	//now perturbe the convex-world transform
+	convexWorldTransform.getBasis()*=btMatrix3x3(perturbeRot);
+	btTransform planeInConvex;
+	planeInConvex= convexWorldTransform.inverse() * planeObj->getWorldTransform();
+	
+	btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal);
+
+	btVector3 vtxInPlane = convexInPlaneTrans(vtx);
+	btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant);
+
+	btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal;
+	btVector3 vtxInPlaneWorld = planeObj->getWorldTransform() * vtxInPlaneProjected;
+
+	hasCollision = distance < m_manifoldPtr->getContactBreakingThreshold();
+	resultOut->setPersistentManifold(m_manifoldPtr);
+	if (hasCollision)
+	{
+		/// report a contact. internally this will be kept persistent, and contact reduction is done
+		btVector3 normalOnSurfaceB = planeObj->getWorldTransform().getBasis() * planeNormal;
+		btVector3 pOnB = vtxInPlaneWorld;
+		resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance);
+	}
+}
+
+
+void btConvexPlaneCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	(void)dispatchInfo;
+	if (!m_manifoldPtr)
+		return;
+
+    btCollisionObject* convexObj = m_isSwapped? body1 : body0;
+	btCollisionObject* planeObj = m_isSwapped? body0: body1;
+
+	btConvexShape* convexShape = (btConvexShape*) convexObj->getCollisionShape();
+	btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObj->getCollisionShape();
+
+    bool hasCollision = false;
+	const btVector3& planeNormal = planeShape->getPlaneNormal();
+	const btScalar& planeConstant = planeShape->getPlaneConstant();
+
+	//first perform a collision query with the non-perturbated collision objects
+	{
+		btQuaternion rotq(0,0,0,1);
+		collideSingleContact(rotq,body0,body1,dispatchInfo,resultOut);
+	}
+
+	if (resultOut->getPersistentManifold()->getNumContacts()<m_minimumPointsPerturbationThreshold)
+	{
+		btVector3 v0,v1;
+		btPlaneSpace1(planeNormal,v0,v1);
+		//now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects
+
+		const btScalar angleLimit = 0.125f * SIMD_PI;
+		btScalar perturbeAngle;
+		btScalar radius = convexShape->getAngularMotionDisc();
+		perturbeAngle = gContactBreakingThreshold / radius;
+		if ( perturbeAngle > angleLimit ) 
+				perturbeAngle = angleLimit;
+
+		btQuaternion perturbeRot(v0,perturbeAngle);
+		for (int i=0;i<m_numPerturbationIterations;i++)
+		{
+			btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations));
+			btQuaternion rotq(planeNormal,iterationAngle);
+			collideSingleContact(rotq.inverse()*perturbeRot*rotq,body0,body1,dispatchInfo,resultOut);
+		}
+	}
+
+	if (m_ownManifold)
+	{
+		if (m_manifoldPtr->getNumContacts())
+		{
+			resultOut->refreshContactPoints();
+		}
+	}
+}
+
+btScalar btConvexPlaneCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	(void)resultOut;
+	(void)dispatchInfo;
+	(void)col0;
+	(void)col1;
+
+	//not yet
+	return btScalar(1.);
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h	(revision 6952)
@@ -0,0 +1,84 @@
+/*
+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_PLANE_COLLISION_ALGORITHM_H
+#define CONVEX_PLANE_COLLISION_ALGORITHM_H
+
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
+class btPersistentManifold;
+#include "btCollisionDispatcher.h"
+
+#include "LinearMath/btVector3.h"
+
+/// btSphereBoxCollisionAlgorithm  provides sphere-box collision detection.
+/// Other features are frame-coherency (persistent data) and collision response.
+class btConvexPlaneCollisionAlgorithm : public btCollisionAlgorithm
+{
+	bool		m_ownManifold;
+	btPersistentManifold*	m_manifoldPtr;
+	bool		m_isSwapped;
+	int			m_numPerturbationIterations;
+	int			m_minimumPointsPerturbationThreshold;
+
+public:
+
+	btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold);
+
+	virtual ~btConvexPlaneCollisionAlgorithm();
+
+	virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+	void collideSingleContact (const btQuaternion& perturbeRot, 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)
+	{
+		if (m_manifoldPtr && m_ownManifold)
+		{
+			manifoldArray.push_back(m_manifoldPtr);
+		}
+	}
+
+	struct CreateFunc :public 	btCollisionAlgorithmCreateFunc
+	{
+		int	m_numPerturbationIterations;
+		int m_minimumPointsPerturbationThreshold;
+			
+		CreateFunc() 
+			: m_numPerturbationIterations(3),
+			m_minimumPointsPerturbationThreshold(3)
+		{
+		}
+		
+		virtual	btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+		{
+			void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexPlaneCollisionAlgorithm));
+			if (!m_swapped)
+			{
+				return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,false,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
+			} else
+			{
+				return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0,body1,true,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold);
+			}
+		}
+	};
+
+};
+
+#endif //CONVEX_PLANE_COLLISION_ALGORITHM_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp	(revision 6952)
@@ -0,0 +1,297 @@
+/*
+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 "btDefaultCollisionConfiguration.h"
+
+#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h"
+#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
+#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h"
+#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
+#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
+#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+
+
+
+#include "LinearMath/btStackAlloc.h"
+#include "LinearMath/btPoolAllocator.h"
+
+
+
+
+
+btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo)
+//btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(btStackAlloc*	stackAlloc,btPoolAllocator*	persistentManifoldPool,btPoolAllocator*	collisionAlgorithmPool)
+{
+
+	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	
+	
+
+	//default CreationFunctions, filling the m_doubleDispatch table
+	mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc),16);
+	m_convexConvexCreateFunc = new(mem) btConvexConvexAlgorithm::CreateFunc(m_simplexSolver,m_pdSolver);
+	mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16);
+	m_convexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::CreateFunc;
+	mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16);
+	m_swappedConvexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::SwappedCreateFunc;
+	mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::CreateFunc),16);
+	m_compoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::CreateFunc;
+	mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::SwappedCreateFunc),16);
+	m_swappedCompoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::SwappedCreateFunc;
+	mem = btAlignedAlloc(sizeof(btEmptyAlgorithm::CreateFunc),16);
+	m_emptyCreateFunc = new(mem) btEmptyAlgorithm::CreateFunc;
+	
+	mem = btAlignedAlloc(sizeof(btSphereSphereCollisionAlgorithm::CreateFunc),16);
+	m_sphereSphereCF = new(mem) btSphereSphereCollisionAlgorithm::CreateFunc;
+#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
+	mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16);
+	m_sphereBoxCF = new(mem) btSphereBoxCollisionAlgorithm::CreateFunc;
+	mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16);
+	m_boxSphereCF = new (mem)btSphereBoxCollisionAlgorithm::CreateFunc;
+	m_boxSphereCF->m_swapped = true;
+#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
+
+	mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16);
+	m_sphereTriangleCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc;
+	mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16);
+	m_triangleSphereCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc;
+	m_triangleSphereCF->m_swapped = true;
+	
+	mem = btAlignedAlloc(sizeof(btBoxBoxCollisionAlgorithm::CreateFunc),16);
+	m_boxBoxCF = new(mem)btBoxBoxCollisionAlgorithm::CreateFunc;
+
+	//convex versus plane
+	mem = btAlignedAlloc (sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc),16);
+	m_convexPlaneCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc;
+	mem = btAlignedAlloc (sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc),16);
+	m_planeConvexCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc;
+	m_planeConvexCF->m_swapped = true;
+	
+	///calculate maximum element size, big enough to fit any collision algorithm in the memory pool
+	int maxSize = sizeof(btConvexConvexAlgorithm);
+	int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm);
+	int maxSize3 = sizeof(btCompoundCollisionAlgorithm);
+	int sl = sizeof(btConvexSeparatingDistanceUtil);
+	sl = sizeof(btGjkPairDetector);
+	int	collisionAlgorithmMaxElementSize = btMax(maxSize,maxSize2);
+	collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3);
+
+	if (constructionInfo.m_stackAlloc)
+	{
+		m_ownsStackAllocator = false;
+		this->m_stackAlloc = constructionInfo.m_stackAlloc;
+	} else
+	{
+		m_ownsStackAllocator = true;
+		void* mem = btAlignedAlloc(sizeof(btStackAlloc),16);
+		m_stackAlloc = new(mem)btStackAlloc(constructionInfo.m_defaultStackAllocatorSize);
+	}
+		
+	if (constructionInfo.m_persistentManifoldPool)
+	{
+		m_ownsPersistentManifoldPool = false;
+		m_persistentManifoldPool = constructionInfo.m_persistentManifoldPool;
+	} else
+	{
+		m_ownsPersistentManifoldPool = true;
+		void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
+		m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold),constructionInfo.m_defaultMaxPersistentManifoldPoolSize);
+	}
+	
+	if (constructionInfo.m_collisionAlgorithmPool)
+	{
+		m_ownsCollisionAlgorithmPool = false;
+		m_collisionAlgorithmPool = constructionInfo.m_collisionAlgorithmPool;
+	} else
+	{
+		m_ownsCollisionAlgorithmPool = true;
+		void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16);
+		m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize);
+	}
+
+
+}
+
+btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration()
+{
+	if (m_ownsStackAllocator)
+	{
+		m_stackAlloc->destroy();
+		m_stackAlloc->~btStackAlloc();
+		btAlignedFree(m_stackAlloc);
+	}
+	if (m_ownsCollisionAlgorithmPool)
+	{
+		m_collisionAlgorithmPool->~btPoolAllocator();
+		btAlignedFree(m_collisionAlgorithmPool);
+	}
+	if (m_ownsPersistentManifoldPool)
+	{
+		m_persistentManifoldPool->~btPoolAllocator();
+		btAlignedFree(m_persistentManifoldPool);
+	}
+
+	m_convexConvexCreateFunc->~btCollisionAlgorithmCreateFunc();
+	btAlignedFree(	m_convexConvexCreateFunc);
+
+	m_convexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
+	btAlignedFree( m_convexConcaveCreateFunc);
+	m_swappedConvexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc();
+	btAlignedFree( m_swappedConvexConcaveCreateFunc);
+
+	m_compoundCreateFunc->~btCollisionAlgorithmCreateFunc();
+	btAlignedFree( m_compoundCreateFunc);
+
+	m_swappedCompoundCreateFunc->~btCollisionAlgorithmCreateFunc();
+	btAlignedFree( m_swappedCompoundCreateFunc);
+
+	m_emptyCreateFunc->~btCollisionAlgorithmCreateFunc();
+	btAlignedFree( m_emptyCreateFunc);
+
+	m_sphereSphereCF->~btCollisionAlgorithmCreateFunc();
+	btAlignedFree( m_sphereSphereCF);
+
+#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
+	m_sphereBoxCF->~btCollisionAlgorithmCreateFunc();
+	btAlignedFree( m_sphereBoxCF);
+	m_boxSphereCF->~btCollisionAlgorithmCreateFunc();
+	btAlignedFree( m_boxSphereCF);
+#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
+
+	m_sphereTriangleCF->~btCollisionAlgorithmCreateFunc();
+	btAlignedFree( m_sphereTriangleCF);
+	m_triangleSphereCF->~btCollisionAlgorithmCreateFunc();
+	btAlignedFree( m_triangleSphereCF);
+	m_boxBoxCF->~btCollisionAlgorithmCreateFunc();
+	btAlignedFree( m_boxBoxCF);
+
+	m_convexPlaneCF->~btCollisionAlgorithmCreateFunc();
+	btAlignedFree( m_convexPlaneCF);
+	m_planeConvexCF->~btCollisionAlgorithmCreateFunc();
+	btAlignedFree( m_planeConvexCF);
+
+	m_simplexSolver->~btVoronoiSimplexSolver();
+	btAlignedFree(m_simplexSolver);
+
+	m_pdSolver->~btConvexPenetrationDepthSolver();
+	
+	btAlignedFree(m_pdSolver);
+
+
+}
+
+
+btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1)
+{
+
+
+
+	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
+	{
+		return	m_sphereSphereCF;
+	}
+#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
+	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==BOX_SHAPE_PROXYTYPE))
+	{
+		return	m_sphereBoxCF;
+	}
+
+	if ((proxyType0 == BOX_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
+	{
+		return	m_boxSphereCF;
+	}
+#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
+
+
+	if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE ) && (proxyType1==TRIANGLE_SHAPE_PROXYTYPE))
+	{
+		return	m_sphereTriangleCF;
+	}
+
+	if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE  ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE))
+	{
+		return	m_triangleSphereCF;
+	} 
+
+	if ((proxyType0 == BOX_SHAPE_PROXYTYPE) && (proxyType1 == BOX_SHAPE_PROXYTYPE))
+	{
+		return m_boxBoxCF;
+	}
+	
+	if (btBroadphaseProxy::isConvex(proxyType0) && (proxyType1 == STATIC_PLANE_PROXYTYPE))
+	{
+		return m_convexPlaneCF;
+	}
+
+	if (btBroadphaseProxy::isConvex(proxyType1) && (proxyType0 == STATIC_PLANE_PROXYTYPE))
+	{
+		return m_planeConvexCF;
+	}
+	
+
+
+	if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1))
+	{
+		return m_convexConvexCreateFunc;
+	}
+
+	if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConcave(proxyType1))
+	{
+		return m_convexConcaveCreateFunc;
+	}
+
+	if (btBroadphaseProxy::isConvex(proxyType1) && btBroadphaseProxy::isConcave(proxyType0))
+	{
+		return m_swappedConvexConcaveCreateFunc;
+	}
+
+	if (btBroadphaseProxy::isCompound(proxyType0))
+	{
+		return m_compoundCreateFunc;
+	} else
+	{
+		if (btBroadphaseProxy::isCompound(proxyType1))
+		{
+			return m_swappedCompoundCreateFunc;
+		}
+	}
+
+	//failed to find an algorithm
+	return m_emptyCreateFunc;
+}
+
+void btDefaultCollisionConfiguration::setConvexConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold)
+{
+	btConvexConvexAlgorithm::CreateFunc* convexConvex = (btConvexConvexAlgorithm::CreateFunc*) m_convexConvexCreateFunc;
+	convexConvex->m_numPerturbationIterations = numPerturbationIterations;
+	convexConvex->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold;
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h	(revision 6952)
@@ -0,0 +1,126 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_DEFAULT_COLLISION_CONFIGURATION
+#define BT_DEFAULT_COLLISION_CONFIGURATION
+
+#include "btCollisionConfiguration.h"
+class btVoronoiSimplexSolver;
+class btConvexPenetrationDepthSolver;
+
+struct	btDefaultCollisionConstructionInfo
+{
+	btStackAlloc*		m_stackAlloc;
+	btPoolAllocator*	m_persistentManifoldPool;
+	btPoolAllocator*	m_collisionAlgorithmPool;
+	int					m_defaultMaxPersistentManifoldPoolSize;
+	int					m_defaultMaxCollisionAlgorithmPoolSize;
+	int					m_defaultStackAllocatorSize;
+
+	btDefaultCollisionConstructionInfo()
+		:m_stackAlloc(0),
+		m_persistentManifoldPool(0),
+		m_collisionAlgorithmPool(0),
+		m_defaultMaxPersistentManifoldPoolSize(4096),
+		m_defaultMaxCollisionAlgorithmPoolSize(4096),
+		m_defaultStackAllocatorSize(0)
+	{
+	}
+};
+
+
+
+///btCollisionConfiguration allows to configure Bullet collision detection
+///stack allocator, pool memory allocators
+///@todo: describe the meaning
+class	btDefaultCollisionConfiguration : public btCollisionConfiguration
+{
+
+protected:
+
+	int	m_persistentManifoldPoolSize;
+	
+	btStackAlloc*	m_stackAlloc;
+	bool	m_ownsStackAllocator;
+
+	btPoolAllocator*	m_persistentManifoldPool;
+	bool	m_ownsPersistentManifoldPool;
+
+
+	btPoolAllocator*	m_collisionAlgorithmPool;
+	bool	m_ownsCollisionAlgorithmPool;
+
+	//default simplex/penetration depth solvers
+	btVoronoiSimplexSolver*	m_simplexSolver;
+	btConvexPenetrationDepthSolver*	m_pdSolver;
+	
+	//default CreationFunctions, filling the m_doubleDispatch table
+	btCollisionAlgorithmCreateFunc*	m_convexConvexCreateFunc;
+	btCollisionAlgorithmCreateFunc*	m_convexConcaveCreateFunc;
+	btCollisionAlgorithmCreateFunc*	m_swappedConvexConcaveCreateFunc;
+	btCollisionAlgorithmCreateFunc*	m_compoundCreateFunc;
+	btCollisionAlgorithmCreateFunc*	m_swappedCompoundCreateFunc;
+	btCollisionAlgorithmCreateFunc* m_emptyCreateFunc;
+	btCollisionAlgorithmCreateFunc* m_sphereSphereCF;
+#ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM
+	btCollisionAlgorithmCreateFunc* m_sphereBoxCF;
+	btCollisionAlgorithmCreateFunc* m_boxSphereCF;
+#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM
+
+	btCollisionAlgorithmCreateFunc* m_boxBoxCF;
+	btCollisionAlgorithmCreateFunc*	m_sphereTriangleCF;
+	btCollisionAlgorithmCreateFunc*	m_triangleSphereCF;
+	btCollisionAlgorithmCreateFunc*	m_planeConvexCF;
+	btCollisionAlgorithmCreateFunc*	m_convexPlaneCF;
+	
+public:
+
+
+	btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo = btDefaultCollisionConstructionInfo());
+
+	virtual ~btDefaultCollisionConfiguration();
+
+		///memory pools
+	virtual btPoolAllocator* getPersistentManifoldPool()
+	{
+		return m_persistentManifoldPool;
+	}
+
+	virtual btPoolAllocator* getCollisionAlgorithmPool()
+	{
+		return m_collisionAlgorithmPool;
+	}
+
+	virtual btStackAlloc*	getStackAllocator()
+	{
+		return m_stackAlloc;
+	}
+
+
+	virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1);
+
+	///Use this method to allow to generate multiple contact points between at once, between two objects using the generic convex-convex algorithm.
+	///By default, this feature is disabled for best performance.
+	///@param numPerturbationIterations controls the number of collision queries. Set it to zero to disable the feature.
+	///@param minimumPointsPerturbationThreshold is the minimum number of points in the contact cache, above which the feature is disabled
+	///3 is a good value for both params, if you want to enable the feature. This is because the default contact cache contains a maximum of 4 points, and one collision query at the unperturbed orientation is performed first.
+	///See Bullet/Demos/CollisionDemo for an example how this feature gathers multiple points.
+	///@todo we could add a per-object setting of those parameters, for level-of-detail collision detection.
+	void	setConvexConvexMultipointIterations(int numPerturbationIterations=3, int minimumPointsPerturbationThreshold = 3);
+
+};
+
+#endif //BT_DEFAULT_COLLISION_CONFIGURATION
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp	(revision 6952)
@@ -0,0 +1,34 @@
+/*
+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 "btEmptyCollisionAlgorithm.h"
+
+
+
+btEmptyAlgorithm::btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& ci)
+	: btCollisionAlgorithm(ci)
+{
+}
+
+void btEmptyAlgorithm::processCollision (btCollisionObject* ,btCollisionObject* ,const btDispatcherInfo& ,btManifoldResult* )
+{
+}
+
+btScalar btEmptyAlgorithm::calculateTimeOfImpact(btCollisionObject* ,btCollisionObject* ,const btDispatcherInfo& ,btManifoldResult* )
+{
+	return btScalar(1.);
+}
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h	(revision 6952)
@@ -0,0 +1,54 @@
+/*
+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 EMPTY_ALGORITH
+#define EMPTY_ALGORITH
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "btCollisionCreateFunc.h"
+#include "btCollisionDispatcher.h"
+
+#define ATTRIBUTE_ALIGNED(a)
+
+///EmptyAlgorithm is a stub for unsupported collision pairs.
+///The dispatcher can dispatch a persistent btEmptyAlgorithm to avoid a search every frame.
+class btEmptyAlgorithm : public btCollisionAlgorithm
+{
+
+public:
+	
+	btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& 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);
+
+	virtual	void	getAllContactManifolds(btManifoldArray&	manifoldArray)
+	{
+	}
+
+	struct CreateFunc :public 	btCollisionAlgorithmCreateFunc
+	{
+		virtual	btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+		{
+			(void)body0;
+			(void)body1;
+			void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btEmptyAlgorithm));
+			return new(mem) btEmptyAlgorithm(ci);
+		}
+	};
+
+} ATTRIBUTE_ALIGNED(16);
+
+#endif //EMPTY_ALGORITH
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btGhostObject.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btGhostObject.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btGhostObject.cpp	(revision 6952)
@@ -0,0 +1,171 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.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 "btGhostObject.h"
+#include "btCollisionWorld.h"
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "LinearMath/btAabbUtil2.h"
+
+btGhostObject::btGhostObject()
+{
+	m_internalType = CO_GHOST_OBJECT;
+}
+
+btGhostObject::~btGhostObject()
+{
+	///btGhostObject should have been removed from the world, so no overlapping objects
+	btAssert(!m_overlappingObjects.size());
+}
+
+
+void btGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy)
+{
+	btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
+	btAssert(otherObject);
+	///if this linearSearch becomes too slow (too many overlapping objects) we should add a more appropriate data structure
+	int index = m_overlappingObjects.findLinearSearch(otherObject);
+	if (index==m_overlappingObjects.size())
+	{
+		//not found
+		m_overlappingObjects.push_back(otherObject);
+	}
+}
+
+void btGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy)
+{
+	btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
+	btAssert(otherObject);
+	int index = m_overlappingObjects.findLinearSearch(otherObject);
+	if (index<m_overlappingObjects.size())
+	{
+		m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
+		m_overlappingObjects.pop_back();
+	}
+}
+
+
+btPairCachingGhostObject::btPairCachingGhostObject()
+{
+	m_hashPairCache = new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache();
+}
+
+btPairCachingGhostObject::~btPairCachingGhostObject()
+{
+	m_hashPairCache->~btHashedOverlappingPairCache();
+	btAlignedFree( m_hashPairCache );
+}
+
+void btPairCachingGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy)
+{
+	btBroadphaseProxy*actualThisProxy = thisProxy ? thisProxy : getBroadphaseHandle();
+	btAssert(actualThisProxy);
+
+	btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
+	btAssert(otherObject);
+	int index = m_overlappingObjects.findLinearSearch(otherObject);
+	if (index==m_overlappingObjects.size())
+	{
+		m_overlappingObjects.push_back(otherObject);
+		m_hashPairCache->addOverlappingPair(actualThisProxy,otherProxy);
+	}
+}
+
+void btPairCachingGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy1)
+{
+	btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
+	btBroadphaseProxy* actualThisProxy = thisProxy1 ? thisProxy1 : getBroadphaseHandle();
+	btAssert(actualThisProxy);
+
+	btAssert(otherObject);
+	int index = m_overlappingObjects.findLinearSearch(otherObject);
+	if (index<m_overlappingObjects.size())
+	{
+		m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size()-1];
+		m_overlappingObjects.pop_back();
+		m_hashPairCache->removeOverlappingPair(actualThisProxy,otherProxy,dispatcher);
+	}
+}
+
+
+void	btGhostObject::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const
+{
+	btTransform	convexFromTrans,convexToTrans;
+	convexFromTrans = convexFromWorld;
+	convexToTrans = convexToWorld;
+	btVector3 castShapeAabbMin, castShapeAabbMax;
+	/* Compute AABB that encompasses angular movement */
+	{
+		btVector3 linVel, angVel;
+		btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel);
+		btTransform R;
+		R.setIdentity ();
+		R.setRotation (convexFromTrans.getRotation());
+		castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax);
+	}
+
+	/// go over all objects, and if the ray intersects their aabb + cast shape aabb,
+	// do a ray-shape query using convexCaster (CCD)
+	int i;
+	for (i=0;i<m_overlappingObjects.size();i++)
+	{
+		btCollisionObject*	collisionObject= m_overlappingObjects[i];
+		//only perform raycast if filterMask matches
+		if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) {
+			//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
+			btVector3 collisionObjectAabbMin,collisionObjectAabbMax;
+			collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax);
+			AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax);
+			btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing
+			btVector3 hitNormal;
+			if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal))
+			{
+				btCollisionWorld::objectQuerySingle(castShape, convexFromTrans,convexToTrans,
+					collisionObject,
+						collisionObject->getCollisionShape(),
+						collisionObject->getWorldTransform(),
+						resultCallback,
+						allowedCcdPenetration);
+			}
+		}
+	}
+
+}
+
+void	btGhostObject::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const
+{
+	btTransform rayFromTrans;
+	rayFromTrans.setIdentity();
+	rayFromTrans.setOrigin(rayFromWorld);
+	btTransform  rayToTrans;
+	rayToTrans.setIdentity();
+	rayToTrans.setOrigin(rayToWorld);
+
+
+	int i;
+	for (i=0;i<m_overlappingObjects.size();i++)
+	{
+		btCollisionObject*	collisionObject= m_overlappingObjects[i];
+		//only perform raycast if filterMask matches
+		if(resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 
+		{
+			btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,
+							collisionObject,
+								collisionObject->getCollisionShape(),
+								collisionObject->getWorldTransform(),
+								resultCallback);
+		}
+	}
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btGhostObject.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btGhostObject.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btGhostObject.h	(revision 6952)
@@ -0,0 +1,174 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.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 BT_GHOST_OBJECT_H
+#define BT_GHOST_OBJECT_H
+
+
+#include "btCollisionObject.h"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h"
+#include "LinearMath/btAlignedAllocator.h"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
+#include "btCollisionWorld.h"
+
+class btConvexShape;
+
+class btDispatcher;
+
+///The btGhostObject can keep track of all objects that are overlapping
+///By default, this overlap is based on the AABB
+///This is useful for creating a character controller, collision sensors/triggers, explosions etc.
+///We plan on adding rayTest and other queries for the btGhostObject
+ATTRIBUTE_ALIGNED16(class) btGhostObject : public btCollisionObject
+{
+protected:
+
+	btAlignedObjectArray<btCollisionObject*> m_overlappingObjects;
+
+public:
+
+	btGhostObject();
+
+	virtual ~btGhostObject();
+
+	void	convexSweepTest(const class btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = 0.f) const;
+
+	void	rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const; 
+
+	///this method is mainly for expert/internal use only.
+	virtual void	addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy=0);
+	///this method is mainly for expert/internal use only.
+	virtual void	removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy=0);
+
+	int	getNumOverlappingObjects() const
+	{
+		return m_overlappingObjects.size();
+	}
+
+	btCollisionObject*	getOverlappingObject(int index)
+	{
+		return m_overlappingObjects[index];
+	}
+
+	const btCollisionObject*	getOverlappingObject(int index) const
+	{
+		return m_overlappingObjects[index];
+	}
+
+	btAlignedObjectArray<btCollisionObject*>&	getOverlappingPairs()
+	{
+		return m_overlappingObjects;
+	}
+
+	const btAlignedObjectArray<btCollisionObject*>	getOverlappingPairs() const
+	{
+		return m_overlappingObjects;
+	}
+
+	//
+	// internal cast
+	//
+
+	static const btGhostObject*	upcast(const btCollisionObject* colObj)
+	{
+		if (colObj->getInternalType()==CO_GHOST_OBJECT)
+			return (const btGhostObject*)colObj;
+		return 0;
+	}
+	static btGhostObject*			upcast(btCollisionObject* colObj)
+	{
+		if (colObj->getInternalType()==CO_GHOST_OBJECT)
+			return (btGhostObject*)colObj;
+		return 0;
+	}
+
+};
+
+class	btPairCachingGhostObject : public btGhostObject
+{
+	btHashedOverlappingPairCache*	m_hashPairCache;
+
+public:
+
+	btPairCachingGhostObject();
+
+	virtual ~btPairCachingGhostObject();
+
+	///this method is mainly for expert/internal use only.
+	virtual void	addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy=0);
+
+	virtual void	removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy=0);
+
+	btHashedOverlappingPairCache*	getOverlappingPairCache()
+	{
+		return m_hashPairCache;
+	}
+
+};
+
+
+
+///The btGhostPairCallback interfaces and forwards adding and removal of overlapping pairs from the btBroadphaseInterface to btGhostObject.
+class btGhostPairCallback : public btOverlappingPairCallback
+{
+	
+public:
+	btGhostPairCallback()
+	{
+	}
+
+	virtual ~btGhostPairCallback()
+	{
+		
+	}
+
+	virtual btBroadphasePair*	addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1)
+	{
+		btCollisionObject* colObj0 = (btCollisionObject*) proxy0->m_clientObject;
+		btCollisionObject* colObj1 = (btCollisionObject*) proxy1->m_clientObject;
+		btGhostObject* ghost0 = 		btGhostObject::upcast(colObj0);
+		btGhostObject* ghost1 = 		btGhostObject::upcast(colObj1);
+		if (ghost0)
+			ghost0->addOverlappingObjectInternal(proxy1, proxy0);
+		if (ghost1)
+			ghost1->addOverlappingObjectInternal(proxy0, proxy1);
+		return 0;
+	}
+
+	virtual void*	removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher)
+	{
+		btCollisionObject* colObj0 = (btCollisionObject*) proxy0->m_clientObject;
+		btCollisionObject* colObj1 = (btCollisionObject*) proxy1->m_clientObject;
+		btGhostObject* ghost0 = 		btGhostObject::upcast(colObj0);
+		btGhostObject* ghost1 = 		btGhostObject::upcast(colObj1);
+		if (ghost0)
+			ghost0->removeOverlappingObjectInternal(proxy1,dispatcher,proxy0);
+		if (ghost1)
+			ghost1->removeOverlappingObjectInternal(proxy0,dispatcher,proxy1);
+		return 0;
+	}
+
+	virtual void	removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0,btDispatcher* dispatcher)
+	{
+		btAssert(0);
+		//need to keep track of all ghost objects and call them here
+		//m_hashPairCache->removeOverlappingPairsContainingProxy(proxy0,dispatcher);
+	}
+
+	
+
+};
+
+#endif
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btManifoldResult.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btManifoldResult.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btManifoldResult.cpp	(revision 6952)
@@ -0,0 +1,119 @@
+/*
+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 "btManifoldResult.h"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+
+
+///This is to allow MaterialCombiner/Custom Friction/Restitution values
+ContactAddedCallback		gContactAddedCallback=0;
+
+///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback;
+inline btScalar	calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1)
+{
+	btScalar friction = body0->getFriction() * body1->getFriction();
+
+	const btScalar MAX_FRICTION  = btScalar(10.);
+	if (friction < -MAX_FRICTION)
+		friction = -MAX_FRICTION;
+	if (friction > MAX_FRICTION)
+		friction = MAX_FRICTION;
+	return friction;
+
+}
+
+inline btScalar	calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1)
+{
+	return body0->getRestitution() * body1->getRestitution();
+}
+
+
+
+btManifoldResult::btManifoldResult(btCollisionObject* body0,btCollisionObject* body1)
+		:m_manifoldPtr(0),
+		m_body0(body0),
+		m_body1(body1)
+{
+	m_rootTransA = body0->getWorldTransform();
+	m_rootTransB = body1->getWorldTransform();
+}
+
+
+void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
+{
+	btAssert(m_manifoldPtr);
+	//order in manifold needs to match
+	
+	if (depth > m_manifoldPtr->getContactBreakingThreshold())
+		return;
+
+	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;
+	
+	int insertIndex = m_manifoldPtr->getCacheEntry(newPt);
+
+	newPt.m_combinedFriction = calculateCombinedFriction(m_body0,m_body1);
+	newPt.m_combinedRestitution = calculateCombinedRestitution(m_body0,m_body1);
+
+   //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;
+	//printf("depth=%f\n",depth);
+	///@todo, check this for any side effects
+	if (insertIndex >= 0)
+	{
+		//const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex);
+		m_manifoldPtr->replaceContactPoint(newPt,insertIndex);
+	} else
+	{
+		insertIndex = m_manifoldPtr->addManifoldPoint(newPt);
+	}
+	
+	//User can override friction and/or restitution
+	if (gContactAddedCallback &&
+		//and if either of the two bodies requires custom material
+		 ((m_body0->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) ||
+		   (m_body1->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK)))
+	{
+		//experimental feature info, for per-triangle material etc.
+		btCollisionObject* obj0 = isSwapped? m_body1 : m_body0;
+		btCollisionObject* obj1 = isSwapped? m_body0 : m_body1;
+		(*gContactAddedCallback)(m_manifoldPtr->getContactPoint(insertIndex),obj0,m_partId0,m_index0,obj1,m_partId1,m_index1);
+	}
+
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btManifoldResult.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btManifoldResult.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btManifoldResult.h	(revision 6952)
@@ -0,0 +1,105 @@
+/*
+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 MANIFOLD_RESULT_H
+#define MANIFOLD_RESULT_H
+
+class btCollisionObject;
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+class btManifoldPoint;
+
+#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
+
+#include "LinearMath/btTransform.h"
+
+typedef bool (*ContactAddedCallback)(btManifoldPoint& cp,	const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1);
+extern ContactAddedCallback		gContactAddedCallback;
+
+
+
+///btManifoldResult is a helper class to manage  contact results.
+class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result
+{
+	btPersistentManifold* m_manifoldPtr;
+
+	//we need this for compounds
+	btTransform	m_rootTransA;
+	btTransform	m_rootTransB;
+
+	btCollisionObject* m_body0;
+	btCollisionObject* m_body1;
+	int	m_partId0;
+	int m_partId1;
+	int m_index0;
+	int m_index1;
+	
+
+public:
+
+	btManifoldResult()
+	{
+	}
+
+	btManifoldResult(btCollisionObject* body0,btCollisionObject* body1);
+
+	virtual ~btManifoldResult() {};
+
+	void	setPersistentManifold(btPersistentManifold* manifoldPtr)
+	{
+		m_manifoldPtr = manifoldPtr;
+	}
+
+	const btPersistentManifold*	getPersistentManifold() const
+	{
+		return m_manifoldPtr;
+	}
+	btPersistentManifold*	getPersistentManifold()
+	{
+		return m_manifoldPtr;
+	}
+
+	virtual void setShapeIdentifiers(int partId0,int index0,	int partId1,int index1)
+	{
+			m_partId0=partId0;
+			m_partId1=partId1;
+			m_index0=index0;
+			m_index1=index1;		
+	}
+
+
+	virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth);
+
+	SIMD_FORCE_INLINE	void refreshContactPoints()
+	{
+		btAssert(m_manifoldPtr);
+		if (!m_manifoldPtr->getNumContacts())
+			return;
+
+		bool isSwapped = m_manifoldPtr->getBody0() != m_body0;
+
+		if (isSwapped)
+		{
+			m_manifoldPtr->refreshContactPoints(m_rootTransB,m_rootTransA);
+		} else
+		{
+			m_manifoldPtr->refreshContactPoints(m_rootTransA,m_rootTransB);
+		}
+	}
+
+
+};
+
+#endif //MANIFOLD_RESULT_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp	(revision 6952)
@@ -0,0 +1,390 @@
+/*
+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 "LinearMath/btScalar.h"
+#include "btSimulationIslandManager.h"
+#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
+
+//#include <stdio.h>
+#include "LinearMath/btQuickprof.h"
+
+btSimulationIslandManager::btSimulationIslandManager():
+m_splitIslands(true)
+{
+}
+
+btSimulationIslandManager::~btSimulationIslandManager()
+{
+}
+
+
+void btSimulationIslandManager::initUnionFind(int n)
+{
+		m_unionFind.reset(n);
+}
+		
+
+void btSimulationIslandManager::findUnions(btDispatcher* /* dispatcher */,btCollisionWorld* colWorld)
+{
+	
+	{
+		
+		for (int i=0;i<colWorld->getPairCache()->getNumOverlappingPairs();i++)
+		{
+			btBroadphasePair* pairPtr = colWorld->getPairCache()->getOverlappingPairArrayPtr();
+			const btBroadphasePair& collisionPair = pairPtr[i];
+			btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject;
+			btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject;
+
+			if (((colObj0) && ((colObj0)->mergesSimulationIslands())) &&
+				((colObj1) && ((colObj1)->mergesSimulationIslands())))
+			{
+
+				m_unionFind.unite((colObj0)->getIslandTag(),
+					(colObj1)->getIslandTag());
+			}
+		}
+	}
+}
+
+
+void	btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher)
+{
+	
+	initUnionFind( int (colWorld->getCollisionObjectArray().size()));
+	
+	// put the index into m_controllers into m_tag	
+	{
+		
+		int index = 0;
+		int i;
+		for (i=0;i<colWorld->getCollisionObjectArray().size(); i++)
+		{
+			btCollisionObject*	collisionObject= colWorld->getCollisionObjectArray()[i];
+			collisionObject->setIslandTag(index);
+			collisionObject->setCompanionId(-1);
+			collisionObject->setHitFraction(btScalar(1.));
+			index++;
+			
+		}
+	}
+	// do the union find
+	
+	findUnions(dispatcher,colWorld);
+	
+
+	
+}
+
+
+
+
+void	btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* colWorld)
+{
+	// put the islandId ('find' value) into m_tag	
+	{
+		
+		
+		int index = 0;
+		int i;
+		for (i=0;i<colWorld->getCollisionObjectArray().size();i++)
+		{
+			btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i];
+			if (!collisionObject->isStaticOrKinematicObject())
+			{
+				collisionObject->setIslandTag( m_unionFind.find(index) );
+				collisionObject->setCompanionId(-1);
+			} else
+			{
+				collisionObject->setIslandTag(-1);
+				collisionObject->setCompanionId(-2);
+			}
+			index++;
+		}
+	}
+}
+
+inline	int	getIslandId(const btPersistentManifold* lhs)
+{
+	int islandId;
+	const btCollisionObject* rcolObj0 = static_cast<const btCollisionObject*>(lhs->getBody0());
+	const btCollisionObject* rcolObj1 = static_cast<const btCollisionObject*>(lhs->getBody1());
+	islandId= rcolObj0->getIslandTag()>=0?rcolObj0->getIslandTag():rcolObj1->getIslandTag();
+	return islandId;
+
+}
+
+
+
+/// function object that routes calls to operator<
+class btPersistentManifoldSortPredicate
+{
+	public:
+
+		SIMD_FORCE_INLINE bool operator() ( const btPersistentManifold* lhs, const btPersistentManifold* rhs )
+		{
+			return getIslandId(lhs) < getIslandId(rhs);
+		}
+};
+
+
+void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld)
+{
+
+	BT_PROFILE("islandUnionFindAndQuickSort");
+	
+	btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray();
+
+	m_islandmanifold.resize(0);
+
+	//we are going to sort the unionfind array, and store the element id in the size
+	//afterwards, we clean unionfind, to make sure no-one uses it anymore
+	
+	getUnionFind().sortIslands();
+	int numElem = getUnionFind().getNumElements();
+
+	int endIslandIndex=1;
+	int startIslandIndex;
+
+
+	//update the sleeping state for bodies, if all are sleeping
+	for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
+	{
+		int islandId = getUnionFind().getElement(startIslandIndex).m_id;
+		for (endIslandIndex = startIslandIndex+1;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
+		{
+		}
+
+		//int numSleeping = 0;
+
+		bool allSleeping = true;
+
+		int idx;
+		for (idx=startIslandIndex;idx<endIslandIndex;idx++)
+		{
+			int i = getUnionFind().getElement(idx).m_sz;
+
+			btCollisionObject* colObj0 = collisionObjects[i];
+			if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
+			{
+//				printf("error in island management\n");
+			}
+
+			btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
+			if (colObj0->getIslandTag() == islandId)
+			{
+				if (colObj0->getActivationState()== ACTIVE_TAG)
+				{
+					allSleeping = false;
+				}
+				if (colObj0->getActivationState()== DISABLE_DEACTIVATION)
+				{
+					allSleeping = false;
+				}
+			}
+		}
+			
+
+		if (allSleeping)
+		{
+			int idx;
+			for (idx=startIslandIndex;idx<endIslandIndex;idx++)
+			{
+				int i = getUnionFind().getElement(idx).m_sz;
+				btCollisionObject* colObj0 = collisionObjects[i];
+				if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
+				{
+//					printf("error in island management\n");
+				}
+
+				btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
+
+				if (colObj0->getIslandTag() == islandId)
+				{
+					colObj0->setActivationState( ISLAND_SLEEPING );
+				}
+			}
+		} else
+		{
+
+			int idx;
+			for (idx=startIslandIndex;idx<endIslandIndex;idx++)
+			{
+				int i = getUnionFind().getElement(idx).m_sz;
+
+				btCollisionObject* colObj0 = collisionObjects[i];
+				if ((colObj0->getIslandTag() != islandId) && (colObj0->getIslandTag() != -1))
+				{
+//					printf("error in island management\n");
+				}
+
+				btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1));
+
+				if (colObj0->getIslandTag() == islandId)
+				{
+					if ( colObj0->getActivationState() == ISLAND_SLEEPING)
+					{
+						colObj0->setActivationState( WANTS_DEACTIVATION);
+						colObj0->setDeactivationTime(0.f);
+					}
+				}
+			}
+		}
+	}
+
+	
+	int i;
+	int maxNumManifolds = dispatcher->getNumManifolds();
+
+//#define SPLIT_ISLANDS 1
+//#ifdef SPLIT_ISLANDS
+
+	
+//#endif //SPLIT_ISLANDS
+
+	
+	for (i=0;i<maxNumManifolds ;i++)
+	{
+		 btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i);
+		 
+		 btCollisionObject* colObj0 = static_cast<btCollisionObject*>(manifold->getBody0());
+		 btCollisionObject* colObj1 = static_cast<btCollisionObject*>(manifold->getBody1());
+		
+		 ///@todo: check sleeping conditions!
+		 if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) ||
+			((colObj1) && colObj1->getActivationState() != ISLAND_SLEEPING))
+		{
+		
+			//kinematic objects don't merge islands, but wake up all connected objects
+			if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING)
+			{
+				colObj1->activate();
+			}
+			if (colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING)
+			{
+				colObj0->activate();
+			}
+			if(m_splitIslands)
+			{ 
+				//filtering for response
+				if (dispatcher->needsResponse(colObj0,colObj1))
+					m_islandmanifold.push_back(manifold);
+			}
+		}
+	}
+}
+
+
+
+///@todo: this is random access, it can be walked 'cache friendly'!
+void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld, IslandCallback* callback)
+{
+	btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray();
+
+	buildIslands(dispatcher,collisionWorld);
+
+	int endIslandIndex=1;
+	int startIslandIndex;
+	int numElem = getUnionFind().getNumElements();
+
+	BT_PROFILE("processIslands");
+
+	if(!m_splitIslands)
+	{
+		btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer();
+		int maxNumManifolds = dispatcher->getNumManifolds();
+		callback->ProcessIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1);
+	}
+	else
+	{
+		// Sort manifolds, based on islands
+		// Sort the vector using predicate and std::sort
+		//std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate);
+
+		int numManifolds = int (m_islandmanifold.size());
+
+		//we should do radix sort, it it much faster (O(n) instead of O (n log2(n))
+		m_islandmanifold.quickSort(btPersistentManifoldSortPredicate());
+
+		//now process all active islands (sets of manifolds for now)
+
+		int startManifoldIndex = 0;
+		int endManifoldIndex = 1;
+
+		//int islandId;
+
+		
+
+	//	printf("Start Islands\n");
+
+		//traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated
+		for ( startIslandIndex=0;startIslandIndex<numElem;startIslandIndex = endIslandIndex)
+		{
+			int islandId = getUnionFind().getElement(startIslandIndex).m_id;
+
+
+			   bool islandSleeping = false;
+	                
+					for (endIslandIndex = startIslandIndex;(endIslandIndex<numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId);endIslandIndex++)
+					{
+							int i = getUnionFind().getElement(endIslandIndex).m_sz;
+							btCollisionObject* colObj0 = collisionObjects[i];
+							m_islandBodies.push_back(colObj0);
+							if (!colObj0->isActive())
+									islandSleeping = true;
+					}
+	                
+
+			//find the accompanying contact manifold for this islandId
+			int numIslandManifolds = 0;
+			btPersistentManifold** startManifold = 0;
+
+			if (startManifoldIndex<numManifolds)
+			{
+				int curIslandId = getIslandId(m_islandmanifold[startManifoldIndex]);
+				if (curIslandId == islandId)
+				{
+					startManifold = &m_islandmanifold[startManifoldIndex];
+				
+					for (endManifoldIndex = startManifoldIndex+1;(endManifoldIndex<numManifolds) && (islandId == getIslandId(m_islandmanifold[endManifoldIndex]));endManifoldIndex++)
+					{
+
+					}
+					/// Process the actual simulation, only if not sleeping/deactivated
+					numIslandManifolds = endManifoldIndex-startManifoldIndex;
+				}
+
+			}
+
+			if (!islandSleeping)
+			{
+				callback->ProcessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId);
+	//			printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds);
+			}
+			
+			if (numIslandManifolds)
+			{
+				startManifoldIndex = endManifoldIndex;
+			}
+
+			m_islandBodies.resize(0);
+		}
+	} // else if(!splitIslands) 
+
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSimulationIslandManager.h	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+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 SIMULATION_ISLAND_MANAGER_H
+#define SIMULATION_ISLAND_MANAGER_H
+
+#include "BulletCollision/CollisionDispatch/btUnionFind.h"
+#include "btCollisionCreateFunc.h"
+#include "LinearMath/btAlignedObjectArray.h"
+#include "btCollisionObject.h"
+
+class btCollisionObject;
+class btCollisionWorld;
+class btDispatcher;
+class btPersistentManifold;
+
+
+///SimulationIslandManager creates and handles simulation islands, using btUnionFind
+class btSimulationIslandManager
+{
+	btUnionFind m_unionFind;
+
+	btAlignedObjectArray<btPersistentManifold*>  m_islandmanifold;
+	btAlignedObjectArray<btCollisionObject* >  m_islandBodies;
+	
+	bool m_splitIslands;
+	
+public:
+	btSimulationIslandManager();
+	virtual ~btSimulationIslandManager();
+
+
+	void initUnionFind(int n);	
+	
+		
+	btUnionFind& getUnionFind() { return m_unionFind;}
+
+	virtual	void	updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher);
+	virtual	void	storeIslandActivationState(btCollisionWorld* world);
+
+
+	void	findUnions(btDispatcher* dispatcher,btCollisionWorld* colWorld);
+
+	
+
+	struct	IslandCallback
+	{
+		virtual ~IslandCallback() {};
+
+		virtual	void	ProcessIsland(btCollisionObject** bodies,int numBodies,class btPersistentManifold**	manifolds,int numManifolds, int islandId) = 0;
+	};
+
+	void	buildAndProcessIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld, IslandCallback* callback);
+
+	void buildIslands(btDispatcher* dispatcher,btCollisionWorld* colWorld);
+
+	bool getSplitIslands()
+	{
+		return m_splitIslands;
+	}
+	void setSplitIslands(bool doSplitIslands)
+	{
+		m_splitIslands = doSplitIslands;
+	}
+
+};
+
+#endif //SIMULATION_ISLAND_MANAGER_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp	(revision 6952)
@@ -0,0 +1,260 @@
+/*
+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 "btSphereBoxCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
+#include "BulletCollision/CollisionShapes/btBoxShape.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+//#include <stdio.h>
+
+btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped)
+: btActivatingCollisionAlgorithm(ci,col0,col1),
+m_ownManifold(false),
+m_manifoldPtr(mf),
+m_isSwapped(isSwapped)
+{
+	btCollisionObject* sphereObj = m_isSwapped? col1 : col0;
+	btCollisionObject* boxObj = m_isSwapped? col0 : col1;
+	
+	if (!m_manifoldPtr && m_dispatcher->needsCollision(sphereObj,boxObj))
+	{
+		m_manifoldPtr = m_dispatcher->getNewManifold(sphereObj,boxObj);
+		m_ownManifold = true;
+	}
+}
+
+
+btSphereBoxCollisionAlgorithm::~btSphereBoxCollisionAlgorithm()
+{
+	if (m_ownManifold)
+	{
+		if (m_manifoldPtr)
+			m_dispatcher->releaseManifold(m_manifoldPtr);
+	}
+}
+
+
+
+void btSphereBoxCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	(void)dispatchInfo;
+	(void)resultOut;
+	if (!m_manifoldPtr)
+		return;
+
+	btCollisionObject* sphereObj = m_isSwapped? body1 : body0;
+	btCollisionObject* boxObj = m_isSwapped? body0 : body1;
+
+
+	btSphereShape* sphere0 = (btSphereShape*)sphereObj->getCollisionShape();
+
+	btVector3 normalOnSurfaceB;
+	btVector3 pOnBox,pOnSphere;
+	btVector3 sphereCenter = sphereObj->getWorldTransform().getOrigin();
+	btScalar radius = sphere0->getRadius();
+	
+	btScalar dist = getSphereDistance(boxObj,pOnBox,pOnSphere,sphereCenter,radius);
+
+	resultOut->setPersistentManifold(m_manifoldPtr);
+
+	if (dist < SIMD_EPSILON)
+	{
+		btVector3 normalOnSurfaceB = (pOnBox- pOnSphere).normalize();
+
+		/// report a contact. internally this will be kept persistent, and contact reduction is done
+
+		resultOut->addContactPoint(normalOnSurfaceB,pOnBox,dist);
+		
+	}
+
+	if (m_ownManifold)
+	{
+		if (m_manifoldPtr->getNumContacts())
+		{
+			resultOut->refreshContactPoints();
+		}
+	}
+
+}
+
+btScalar btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	(void)resultOut;
+	(void)dispatchInfo;
+	(void)col0;
+	(void)col1;
+
+	//not yet
+	return btScalar(1.);
+}
+
+
+btScalar btSphereBoxCollisionAlgorithm::getSphereDistance(btCollisionObject* boxObj, btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius ) 
+{
+
+	btScalar margins;
+	btVector3 bounds[2];
+	btBoxShape* boxShape= (btBoxShape*)boxObj->getCollisionShape();
+	
+	bounds[0] = -boxShape->getHalfExtentsWithoutMargin();
+	bounds[1] = boxShape->getHalfExtentsWithoutMargin();
+
+	margins = boxShape->getMargin();//also add sphereShape margin?
+
+	const btTransform&	m44T = boxObj->getWorldTransform();
+
+	btVector3	boundsVec[2];
+	btScalar	fPenetration;
+
+	boundsVec[0] = bounds[0];
+	boundsVec[1] = bounds[1];
+
+	btVector3	marginsVec( margins, margins, margins );
+
+	// add margins
+	bounds[0] += marginsVec;
+	bounds[1] -= marginsVec;
+
+	/////////////////////////////////////////////////
+
+	btVector3	tmp, prel, n[6], normal, v3P;
+	btScalar   fSep = btScalar(10000000.0), fSepThis;
+
+	n[0].setValue( btScalar(-1.0),  btScalar(0.0),  btScalar(0.0) );
+	n[1].setValue(  btScalar(0.0), btScalar(-1.0),  btScalar(0.0) );
+	n[2].setValue(  btScalar(0.0),  btScalar(0.0), btScalar(-1.0) );
+	n[3].setValue(  btScalar(1.0),  btScalar(0.0),  btScalar(0.0) );
+	n[4].setValue(  btScalar(0.0),  btScalar(1.0),  btScalar(0.0) );
+	n[5].setValue(  btScalar(0.0),  btScalar(0.0),  btScalar(1.0) );
+
+	// convert  point in local space
+	prel = m44T.invXform( sphereCenter);
+	
+	bool	bFound = false;
+
+	v3P = prel;
+
+	for (int i=0;i<6;i++)
+	{
+		int j = i<3? 0:1;
+		if ( (fSepThis = ((v3P-bounds[j]) .dot(n[i]))) > btScalar(0.0) )
+		{
+			v3P = v3P - n[i]*fSepThis;		
+			bFound = true;
+		}
+	}
+	
+	//
+
+	if ( bFound )
+	{
+		bounds[0] = boundsVec[0];
+		bounds[1] = boundsVec[1];
+
+		normal = (prel - v3P).normalize();
+		pointOnBox = v3P + normal*margins;
+		v3PointOnSphere = prel - normal*fRadius;
+
+		if ( ((v3PointOnSphere - pointOnBox) .dot (normal)) > btScalar(0.0) )
+		{
+			return btScalar(1.0);
+		}
+
+		// transform back in world space
+		tmp = m44T( pointOnBox);
+		pointOnBox    = tmp;
+		tmp  = m44T( v3PointOnSphere);		
+		v3PointOnSphere = tmp;
+		btScalar fSeps2 = (pointOnBox-v3PointOnSphere).length2();
+		
+		//if this fails, fallback into deeper penetration case, below
+		if (fSeps2 > SIMD_EPSILON)
+		{
+			fSep = - btSqrt(fSeps2);
+			normal = (pointOnBox-v3PointOnSphere);
+			normal *= btScalar(1.)/fSep;
+		}
+
+		return fSep;
+	}
+
+	//////////////////////////////////////////////////
+	// Deep penetration case
+
+	fPenetration = getSpherePenetration( boxObj,pointOnBox, v3PointOnSphere, sphereCenter, fRadius,bounds[0],bounds[1] );
+
+	bounds[0] = boundsVec[0];
+	bounds[1] = boundsVec[1];
+
+	if ( fPenetration <= btScalar(0.0) )
+		return (fPenetration-margins);
+	else
+		return btScalar(1.0);
+}
+
+btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btCollisionObject* boxObj,btVector3& pointOnBox, btVector3& v3PointOnSphere, const btVector3& sphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax) 
+{
+
+	btVector3 bounds[2];
+
+	bounds[0] = aabbMin;
+	bounds[1] = aabbMax;
+
+	btVector3	p0, tmp, prel, n[6], normal;
+	btScalar   fSep = btScalar(-10000000.0), fSepThis;
+
+	// set p0 and normal to a default value to shup up GCC
+	p0.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
+	normal.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
+
+	n[0].setValue( btScalar(-1.0),  btScalar(0.0),  btScalar(0.0) );
+	n[1].setValue(  btScalar(0.0), btScalar(-1.0),  btScalar(0.0) );
+	n[2].setValue(  btScalar(0.0),  btScalar(0.0), btScalar(-1.0) );
+	n[3].setValue(  btScalar(1.0),  btScalar(0.0),  btScalar(0.0) );
+	n[4].setValue(  btScalar(0.0),  btScalar(1.0),  btScalar(0.0) );
+	n[5].setValue(  btScalar(0.0),  btScalar(0.0),  btScalar(1.0) );
+
+	const btTransform&	m44T = boxObj->getWorldTransform();
+
+	// convert  point in local space
+	prel = m44T.invXform( sphereCenter);
+
+	///////////
+
+	for (int i=0;i<6;i++)
+	{
+		int j = i<3 ? 0:1;
+		if ( (fSepThis = ((prel-bounds[j]) .dot( n[i]))-fRadius) > btScalar(0.0) )	return btScalar(1.0);
+		if ( fSepThis > fSep )
+		{
+			p0 = bounds[j];	normal = (btVector3&)n[i];
+			fSep = fSepThis;
+		}
+	}
+
+	pointOnBox = prel - normal*(normal.dot((prel-p0)));
+	v3PointOnSphere = pointOnBox + normal*fSep;
+
+	// transform back in world space
+	tmp  = m44T( pointOnBox);		
+	pointOnBox    = tmp;
+	tmp  = m44T( v3PointOnSphere);		v3PointOnSphere = tmp;
+	normal = (pointOnBox-v3PointOnSphere).normalize();
+
+	return fSep;
+
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h	(revision 6952)
@@ -0,0 +1,75 @@
+/*
+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 SPHERE_BOX_COLLISION_ALGORITHM_H
+#define SPHERE_BOX_COLLISION_ALGORITHM_H
+
+#include "btActivatingCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
+class btPersistentManifold;
+#include "btCollisionDispatcher.h"
+
+#include "LinearMath/btVector3.h"
+
+/// btSphereBoxCollisionAlgorithm  provides sphere-box collision detection.
+/// Other features are frame-coherency (persistent data) and collision response.
+class btSphereBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm
+{
+	bool	m_ownManifold;
+	btPersistentManifold*	m_manifoldPtr;
+	bool	m_isSwapped;
+	
+public:
+
+	btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1, bool isSwapped);
+
+	virtual ~btSphereBoxCollisionAlgorithm();
+
+	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)
+	{
+		if (m_manifoldPtr && m_ownManifold)
+		{
+			manifoldArray.push_back(m_manifoldPtr);
+		}
+	}
+
+	btScalar getSphereDistance( btCollisionObject* boxObj,btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius );
+
+	btScalar getSpherePenetration( btCollisionObject* boxObj, btVector3& v3PointOnBox, btVector3& v3PointOnSphere, const btVector3& v3SphereCenter, btScalar fRadius, const btVector3& aabbMin, const btVector3& aabbMax);
+	
+	struct CreateFunc :public 	btCollisionAlgorithmCreateFunc
+	{
+		virtual	btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+		{
+			void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereBoxCollisionAlgorithm));
+			if (!m_swapped)
+			{
+				return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0,body1,false);
+			} else
+			{
+				return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0,body1,true);
+			}
+		}
+	};
+
+};
+
+#endif //SPHERE_BOX_COLLISION_ALGORITHM_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp	(revision 6952)
@@ -0,0 +1,105 @@
+/*
+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 "btSphereSphereCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+
+btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1)
+: btActivatingCollisionAlgorithm(ci,col0,col1),
+m_ownManifold(false),
+m_manifoldPtr(mf)
+{
+	if (!m_manifoldPtr)
+	{
+		m_manifoldPtr = m_dispatcher->getNewManifold(col0,col1);
+		m_ownManifold = true;
+	}
+}
+
+btSphereSphereCollisionAlgorithm::~btSphereSphereCollisionAlgorithm()
+{
+	if (m_ownManifold)
+	{
+		if (m_manifoldPtr)
+			m_dispatcher->releaseManifold(m_manifoldPtr);
+	}
+}
+
+void btSphereSphereCollisionAlgorithm::processCollision (btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	(void)dispatchInfo;
+
+	if (!m_manifoldPtr)
+		return;
+
+	resultOut->setPersistentManifold(m_manifoldPtr);
+
+	btSphereShape* sphere0 = (btSphereShape*)col0->getCollisionShape();
+	btSphereShape* sphere1 = (btSphereShape*)col1->getCollisionShape();
+
+	btVector3 diff = col0->getWorldTransform().getOrigin()-  col1->getWorldTransform().getOrigin();
+	btScalar len = diff.length();
+	btScalar radius0 = sphere0->getRadius();
+	btScalar radius1 = sphere1->getRadius();
+
+#ifdef CLEAR_MANIFOLD
+	m_manifoldPtr->clearManifold(); //don't do this, it disables warmstarting
+#endif
+
+	///iff distance positive, don't generate a new contact
+	if ( len > (radius0+radius1))
+	{
+#ifndef CLEAR_MANIFOLD
+		resultOut->refreshContactPoints();
+#endif //CLEAR_MANIFOLD
+		return;
+	}
+	///distance (negative means penetration)
+	btScalar dist = len - (radius0+radius1);
+
+	btVector3 normalOnSurfaceB(1,0,0);
+	if (len > SIMD_EPSILON)
+	{
+		normalOnSurfaceB = diff / len;
+	}
+
+	///point on A (worldspace)
+	///btVector3 pos0 = col0->getWorldTransform().getOrigin() - radius0 * normalOnSurfaceB;
+	///point on B (worldspace)
+	btVector3 pos1 = col1->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB;
+
+	/// report a contact. internally this will be kept persistent, and contact reduction is done
+	
+	
+	resultOut->addContactPoint(normalOnSurfaceB,pos1,dist);
+
+#ifndef CLEAR_MANIFOLD
+	resultOut->refreshContactPoints();
+#endif //CLEAR_MANIFOLD
+
+}
+
+btScalar btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	(void)col0;
+	(void)col1;
+	(void)dispatchInfo;
+	(void)resultOut;
+
+	//not yet
+	return btScalar(1.);
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h	(revision 6952)
@@ -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 SPHERE_SPHERE_COLLISION_ALGORITHM_H
+#define SPHERE_SPHERE_COLLISION_ALGORITHM_H
+
+#include "btActivatingCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
+#include "btCollisionDispatcher.h"
+
+class btPersistentManifold;
+
+/// btSphereSphereCollisionAlgorithm  provides sphere-sphere collision detection.
+/// Other features are frame-coherency (persistent data) and collision response.
+/// Also provides the most basic sample for custom/user btCollisionAlgorithm
+class btSphereSphereCollisionAlgorithm : public btActivatingCollisionAlgorithm
+{
+	bool	m_ownManifold;
+	btPersistentManifold*	m_manifoldPtr;
+	
+public:
+	btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
+
+	btSphereSphereCollisionAlgorithm(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);
+
+	virtual	void	getAllContactManifolds(btManifoldArray&	manifoldArray)
+	{
+		if (m_manifoldPtr && m_ownManifold)
+		{
+			manifoldArray.push_back(m_manifoldPtr);
+		}
+	}
+	
+	virtual ~btSphereSphereCollisionAlgorithm();
+
+	struct CreateFunc :public 	btCollisionAlgorithmCreateFunc
+	{
+		virtual	btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+		{
+			void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereSphereCollisionAlgorithm));
+			return new(mem) btSphereSphereCollisionAlgorithm(0,ci,body0,body1);
+		}
+	};
+
+};
+
+#endif //SPHERE_SPHERE_COLLISION_ALGORITHM_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp	(revision 6952)
@@ -0,0 +1,84 @@
+/*
+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 "btSphereTriangleCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "SphereTriangleDetector.h"
+
+
+btSphereTriangleCollisionAlgorithm::btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* col0,btCollisionObject* col1,bool swapped)
+: btActivatingCollisionAlgorithm(ci,col0,col1),
+m_ownManifold(false),
+m_manifoldPtr(mf),
+m_swapped(swapped)
+{
+	if (!m_manifoldPtr)
+	{
+		m_manifoldPtr = m_dispatcher->getNewManifold(col0,col1);
+		m_ownManifold = true;
+	}
+}
+
+btSphereTriangleCollisionAlgorithm::~btSphereTriangleCollisionAlgorithm()
+{
+	if (m_ownManifold)
+	{
+		if (m_manifoldPtr)
+			m_dispatcher->releaseManifold(m_manifoldPtr);
+	}
+}
+
+void btSphereTriangleCollisionAlgorithm::processCollision (btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	if (!m_manifoldPtr)
+		return;
+
+	btCollisionObject* sphereObj = m_swapped? col1 : col0;
+	btCollisionObject* triObj = m_swapped? col0 : col1;
+
+	btSphereShape* sphere = (btSphereShape*)sphereObj->getCollisionShape();
+	btTriangleShape* triangle = (btTriangleShape*)triObj->getCollisionShape();
+	
+	/// report a contact. internally this will be kept persistent, and contact reduction is done
+	resultOut->setPersistentManifold(m_manifoldPtr);
+	SphereTriangleDetector detector(sphere,triangle, m_manifoldPtr->getContactBreakingThreshold());
+	
+	btDiscreteCollisionDetectorInterface::ClosestPointInput input;
+	input.m_maximumDistanceSquared = btScalar(1e30);///@todo: tighter bounds
+	input.m_transformA = sphereObj->getWorldTransform();
+	input.m_transformB = triObj->getWorldTransform();
+
+	bool swapResults = m_swapped;
+
+	detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw,swapResults);
+
+	if (m_ownManifold)
+		resultOut->refreshContactPoints();
+	
+}
+
+btScalar btSphereTriangleCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	(void)resultOut;
+	(void)dispatchInfo;
+	(void)col0;
+	(void)col1;
+
+	//not yet
+	return btScalar(1.);
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h	(revision 6952)
@@ -0,0 +1,69 @@
+/*
+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 SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
+#define SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
+
+#include "btActivatingCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
+class btPersistentManifold;
+#include "btCollisionDispatcher.h"
+
+/// btSphereSphereCollisionAlgorithm  provides sphere-sphere collision detection.
+/// Other features are frame-coherency (persistent data) and collision response.
+/// Also provides the most basic sample for custom/user btCollisionAlgorithm
+class btSphereTriangleCollisionAlgorithm : public btActivatingCollisionAlgorithm
+{
+	bool	m_ownManifold;
+	btPersistentManifold*	m_manifoldPtr;
+	bool	m_swapped;
+	
+public:
+	btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1,bool swapped);
+
+	btSphereTriangleCollisionAlgorithm(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);
+
+	virtual	void	getAllContactManifolds(btManifoldArray&	manifoldArray)
+	{
+		if (m_manifoldPtr && m_ownManifold)
+		{
+			manifoldArray.push_back(m_manifoldPtr);
+		}
+	}
+	
+	virtual ~btSphereTriangleCollisionAlgorithm();
+
+	struct CreateFunc :public 	btCollisionAlgorithmCreateFunc
+	{
+		
+		virtual	btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+		{
+			
+			void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereTriangleCollisionAlgorithm));
+
+			return new(mem) btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0,body1,m_swapped);
+		}
+	};
+
+};
+
+#endif //SPHERE_TRIANGLE_COLLISION_ALGORITHM_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btUnionFind.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btUnionFind.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btUnionFind.cpp	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+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 "btUnionFind.h"
+
+
+
+btUnionFind::~btUnionFind()
+{
+	Free();
+
+}
+
+btUnionFind::btUnionFind()
+{ 
+
+}
+
+void	btUnionFind::allocate(int N)
+{
+	m_elements.resize(N);
+}
+void	btUnionFind::Free()
+{
+	m_elements.clear();
+}
+
+
+void	btUnionFind::reset(int N)
+{
+	allocate(N);
+
+	for (int i = 0; i < N; i++) 
+	{ 
+		m_elements[i].m_id = i; m_elements[i].m_sz = 1; 
+	} 
+}
+
+
+class btUnionFindElementSortPredicate
+{
+	public:
+
+		bool operator() ( const btElement& lhs, const btElement& rhs )
+		{
+			return lhs.m_id < rhs.m_id;
+		}
+};
+
+///this is a special operation, destroying the content of btUnionFind.
+///it sorts the elements, based on island id, in order to make it easy to iterate over islands
+void	btUnionFind::sortIslands()
+{
+
+	//first store the original body index, and islandId
+	int numElements = m_elements.size();
+	
+	for (int i=0;i<numElements;i++)
+	{
+		m_elements[i].m_id = find(i);
+		m_elements[i].m_sz = i;
+	}
+	
+	 // Sort the vector using predicate and std::sort
+	  //std::sort(m_elements.begin(), m_elements.end(), btUnionFindElementSortPredicate);
+	  m_elements.quickSort(btUnionFindElementSortPredicate());
+
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btUnionFind.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btUnionFind.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionDispatch/btUnionFind.h	(revision 6952)
@@ -0,0 +1,124 @@
+/*
+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 UNION_FIND_H
+#define UNION_FIND_H
+
+#include "LinearMath/btAlignedObjectArray.h"
+
+	#define USE_PATH_COMPRESSION 1
+
+struct	btElement
+{
+	int	m_id;
+	int	m_sz;
+};
+
+///UnionFind calculates connected subsets
+// Implements weighted Quick Union with path compression
+// optimization: could use short ints instead of ints (halving memory, would limit the number of rigid bodies to 64k, sounds reasonable)
+class btUnionFind
+  {
+    private:
+		btAlignedObjectArray<btElement>	m_elements;
+
+    public:
+	  
+		btUnionFind();
+		~btUnionFind();
+
+	
+		//this is a special operation, destroying the content of btUnionFind.
+		//it sorts the elements, based on island id, in order to make it easy to iterate over islands
+		void	sortIslands();
+
+	  void	reset(int N);
+
+	  SIMD_FORCE_INLINE int	getNumElements() const
+	  {
+		  return int(m_elements.size());
+	  }
+	  SIMD_FORCE_INLINE bool  isRoot(int x) const
+	  {
+		  return (x == m_elements[x].m_id);
+	  }
+
+	  btElement&	getElement(int index)
+	  {
+		  return m_elements[index];
+	  }
+	  const btElement& getElement(int index) const
+	  {
+		  return m_elements[index];
+	  }
+   
+	  void	allocate(int N);
+	  void	Free();
+
+
+
+
+	  int find(int p, int q)
+		{ 
+			return (find(p) == find(q)); 
+		}
+
+		void unite(int p, int q)
+		{
+			int i = find(p), j = find(q);
+			if (i == j) 
+				return;
+
+#ifndef USE_PATH_COMPRESSION
+			//weighted quick union, this keeps the 'trees' balanced, and keeps performance of unite O( log(n) )
+			if (m_elements[i].m_sz < m_elements[j].m_sz)
+			{ 
+				m_elements[i].m_id = j; m_elements[j].m_sz += m_elements[i].m_sz; 
+			}
+			else 
+			{ 
+				m_elements[j].m_id = i; m_elements[i].m_sz += m_elements[j].m_sz; 
+			}
+#else
+			m_elements[i].m_id = j; m_elements[j].m_sz += m_elements[i].m_sz; 
+#endif //USE_PATH_COMPRESSION
+		}
+
+		int find(int x)
+		{ 
+			//btAssert(x < m_N);
+			//btAssert(x >= 0);
+
+			while (x != m_elements[x].m_id) 
+			{
+		//not really a reason not to use path compression, and it flattens the trees/improves find performance dramatically
+	
+		#ifdef USE_PATH_COMPRESSION
+				//
+				m_elements[x].m_id = m_elements[m_elements[x].m_id].m_id;
+		#endif //
+				x = m_elements[x].m_id;
+				//btAssert(x < m_N);
+				//btAssert(x >= 0);
+
+			}
+			return x; 
+		}
+
+
+  };
+
+
+#endif //UNION_FIND_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btBoxShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btBoxShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btBoxShape.cpp	(revision 6952)
@@ -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 "btBoxShape.h"
+
+
+//{ 
+
+
+void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	btTransformAabb(getHalfExtentsWithoutMargin(),getMargin(),t,aabbMin,aabbMax);
+}
+
+
+void	btBoxShape::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/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btBoxShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btBoxShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btBoxShape.h	(revision 6952)
@@ -0,0 +1,317 @@
+/*
+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_MINKOWSKI_H
+#define OBB_BOX_MINKOWSKI_H
+
+#include "btPolyhedralConvexShape.h"
+#include "btCollisionMargin.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btMinMax.h"
+
+///The btBoxShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space.
+class btBoxShape: public btPolyhedralConvexShape
+{
+
+	//btVector3	m_boxHalfExtents1; //use m_implicitShapeDimensions instead
+
+
+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())); 
+		}
+
+	}
+
+
+	btBoxShape( const btVector3& boxHalfExtents) 
+		: btPolyhedralConvexShape()
+	{
+		m_shapeType = BOX_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;
+
+	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);
+	}
+
+	
+	virtual int getNumPlanes() const
+	{
+		return 6;
+	}	
+	
+	virtual int	getNumVertices() const 
+	{
+		return 8;
+	}
+
+	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 "Box";
+	}
+
+	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_MINKOWSKI_H
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp	(revision 6952)
@@ -0,0 +1,374 @@
+/*
+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.
+*/
+
+//#define DISABLE_BVH
+
+#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
+#include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
+
+///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization.
+///Uses an interface to access the triangles to allow for sharing graphics/physics triangles.
+btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh)
+:btTriangleMeshShape(meshInterface),
+m_bvh(0),
+m_useQuantizedAabbCompression(useQuantizedAabbCompression),
+m_ownsBvh(false)
+{
+	m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
+	//construct bvh from meshInterface
+#ifndef DISABLE_BVH
+
+	btVector3 bvhAabbMin,bvhAabbMax;
+	if(meshInterface->hasPremadeAabb())
+	{
+		meshInterface->getPremadeAabb(&bvhAabbMin, &bvhAabbMax);
+	}
+	else
+	{
+		meshInterface->calculateAabbBruteForce(bvhAabbMin,bvhAabbMax);
+	}
+	
+	if (buildBvh)
+	{
+		void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
+		m_bvh = new (mem) btOptimizedBvh();
+		m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
+		m_ownsBvh = true;
+	}
+
+#endif //DISABLE_BVH
+
+}
+
+btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,bool buildBvh)
+:btTriangleMeshShape(meshInterface),
+m_bvh(0),
+m_useQuantizedAabbCompression(useQuantizedAabbCompression),
+m_ownsBvh(false)
+{
+	m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
+	//construct bvh from meshInterface
+#ifndef DISABLE_BVH
+
+	if (buildBvh)
+	{
+		void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
+		m_bvh = new (mem) btOptimizedBvh();
+		
+		m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax);
+		m_ownsBvh = true;
+	}
+
+#endif //DISABLE_BVH
+
+}
+
+void	btBvhTriangleMeshShape::partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax)
+{
+	m_bvh->refitPartial( m_meshInterface,aabbMin,aabbMax );
+	
+	m_localAabbMin.setMin(aabbMin);
+	m_localAabbMax.setMax(aabbMax);
+}
+
+
+void	btBvhTriangleMeshShape::refitTree(const btVector3& aabbMin,const btVector3& aabbMax)
+{
+	m_bvh->refit( m_meshInterface, aabbMin,aabbMax );
+	
+	recalcLocalAabb();
+}
+
+btBvhTriangleMeshShape::~btBvhTriangleMeshShape()
+{
+	if (m_ownsBvh)
+	{
+		m_bvh->~btOptimizedBvh();
+		btAlignedFree(m_bvh);
+	}
+}
+
+void	btBvhTriangleMeshShape::performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget)
+{
+	struct	MyNodeOverlapCallback : public btNodeOverlapCallback
+	{
+		btStridingMeshInterface*	m_meshInterface;
+		btTriangleCallback* m_callback;
+
+		MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
+			:m_meshInterface(meshInterface),
+			m_callback(callback)
+		{
+		}
+				
+		virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
+		{
+			btVector3 m_triangle[3];
+			const unsigned char *vertexbase;
+			int numverts;
+			PHY_ScalarType type;
+			int stride;
+			const unsigned char *indexbase;
+			int indexstride;
+			int numfaces;
+			PHY_ScalarType indicestype;
+
+			m_meshInterface->getLockedReadOnlyVertexIndexBase(
+				&vertexbase,
+				numverts,
+				type,
+				stride,
+				&indexbase,
+				indexstride,
+				numfaces,
+				indicestype,
+				nodeSubPart);
+
+			unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride);
+			btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
+	
+			const btVector3& meshScaling = m_meshInterface->getScaling();
+			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);
+					
+					m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());		
+				}
+				else
+				{
+					double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
+					
+					m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ());		
+				}
+			}
+
+			/* Perform ray vs. triangle collision here */
+			m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
+			m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
+		}
+	};
+
+	MyNodeOverlapCallback	myNodeCallback(callback,m_meshInterface);
+
+	m_bvh->reportRayOverlappingNodex(&myNodeCallback,raySource,rayTarget);
+}
+
+void	btBvhTriangleMeshShape::performConvexcast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax)
+{
+	struct	MyNodeOverlapCallback : public btNodeOverlapCallback
+	{
+		btStridingMeshInterface*	m_meshInterface;
+		btTriangleCallback* m_callback;
+
+		MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
+			:m_meshInterface(meshInterface),
+			m_callback(callback)
+		{
+		}
+				
+		virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
+		{
+			btVector3 m_triangle[3];
+			const unsigned char *vertexbase;
+			int numverts;
+			PHY_ScalarType type;
+			int stride;
+			const unsigned char *indexbase;
+			int indexstride;
+			int numfaces;
+			PHY_ScalarType indicestype;
+
+			m_meshInterface->getLockedReadOnlyVertexIndexBase(
+				&vertexbase,
+				numverts,
+				type,
+				stride,
+				&indexbase,
+				indexstride,
+				numfaces,
+				indicestype,
+				nodeSubPart);
+
+			unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride);
+			btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
+	
+			const btVector3& meshScaling = m_meshInterface->getScaling();
+			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);
+
+					m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ());		
+				}
+				else
+				{
+					double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
+					
+					m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ());		
+				}
+			}
+
+			/* Perform ray vs. triangle collision here */
+			m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
+			m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
+		}
+	};
+
+	MyNodeOverlapCallback	myNodeCallback(callback,m_meshInterface);
+
+	m_bvh->reportBoxCastOverlappingNodex (&myNodeCallback, raySource, rayTarget, aabbMin, aabbMax);
+}
+
+//perform bvh tree traversal and report overlapping triangles to 'callback'
+void	btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+
+#ifdef DISABLE_BVH
+	//brute force traverse all triangles
+	btTriangleMeshShape::processAllTriangles(callback,aabbMin,aabbMax);
+#else
+
+	//first get all the nodes
+
+	
+	struct	MyNodeOverlapCallback : public btNodeOverlapCallback
+	{
+		btStridingMeshInterface*	m_meshInterface;
+		btTriangleCallback*		m_callback;
+		btVector3				m_triangle[3];
+
+
+		MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface)
+			:m_meshInterface(meshInterface),
+			m_callback(callback)
+		{
+		}
+				
+		virtual void processNode(int nodeSubPart, int nodeTriangleIndex)
+		{
+			const unsigned char *vertexbase;
+			int numverts;
+			PHY_ScalarType type;
+			int stride;
+			const unsigned char *indexbase;
+			int indexstride;
+			int numfaces;
+			PHY_ScalarType indicestype;
+			
+
+			m_meshInterface->getLockedReadOnlyVertexIndexBase(
+				&vertexbase,
+				numverts,
+				type,
+				stride,
+				&indexbase,
+				indexstride,
+				numfaces,
+				indicestype,
+				nodeSubPart);
+
+			unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride);
+			btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
+	
+			const btVector3& meshScaling = m_meshInterface->getScaling();
+			for (int j=2;j>=0;j--)
+			{
+				
+				int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j];
+
+
+#ifdef DEBUG_TRIANGLE_MESH
+				printf("%d ,",graphicsindex);
+#endif //DEBUG_TRIANGLE_MESH
+				if (type == PHY_FLOAT)
+				{
+					float* graphicsbase = (float*)(vertexbase+graphicsindex*stride);
+					
+					m_triangle[j] = btVector3(
+																		graphicsbase[0]*meshScaling.getX(),
+																		graphicsbase[1]*meshScaling.getY(),
+																		graphicsbase[2]*meshScaling.getZ());
+				}
+				else
+				{
+					double* graphicsbase = (double*)(vertexbase+graphicsindex*stride);
+
+					m_triangle[j] = btVector3(
+						btScalar(graphicsbase[0])*meshScaling.getX(),
+						btScalar(graphicsbase[1])*meshScaling.getY(),
+						btScalar(graphicsbase[2])*meshScaling.getZ());
+				}
+#ifdef DEBUG_TRIANGLE_MESH
+				printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z());
+#endif //DEBUG_TRIANGLE_MESH
+			}
+
+			m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex);
+			m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart);
+		}
+
+	};
+
+	MyNodeOverlapCallback	myNodeCallback(callback,m_meshInterface);
+
+	m_bvh->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax);
+
+
+#endif//DISABLE_BVH
+
+
+}
+
+void   btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling)
+{
+   if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON)
+   {
+      btTriangleMeshShape::setLocalScaling(scaling);
+      if (m_ownsBvh)
+      {
+         m_bvh->~btOptimizedBvh();
+         btAlignedFree(m_bvh);
+      }
+      ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work
+      void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16);
+      m_bvh = new(mem) btOptimizedBvh();
+      //rebuild the bvh...
+      m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax);
+      m_ownsBvh = true;
+   }
+}
+
+void   btBvhTriangleMeshShape::setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& scaling)
+{
+   btAssert(!m_bvh);
+   btAssert(!m_ownsBvh);
+
+   m_bvh = bvh;
+   m_ownsBvh = false;
+   // update the scaling without rebuilding the bvh
+   if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON)
+   {
+      btTriangleMeshShape::setLocalScaling(scaling);
+   }
+}
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h	(revision 6952)
@@ -0,0 +1,86 @@
+/*
+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 BVH_TRIANGLE_MESH_SHAPE_H
+#define BVH_TRIANGLE_MESH_SHAPE_H
+
+#include "btTriangleMeshShape.h"
+#include "btOptimizedBvh.h"
+#include "LinearMath/btAlignedAllocator.h"
+
+
+///The btBvhTriangleMeshShape is a static-triangle mesh shape with several optimizations, such as bounding volume hierarchy and cache friendly traversal for PlayStation 3 Cell SPU. It is recommended to enable useQuantizedAabbCompression for better memory usage.
+///It takes a triangle mesh as input, for example a btTriangleMesh or btTriangleIndexVertexArray. The btBvhTriangleMeshShape class allows for triangle mesh deformations by a refit or partialRefit method.
+///Instead of building the bounding volume hierarchy acceleration structure, it is also possible to serialize (save) and deserialize (load) the structure from disk.
+///See Demos\ConcaveDemo\ConcavePhysicsDemo.cpp for an example.
+ATTRIBUTE_ALIGNED16(class) btBvhTriangleMeshShape : public btTriangleMeshShape
+{
+
+	btOptimizedBvh*	m_bvh;
+	bool m_useQuantizedAabbCompression;
+	bool m_ownsBvh;
+	bool m_pad[11];////need padding due to alignment
+
+public:
+
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	btBvhTriangleMeshShape() : btTriangleMeshShape(0),m_bvh(0),m_ownsBvh(false) {m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;};
+	btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true);
+
+	///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb
+	btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax, bool buildBvh = true);
+	
+	virtual ~btBvhTriangleMeshShape();
+
+	bool getOwnsBvh () const
+	{
+		return m_ownsBvh;
+	}
+
+
+	
+	void performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget);
+	void performConvexcast (btTriangleCallback* callback, const btVector3& boxSource, const btVector3& boxTarget, const btVector3& boxMin, const btVector3& boxMax);
+
+	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+
+	void	refitTree(const btVector3& aabbMin,const btVector3& aabbMax);
+
+	///for a fast incremental refit of parts of the tree. Note: the entire AABB of the tree will become more conservative, it never shrinks
+	void	partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax);
+
+	//debugging
+	virtual const char*	getName()const {return "BVHTRIANGLEMESH";}
+
+
+	virtual void	setLocalScaling(const btVector3& scaling);
+	
+	btOptimizedBvh*	getOptimizedBvh()
+	{
+		return m_bvh;
+	}
+
+
+	void	setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& localScaling=btVector3(1,1,1));
+
+	bool	usesQuantizedAabbCompression() const
+	{
+		return	m_useQuantizedAabbCompression;
+	}
+}
+;
+
+#endif //BVH_TRIANGLE_MESH_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCapsuleShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCapsuleShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCapsuleShape.cpp	(revision 6952)
@@ -0,0 +1,171 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#include "btCapsuleShape.h"
+
+#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+#include "LinearMath/btQuaternion.h"
+
+btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInternalShape ()
+{
+	m_shapeType = CAPSULE_SHAPE_PROXYTYPE;
+	m_upAxis = 1;
+	m_implicitShapeDimensions.setValue(radius,0.5f*height,radius);
+}
+
+ 
+ btVector3	btCapsuleShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
+{
+
+	btVector3 supVec(0,0,0);
+
+	btScalar maxDot(btScalar(-1e30));
+
+	btVector3 vec = vec0;
+	btScalar lenSqr = vec.length2();
+	if (lenSqr < btScalar(0.0001))
+	{
+		vec.setValue(1,0,0);
+	} else
+	{
+		btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
+		vec *= rlen;
+	}
+
+	btVector3 vtx;
+	btScalar newDot;
+	
+	btScalar radius = getRadius();
+
+
+	{
+		btVector3 pos(0,0,0);
+		pos[getUpAxis()] = getHalfHeight();
+
+		vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
+		newDot = vec.dot(vtx);
+		if (newDot > maxDot)
+		{
+			maxDot = newDot;
+			supVec = vtx;
+		}
+	}
+	{
+		btVector3 pos(0,0,0);
+		pos[getUpAxis()] = -getHalfHeight();
+
+		vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
+		newDot = vec.dot(vtx);
+		if (newDot > maxDot)
+		{
+			maxDot = newDot;
+			supVec = vtx;
+		}
+	}
+
+	return supVec;
+
+}
+
+ void	btCapsuleShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+
+	
+	btScalar radius = getRadius();
+
+	for (int j=0;j<numVectors;j++)
+	{
+		btScalar maxDot(btScalar(-1e30));
+		const btVector3& vec = vectors[j];
+
+		btVector3 vtx;
+		btScalar newDot;
+		{
+			btVector3 pos(0,0,0);
+			pos[getUpAxis()] = getHalfHeight();
+			vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
+			newDot = vec.dot(vtx);
+			if (newDot > maxDot)
+			{
+				maxDot = newDot;
+				supportVerticesOut[j] = vtx;
+			}
+		}
+		{
+			btVector3 pos(0,0,0);
+			pos[getUpAxis()] = -getHalfHeight();
+			vtx = pos +vec*m_localScaling*(radius) - vec * getMargin();
+			newDot = vec.dot(vtx);
+			if (newDot > maxDot)
+			{
+				maxDot = newDot;
+				supportVerticesOut[j] = vtx;
+			}
+		}
+		
+	}
+}
+
+
+void	btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+	//as an approximation, take the inertia of the box that bounds the spheres
+
+	btTransform ident;
+	ident.setIdentity();
+
+	
+	btScalar radius = getRadius();
+
+	btVector3 halfExtents(radius,radius,radius);
+	halfExtents[getUpAxis()]+=getHalfHeight();
+
+	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);
+
+}
+
+btCapsuleShapeX::btCapsuleShapeX(btScalar radius,btScalar height)
+{
+	m_upAxis = 0;
+	m_implicitShapeDimensions.setValue(0.5f*height, radius,radius);
+}
+
+
+
+
+
+
+btCapsuleShapeZ::btCapsuleShapeZ(btScalar radius,btScalar height)
+{
+	m_upAxis = 2;
+	m_implicitShapeDimensions.setValue(radius,radius,0.5f*height);
+}
+
+
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCapsuleShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCapsuleShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCapsuleShape.h	(revision 6952)
@@ -0,0 +1,118 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_CAPSULE_SHAPE_H
+#define BT_CAPSULE_SHAPE_H
+
+#include "btConvexInternalShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+
+
+///The btCapsuleShape represents a capsule around the Y axis, there is also the btCapsuleShapeX aligned around the X axis and btCapsuleShapeZ around the Z axis.
+///The total height is height+2*radius, so the height is just the height between the center of each 'sphere' of the capsule caps.
+///The btCapsuleShape is a convex hull of two spheres. The btMultiSphereShape is a more general collision shape that takes the convex hull of multiple sphere, so it can also represent a capsule when just using two spheres.
+class btCapsuleShape : public btConvexInternalShape
+{
+protected:
+	int	m_upAxis;
+
+protected:
+	///only used for btCapsuleShapeZ and btCapsuleShapeX subclasses.
+	btCapsuleShape() : btConvexInternalShape() {m_shapeType = CAPSULE_SHAPE_PROXYTYPE;};
+
+public:
+	btCapsuleShape(btScalar radius,btScalar height);
+
+	///CollisionShape Interface
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
+	/// btConvexShape Interface
+	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
+
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+	
+	virtual void getAabb (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
+	{
+			btVector3 halfExtents(getRadius(),getRadius(),getRadius());
+			halfExtents[m_upAxis] = getRadius() + getHalfHeight();
+			halfExtents += btVector3(getMargin(),getMargin(),getMargin());
+			btMatrix3x3 abs_b = t.getBasis().absolute();  
+			btVector3 center = t.getOrigin();
+			btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));		  
+			
+			aabbMin = center - extent;
+			aabbMax = center + extent;
+	}
+
+	virtual const char*	getName()const 
+	{
+		return "CapsuleShape";
+	}
+
+	int	getUpAxis() const
+	{
+		return m_upAxis;
+	}
+
+	btScalar	getRadius() const
+	{
+		int radiusAxis = (m_upAxis+2)%3;
+		return m_implicitShapeDimensions[radiusAxis];
+	}
+
+	btScalar	getHalfHeight() const
+	{
+		return m_implicitShapeDimensions[m_upAxis];
+	}
+
+};
+
+///btCapsuleShapeX represents a capsule around the Z axis
+///the total height is height+2*radius, so the height is just the height between the center of each 'sphere' of the capsule caps.
+class btCapsuleShapeX : public btCapsuleShape
+{
+public:
+
+	btCapsuleShapeX(btScalar radius,btScalar height);
+		
+	//debugging
+	virtual const char*	getName()const
+	{
+		return "CapsuleX";
+	}
+
+	
+
+};
+
+///btCapsuleShapeZ represents a capsule around the Z axis
+///the total height is height+2*radius, so the height is just the height between the center of each 'sphere' of the capsule caps.
+class btCapsuleShapeZ : public btCapsuleShape
+{
+public:
+	btCapsuleShapeZ(btScalar radius,btScalar height);
+
+		//debugging
+	virtual const char*	getName()const
+	{
+		return "CapsuleZ";
+	}
+
+	
+};
+
+
+
+#endif //BT_CAPSULE_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionMargin.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionMargin.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionMargin.h	(revision 6952)
@@ -0,0 +1,26 @@
+/*
+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 COLLISION_MARGIN_H
+#define COLLISION_MARGIN_H
+
+//used by Gjk and some other algorithms
+
+#define CONVEX_DISTANCE_MARGIN btScalar(0.04)// btScalar(0.1)//;//btScalar(0.01)
+
+
+
+#endif //COLLISION_MARGIN_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionShape.cpp	(revision 6952)
@@ -0,0 +1,98 @@
+/*
+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 "BulletCollision/CollisionShapes/btCollisionShape.h"
+
+
+btScalar gContactThresholdFactor=btScalar(0.02);
+
+
+/*
+  Make sure this dummy function never changes so that it
+  can be used by probes that are checking whether the
+  library is actually installed.
+*/
+extern "C" 
+{
+void btBulletCollisionProbe ();
+
+void btBulletCollisionProbe () {}
+}
+
+
+
+void	btCollisionShape::getBoundingSphere(btVector3& center,btScalar& radius) const
+{
+	btTransform tr;
+	tr.setIdentity();
+	btVector3 aabbMin,aabbMax;
+
+	getAabb(tr,aabbMin,aabbMax);
+
+	radius = (aabbMax-aabbMin).length()*btScalar(0.5);
+	center = (aabbMin+aabbMax)*btScalar(0.5);
+}
+
+btScalar	btCollisionShape::getContactBreakingThreshold() const
+{
+	return getAngularMotionDisc() * gContactThresholdFactor;
+}
+btScalar	btCollisionShape::getAngularMotionDisc() const
+{
+	///@todo cache this value, to improve performance
+	btVector3	center;
+	btScalar disc;
+	getBoundingSphere(center,disc);
+	disc += (center).length();
+	return disc;
+}
+
+void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax) const
+{
+	//start with static aabb
+	getAabb(curTrans,temporalAabbMin,temporalAabbMax);
+
+	btScalar temporalAabbMaxx = temporalAabbMax.getX();
+	btScalar temporalAabbMaxy = temporalAabbMax.getY();
+	btScalar temporalAabbMaxz = temporalAabbMax.getZ();
+	btScalar temporalAabbMinx = temporalAabbMin.getX();
+	btScalar temporalAabbMiny = temporalAabbMin.getY();
+	btScalar temporalAabbMinz = temporalAabbMin.getZ();
+
+	// add linear motion
+	btVector3 linMotion = linvel*timeStep;
+	///@todo: simd would have a vector max/min operation, instead of per-element access
+	if (linMotion.x() > btScalar(0.))
+		temporalAabbMaxx += linMotion.x(); 
+	else
+		temporalAabbMinx += linMotion.x();
+	if (linMotion.y() > btScalar(0.))
+		temporalAabbMaxy += linMotion.y(); 
+	else
+		temporalAabbMiny += linMotion.y();
+	if (linMotion.z() > btScalar(0.))
+		temporalAabbMaxz += linMotion.z(); 
+	else
+		temporalAabbMinz += linMotion.z();
+
+	//add conservative angular motion
+	btScalar angularMotion = angvel.length() * getAngularMotionDisc() * timeStep;
+	btVector3 angularMotion3d(angularMotion,angularMotion,angularMotion);
+	temporalAabbMin = btVector3(temporalAabbMinx,temporalAabbMiny,temporalAabbMinz);
+	temporalAabbMax = btVector3(temporalAabbMaxx,temporalAabbMaxy,temporalAabbMaxz);
+
+	temporalAabbMin -= angularMotion3d;
+	temporalAabbMax += angularMotion3d;
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCollisionShape.h	(revision 6952)
@@ -0,0 +1,112 @@
+/*
+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 COLLISION_SHAPE_H
+#define COLLISION_SHAPE_H
+
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btMatrix3x3.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types
+
+///The btCollisionShape class provides an interface for collision shapes that can be shared among btCollisionObjects.
+class btCollisionShape
+{
+protected:
+	int m_shapeType;
+	void* m_userPointer;
+
+public:
+
+	btCollisionShape() : m_shapeType (INVALID_SHAPE_PROXYTYPE), m_userPointer(0)
+	{
+	}
+
+	virtual ~btCollisionShape()
+	{
+	}
+
+	///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t.
+	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0;
+
+	virtual void	getBoundingSphere(btVector3& center,btScalar& radius) const;
+
+	///getAngularMotionDisc returns the maximus radius needed for Conservative Advancement to handle time-of-impact with rotations.
+	virtual btScalar	getAngularMotionDisc() const;
+
+	virtual btScalar	getContactBreakingThreshold() const;
+
+
+	///calculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep)
+	///result is conservative
+	void calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax) const;
+
+#ifndef __SPU__
+
+	SIMD_FORCE_INLINE bool	isPolyhedral() const
+	{
+		return btBroadphaseProxy::isPolyhedral(getShapeType());
+	}
+
+	SIMD_FORCE_INLINE bool	isConvex() const
+	{
+		return btBroadphaseProxy::isConvex(getShapeType());
+	}
+	SIMD_FORCE_INLINE bool	isConcave() const
+	{
+		return btBroadphaseProxy::isConcave(getShapeType());
+	}
+	SIMD_FORCE_INLINE bool	isCompound() const
+	{
+		return btBroadphaseProxy::isCompound(getShapeType());
+	}
+
+	///isInfinite is used to catch simulation error (aabb check)
+	SIMD_FORCE_INLINE bool isInfinite() const
+	{
+		return btBroadphaseProxy::isInfinite(getShapeType());
+	}
+
+	
+	virtual void	setLocalScaling(const btVector3& scaling) =0;
+	virtual const btVector3& getLocalScaling() const =0;
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const = 0;
+
+
+//debugging support
+	virtual const char*	getName()const =0 ;
+#endif //__SPU__
+
+	
+	int		getShapeType() const { return m_shapeType; }
+	virtual void	setMargin(btScalar margin) = 0;
+	virtual btScalar	getMargin() const = 0;
+
+	
+	///optional user data pointer
+	void	setUserPointer(void*  userPtr)
+	{
+		m_userPointer = userPtr;
+	}
+
+	void*	getUserPointer() const
+	{
+		return m_userPointer;
+	}
+
+};	
+
+#endif //COLLISION_SHAPE_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCompoundShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCompoundShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCompoundShape.cpp	(revision 6952)
@@ -0,0 +1,273 @@
+/*
+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 "btCompoundShape.h"
+#include "btCollisionShape.h"
+#include "BulletCollision/BroadphaseCollision/btDbvt.h"
+
+btCompoundShape::btCompoundShape(bool enableDynamicAabbTree)
+: m_localAabbMin(btScalar(1e30),btScalar(1e30),btScalar(1e30)),
+m_localAabbMax(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)),
+m_collisionMargin(btScalar(0.)),
+m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
+m_dynamicAabbTree(0),
+m_updateRevision(1)
+{
+	m_shapeType = COMPOUND_SHAPE_PROXYTYPE;
+
+	if (enableDynamicAabbTree)
+	{
+		void* mem = btAlignedAlloc(sizeof(btDbvt),16);
+		m_dynamicAabbTree = new(mem) btDbvt();
+		btAssert(mem==m_dynamicAabbTree);
+	}
+}
+
+
+btCompoundShape::~btCompoundShape()
+{
+	if (m_dynamicAabbTree)
+	{
+		m_dynamicAabbTree->~btDbvt();
+		btAlignedFree(m_dynamicAabbTree);
+	}
+}
+
+void	btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape)
+{
+	m_updateRevision++;
+	//m_childTransforms.push_back(localTransform);
+	//m_childShapes.push_back(shape);
+	btCompoundShapeChild child;
+	child.m_transform = localTransform;
+	child.m_childShape = shape;
+	child.m_childShapeType = shape->getShapeType();
+	child.m_childMargin = shape->getMargin();
+
+	
+	//extend the local aabbMin/aabbMax
+	btVector3 localAabbMin,localAabbMax;
+	shape->getAabb(localTransform,localAabbMin,localAabbMax);
+	for (int i=0;i<3;i++)
+	{
+		if (m_localAabbMin[i] > localAabbMin[i])
+		{
+			m_localAabbMin[i] = localAabbMin[i];
+		}
+		if (m_localAabbMax[i] < localAabbMax[i])
+		{
+			m_localAabbMax[i] = localAabbMax[i];
+		}
+
+	}
+	if (m_dynamicAabbTree)
+	{
+		const btDbvtVolume	bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
+		int index = m_children.size();
+		child.m_node = m_dynamicAabbTree->insert(bounds,(void*)index);
+	}
+
+	m_children.push_back(child);
+
+}
+
+void	btCompoundShape::updateChildTransform(int childIndex, const btTransform& newChildTransform)
+{
+	m_children[childIndex].m_transform = newChildTransform;
+
+	if (m_dynamicAabbTree)
+	{
+		///update the dynamic aabb tree
+		btVector3 localAabbMin,localAabbMax;
+		m_children[childIndex].m_childShape->getAabb(newChildTransform,localAabbMin,localAabbMax);
+		ATTRIBUTE_ALIGNED16(btDbvtVolume)	bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax);
+		int index = m_children.size()-1;
+		m_dynamicAabbTree->update(m_children[childIndex].m_node,bounds);
+	}
+
+	recalculateLocalAabb();
+}
+
+void btCompoundShape::removeChildShapeByIndex(int childShapeIndex)
+{
+	m_updateRevision++;
+	btAssert(childShapeIndex >=0 && childShapeIndex < m_children.size());
+	if (m_dynamicAabbTree)
+	{
+		m_dynamicAabbTree->remove(m_children[childShapeIndex].m_node);
+	}
+	m_children.swap(childShapeIndex,m_children.size()-1);
+	m_children.pop_back();
+
+}
+
+
+
+void btCompoundShape::removeChildShape(btCollisionShape* shape)
+{
+	m_updateRevision++;
+	// Find the children containing the shape specified, and remove those children.
+	//note: there might be multiple children using the same shape!
+	for(int i = m_children.size()-1; i >= 0 ; i--)
+	{
+		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();
+		}
+	}
+
+
+
+	recalculateLocalAabb();
+}
+
+void btCompoundShape::recalculateLocalAabb()
+{
+	// Recalculate the local aabb
+	// 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));
+
+	//extend the local aabbMin/aabbMax
+	for (int j = 0; j < m_children.size(); j++)
+	{
+		btVector3 localAabbMin,localAabbMax;
+		m_children[j].m_childShape->getAabb(m_children[j].m_transform, localAabbMin, localAabbMax);
+		for (int i=0;i<3;i++)
+		{
+			if (m_localAabbMin[i] > localAabbMin[i])
+				m_localAabbMin[i] = localAabbMin[i];
+			if (m_localAabbMax[i] < localAabbMax[i])
+				m_localAabbMax[i] = localAabbMax[i];
+		}
+	}
+}
+
+///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
+void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
+	btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
+	
+	//avoid an illegal AABB when there are no children
+	if (!m_children.size())
+	{
+		localHalfExtents.setValue(0,0,0);
+		localCenter.setValue(0,0,0);
+	}
+	localHalfExtents += btVector3(getMargin(),getMargin(),getMargin());
+		
+
+	btMatrix3x3 abs_b = trans.getBasis().absolute();  
+
+	btVector3 center = trans(localCenter);
+
+	btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
+		abs_b[1].dot(localHalfExtents),
+		abs_b[2].dot(localHalfExtents));
+	aabbMin = center-extent;
+	aabbMax = center+extent;
+	
+}
+
+void	btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+	//approximation: take the inertia from the aabb for now
+	btTransform ident;
+	ident.setIdentity();
+	btVector3 aabbMin,aabbMax;
+	getAabb(ident,aabbMin,aabbMax);
+
+	btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5);
+
+	btScalar lx=btScalar(2.)*(halfExtents.x());
+	btScalar ly=btScalar(2.)*(halfExtents.y());
+	btScalar lz=btScalar(2.)*(halfExtents.z());
+
+	inertia[0] = mass/(btScalar(12.0)) * (ly*ly + lz*lz);
+	inertia[1] = mass/(btScalar(12.0)) * (lx*lx + lz*lz);
+	inertia[2] = mass/(btScalar(12.0)) * (lx*lx + ly*ly);
+
+}
+
+
+
+
+void btCompoundShape::calculatePrincipalAxisTransform(btScalar* masses, btTransform& principal, btVector3& inertia) const
+{
+	int n = m_children.size();
+
+	btScalar totalMass = 0;
+	btVector3 center(0, 0, 0);
+	int k;
+
+	for (k = 0; k < n; k++)
+	{
+		center += m_children[k].m_transform.getOrigin() * masses[k];
+		totalMass += masses[k];
+	}
+	center /= totalMass;
+	principal.setOrigin(center);
+
+	btMatrix3x3 tensor(0, 0, 0, 0, 0, 0, 0, 0, 0);
+	for ( k = 0; k < n; k++)
+	{
+		btVector3 i;
+		m_children[k].m_childShape->calculateLocalInertia(masses[k], i);
+
+		const btTransform& t = m_children[k].m_transform;
+		btVector3 o = t.getOrigin() - center;
+
+		//compute inertia tensor in coordinate system of compound shape
+		btMatrix3x3 j = t.getBasis().transpose();
+		j[0] *= i[0];
+		j[1] *= i[1];
+		j[2] *= i[2];
+		j = t.getBasis() * j;
+
+		//add inertia tensor
+		tensor[0] += j[0];
+		tensor[1] += j[1];
+		tensor[2] += j[2];
+
+		//compute inertia tensor of pointmass at o
+		btScalar o2 = o.length2();
+		j[0].setValue(o2, 0, 0);
+		j[1].setValue(0, o2, 0);
+		j[2].setValue(0, 0, o2);
+		j[0] += o * -o.x(); 
+		j[1] += o * -o.y(); 
+		j[2] += o * -o.z();
+
+		//add inertia tensor of pointmass
+		tensor[0] += masses[k] * j[0];
+		tensor[1] += masses[k] * j[1];
+		tensor[2] += masses[k] * j[2];
+	}
+
+	tensor.diagonalize(principal.getBasis(), btScalar(0.00001), 20);
+	inertia.setValue(tensor[0][0], tensor[1][1], tensor[2][2]);
+}
+
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCompoundShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCompoundShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCompoundShape.h	(revision 6952)
@@ -0,0 +1,172 @@
+/*
+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 COMPOUND_SHAPE_H
+#define COMPOUND_SHAPE_H
+
+#include "btCollisionShape.h"
+
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btMatrix3x3.h"
+#include "btCollisionMargin.h"
+#include "LinearMath/btAlignedObjectArray.h"
+
+//class btOptimizedBvh;
+struct btDbvt;
+
+ATTRIBUTE_ALIGNED16(struct) btCompoundShapeChild
+{
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	btTransform			m_transform;
+	btCollisionShape*	m_childShape;
+	int					m_childShapeType;
+	btScalar			m_childMargin;
+	struct btDbvtNode*	m_node;
+};
+
+SIMD_FORCE_INLINE bool operator==(const btCompoundShapeChild& c1, const btCompoundShapeChild& c2)
+{
+	return  ( c1.m_transform      == c2.m_transform &&
+		c1.m_childShape     == c2.m_childShape &&
+		c1.m_childShapeType == c2.m_childShapeType &&
+		c1.m_childMargin    == c2.m_childMargin );
+}
+
+/// The btCompoundShape allows to store multiple other btCollisionShapes
+/// This allows for moving concave collision objects. This is more general then the static concave btBvhTriangleMeshShape.
+/// It has an (optional) dynamic aabb tree to accelerate early rejection tests. 
+/// @todo: This aabb tree can also be use to speed up ray tests on btCompoundShape, see http://code.google.com/p/bullet/issues/detail?id=25
+/// Currently, removal of child shapes is only supported when disabling the aabb tree (pass 'false' in the constructor of btCompoundShape)
+ATTRIBUTE_ALIGNED16(class) btCompoundShape	: public btCollisionShape
+{
+	btAlignedObjectArray<btCompoundShapeChild> m_children;
+	btVector3						m_localAabbMin;
+	btVector3						m_localAabbMax;
+
+	btDbvt*							m_dynamicAabbTree;
+
+	///increment m_updateRevision when adding/removing/replacing child shapes, so that some caches can be updated
+	int								m_updateRevision;
+
+public:
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	btCompoundShape(bool enableDynamicAabbTree = true);
+
+	virtual ~btCompoundShape();
+
+	void	addChildShape(const btTransform& localTransform,btCollisionShape* shape);
+
+	/// Remove all children shapes that contain the specified shape
+	virtual void removeChildShape(btCollisionShape* shape);
+
+	void removeChildShapeByIndex(int childShapeindex);
+
+
+	int		getNumChildShapes() const
+	{
+		return int (m_children.size());
+	}
+
+	btCollisionShape* getChildShape(int index)
+	{
+		return m_children[index].m_childShape;
+	}
+	const btCollisionShape* getChildShape(int index) const
+	{
+		return m_children[index].m_childShape;
+	}
+
+	btTransform&	getChildTransform(int index)
+	{
+		return m_children[index].m_transform;
+	}
+	const btTransform&	getChildTransform(int index) const
+	{
+		return m_children[index].m_transform;
+	}
+
+	///set a new transform for a child, and update internal data structures (local aabb and dynamic tree)
+	void	updateChildTransform(int childIndex, const btTransform& newChildTransform);
+
+
+	btCompoundShapeChild* getChildList()
+	{
+		return &m_children[0];
+	}
+
+	///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
+	virtual	void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
+
+	/** Re-calculate the local Aabb. Is called at the end of removeChildShapes. 
+	Use this yourself if you modify the children or their transforms. */
+	virtual void recalculateLocalAabb(); 
+
+	virtual void	setLocalScaling(const btVector3& scaling)
+	{
+		m_localScaling = scaling;
+	}
+	virtual const btVector3& getLocalScaling() const 
+	{
+		return m_localScaling;
+	}
+
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
+	virtual void	setMargin(btScalar margin)
+	{
+		m_collisionMargin = margin;
+	}
+	virtual btScalar	getMargin() const
+	{
+		return m_collisionMargin;
+	}
+	virtual const char*	getName()const
+	{
+		return "Compound";
+	}
+
+	//this is optional, but should make collision queries faster, by culling non-overlapping nodes
+	void	createAabbTreeFromChildren();
+
+	btDbvt*							getDynamicAabbTree()
+	{
+		return m_dynamicAabbTree;
+	}
+
+	///computes the exact moment of inertia and the transform from the coordinate system defined by the principal axes of the moment of inertia
+	///and the center of mass to the current coordinate system. "masses" points to an array of masses of the children. The resulting transform
+	///"principal" has to be applied inversely to all children transforms in order for the local coordinate system of the compound
+	///shape to be centered at the center of mass and to coincide with the principal axes. This also necessitates a correction of the world transform
+	///of the collision object by the principal transform.
+	void calculatePrincipalAxisTransform(btScalar* masses, btTransform& principal, btVector3& inertia) const;
+
+	int	getUpdateRevision() const
+	{
+		return m_updateRevision;
+	}
+
+private:
+	btScalar	m_collisionMargin;
+protected:
+	btVector3	m_localScaling;
+
+};
+
+
+
+#endif //COMPOUND_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConcaveShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConcaveShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConcaveShape.cpp	(revision 6952)
@@ -0,0 +1,28 @@
+
+/*
+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 "btConcaveShape.h"
+
+btConcaveShape::btConcaveShape() : m_collisionMargin(btScalar(0.))
+{
+
+}
+
+btConcaveShape::~btConcaveShape()
+{
+
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConcaveShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConcaveShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConcaveShape.h	(revision 6952)
@@ -0,0 +1,60 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef CONCAVE_SHAPE_H
+#define CONCAVE_SHAPE_H
+
+#include "btCollisionShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "btTriangleCallback.h"
+
+/// PHY_ScalarType enumerates possible scalar types.
+/// See the btStridingMeshInterface or btHeightfieldTerrainShape for its use
+typedef enum PHY_ScalarType {
+	PHY_FLOAT,
+	PHY_DOUBLE,
+	PHY_INTEGER,
+	PHY_SHORT,
+	PHY_FIXEDPOINT88,
+	PHY_UCHAR
+} PHY_ScalarType;
+
+///The btConcaveShape class provides an interface for non-moving (static) concave shapes.
+///It has been implemented by the btStaticPlaneShape, btBvhTriangleMeshShape and btHeightfieldTerrainShape.
+class btConcaveShape : public btCollisionShape
+{
+protected:
+	btScalar m_collisionMargin;
+
+public:
+	btConcaveShape();
+
+	virtual ~btConcaveShape();
+
+	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const = 0;
+
+	virtual btScalar getMargin() const {
+		return m_collisionMargin;
+	}
+	virtual void setMargin(btScalar collisionMargin)
+	{
+		m_collisionMargin = collisionMargin;
+	}
+
+
+
+};
+
+#endif //CONCAVE_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConeShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConeShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConeShape.cpp	(revision 6952)
@@ -0,0 +1,133 @@
+/*
+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 "btConeShape.h"
+
+
+
+btConeShape::btConeShape (btScalar radius,btScalar height): btConvexInternalShape (),
+m_radius (radius),
+m_height(height)
+{
+	m_shapeType = CONE_SHAPE_PROXYTYPE;
+	setConeUpIndex(1);
+	btVector3 halfExtents;
+	m_sinAngle = (m_radius / btSqrt(m_radius * m_radius + m_height * m_height));
+}
+
+btConeShapeZ::btConeShapeZ (btScalar radius,btScalar height):
+btConeShape(radius,height)
+{
+	setConeUpIndex(2);
+}
+
+btConeShapeX::btConeShapeX (btScalar radius,btScalar height):
+btConeShape(radius,height)
+{
+	setConeUpIndex(0);
+}
+
+///choose upAxis index
+void	btConeShape::setConeUpIndex(int upIndex)
+{
+	switch (upIndex)
+	{
+	case 0:
+			m_coneIndices[0] = 1;
+			m_coneIndices[1] = 0;
+			m_coneIndices[2] = 2;
+		break;
+	case 1:
+			m_coneIndices[0] = 0;
+			m_coneIndices[1] = 1;
+			m_coneIndices[2] = 2;
+		break;
+	case 2:
+			m_coneIndices[0] = 0;
+			m_coneIndices[1] = 2;
+			m_coneIndices[2] = 1;
+		break;
+	default:
+		btAssert(0);
+	};
+}
+
+btVector3 btConeShape::coneLocalSupport(const btVector3& v) const
+{
+	
+	btScalar halfHeight = m_height * btScalar(0.5);
+
+ if (v[m_coneIndices[1]] > v.length() * m_sinAngle)
+ {
+	btVector3 tmp;
+
+	tmp[m_coneIndices[0]] = btScalar(0.);
+	tmp[m_coneIndices[1]] = halfHeight;
+	tmp[m_coneIndices[2]] = btScalar(0.);
+	return tmp;
+ }
+  else {
+    btScalar s = btSqrt(v[m_coneIndices[0]] * v[m_coneIndices[0]] + v[m_coneIndices[2]] * v[m_coneIndices[2]]);
+    if (s > SIMD_EPSILON) {
+      btScalar d = m_radius / s;
+	  btVector3 tmp;
+	  tmp[m_coneIndices[0]] = v[m_coneIndices[0]] * d;
+	  tmp[m_coneIndices[1]] = -halfHeight;
+	  tmp[m_coneIndices[2]] = v[m_coneIndices[2]] * d;
+	  return tmp;
+    }
+    else  {
+		btVector3 tmp;
+		tmp[m_coneIndices[0]] = btScalar(0.);
+		tmp[m_coneIndices[1]] = -halfHeight;
+		tmp[m_coneIndices[2]] = btScalar(0.);
+		return tmp;
+	}
+  }
+
+}
+
+btVector3	btConeShape::localGetSupportingVertexWithoutMargin(const btVector3& vec) const
+{
+		return coneLocalSupport(vec);
+}
+
+void	btConeShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+	for (int i=0;i<numVectors;i++)
+	{
+		const btVector3& vec = vectors[i];
+		supportVerticesOut[i] = coneLocalSupport(vec);
+	}
+}
+
+
+btVector3	btConeShape::localGetSupportingVertex(const btVector3& vec)  const
+{
+	btVector3 supVertex = coneLocalSupport(vec);
+	if ( getMargin()!=btScalar(0.) )
+	{
+		btVector3 vecnorm = vec;
+		if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
+		{
+			vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
+		} 
+		vecnorm.normalize();
+		supVertex+= getMargin() * vecnorm;
+	}
+	return supVertex;
+}
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConeShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConeShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConeShape.h	(revision 6952)
@@ -0,0 +1,100 @@
+/*
+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 CONE_MINKOWSKI_H
+#define CONE_MINKOWSKI_H
+
+#include "btConvexInternalShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+
+///The btConeShape implements a cone shape primitive, centered around the origin and aligned with the Y axis. The btConeShapeX is aligned around the X axis and btConeShapeZ around the Z axis.
+class btConeShape : public btConvexInternalShape
+
+{
+
+	btScalar m_sinAngle;
+	btScalar m_radius;
+	btScalar m_height;
+	int		m_coneIndices[3];
+	btVector3 coneLocalSupport(const btVector3& v) const;
+
+
+public:
+	btConeShape (btScalar radius,btScalar height);
+	
+	virtual btVector3	localGetSupportingVertex(const btVector3& vec) const;
+	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec) const;
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+
+	btScalar getRadius() const { return m_radius;}
+	btScalar getHeight() const { return m_height;}
+
+
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const
+	{
+		btTransform identity;
+		identity.setIdentity();
+		btVector3 aabbMin,aabbMax;
+		getAabb(identity,aabbMin,aabbMax);
+
+		btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5);
+
+		btScalar margin = getMargin();
+
+		btScalar lx=btScalar(2.)*(halfExtents.x()+margin);
+		btScalar ly=btScalar(2.)*(halfExtents.y()+margin);
+		btScalar lz=btScalar(2.)*(halfExtents.z()+margin);
+		const btScalar x2 = lx*lx;
+		const btScalar y2 = ly*ly;
+		const btScalar z2 = lz*lz;
+		const btScalar scaledmass = mass * btScalar(0.08333333);
+
+		inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
+
+//		inertia.x() = scaledmass * (y2+z2);
+//		inertia.y() = scaledmass * (x2+z2);
+//		inertia.z() = scaledmass * (x2+y2);
+	}
+
+
+		virtual const char*	getName()const 
+		{
+			return "Cone";
+		}
+		
+		///choose upAxis index
+		void	setConeUpIndex(int upIndex);
+		
+		int	getConeUpIndex() const
+		{
+			return m_coneIndices[1];
+		}
+};
+
+///btConeShape implements a Cone shape, around the X axis
+class btConeShapeX : public btConeShape
+{
+	public:
+		btConeShapeX(btScalar radius,btScalar height);
+};
+
+///btConeShapeZ implements a Cone shape, around the Z axis
+class btConeShapeZ : public btConeShape
+{
+	public:
+		btConeShapeZ(btScalar radius,btScalar height);
+};
+#endif //CONE_MINKOWSKI_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexHullShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexHullShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexHullShape.cpp	(revision 6952)
@@ -0,0 +1,187 @@
+/*
+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 "btConvexHullShape.h"
+#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+
+#include "LinearMath/btQuaternion.h"
+
+
+
+btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride) : btPolyhedralConvexShape ()
+{
+	m_shapeType = CONVEX_HULL_SHAPE_PROXYTYPE;
+	m_unscaledPoints.resize(numPoints);
+
+	unsigned char* pointsBaseAddress = (unsigned char*)points;
+
+	for (int i=0;i<numPoints;i++)
+	{
+		btVector3* point = (btVector3*)(pointsBaseAddress + i*stride);
+		m_unscaledPoints[i] = point[0];
+	}
+
+	recalcLocalAabb();
+
+}
+
+
+
+void btConvexHullShape::setLocalScaling(const btVector3& scaling)
+{
+	m_localScaling = scaling;
+	recalcLocalAabb();
+}
+
+void btConvexHullShape::addPoint(const btVector3& point)
+{
+	m_unscaledPoints.push_back(point);
+	recalcLocalAabb();
+
+}
+
+btVector3	btConvexHullShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)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;
+	}
+
+
+	for (int i=0;i<m_unscaledPoints.size();i++)
+	{
+		btVector3 vtx = m_unscaledPoints[i] * m_localScaling;
+
+		newDot = vec.dot(vtx);
+		if (newDot > maxDot)
+		{
+			maxDot = newDot;
+			supVec = vtx;
+		}
+	}
+	return supVec;
+}
+
+void	btConvexHullShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+	btScalar newDot;
+	//use 'w' component of supportVerticesOut?
+	{
+		for (int i=0;i<numVectors;i++)
+		{
+			supportVerticesOut[i][3] = btScalar(-1e30);
+		}
+	}
+	for (int i=0;i<m_unscaledPoints.size();i++)
+	{
+		btVector3 vtx = getScaledPoint(i);
+
+		for (int j=0;j<numVectors;j++)
+		{
+			const btVector3& vec = vectors[j];
+			
+			newDot = vec.dot(vtx);
+			if (newDot > supportVerticesOut[j][3])
+			{
+				//WARNING: don't swap next lines, the w component would get overwritten!
+				supportVerticesOut[j] = vtx;
+				supportVerticesOut[j][3] = newDot;
+			}
+		}
+	}
+
+
+
+}
+	
+
+
+btVector3	btConvexHullShape::localGetSupportingVertex(const btVector3& vec)const
+{
+	btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
+
+	if ( getMargin()!=btScalar(0.) )
+	{
+		btVector3 vecnorm = vec;
+		if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
+		{
+			vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
+		} 
+		vecnorm.normalize();
+		supVertex+= getMargin() * vecnorm;
+	}
+	return supVertex;
+}
+
+
+
+
+
+
+
+
+
+//currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection
+//Please note that you can debug-draw btConvexHullShape with the Raytracer Demo
+int	btConvexHullShape::getNumVertices() const
+{
+	return m_unscaledPoints.size();
+}
+
+int btConvexHullShape::getNumEdges() const
+{
+	return m_unscaledPoints.size();
+}
+
+void btConvexHullShape::getEdge(int i,btVector3& pa,btVector3& pb) const
+{
+
+	int index0 = i%m_unscaledPoints.size();
+	int index1 = (i+1)%m_unscaledPoints.size();
+	pa = getScaledPoint(index0);
+	pb = getScaledPoint(index1);
+}
+
+void btConvexHullShape::getVertex(int i,btVector3& vtx) const
+{
+	vtx = getScaledPoint(i);
+}
+
+int	btConvexHullShape::getNumPlanes() const
+{
+	return 0;
+}
+
+void btConvexHullShape::getPlane(btVector3& ,btVector3& ,int ) const
+{
+
+	btAssert(0);
+}
+
+//not yet
+bool btConvexHullShape::isInside(const btVector3& ,btScalar ) const
+{
+	btAssert(0);
+	return false;
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexHullShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexHullShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexHullShape.h	(revision 6952)
@@ -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_HULL_SHAPE_H
+#define CONVEX_HULL_SHAPE_H
+
+#include "btPolyhedralConvexShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#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
+{
+	btAlignedObjectArray<btVector3>	m_unscaledPoints;
+
+public:
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	
+	///this constructor optionally takes in a pointer to points. Each point is assumed to be 3 consecutive btScalar (x,y,z), the striding defines the number of bytes between each point, in memory.
+	///It is easier to not pass any points in the constructor, and just add one point at a time, using addPoint.
+	///btConvexHullShape make an internal copy of the points.
+	btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btVector3));
+
+	void addPoint(const btVector3& point);
+
+	
+	btVector3* getUnscaledPoints()
+	{
+		return &m_unscaledPoints[0];
+	}
+
+	const btVector3* getUnscaledPoints() const
+	{
+		return &m_unscaledPoints[0];
+	}
+
+	///getPoints is obsolete, please use getUnscaledPoints
+	const btVector3* getPoints() const
+	{
+		return getUnscaledPoints();
+	}
+
+	
+
+
+	SIMD_FORCE_INLINE	btVector3 getScaledPoint(int i) const
+	{
+		return m_unscaledPoints[i] * m_localScaling;
+	}
+
+	SIMD_FORCE_INLINE	int getNumPoints() const 
+	{
+		return m_unscaledPoints.size();
+	}
+
+	virtual btVector3	localGetSupportingVertex(const btVector3& vec)const;
+	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+	
+
+
+	//debugging
+	virtual const char*	getName()const {return "Convex";}
+
+	
+	virtual int	getNumVertices() const;
+	virtual int getNumEdges() const;
+	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
+	virtual void getVertex(int i,btVector3& vtx) const;
+	virtual int	getNumPlanes() const;
+	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const;
+	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const;
+
+	///in case we receive negative scaling
+	virtual void	setLocalScaling(const btVector3& scaling);
+
+};
+
+
+#endif //CONVEX_HULL_SHAPE_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.cpp	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+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 "btConvexInternalShape.h"
+
+
+
+btConvexInternalShape::btConvexInternalShape()
+: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)),
+m_collisionMargin(CONVEX_DISTANCE_MARGIN)
+{
+}
+
+
+void	btConvexInternalShape::setLocalScaling(const btVector3& scaling)
+{
+	m_localScaling = scaling.absolute();
+}
+
+
+
+void	btConvexInternalShape::getAabbSlow(const btTransform& trans,btVector3&minAabb,btVector3&maxAabb) const
+{
+
+	btScalar margin = getMargin();
+	for (int i=0;i<3;i++)
+	{
+		btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
+		vec[i] = btScalar(1.);
+
+		btVector3 sv = localGetSupportingVertex(vec*trans.getBasis());
+
+		btVector3 tmp = trans(sv);
+		maxAabb[i] = tmp[i]+margin;
+		vec[i] = btScalar(-1.);
+		tmp = trans(localGetSupportingVertex(vec*trans.getBasis()));
+		minAabb[i] = tmp[i]-margin;
+	}
+}
+
+
+
+btVector3	btConvexInternalShape::localGetSupportingVertex(const btVector3& vec)const
+{
+#ifndef __SPU__
+
+	 btVector3	supVertex = localGetSupportingVertexWithoutMargin(vec);
+
+	if ( getMargin()!=btScalar(0.) )
+	{
+		btVector3 vecnorm = vec;
+		if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
+		{
+			vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
+		} 
+		vecnorm.normalize();
+		supVertex+= getMargin() * vecnorm;
+	}
+	return supVertex;
+
+#else
+	btAssert(0);
+	return btVector3(0,0,0);
+#endif //__SPU__
+
+ }
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexInternalShape.h	(revision 6952)
@@ -0,0 +1,93 @@
+
+#ifndef BT_CONVEX_INTERNAL_SHAPE_H
+#define BT_CONVEX_INTERNAL_SHAPE_H
+
+#include "btConvexShape.h"
+
+///The btConvexInternalShape is an internal base class, shared by most convex shape implementations.
+class btConvexInternalShape : public btConvexShape
+{
+
+	protected:
+
+	//local scaling. collisionMargin is not scaled !
+	btVector3	m_localScaling;
+
+	btVector3	m_implicitShapeDimensions;
+	
+	btScalar	m_collisionMargin;
+
+	btScalar	m_padding;
+
+	btConvexInternalShape();
+
+public:
+
+	
+
+	virtual ~btConvexInternalShape()
+	{
+
+	}
+
+	virtual btVector3	localGetSupportingVertex(const btVector3& vec)const;
+
+	const btVector3& getImplicitShapeDimensions() const
+	{
+		return m_implicitShapeDimensions;
+	}
+
+	///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
+	void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+	{
+		getAabbSlow(t,aabbMin,aabbMax);
+	}
+
+
+	
+	virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
+
+
+	virtual void	setLocalScaling(const btVector3& scaling);
+	virtual const btVector3& getLocalScaling() const 
+	{
+		return m_localScaling;
+	}
+
+	const btVector3& getLocalScalingNV() const 
+	{
+		return m_localScaling;
+	}
+
+	virtual void	setMargin(btScalar margin)
+	{
+		m_collisionMargin = margin;
+	}
+	virtual btScalar	getMargin() const
+	{
+		return m_collisionMargin;
+	}
+
+	btScalar	getMarginNV() const
+	{
+		return m_collisionMargin;
+	}
+
+	virtual int		getNumPreferredPenetrationDirections() const
+	{
+		return 0;
+	}
+	
+	virtual void	getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
+	{
+		(void)penetrationVector;
+		(void)index;
+		btAssert(0);
+	}
+
+
+	
+};
+
+
+#endif //BT_CONVEX_INTERNAL_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp	(revision 6952)
@@ -0,0 +1,156 @@
+/*
+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 "btConvexPointCloudShape.h"
+#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+
+#include "LinearMath/btQuaternion.h"
+
+void btConvexPointCloudShape::setLocalScaling(const btVector3& scaling)
+{
+	m_localScaling = scaling;
+	recalcLocalAabb();
+}
+
+#ifndef __SPU__
+btVector3	btConvexPointCloudShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)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;
+	}
+
+
+	for (int i=0;i<m_numPoints;i++)
+	{
+		btVector3 vtx = getScaledPoint(i);
+
+		newDot = vec.dot(vtx);
+		if (newDot > maxDot)
+		{
+			maxDot = newDot;
+			supVec = vtx;
+		}
+	}
+	return supVec;
+}
+
+void	btConvexPointCloudShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+	btScalar newDot;
+	//use 'w' component of supportVerticesOut?
+	{
+		for (int i=0;i<numVectors;i++)
+		{
+			supportVerticesOut[i][3] = btScalar(-1e30);
+		}
+	}
+	for (int i=0;i<m_numPoints;i++)
+	{
+		btVector3 vtx = getScaledPoint(i);
+
+		for (int j=0;j<numVectors;j++)
+		{
+			const btVector3& vec = vectors[j];
+			
+			newDot = vec.dot(vtx);
+			if (newDot > supportVerticesOut[j][3])
+			{
+				//WARNING: don't swap next lines, the w component would get overwritten!
+				supportVerticesOut[j] = vtx;
+				supportVerticesOut[j][3] = newDot;
+			}
+		}
+	}
+
+
+
+}
+	
+
+
+btVector3	btConvexPointCloudShape::localGetSupportingVertex(const btVector3& vec)const
+{
+	btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
+
+	if ( getMargin()!=btScalar(0.) )
+	{
+		btVector3 vecnorm = vec;
+		if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
+		{
+			vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
+		} 
+		vecnorm.normalize();
+		supVertex+= getMargin() * vecnorm;
+	}
+	return supVertex;
+}
+
+
+#endif
+
+
+
+
+
+
+//currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection
+//Please note that you can debug-draw btConvexHullShape with the Raytracer Demo
+int	btConvexPointCloudShape::getNumVertices() const
+{
+	return m_numPoints;
+}
+
+int btConvexPointCloudShape::getNumEdges() const
+{
+	return 0;
+}
+
+void btConvexPointCloudShape::getEdge(int i,btVector3& pa,btVector3& pb) const
+{
+	btAssert (0);
+}
+
+void btConvexPointCloudShape::getVertex(int i,btVector3& vtx) const
+{
+	vtx = m_unscaledPoints[i]*m_localScaling;
+}
+
+int	btConvexPointCloudShape::getNumPlanes() const
+{
+	return 0;
+}
+
+void btConvexPointCloudShape::getPlane(btVector3& ,btVector3& ,int ) const
+{
+
+	btAssert(0);
+}
+
+//not yet
+bool btConvexPointCloudShape::isInside(const btVector3& ,btScalar ) const
+{
+	btAssert(0);
+	return false;
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexPointCloudShape.h	(revision 6952)
@@ -0,0 +1,96 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_CONVEX_POINT_CLOUD_SHAPE_H
+#define BT_CONVEX_POINT_CLOUD_SHAPE_H
+
+#include "btPolyhedralConvexShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "LinearMath/btAlignedObjectArray.h"
+
+///The btConvexPointCloudShape implements an implicit convex hull of an array of vertices.
+ATTRIBUTE_ALIGNED16(class) btConvexPointCloudShape : public btPolyhedralConvexShape
+{
+	btVector3* m_unscaledPoints;
+	int m_numPoints;
+
+public:
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	btConvexPointCloudShape(btVector3* points,int numPoints, const btVector3& localScaling,bool computeAabb = true)
+	{
+		m_localScaling = localScaling;
+		m_shapeType = CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE;
+		m_unscaledPoints = points;
+		m_numPoints = numPoints;
+
+		if (computeAabb)
+			recalcLocalAabb();
+	}
+
+	void setPoints (btVector3* points, int numPoints, bool computeAabb = true)
+	{
+		m_unscaledPoints = points;
+		m_numPoints = numPoints;
+
+		if (computeAabb)
+			recalcLocalAabb();
+	}
+
+	SIMD_FORCE_INLINE	btVector3* getUnscaledPoints()
+	{
+		return m_unscaledPoints;
+	}
+
+	SIMD_FORCE_INLINE	const btVector3* getUnscaledPoints() const
+	{
+		return m_unscaledPoints;
+	}
+
+	SIMD_FORCE_INLINE	int getNumPoints() const 
+	{
+		return m_numPoints;
+	}
+
+	SIMD_FORCE_INLINE	btVector3	getScaledPoint( int index) const
+	{
+		return m_unscaledPoints[index] * m_localScaling;
+	}
+
+#ifndef __SPU__
+	virtual btVector3	localGetSupportingVertex(const btVector3& vec)const;
+	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+#endif
+
+
+	//debugging
+	virtual const char*	getName()const {return "ConvexPointCloud";}
+
+	virtual int	getNumVertices() const;
+	virtual int getNumEdges() const;
+	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
+	virtual void getVertex(int i,btVector3& vtx) const;
+	virtual int	getNumPlanes() const;
+	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const;
+	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const;
+
+	///in case we receive negative scaling
+	virtual void	setLocalScaling(const btVector3& scaling);
+};
+
+
+#endif //BT_CONVEX_POINT_CLOUD_SHAPE_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexShape.cpp	(revision 6952)
@@ -0,0 +1,379 @@
+/*
+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 "btConvexShape.h"
+#include "btTriangleShape.h"
+#include "btSphereShape.h"
+#include "btCylinderShape.h"
+#include "btCapsuleShape.h"
+#include "btConvexHullShape.h"
+#include "btConvexPointCloudShape.h"
+
+btConvexShape::btConvexShape ()
+{
+}
+
+btConvexShape::~btConvexShape()
+{
+
+}
+
+
+
+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;
+	}
+
+
+	for (int i=0;i<numPoints;i++)
+	{
+		btVector3 vtx = points[i] * localScaling;
+
+		newDot = vec.dot(vtx);
+		if (newDot > maxDot)
+		{
+			maxDot = newDot;
+			supVec = vtx;
+		}
+	}
+	return btVector3(supVec.getX(),supVec.getY(),supVec.getZ());
+}
+
+btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual (const btVector3& localDir) const
+{
+	switch (m_shapeType)
+	{
+    case SPHERE_SHAPE_PROXYTYPE:
+	{
+		return btVector3(0,0,0);
+    }
+	case BOX_SHAPE_PROXYTYPE:
+	{
+		btBoxShape* convexShape = (btBoxShape*)this;
+		const btVector3& halfExtents = convexShape->getImplicitShapeDimensions();
+
+		return btVector3(btFsels(localDir.x(), halfExtents.x(), -halfExtents.x()),
+			btFsels(localDir.y(), halfExtents.y(), -halfExtents.y()),
+			btFsels(localDir.z(), halfExtents.z(), -halfExtents.z()));
+	}
+	case TRIANGLE_SHAPE_PROXYTYPE:
+	{
+		btTriangleShape* triangleShape = (btTriangleShape*)this;
+		btVector3 dir(localDir.getX(),localDir.getY(),localDir.getZ());
+		btVector3* vertices = &triangleShape->m_vertices1[0];
+		btVector3 dots(dir.dot(vertices[0]), dir.dot(vertices[1]), dir.dot(vertices[2]));
+		btVector3 sup = vertices[dots.maxAxis()];
+		return btVector3(sup.getX(),sup.getY(),sup.getZ());
+	}
+	case CYLINDER_SHAPE_PROXYTYPE:
+	{
+		btCylinderShape* cylShape = (btCylinderShape*)this;
+		//mapping of halfextents/dimension onto radius/height depends on how cylinder local orientation is (upAxis)
+
+		btVector3 halfExtents = cylShape->getImplicitShapeDimensions();
+		btVector3 v(localDir.getX(),localDir.getY(),localDir.getZ());
+		int cylinderUpAxis = cylShape->getUpAxis();
+		int XX(1),YY(0),ZZ(2);
+
+		switch (cylinderUpAxis)
+		{
+		case 0:
+		{
+			XX = 1;
+			YY = 0;
+			ZZ = 2;
+		}
+		break;
+		case 1:
+		{
+			XX = 0;
+			YY = 1;
+			ZZ = 2;	
+		}
+		break;
+		case 2:
+		{
+			XX = 0;
+			YY = 2;
+			ZZ = 1;
+			
+		}
+		break;
+		default:
+			btAssert(0);
+		break;
+		};
+
+		btScalar radius = halfExtents[XX];
+		btScalar halfHeight = halfExtents[cylinderUpAxis];
+
+		btVector3 tmp;
+		btScalar d ;
+
+		btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
+		if (s != btScalar(0.0))
+		{
+			d = radius / s;  
+			tmp[XX] = v[XX] * d;
+			tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+			tmp[ZZ] = v[ZZ] * d;
+			return btVector3(tmp.getX(),tmp.getY(),tmp.getZ());
+		} else {
+			tmp[XX] = radius;
+			tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+			tmp[ZZ] = btScalar(0.0);
+			return btVector3(tmp.getX(),tmp.getY(),tmp.getZ());
+		}
+	}
+	case CAPSULE_SHAPE_PROXYTYPE:
+	{
+		btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ());
+
+		btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
+		btScalar halfHeight = capsuleShape->getHalfHeight();
+		int capsuleUpAxis = capsuleShape->getUpAxis();
+
+		btScalar radius = capsuleShape->getRadius();
+		btVector3 supVec(0,0,0);
+
+		btScalar maxDot(btScalar(-1e30));
+
+		btVector3 vec = vec0;
+		btScalar lenSqr = vec.length2();
+		if (lenSqr < btScalar(0.0001))
+		{
+			vec.setValue(1,0,0);
+		} else
+		{
+			btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
+			vec *= rlen;
+		}
+		btVector3 vtx;
+		btScalar newDot;
+		{
+			btVector3 pos(0,0,0);
+			pos[capsuleUpAxis] = halfHeight;
+
+			//vtx = pos +vec*(radius);
+			vtx = pos +vec*capsuleShape->getLocalScalingNV()*(radius) - vec * capsuleShape->getMarginNV();
+			newDot = vec.dot(vtx);
+			
+
+			if (newDot > maxDot)
+			{
+				maxDot = newDot;
+				supVec = vtx;
+			}
+		}
+		{
+			btVector3 pos(0,0,0);
+			pos[capsuleUpAxis] = -halfHeight;
+
+			//vtx = pos +vec*(radius);
+			vtx = pos +vec*capsuleShape->getLocalScalingNV()*(radius) - vec * capsuleShape->getMarginNV();
+			newDot = vec.dot(vtx);
+			if (newDot > maxDot)
+			{
+				maxDot = newDot;
+				supVec = vtx;
+			}
+		}
+		return btVector3(supVec.getX(),supVec.getY(),supVec.getZ());	
+	}
+	case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
+	{
+		btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this;
+		btVector3* points = convexPointCloudShape->getUnscaledPoints ();
+		int numPoints = convexPointCloudShape->getNumPoints ();
+		return convexHullSupport (localDir, points, numPoints,convexPointCloudShape->getLocalScalingNV());
+	}
+	case CONVEX_HULL_SHAPE_PROXYTYPE:
+	{
+		btConvexHullShape* convexHullShape = (btConvexHullShape*)this;
+		btVector3* points = convexHullShape->getUnscaledPoints();
+		int numPoints = convexHullShape->getNumPoints ();
+		return convexHullSupport (localDir, points, numPoints,convexHullShape->getLocalScalingNV());
+	}
+    default:
+#ifndef __SPU__
+		return this->localGetSupportingVertexWithoutMargin (localDir);
+#else
+		btAssert (0);
+#endif
+	}
+
+	// should never reach here
+	btAssert (0);
+	return btVector3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f));
+}
+
+btVector3 btConvexShape::localGetSupportVertexNonVirtual (const btVector3& localDir) const
+{
+	btVector3 localDirNorm = localDir;
+	if (localDirNorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
+	{
+		localDirNorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
+	}
+	localDirNorm.normalize ();
+
+	return localGetSupportVertexWithoutMarginNonVirtual(localDirNorm)+ getMarginNonVirtual() * localDirNorm;
+}
+
+/* TODO: This should be bumped up to btCollisionShape () */
+btScalar btConvexShape::getMarginNonVirtual () const
+{
+	switch (m_shapeType)
+	{
+    case SPHERE_SHAPE_PROXYTYPE:
+	{
+		btSphereShape* sphereShape = (btSphereShape*)this;
+		return sphereShape->getRadius ();
+	}
+	case BOX_SHAPE_PROXYTYPE:
+	{
+		btBoxShape* convexShape = (btBoxShape*)this;
+		return convexShape->getMarginNV ();
+	}
+	case TRIANGLE_SHAPE_PROXYTYPE:
+	{
+		btTriangleShape* triangleShape = (btTriangleShape*)this;
+		return triangleShape->getMarginNV ();
+	}
+	case CYLINDER_SHAPE_PROXYTYPE:
+	{
+		btCylinderShape* cylShape = (btCylinderShape*)this;
+		return cylShape->getMarginNV();
+	}
+	case CAPSULE_SHAPE_PROXYTYPE:
+	{
+		btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
+		return capsuleShape->getMarginNV();
+	}
+	case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
+	/* fall through */
+	case CONVEX_HULL_SHAPE_PROXYTYPE:
+	{
+		btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this;
+		return convexHullShape->getMarginNV();
+	}
+    default:
+#ifndef __SPU__
+		return this->getMargin ();
+#else
+		btAssert (0);
+#endif
+	}
+
+	// should never reach here
+	btAssert (0);
+	return btScalar(0.0f);
+}
+
+void btConvexShape::getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const
+{
+	switch (m_shapeType)
+	{
+    case SPHERE_SHAPE_PROXYTYPE:
+	{
+		btSphereShape* sphereShape = (btSphereShape*)this;
+		btScalar radius = sphereShape->getImplicitShapeDimensions().getX();// * convexShape->getLocalScaling().getX();
+		btScalar margin = radius + sphereShape->getMarginNonVirtual();
+		const btVector3& center = t.getOrigin();
+		btVector3 extent(margin,margin,margin);
+		aabbMin = center - extent;
+		aabbMax = center + extent;
+    }
+	break;
+	case CYLINDER_SHAPE_PROXYTYPE:
+	/* fall through */
+	case BOX_SHAPE_PROXYTYPE:
+	{
+		btBoxShape* convexShape = (btBoxShape*)this;
+		btScalar margin=convexShape->getMarginNonVirtual();
+		btVector3 halfExtents = convexShape->getImplicitShapeDimensions();
+		halfExtents += btVector3(margin,margin,margin);
+		btMatrix3x3 abs_b = t.getBasis().absolute();  
+		btVector3 center = t.getOrigin();
+		btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));
+		
+		aabbMin = center - extent;
+		aabbMax = center + extent;
+		break;
+	}
+	case TRIANGLE_SHAPE_PROXYTYPE:
+	{
+		btTriangleShape* triangleShape = (btTriangleShape*)this;
+		btScalar margin = triangleShape->getMarginNonVirtual();
+		for (int i=0;i<3;i++)
+		{
+			btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.));
+			vec[i] = btScalar(1.);
+
+			btVector3 sv = localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis());
+
+			btVector3 tmp = t(sv);
+			aabbMax[i] = tmp[i]+margin;
+			vec[i] = btScalar(-1.);
+			tmp = t(localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis()));
+			aabbMin[i] = tmp[i]-margin;
+		}	
+	}
+	break;
+	case CAPSULE_SHAPE_PROXYTYPE:
+	{
+		btCapsuleShape* capsuleShape = (btCapsuleShape*)this;
+		btVector3 halfExtents(capsuleShape->getRadius(),capsuleShape->getRadius(),capsuleShape->getRadius());
+		int m_upAxis = capsuleShape->getUpAxis();
+		halfExtents[m_upAxis] = capsuleShape->getRadius() + capsuleShape->getHalfHeight();
+		halfExtents += btVector3(capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual());
+		btMatrix3x3 abs_b = t.getBasis().absolute();  
+		btVector3 center = t.getOrigin();
+		btVector3 extent = btVector3(abs_b[0].dot(halfExtents),abs_b[1].dot(halfExtents),abs_b[2].dot(halfExtents));		  	
+		aabbMin = center - extent;
+		aabbMax = center + extent;
+	}
+	break;
+	case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE:
+	case CONVEX_HULL_SHAPE_PROXYTYPE:
+	{
+		btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this;
+		btScalar margin = convexHullShape->getMarginNonVirtual();
+		convexHullShape->getNonvirtualAabb (t, aabbMin, aabbMax, margin);
+	}
+	break;
+    default:
+#ifndef __SPU__
+		this->getAabb (t, aabbMin, aabbMax);
+#else
+		btAssert (0);
+#endif
+	break;
+	}
+
+	// should never reach here
+	btAssert (0);
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexShape.h	(revision 6952)
@@ -0,0 +1,82 @@
+/*
+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_SHAPE_INTERFACE1
+#define CONVEX_SHAPE_INTERFACE1
+
+#include "btCollisionShape.h"
+
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btMatrix3x3.h"
+#include "btCollisionMargin.h"
+#include "LinearMath/btAlignedAllocator.h"
+
+#define MAX_PREFERRED_PENETRATION_DIRECTIONS 10
+
+/// The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape, btConvexHullShape etc.
+/// It describes general convex shapes using the localGetSupportingVertex interface, used by collision detectors such as btGjkPairDetector.
+ATTRIBUTE_ALIGNED16(class) btConvexShape : public btCollisionShape
+{
+
+
+public:
+
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	btConvexShape ();
+
+	virtual ~btConvexShape();
+
+	virtual btVector3	localGetSupportingVertex(const btVector3& vec)const = 0;
+
+	////////
+	#ifndef __SPU__
+	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec) const=0;
+	#endif //#ifndef __SPU__
+
+	btVector3 localGetSupportVertexWithoutMarginNonVirtual (const btVector3& vec) const;
+	btVector3 localGetSupportVertexNonVirtual (const btVector3& vec) const;
+	btScalar getMarginNonVirtual () const;
+	void getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const;
+
+	
+	//notice that the vectors should be unit length
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0;
+
+	///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 =0;
+
+	virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0;
+
+	virtual void	setLocalScaling(const btVector3& scaling) =0;
+	virtual const btVector3& getLocalScaling() const =0;
+
+	virtual void	setMargin(btScalar margin)=0;
+
+	virtual btScalar	getMargin() const=0;
+
+	virtual int		getNumPreferredPenetrationDirections() const=0;
+	
+	virtual void	getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const=0;
+
+
+	
+	
+};
+
+
+
+#endif //CONVEX_SHAPE_INTERFACE1
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp	(revision 6952)
@@ -0,0 +1,314 @@
+/*
+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 "btConvexTriangleMeshShape.h"
+#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+
+#include "LinearMath/btQuaternion.h"
+#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h"
+
+
+btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface, bool calcAabb)
+: btPolyhedralConvexShape(), m_stridingMesh(meshInterface)
+{
+	m_shapeType = CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE;
+	if ( calcAabb )
+		recalcLocalAabb();
+}
+
+
+
+
+///It's not nice to have all this virtual function overhead, so perhaps we can also gather the points once
+///but then we are duplicating
+class LocalSupportVertexCallback: public btInternalTriangleIndexCallback
+{
+
+	btVector3 m_supportVertexLocal;
+public:
+
+	btScalar m_maxDot;
+	btVector3 m_supportVecLocal;
+
+	LocalSupportVertexCallback(const btVector3& supportVecLocal)
+		: m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)),
+		m_maxDot(btScalar(-1e30)),
+                m_supportVecLocal(supportVecLocal)
+	{
+	}
+
+	virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
+	{
+		(void)triangleIndex;
+		(void)partId;
+
+		for (int i=0;i<3;i++)
+		{
+			btScalar dot = m_supportVecLocal.dot(triangle[i]);
+			if (dot > m_maxDot)
+			{
+				m_maxDot = dot;
+				m_supportVertexLocal = triangle[i];
+			}
+		}
+	}
+	
+	btVector3	GetSupportVertexLocal()
+	{
+		return m_supportVertexLocal;
+	}
+
+};
+
+
+
+
+
+btVector3	btConvexTriangleMeshShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
+{
+	btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.));
+
+	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;
+	}
+
+	LocalSupportVertexCallback	supportCallback(vec);
+	btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+	m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
+	supVec = supportCallback.GetSupportVertexLocal();
+
+	return supVec;
+}
+
+void	btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+	//use 'w' component of supportVerticesOut?
+	{
+		for (int i=0;i<numVectors;i++)
+		{
+			supportVerticesOut[i][3] = btScalar(-1e30);
+		}
+	}
+	
+	///@todo: could do the batch inside the callback!
+
+
+	for (int j=0;j<numVectors;j++)
+	{
+		const btVector3& vec = vectors[j];
+		LocalSupportVertexCallback	supportCallback(vec);
+		btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+		m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax);
+		supportVerticesOut[j] = supportCallback.GetSupportVertexLocal();
+	}
+	
+}
+	
+
+
+btVector3	btConvexTriangleMeshShape::localGetSupportingVertex(const btVector3& vec)const
+{
+	btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec);
+
+	if ( getMargin()!=btScalar(0.) )
+	{
+		btVector3 vecnorm = vec;
+		if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
+		{
+			vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
+		} 
+		vecnorm.normalize();
+		supVertex+= getMargin() * vecnorm;
+	}
+	return supVertex;
+}
+
+
+
+
+
+
+
+
+
+//currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection
+//Please note that you can debug-draw btConvexTriangleMeshShape with the Raytracer Demo
+int	btConvexTriangleMeshShape::getNumVertices() const
+{
+	//cache this?
+	return 0;
+	
+}
+
+int btConvexTriangleMeshShape::getNumEdges() const
+{
+	return 0;
+}
+
+void btConvexTriangleMeshShape::getEdge(int ,btVector3& ,btVector3& ) const
+{
+	btAssert(0);	
+}
+
+void btConvexTriangleMeshShape::getVertex(int ,btVector3& ) const
+{
+	btAssert(0);
+}
+
+int	btConvexTriangleMeshShape::getNumPlanes() const
+{
+	return 0;
+}
+
+void btConvexTriangleMeshShape::getPlane(btVector3& ,btVector3& ,int  ) const
+{
+	btAssert(0);
+}
+
+//not yet
+bool btConvexTriangleMeshShape::isInside(const btVector3& ,btScalar ) const
+{
+	btAssert(0);
+	return false;
+}
+
+
+
+void	btConvexTriangleMeshShape::setLocalScaling(const btVector3& scaling)
+{
+	m_stridingMesh->setScaling(scaling);
+	
+	recalcLocalAabb();
+	
+}
+
+
+const btVector3& btConvexTriangleMeshShape::getLocalScaling() const
+{
+	return m_stridingMesh->getScaling();
+}
+
+void btConvexTriangleMeshShape::calculatePrincipalAxisTransform(btTransform& principal, btVector3& inertia, btScalar& volume) const
+{
+   class CenterCallback: public btInternalTriangleIndexCallback
+   {
+      bool first;
+      btVector3 ref;
+      btVector3 sum;
+      btScalar volume;
+
+   public:
+
+      CenterCallback() : first(true), ref(0, 0, 0), sum(0, 0, 0), volume(0)
+      {
+      }
+
+      virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex)
+      {
+         (void) triangleIndex;
+         (void) partId;
+         if (first)
+         {
+            ref = triangle[0];
+            first = false;
+         }
+         else
+         {
+            btScalar vol = btFabs((triangle[0] - ref).triple(triangle[1] - ref, triangle[2] - ref));
+            sum += (btScalar(0.25) * vol) * ((triangle[0] + triangle[1] + triangle[2] + ref));
+            volume += vol;
+         }
+      }
+      
+      btVector3 getCenter()
+      {
+         return (volume > 0) ? sum / volume : ref;
+      }
+
+      btScalar getVolume()
+      {
+         return volume * btScalar(1. / 6);
+      }
+
+   };
+
+   class InertiaCallback: public btInternalTriangleIndexCallback
+   {
+      btMatrix3x3 sum;
+      btVector3 center;
+
+   public:
+
+      InertiaCallback(btVector3& center) : sum(0, 0, 0, 0, 0, 0, 0, 0, 0), center(center)
+      {
+      }
+
+      virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex)
+      {
+         (void) triangleIndex;
+         (void) partId;
+         btMatrix3x3 i;
+         btVector3 a = triangle[0] - center;
+         btVector3 b = triangle[1] - center;
+         btVector3 c = triangle[2] - center;
+         btScalar volNeg = -btFabs(a.triple(b, c)) * btScalar(1. / 6);
+         for (int j = 0; j < 3; j++)
+         {
+            for (int k = 0; k <= j; k++)
+            {
+               i[j][k] = i[k][j] = volNeg * (btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k])
+                  + btScalar(0.05) * (a[j] * b[k] + a[k] * b[j] + a[j] * c[k] + a[k] * c[j] + b[j] * c[k] + b[k] * c[j]));
+            }
+         }
+         btScalar i00 = -i[0][0];
+         btScalar i11 = -i[1][1];
+         btScalar i22 = -i[2][2];
+         i[0][0] = i11 + i22; 
+         i[1][1] = i22 + i00; 
+         i[2][2] = i00 + i11;
+         sum[0] += i[0];
+         sum[1] += i[1];
+         sum[2] += i[2];
+      }
+      
+      btMatrix3x3& getInertia()
+      {
+         return sum;
+      }
+
+   };
+
+   CenterCallback centerCallback;
+   btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+   m_stridingMesh->InternalProcessAllTriangles(&centerCallback, -aabbMax, aabbMax);
+   btVector3 center = centerCallback.getCenter();
+   principal.setOrigin(center);
+   volume = centerCallback.getVolume();
+
+   InertiaCallback inertiaCallback(center);
+   m_stridingMesh->InternalProcessAllTriangles(&inertiaCallback, -aabbMax, aabbMax);
+
+   btMatrix3x3& i = inertiaCallback.getInertia();
+   i.diagonalize(principal.getBasis(), btScalar(0.00001), 20);
+   inertia.setValue(i[0][0], i[1][1], i[2][2]);
+   inertia /= volume;
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h	(revision 6952)
@@ -0,0 +1,61 @@
+#ifndef CONVEX_TRIANGLEMESH_SHAPE_H
+#define CONVEX_TRIANGLEMESH_SHAPE_H
+
+
+#include "btPolyhedralConvexShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+
+
+/// 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 btStridingMeshInterface*	m_stridingMesh;
+
+public:
+	btConvexTriangleMeshShape(btStridingMeshInterface* meshInterface, bool calcAabb = true);
+
+	class btStridingMeshInterface*	getMeshInterface()
+	{
+		return m_stridingMesh;
+	}
+	const class btStridingMeshInterface* getMeshInterface() const
+	{
+		return m_stridingMesh;
+	}
+	
+	virtual btVector3	localGetSupportingVertex(const btVector3& vec)const;
+	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+	
+	//debugging
+	virtual const char*	getName()const {return "ConvexTrimesh";}
+	
+	virtual int	getNumVertices() const;
+	virtual int getNumEdges() const;
+	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
+	virtual void getVertex(int i,btVector3& vtx) const;
+	virtual int	getNumPlanes() const;
+	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const;
+	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const;
+
+	
+	virtual void	setLocalScaling(const btVector3& scaling);
+	virtual const btVector3& getLocalScaling() const;
+
+	///computes the exact moment of inertia and the transform from the coordinate system defined by the principal axes of the moment of inertia
+	///and the center of mass to the current coordinate system. A mass of 1 is assumed, for other masses just multiply the computed "inertia"
+	///by the mass. The resulting transform "principal" has to be applied inversely to the mesh in order for the local coordinate system of the
+	///shape to be centered at the center of mass and to coincide with the principal axes. This also necessitates a correction of the world transform
+	///of the collision object by the principal transform. This method also computes the volume of the convex mesh.
+	void calculatePrincipalAxisTransform(btTransform& principal, btVector3& inertia, btScalar& volume) const;
+
+};
+
+
+
+#endif //CONVEX_TRIANGLEMESH_SHAPE_H
+
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCylinderShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCylinderShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCylinderShape.cpp	(revision 6952)
@@ -0,0 +1,206 @@
+/*
+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 "btCylinderShape.h"
+
+btCylinderShape::btCylinderShape (const btVector3& halfExtents)
+:btBoxShape(halfExtents),
+m_upAxis(1)
+{
+	m_shapeType = CYLINDER_SHAPE_PROXYTYPE;
+	recalcLocalAabb();
+}
+
+
+btCylinderShapeX::btCylinderShapeX (const btVector3& halfExtents)
+:btCylinderShape(halfExtents)
+{
+	m_upAxis = 0;
+	recalcLocalAabb();
+}
+
+
+btCylinderShapeZ::btCylinderShapeZ (const btVector3& halfExtents)
+:btCylinderShape(halfExtents)
+{
+	m_upAxis = 2;
+	recalcLocalAabb();
+}
+
+void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	//skip the box 'getAabb'
+	btPolyhedralConvexShape::getAabb(t,aabbMin,aabbMax);
+}
+
+
+SIMD_FORCE_INLINE btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v) 
+{
+const int cylinderUpAxis = 0;
+const int XX = 1;
+const int YY = 0;
+const int ZZ = 2;
+
+	//mapping depends on how cylinder local orientation is
+	// extents of the cylinder is: X,Y is for radius, and Z for height
+
+
+	btScalar radius = halfExtents[XX];
+	btScalar halfHeight = halfExtents[cylinderUpAxis];
+
+
+    btVector3 tmp;
+	btScalar d ;
+
+    btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
+    if (s != btScalar(0.0))
+	{
+        d = radius / s;  
+		tmp[XX] = v[XX] * d;
+		tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+		tmp[ZZ] = v[ZZ] * d;
+		return tmp;
+	}
+    else
+	{
+	    tmp[XX] = radius;
+		tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+		tmp[ZZ] = btScalar(0.0);
+		return tmp;
+    }
+
+
+}
+
+
+
+
+
+
+inline  btVector3 CylinderLocalSupportY(const btVector3& halfExtents,const btVector3& v) 
+{
+
+const int cylinderUpAxis = 1;
+const int XX = 0;
+const int YY = 1;
+const int ZZ = 2;
+
+
+	btScalar radius = halfExtents[XX];
+	btScalar halfHeight = halfExtents[cylinderUpAxis];
+
+
+    btVector3 tmp;
+	btScalar d ;
+
+    btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
+    if (s != btScalar(0.0))
+	{
+        d = radius / s;  
+		tmp[XX] = v[XX] * d;
+		tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+		tmp[ZZ] = v[ZZ] * d;
+		return tmp;
+	}
+    else
+	{
+	    tmp[XX] = radius;
+		tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+		tmp[ZZ] = btScalar(0.0);
+		return tmp;
+    }
+
+}
+
+inline btVector3 CylinderLocalSupportZ(const btVector3& halfExtents,const btVector3& v) 
+{
+const int cylinderUpAxis = 2;
+const int XX = 0;
+const int YY = 2;
+const int ZZ = 1;
+
+	//mapping depends on how cylinder local orientation is
+	// extents of the cylinder is: X,Y is for radius, and Z for height
+
+
+	btScalar radius = halfExtents[XX];
+	btScalar halfHeight = halfExtents[cylinderUpAxis];
+
+
+    btVector3 tmp;
+	btScalar d ;
+
+    btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]);
+    if (s != btScalar(0.0))
+	{
+        d = radius / s;  
+		tmp[XX] = v[XX] * d;
+		tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+		tmp[ZZ] = v[ZZ] * d;
+		return tmp;
+	}
+    else
+	{
+	    tmp[XX] = radius;
+		tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight;
+		tmp[ZZ] = btScalar(0.0);
+		return tmp;
+    }
+
+
+}
+
+btVector3	btCylinderShapeX::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
+{
+	return CylinderLocalSupportX(getHalfExtentsWithoutMargin(),vec);
+}
+
+
+btVector3	btCylinderShapeZ::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
+{
+	return CylinderLocalSupportZ(getHalfExtentsWithoutMargin(),vec);
+}
+btVector3	btCylinderShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
+{
+	return CylinderLocalSupportY(getHalfExtentsWithoutMargin(),vec);
+}
+
+void	btCylinderShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+	for (int i=0;i<numVectors;i++)
+	{
+		supportVerticesOut[i] = CylinderLocalSupportY(getHalfExtentsWithoutMargin(),vectors[i]);
+	}
+}
+
+void	btCylinderShapeZ::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+	for (int i=0;i<numVectors;i++)
+	{
+		supportVerticesOut[i] = CylinderLocalSupportZ(getHalfExtentsWithoutMargin(),vectors[i]);
+	}
+}
+
+
+
+
+void	btCylinderShapeX::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+	for (int i=0;i<numVectors;i++)
+	{
+		supportVerticesOut[i] = CylinderLocalSupportX(getHalfExtentsWithoutMargin(),vectors[i]);
+	}
+}
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCylinderShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCylinderShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btCylinderShape.h	(revision 6952)
@@ -0,0 +1,134 @@
+/*
+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 CYLINDER_MINKOWSKI_H
+#define CYLINDER_MINKOWSKI_H
+
+#include "btBoxShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+#include "LinearMath/btVector3.h"
+
+/// 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
+
+{
+
+protected:
+
+	int	m_upAxis;
+
+public:
+	btCylinderShape (const btVector3& halfExtents);
+	
+	///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
+	void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
+
+	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
+
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+
+	virtual btVector3	localGetSupportingVertex(const btVector3& vec) const
+	{
+
+		btVector3 supVertex;
+		supVertex = localGetSupportingVertexWithoutMargin(vec);
+		
+		if ( getMargin()!=btScalar(0.) )
+		{
+			btVector3 vecnorm = vec;
+			if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
+			{
+				vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
+			} 
+			vecnorm.normalize();
+			supVertex+= getMargin() * vecnorm;
+		}
+		return supVertex;
+	}
+
+
+	//use box inertia
+	//	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
+
+	int	getUpAxis() const
+	{
+		return m_upAxis;
+	}
+
+	virtual btScalar getRadius() const
+	{
+		return getHalfExtentsWithMargin().getX();
+	}
+
+	//debugging
+	virtual const char*	getName()const
+	{
+		return "CylinderY";
+	}
+
+
+
+};
+
+class btCylinderShapeX : public btCylinderShape
+{
+public:
+	btCylinderShapeX (const btVector3& halfExtents);
+
+	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+	
+		//debugging
+	virtual const char*	getName()const
+	{
+		return "CylinderX";
+	}
+
+	virtual btScalar getRadius() const
+	{
+		return getHalfExtentsWithMargin().getY();
+	}
+
+};
+
+class btCylinderShapeZ : public btCylinderShape
+{
+public:
+	btCylinderShapeZ (const btVector3& halfExtents);
+
+	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+
+	virtual int	getUpAxis() const
+	{
+		return 2;
+	}
+		//debugging
+	virtual const char*	getName()const
+	{
+		return "CylinderZ";
+	}
+
+	virtual btScalar getRadius() const
+	{
+		return getHalfExtentsWithMargin().getX();
+	}
+
+};
+
+
+#endif //CYLINDER_MINKOWSKI_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btEmptyShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btEmptyShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btEmptyShape.cpp	(revision 6952)
@@ -0,0 +1,50 @@
+/*
+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 "btEmptyShape.h"
+
+
+#include "btCollisionShape.h"
+
+
+btEmptyShape::btEmptyShape() : btConcaveShape ()
+{
+	m_shapeType = EMPTY_SHAPE_PROXYTYPE;
+}
+
+
+btEmptyShape::~btEmptyShape()
+{
+}
+
+
+	///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
+void btEmptyShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	btVector3 margin(getMargin(),getMargin(),getMargin());
+
+	aabbMin = t.getOrigin() - margin;
+
+	aabbMax = t.getOrigin() + margin;
+
+}
+
+void	btEmptyShape::calculateLocalInertia(btScalar ,btVector3& ) const
+{
+	btAssert(0);
+}
+
+	
+	
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btEmptyShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btEmptyShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btEmptyShape.h	(revision 6952)
@@ -0,0 +1,70 @@
+/*
+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 EMPTY_SHAPE_H
+#define EMPTY_SHAPE_H
+
+#include "btConcaveShape.h"
+
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btMatrix3x3.h"
+#include "btCollisionMargin.h"
+
+
+
+
+/// The btEmptyShape is a collision shape without actual collision detection shape, so most users should ignore this class.
+/// It can be replaced by another shape during runtime, but the inertia tensor should be recomputed.
+class btEmptyShape	: public btConcaveShape
+{
+public:
+	btEmptyShape();
+
+	virtual ~btEmptyShape();
+
+
+	///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	setLocalScaling(const btVector3& scaling)
+	{
+		m_localScaling = scaling;
+	}
+	virtual const btVector3& getLocalScaling() const 
+	{
+		return m_localScaling;
+	}
+
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+	
+	virtual const char*	getName()const
+	{
+		return "Empty";
+	}
+
+	virtual void processAllTriangles(btTriangleCallback* ,const btVector3& ,const btVector3& ) const
+	{
+	}
+
+protected:
+	btVector3	m_localScaling;
+
+};
+
+
+
+#endif //EMPTY_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp	(revision 6952)
@@ -0,0 +1,411 @@
+/*
+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 "btHeightfieldTerrainShape.h"
+
+#include "LinearMath/btTransformUtil.h"
+
+
+
+btHeightfieldTerrainShape::btHeightfieldTerrainShape
+(
+int heightStickWidth, int heightStickLength, void* heightfieldData,
+btScalar heightScale, btScalar minHeight, btScalar maxHeight,int upAxis,
+PHY_ScalarType hdt, bool flipQuadEdges
+)
+{
+	initialize(heightStickWidth, heightStickLength, heightfieldData,
+	           heightScale, minHeight, maxHeight, upAxis, hdt,
+	           flipQuadEdges);
+}
+
+
+
+btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength,void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges)
+{
+	// legacy constructor: support only float or unsigned char,
+	// 	and min height is zero
+	PHY_ScalarType hdt = (useFloatData) ? PHY_FLOAT : PHY_UCHAR;
+	btScalar minHeight = 0.0;
+
+	// previously, height = uchar * maxHeight / 65535.
+	// So to preserve legacy behavior, heightScale = maxHeight / 65535
+	btScalar heightScale = maxHeight / 65535;
+
+	initialize(heightStickWidth, heightStickLength, heightfieldData,
+	           heightScale, minHeight, maxHeight, upAxis, hdt,
+	           flipQuadEdges);
+}
+
+
+
+void btHeightfieldTerrainShape::initialize
+(
+int heightStickWidth, int heightStickLength, void* heightfieldData,
+btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis,
+PHY_ScalarType hdt, bool flipQuadEdges
+)
+{
+	// validation
+	btAssert(heightStickWidth > 1 && "bad width");
+	btAssert(heightStickLength > 1 && "bad length");
+	btAssert(heightfieldData && "null heightfield data");
+	// btAssert(heightScale) -- do we care?  Trust caller here
+	btAssert(minHeight <= maxHeight && "bad min/max height");
+	btAssert(upAxis >= 0 && upAxis < 3 &&
+	    "bad upAxis--should be in range [0,2]");
+	btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT &&
+	    "Bad height data type enum");
+
+	// initialize member variables
+	m_shapeType = TERRAIN_SHAPE_PROXYTYPE;
+	m_heightStickWidth = heightStickWidth;
+	m_heightStickLength = heightStickLength;
+	m_minHeight = minHeight;
+	m_maxHeight = maxHeight;
+	m_width = (btScalar) (heightStickWidth - 1);
+	m_length = (btScalar) (heightStickLength - 1);
+	m_heightScale = heightScale;
+	m_heightfieldDataUnknown = heightfieldData;
+	m_heightDataType = hdt;
+	m_flipQuadEdges = flipQuadEdges;
+	m_useDiamondSubdivision = false;
+	m_upAxis = upAxis;
+	m_localScaling.setValue(btScalar(1.), btScalar(1.), btScalar(1.));
+
+	// determine min/max axis-aligned bounding box (aabb) values
+	switch (m_upAxis)
+	{
+	case 0:
+		{
+			m_localAabbMin.setValue(m_minHeight, 0, 0);
+			m_localAabbMax.setValue(m_maxHeight, m_width, m_length);
+			break;
+		}
+	case 1:
+		{
+			m_localAabbMin.setValue(0, m_minHeight, 0);
+			m_localAabbMax.setValue(m_width, m_maxHeight, m_length);
+			break;
+		};
+	case 2:
+		{
+			m_localAabbMin.setValue(0, 0, m_minHeight);
+			m_localAabbMax.setValue(m_width, m_length, m_maxHeight);
+			break;
+		}
+	default:
+		{
+			//need to get valid m_upAxis
+			btAssert(0 && "Bad m_upAxis");
+		}
+	}
+
+	// remember origin (defined as exact middle of aabb)
+	m_localOrigin = btScalar(0.5) * (m_localAabbMin + m_localAabbMax);
+}
+
+
+
+btHeightfieldTerrainShape::~btHeightfieldTerrainShape()
+{
+}
+
+
+
+void btHeightfieldTerrainShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	btVector3 halfExtents = (m_localAabbMax-m_localAabbMin)* m_localScaling * btScalar(0.5);
+
+	btVector3 localOrigin(0, 0, 0);
+	localOrigin[m_upAxis] = (m_minHeight + m_maxHeight) * btScalar(0.5);
+	localOrigin *= m_localScaling;
+
+	btMatrix3x3 abs_b = t.getBasis().absolute();  
+	btVector3 center = t.getOrigin();
+	btVector3 extent = btVector3(abs_b[0].dot(halfExtents),
+		   abs_b[1].dot(halfExtents),
+		  abs_b[2].dot(halfExtents));
+	extent += btVector3(getMargin(),getMargin(),getMargin());
+
+	aabbMin = center - extent;
+	aabbMax = center + extent;
+}
+
+
+/// This returns the "raw" (user's initial) height, not the actual height.
+/// The actual height needs to be adjusted to be relative to the center
+///   of the heightfield's AABB.
+btScalar
+btHeightfieldTerrainShape::getRawHeightFieldValue(int x,int y) const
+{
+	btScalar val = 0.f;
+	switch (m_heightDataType)
+	{
+	case PHY_FLOAT:
+		{
+			val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x];
+			break;
+		}
+
+	case PHY_UCHAR:
+		{
+			unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x];
+			val = heightFieldValue * m_heightScale;
+			break;
+		}
+
+	case PHY_SHORT:
+		{
+			short hfValue = m_heightfieldDataShort[(y * m_heightStickWidth) + x];
+			val = hfValue * m_heightScale;
+			break;
+		}
+
+	default:
+		{
+			btAssert(!"Bad m_heightDataType");
+		}
+	}
+
+	return val;
+}
+
+
+
+
+/// this returns the vertex in bullet-local coordinates
+void	btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const
+{
+	btAssert(x>=0);
+	btAssert(y>=0);
+	btAssert(x<m_heightStickWidth);
+	btAssert(y<m_heightStickLength);
+
+	btScalar	height = getRawHeightFieldValue(x,y);
+
+	switch (m_upAxis)
+	{
+	case 0:
+		{
+		vertex.setValue(
+			height - m_localOrigin.getX(),
+			(-m_width/btScalar(2.0)) + x,
+			(-m_length/btScalar(2.0) ) + y
+			);
+			break;
+		}
+	case 1:
+		{
+			vertex.setValue(
+			(-m_width/btScalar(2.0)) + x,
+			height - m_localOrigin.getY(),
+			(-m_length/btScalar(2.0)) + y
+			);
+			break;
+		};
+	case 2:
+		{
+			vertex.setValue(
+			(-m_width/btScalar(2.0)) + x,
+			(-m_length/btScalar(2.0)) + y,
+			height - m_localOrigin.getZ()
+			);
+			break;
+		}
+	default:
+		{
+			//need to get valid m_upAxis
+			btAssert(0);
+		}
+	}
+
+	vertex*=m_localScaling;
+}
+
+
+
+static inline int
+getQuantized
+(
+btScalar x
+)
+{
+	if (x < 0.0) {
+		return (int) (x - 0.5);
+	}
+	return (int) (x + 0.5);
+}
+
+
+
+/// given input vector, return quantized version
+/**
+  This routine is basically determining the gridpoint indices for a given
+  input vector, answering the question: "which gridpoint is closest to the
+  provided point?".
+
+  "with clamp" means that we restrict the point to be in the heightfield's
+  axis-aligned bounding box.
+ */
+void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& point,int /*isMax*/) const
+{
+	btVector3 clampedPoint(point);
+	clampedPoint.setMax(m_localAabbMin);
+	clampedPoint.setMin(m_localAabbMax);
+
+	out[0] = getQuantized(clampedPoint.getX());
+	out[1] = getQuantized(clampedPoint.getY());
+	out[2] = getQuantized(clampedPoint.getZ());
+		
+}
+
+
+
+/// process all triangles within the provided axis-aligned bounding box
+/**
+  basic algorithm:
+    - convert input aabb to local coordinates (scale down and shift for local origin)
+    - convert input aabb to a range of heightfield grid points (quantize)
+    - iterate over all triangles in that subset of the grid
+ */
+void	btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+	// scale down the input aabb's so they are in local (non-scaled) coordinates
+	btVector3	localAabbMin = aabbMin*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
+	btVector3	localAabbMax = aabbMax*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
+
+	// account for local origin
+	localAabbMin += m_localOrigin;
+	localAabbMax += m_localOrigin;
+
+	//quantize the aabbMin and aabbMax, and adjust the start/end ranges
+	int	quantizedAabbMin[3];
+	int	quantizedAabbMax[3];
+	quantizeWithClamp(quantizedAabbMin, localAabbMin,0);
+	quantizeWithClamp(quantizedAabbMax, localAabbMax,1);
+	
+	// expand the min/max quantized values
+	// this is to catch the case where the input aabb falls between grid points!
+	for (int i = 0; i < 3; ++i) {
+		quantizedAabbMin[i]--;
+		quantizedAabbMax[i]++;
+	}	
+
+	int startX=0;
+	int endX=m_heightStickWidth-1;
+	int startJ=0;
+	int endJ=m_heightStickLength-1;
+
+	switch (m_upAxis)
+	{
+	case 0:
+		{
+			if (quantizedAabbMin[1]>startX)
+				startX = quantizedAabbMin[1];
+			if (quantizedAabbMax[1]<endX)
+				endX = quantizedAabbMax[1];
+			if (quantizedAabbMin[2]>startJ)
+				startJ = quantizedAabbMin[2];
+			if (quantizedAabbMax[2]<endJ)
+				endJ = quantizedAabbMax[2];
+			break;
+		}
+	case 1:
+		{
+			if (quantizedAabbMin[0]>startX)
+				startX = quantizedAabbMin[0];
+			if (quantizedAabbMax[0]<endX)
+				endX = quantizedAabbMax[0];
+			if (quantizedAabbMin[2]>startJ)
+				startJ = quantizedAabbMin[2];
+			if (quantizedAabbMax[2]<endJ)
+				endJ = quantizedAabbMax[2];
+			break;
+		};
+	case 2:
+		{
+			if (quantizedAabbMin[0]>startX)
+				startX = quantizedAabbMin[0];
+			if (quantizedAabbMax[0]<endX)
+				endX = quantizedAabbMax[0];
+			if (quantizedAabbMin[1]>startJ)
+				startJ = quantizedAabbMin[1];
+			if (quantizedAabbMax[1]<endJ)
+				endJ = quantizedAabbMax[1];
+			break;
+		}
+	default:
+		{
+			//need to get valid m_upAxis
+			btAssert(0);
+		}
+	}
+
+	
+  
+
+	for(int j=startJ; j<endJ; j++)
+	{
+		for(int x=startX; x<endX; x++)
+		{
+			btVector3 vertices[3];
+			if (m_flipQuadEdges || (m_useDiamondSubdivision && !((j+x) & 1)))
+			{
+        //first triangle
+        getVertex(x,j,vertices[0]);
+        getVertex(x+1,j,vertices[1]);
+        getVertex(x+1,j+1,vertices[2]);
+        callback->processTriangle(vertices,x,j);
+        //second triangle
+        getVertex(x,j,vertices[0]);
+        getVertex(x+1,j+1,vertices[1]);
+        getVertex(x,j+1,vertices[2]);
+        callback->processTriangle(vertices,x,j);				
+			} else
+			{
+        //first triangle
+        getVertex(x,j,vertices[0]);
+        getVertex(x,j+1,vertices[1]);
+        getVertex(x+1,j,vertices[2]);
+        callback->processTriangle(vertices,x,j);
+        //second triangle
+        getVertex(x+1,j,vertices[0]);
+        getVertex(x,j+1,vertices[1]);
+        getVertex(x+1,j+1,vertices[2]);
+        callback->processTriangle(vertices,x,j);
+			}
+		}
+	}
+
+	
+
+}
+
+void	btHeightfieldTerrainShape::calculateLocalInertia(btScalar ,btVector3& inertia) const
+{
+	//moving concave objects not supported
+	
+	inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
+}
+
+void	btHeightfieldTerrainShape::setLocalScaling(const btVector3& scaling)
+{
+	m_localScaling = scaling;
+}
+const btVector3& btHeightfieldTerrainShape::getLocalScaling() const
+{
+	return m_localScaling;
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h	(revision 6952)
@@ -0,0 +1,161 @@
+/*
+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 HEIGHTFIELD_TERRAIN_SHAPE_H
+#define HEIGHTFIELD_TERRAIN_SHAPE_H
+
+#include "btConcaveShape.h"
+
+///btHeightfieldTerrainShape simulates a 2D heightfield terrain
+/**
+  The caller is responsible for maintaining the heightfield array; this
+  class does not make a copy.
+
+  The heightfield can be dynamic so long as the min/max height values
+  capture the extremes (heights must always be in that range).
+
+  The local origin of the heightfield is assumed to be the exact
+  center (as determined by width and length and height, with each
+  axis multiplied by the localScaling).
+
+  \b NOTE: be careful with coordinates.  If you have a heightfield with a local
+  min height of -100m, and a max height of +500m, you may be tempted to place it
+  at the origin (0,0) and expect the heights in world coordinates to be
+  -100 to +500 meters.
+  Actually, the heights will be -300 to +300m, because bullet will re-center
+  the heightfield based on its AABB (which is determined by the min/max
+  heights).  So keep in mind that once you create a btHeightfieldTerrainShape
+  object, the heights will be adjusted relative to the center of the AABB.  This
+  is different to the behavior of many rendering engines, but is useful for
+  physics engines.
+
+  Most (but not all) rendering and heightfield libraries assume upAxis = 1
+  (that is, the y-axis is "up").  This class allows any of the 3 coordinates
+  to be "up".  Make sure your choice of axis is consistent with your rendering
+  system.
+
+  The heightfield heights are determined from the data type used for the
+  heightfieldData array.  
+
+   - PHY_UCHAR: height at a point is the uchar value at the
+       grid point, multipled by heightScale.  uchar isn't recommended
+       because of its inability to deal with negative values, and
+       low resolution (8-bit).
+
+   - PHY_SHORT: height at a point is the short int value at that grid
+       point, multipled by heightScale.
+
+   - PHY_FLOAT: height at a point is the float value at that grid
+       point.  heightScale is ignored when using the float heightfield
+       data type.
+
+  Whatever the caller specifies as minHeight and maxHeight will be honored.
+  The class will not inspect the heightfield to discover the actual minimum
+  or maximum heights.  These values are used to determine the heightfield's
+  axis-aligned bounding box, multiplied by localScaling.
+
+  For usage and testing see the TerrainDemo.
+ */
+class btHeightfieldTerrainShape : public btConcaveShape
+{
+protected:
+	btVector3	m_localAabbMin;
+	btVector3	m_localAabbMax;
+	btVector3	m_localOrigin;
+
+	///terrain data
+	int	m_heightStickWidth;
+	int m_heightStickLength;
+	btScalar	m_minHeight;
+	btScalar	m_maxHeight;
+	btScalar m_width;
+	btScalar m_length;
+	btScalar m_heightScale;
+	union
+	{
+		unsigned char*	m_heightfieldDataUnsignedChar;
+		short*		m_heightfieldDataShort;
+		btScalar*			m_heightfieldDataFloat;
+		void*			m_heightfieldDataUnknown;
+	};
+
+	PHY_ScalarType	m_heightDataType;	
+	bool	m_flipQuadEdges;
+  bool  m_useDiamondSubdivision;
+
+	int	m_upAxis;
+	
+	btVector3	m_localScaling;
+
+	virtual btScalar	getRawHeightFieldValue(int x,int y) const;
+	void		quantizeWithClamp(int* out, const btVector3& point,int isMax) const;
+	void		getVertex(int x,int y,btVector3& vertex) const;
+
+
+
+	/// protected initialization
+	/**
+	  Handles the work of constructors so that public constructors can be
+	  backwards-compatible without a lot of copy/paste.
+	 */
+	void initialize(int heightStickWidth, int heightStickLength,
+	                void* heightfieldData, btScalar heightScale,
+	                btScalar minHeight, btScalar maxHeight, int upAxis,
+	                PHY_ScalarType heightDataType, bool flipQuadEdges);
+
+public:
+	/// preferred constructor
+	/**
+	  This constructor supports a range of heightfield
+	  data types, and allows for a non-zero minimum height value.
+	  heightScale is needed for any integer-based heightfield data types.
+	 */
+	btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength,
+	                          void* heightfieldData, btScalar heightScale,
+	                          btScalar minHeight, btScalar maxHeight,
+	                          int upAxis, PHY_ScalarType heightDataType,
+	                          bool flipQuadEdges);
+
+	/// legacy constructor
+	/**
+	  The legacy constructor assumes the heightfield has a minimum height
+	  of zero.  Only unsigned char or floats are supported.  For legacy
+	  compatibility reasons, heightScale is calculated as maxHeight / 65535 
+	  (and is only used when useFloatData = false).
+ 	 */
+	btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength,void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges);
+
+	virtual ~btHeightfieldTerrainShape();
+
+
+	void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;}
+
+
+	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
+
+	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
+	virtual void	setLocalScaling(const btVector3& scaling);
+	
+	virtual const btVector3& getLocalScaling() const;
+	
+	//debugging
+	virtual const char*	getName()const {return "HEIGHTFIELD";}
+
+};
+
+#endif //HEIGHTFIELD_TERRAIN_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMaterial.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMaterial.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMaterial.h	(revision 6952)
@@ -0,0 +1,34 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 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.
+*/
+
+/// This file was created by Alex Silverman
+
+#ifndef MATERIAL_H
+#define MATERIAL_H
+
+// Material class to be used by btMultimaterialTriangleMeshShape to store triangle properties
+class btMaterial
+{
+    // public members so that materials can change due to world events
+public:
+    btScalar m_friction;
+    btScalar m_restitution;
+    int pad[2];
+
+    btMaterial(){}
+    btMaterial(btScalar fric, btScalar rest) { m_friction = fric; m_restitution = rest; }
+};
+
+#endif // MATERIAL_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp	(revision 6952)
@@ -0,0 +1,59 @@
+/*
+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 "btMinkowskiSumShape.h"
+
+
+btMinkowskiSumShape::btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB)
+: btConvexInternalShape (),
+m_shapeA(shapeA),
+m_shapeB(shapeB)
+{
+	m_shapeType = MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE;
+	m_transA.setIdentity();
+	m_transB.setIdentity();
+}
+
+btVector3 btMinkowskiSumShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
+{
+	btVector3 supVertexA = m_transA(m_shapeA->localGetSupportingVertexWithoutMargin(vec*m_transA.getBasis()));
+	btVector3 supVertexB = m_transB(m_shapeB->localGetSupportingVertexWithoutMargin(-vec*m_transB.getBasis()));
+	return  supVertexA - supVertexB;
+}
+
+void	btMinkowskiSumShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+	///@todo: could make recursive use of batching. probably this shape is not used frequently.
+	for (int i=0;i<numVectors;i++)
+	{
+		supportVerticesOut[i] = localGetSupportingVertexWithoutMargin(vectors[i]);
+	}
+
+}
+
+
+
+btScalar	btMinkowskiSumShape::getMargin() const
+{
+	return m_shapeA->getMargin() + m_shapeB->getMargin();
+}
+
+
+void	btMinkowskiSumShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+	(void)mass;
+	btAssert(0);
+	inertia.setValue(0,0,0);
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMinkowskiSumShape.h	(revision 6952)
@@ -0,0 +1,60 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef MINKOWSKI_SUM_SHAPE_H
+#define MINKOWSKI_SUM_SHAPE_H
+
+#include "btConvexInternalShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+
+/// The btMinkowskiSumShape is only for advanced users. This shape represents implicit based minkowski sum of two convex implicit shapes.
+class btMinkowskiSumShape : public btConvexInternalShape
+{
+
+	btTransform	m_transA;
+	btTransform	m_transB;
+	const btConvexShape*	m_shapeA;
+	const btConvexShape*	m_shapeB;
+
+public:
+
+	btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB);
+
+	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;
+
+	void	setTransformA(const btTransform&	transA) { m_transA = transA;}
+	void	setTransformB(const btTransform&	transB) { m_transB = transB;}
+
+	const btTransform& getTransformA()const  { return m_transA;}
+	const btTransform& GetTransformB()const  { return m_transB;}
+
+
+	virtual btScalar	getMargin() const;
+
+	const btConvexShape*	getShapeA() const { return m_shapeA;}
+	const btConvexShape*	getShapeB() const { return m_shapeB;}
+
+	virtual const char*	getName()const 
+	{
+		return "MinkowskiSum";
+	}
+};
+
+#endif //MINKOWSKI_SUM_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMultiSphereShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMultiSphereShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMultiSphereShape.cpp	(revision 6952)
@@ -0,0 +1,149 @@
+/*
+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 "btMultiSphereShape.h"
+#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+#include "LinearMath/btQuaternion.h"
+
+btMultiSphereShape::btMultiSphereShape (const btVector3& inertiaHalfExtents,const btVector3* positions,const btScalar* radi,int numSpheres)
+:btConvexInternalShape (), m_inertiaHalfExtents(inertiaHalfExtents)
+{
+	m_shapeType = MULTI_SPHERE_SHAPE_PROXYTYPE;
+	btScalar startMargin = btScalar(1e30);
+
+	m_numSpheres = numSpheres;
+	for (int i=0;i<m_numSpheres;i++)
+	{
+		m_localPositions[i] = positions[i];
+		m_radi[i] = radi[i];
+		if (radi[i] < startMargin)
+			startMargin = radi[i];
+	}
+	setMargin(startMargin);
+
+}
+
+
+
+ 
+ btVector3	btMultiSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
+{
+	int i;
+	btVector3 supVec(0,0,0);
+
+	btScalar maxDot(btScalar(-1e30));
+
+
+	btVector3 vec = vec0;
+	btScalar lenSqr = vec.length2();
+	if (lenSqr < (SIMD_EPSILON*SIMD_EPSILON))
+	{
+		vec.setValue(1,0,0);
+	} else
+	{
+		btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
+		vec *= rlen;
+	}
+
+	btVector3 vtx;
+	btScalar newDot;
+
+	const btVector3* pos = &m_localPositions[0];
+	const btScalar* rad = &m_radi[0];
+
+	for (i=0;i<m_numSpheres;i++)
+	{
+		vtx = (*pos) +vec*m_localScaling*(*rad) - vec * getMargin();
+		pos++;
+		rad++;
+		newDot = vec.dot(vtx);
+		if (newDot > maxDot)
+		{
+			maxDot = newDot;
+			supVec = vtx;
+		}
+	}
+
+	return supVec;
+
+}
+
+ void	btMultiSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+
+	for (int j=0;j<numVectors;j++)
+	{
+		btScalar maxDot(btScalar(-1e30));
+
+		const btVector3& vec = vectors[j];
+
+		btVector3 vtx;
+		btScalar newDot;
+
+		const btVector3* pos = &m_localPositions[0];
+		const btScalar* rad = &m_radi[0];
+
+		for (int i=0;i<m_numSpheres;i++)
+		{
+			vtx = (*pos) +vec*m_localScaling*(*rad) - vec * getMargin();
+			pos++;
+			rad++;
+			newDot = vec.dot(vtx);
+			if (newDot > maxDot)
+			{
+				maxDot = newDot;
+				supportVerticesOut[j] = vtx;
+			}
+		}
+	}
+}
+
+
+
+
+
+
+
+
+void	btMultiSphereShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+	//as an approximation, take the inertia of the box that bounds the spheres
+
+	btTransform ident;
+	ident.setIdentity();
+//	btVector3 aabbMin,aabbMax;
+
+//	getAabb(ident,aabbMin,aabbMax);
+
+	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);
+
+}
+
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMultiSphereShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMultiSphereShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMultiSphereShape.h	(revision 6952)
@@ -0,0 +1,74 @@
+/*
+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 MULTI_SPHERE_MINKOWSKI_H
+#define MULTI_SPHERE_MINKOWSKI_H
+
+#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;
+	
+
+
+
+public:
+	btMultiSphereShape (const btVector3& inertiaHalfExtents,const btVector3* positions,const btScalar* radi,int numSpheres);
+
+	///CollisionShape Interface
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
+	/// btConvexShape Interface
+	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
+
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+	
+	int	getSphereCount() const
+	{
+		return m_numSpheres;
+	}
+
+	const btVector3&	getSpherePosition(int index) const
+	{
+		return m_localPositions[index];
+	}
+
+	btScalar	getSphereRadius(int index) const
+	{
+		return m_radi[index];
+	}
+
+
+	virtual const char*	getName()const 
+	{
+		return "MultiSphere";
+	}
+
+};
+
+
+#endif //MULTI_SPHERE_MINKOWSKI_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp	(revision 6952)
@@ -0,0 +1,45 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 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.
+*/
+
+/// This file was created by Alex Silverman
+
+#include "BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h"
+#include "BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h"
+//#include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
+
+
+///Obtains the material for a specific triangle
+const btMaterial * btMultimaterialTriangleMeshShape::getMaterialProperties(int partID, int triIndex)
+{
+    const unsigned char * materialBase = 0;
+    int numMaterials;
+    PHY_ScalarType materialType;
+    int materialStride;
+    const unsigned char * triangleMaterialBase = 0;
+    int numTriangles;
+    int triangleMaterialStride;
+    PHY_ScalarType triangleType;
+
+    ((btTriangleIndexVertexMaterialArray*)m_meshInterface)->getLockedReadOnlyMaterialBase(&materialBase, numMaterials, materialType, materialStride,
+        &triangleMaterialBase, numTriangles, triangleMaterialStride, triangleType, partID);
+
+    // return the pointer to the place with the friction for the triangle
+    // TODO: This depends on whether it's a moving mesh or not
+    // BUG IN GIMPACT
+    //return (btScalar*)(&materialBase[triangleMaterialBase[(triIndex-1) * triangleMaterialStride] * materialStride]);
+    int * matInd = (int *)(&(triangleMaterialBase[(triIndex * triangleMaterialStride)]));
+    btMaterial *matVal = (btMaterial *)(&(materialBase[*matInd * materialStride]));
+    return (matVal);
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h	(revision 6952)
@@ -0,0 +1,123 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 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.
+*/
+
+/// This file was created by Alex Silverman
+
+#ifndef BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H
+#define BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H
+
+#include "btBvhTriangleMeshShape.h"
+#include "btMaterial.h"
+
+///The BvhTriangleMaterialMeshShape extends the btBvhTriangleMeshShape. Its main contribution is the interface into a material array, which allows per-triangle friction and restitution.
+ATTRIBUTE_ALIGNED16(class) btMultimaterialTriangleMeshShape : public btBvhTriangleMeshShape
+{
+    btAlignedObjectArray <btMaterial*> m_materialList;
+    int ** m_triangleMaterials;
+
+public:
+
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+    btMultimaterialTriangleMeshShape(): btBvhTriangleMeshShape() {m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;}
+    btMultimaterialTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true):
+        btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, buildBvh)
+        {
+            m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;
+
+            btVector3 m_triangle[3];
+            const unsigned char *vertexbase;
+            int numverts;
+            PHY_ScalarType type;
+            int stride;
+            const unsigned char *indexbase;
+            int indexstride;
+            int numfaces;
+            PHY_ScalarType indicestype;
+
+            //m_materialLookup = (int**)(btAlignedAlloc(sizeof(int*) * meshInterface->getNumSubParts(), 16));
+
+            for(int i = 0; i < meshInterface->getNumSubParts(); i++)
+            {
+                m_meshInterface->getLockedReadOnlyVertexIndexBase(
+                    &vertexbase,
+                    numverts,
+                    type,
+                    stride,
+                    &indexbase,
+                    indexstride,
+                    numfaces,
+                    indicestype,
+                    i);
+                //m_materialLookup[i] = (int*)(btAlignedAlloc(sizeof(int) * numfaces, 16));
+            }
+        }
+
+	///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb
+	btMultimaterialTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax, bool buildBvh = true):
+        btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, bvhAabbMin, bvhAabbMax, buildBvh)
+        {
+            m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE;
+
+            btVector3 m_triangle[3];
+            const unsigned char *vertexbase;
+            int numverts;
+            PHY_ScalarType type;
+            int stride;
+            const unsigned char *indexbase;
+            int indexstride;
+            int numfaces;
+            PHY_ScalarType indicestype;
+
+            //m_materialLookup = (int**)(btAlignedAlloc(sizeof(int*) * meshInterface->getNumSubParts(), 16));
+
+            for(int i = 0; i < meshInterface->getNumSubParts(); i++)
+            {
+                m_meshInterface->getLockedReadOnlyVertexIndexBase(
+                    &vertexbase,
+                    numverts,
+                    type,
+                    stride,
+                    &indexbase,
+                    indexstride,
+                    numfaces,
+                    indicestype,
+                    i);
+                //m_materialLookup[i] = (int*)(btAlignedAlloc(sizeof(int) * numfaces * 2, 16));
+            }
+        }
+	
+    virtual ~btMultimaterialTriangleMeshShape()
+    {
+/*
+        for(int i = 0; i < m_meshInterface->getNumSubParts(); i++)
+        {
+            btAlignedFree(m_materialValues[i]);
+            m_materialLookup[i] = NULL;
+        }
+        btAlignedFree(m_materialValues);
+        m_materialLookup = NULL;
+*/
+    }
+	//debugging
+	virtual const char*	getName()const {return "MULTIMATERIALTRIANGLEMESH";}
+
+    ///Obtains the material for a specific triangle
+    const btMaterial * getMaterialProperties(int partID, int triIndex);
+
+}
+;
+
+#endif //BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.cpp	(revision 6952)
@@ -0,0 +1,390 @@
+/*
+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 "btOptimizedBvh.h"
+#include "btStridingMeshInterface.h"
+#include "LinearMath/btAabbUtil2.h"
+#include "LinearMath/btIDebugDraw.h"
+
+
+btOptimizedBvh::btOptimizedBvh()
+{ 
+}
+
+btOptimizedBvh::~btOptimizedBvh()
+{
+}
+
+
+void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax)
+{
+	m_useQuantization = useQuantizedAabbCompression;
+
+
+	// NodeArray	triangleNodes;
+
+	struct	NodeTriangleCallback : public btInternalTriangleIndexCallback
+	{
+
+		NodeArray&	m_triangleNodes;
+
+		NodeTriangleCallback& operator=(NodeTriangleCallback& other)
+		{
+			m_triangleNodes = other.m_triangleNodes;
+			return *this;
+		}
+		
+		NodeTriangleCallback(NodeArray&	triangleNodes)
+			:m_triangleNodes(triangleNodes)
+		{
+		}
+
+		virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
+		{
+			btOptimizedBvhNode node;
+			btVector3	aabbMin,aabbMax;
+			aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+			aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); 
+			aabbMin.setMin(triangle[0]);
+			aabbMax.setMax(triangle[0]);
+			aabbMin.setMin(triangle[1]);
+			aabbMax.setMax(triangle[1]);
+			aabbMin.setMin(triangle[2]);
+			aabbMax.setMax(triangle[2]);
+
+			//with quantization?
+			node.m_aabbMinOrg = aabbMin;
+			node.m_aabbMaxOrg = aabbMax;
+
+			node.m_escapeIndex = -1;
+	
+			//for child nodes
+			node.m_subPart = partId;
+			node.m_triangleIndex = triangleIndex;
+			m_triangleNodes.push_back(node);
+		}
+	};
+	struct	QuantizedNodeTriangleCallback : public btInternalTriangleIndexCallback
+	{
+		QuantizedNodeArray&	m_triangleNodes;
+		const btQuantizedBvh* m_optimizedTree; // for quantization
+
+		QuantizedNodeTriangleCallback& operator=(QuantizedNodeTriangleCallback& other)
+		{
+			m_triangleNodes = other.m_triangleNodes;
+			m_optimizedTree = other.m_optimizedTree;
+			return *this;
+		}
+
+		QuantizedNodeTriangleCallback(QuantizedNodeArray&	triangleNodes,const btQuantizedBvh* tree)
+			:m_triangleNodes(triangleNodes),m_optimizedTree(tree)
+		{
+		}
+
+		virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
+		{
+			// The partId and triangle index must fit in the same (positive) integer
+			btAssert(partId < (1<<MAX_NUM_PARTS_IN_BITS));
+			btAssert(triangleIndex < (1<<(31-MAX_NUM_PARTS_IN_BITS)));
+			//negative indices are reserved for escapeIndex
+			btAssert(triangleIndex>=0);
+
+			btQuantizedBvhNode node;
+			btVector3	aabbMin,aabbMax;
+			aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+			aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); 
+			aabbMin.setMin(triangle[0]);
+			aabbMax.setMax(triangle[0]);
+			aabbMin.setMin(triangle[1]);
+			aabbMax.setMax(triangle[1]);
+			aabbMin.setMin(triangle[2]);
+			aabbMax.setMax(triangle[2]);
+
+			//PCK: add these checks for zero dimensions of aabb
+			const btScalar MIN_AABB_DIMENSION = btScalar(0.002);
+			const btScalar MIN_AABB_HALF_DIMENSION = btScalar(0.001);
+			if (aabbMax.x() - aabbMin.x() < MIN_AABB_DIMENSION)
+			{
+				aabbMax.setX(aabbMax.x() + MIN_AABB_HALF_DIMENSION);
+				aabbMin.setX(aabbMin.x() - MIN_AABB_HALF_DIMENSION);
+			}
+			if (aabbMax.y() - aabbMin.y() < MIN_AABB_DIMENSION)
+			{
+				aabbMax.setY(aabbMax.y() + MIN_AABB_HALF_DIMENSION);
+				aabbMin.setY(aabbMin.y() - MIN_AABB_HALF_DIMENSION);
+			}
+			if (aabbMax.z() - aabbMin.z() < MIN_AABB_DIMENSION)
+			{
+				aabbMax.setZ(aabbMax.z() + MIN_AABB_HALF_DIMENSION);
+				aabbMin.setZ(aabbMin.z() - MIN_AABB_HALF_DIMENSION);
+			}
+
+			m_optimizedTree->quantize(&node.m_quantizedAabbMin[0],aabbMin,0);
+			m_optimizedTree->quantize(&node.m_quantizedAabbMax[0],aabbMax,1);
+
+			node.m_escapeIndexOrTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex;
+
+			m_triangleNodes.push_back(node);
+		}
+	};
+	
+
+
+	int numLeafNodes = 0;
+
+	
+	if (m_useQuantization)
+	{
+
+		//initialize quantization values
+		setQuantizationValues(bvhAabbMin,bvhAabbMax);
+
+		QuantizedNodeTriangleCallback	callback(m_quantizedLeafNodes,this);
+
+	
+		triangles->InternalProcessAllTriangles(&callback,m_bvhAabbMin,m_bvhAabbMax);
+
+		//now we have an array of leafnodes in m_leafNodes
+		numLeafNodes = m_quantizedLeafNodes.size();
+
+
+		m_quantizedContiguousNodes.resize(2*numLeafNodes);
+
+
+	} else
+	{
+		NodeTriangleCallback	callback(m_leafNodes);
+
+		btVector3 aabbMin(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
+		btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+
+		triangles->InternalProcessAllTriangles(&callback,aabbMin,aabbMax);
+
+		//now we have an array of leafnodes in m_leafNodes
+		numLeafNodes = m_leafNodes.size();
+
+		m_contiguousNodes.resize(2*numLeafNodes);
+	}
+
+	m_curNodeIndex = 0;
+
+	buildTree(0,numLeafNodes);
+
+	///if the entire tree is small then subtree size, we need to create a header info for the tree
+	if(m_useQuantization && !m_SubtreeHeaders.size())
+	{
+		btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand();
+		subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]);
+		subtree.m_rootNodeIndex = 0;
+		subtree.m_subtreeSize = m_quantizedContiguousNodes[0].isLeafNode() ? 1 : m_quantizedContiguousNodes[0].getEscapeIndex();
+	}
+
+	//PCK: update the copy of the size
+	m_subtreeHeaderCount = m_SubtreeHeaders.size();
+
+	//PCK: clear m_quantizedLeafNodes and m_leafNodes, they are temporary
+	m_quantizedLeafNodes.clear();
+	m_leafNodes.clear();
+}
+
+
+
+
+void	btOptimizedBvh::refit(btStridingMeshInterface* meshInterface,const btVector3& aabbMin,const btVector3& aabbMax)
+{
+	if (m_useQuantization)
+	{
+
+		setQuantizationValues(aabbMin,aabbMax);
+
+		updateBvhNodes(meshInterface,0,m_curNodeIndex,0);
+
+		///now update all subtree headers
+
+		int i;
+		for (i=0;i<m_SubtreeHeaders.size();i++)
+		{
+			btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
+			subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]);
+		}
+
+	} else
+	{
+
+	}
+}
+
+
+
+
+void	btOptimizedBvh::refitPartial(btStridingMeshInterface* meshInterface,const btVector3& aabbMin,const btVector3& aabbMax)
+{
+	//incrementally initialize quantization values
+	btAssert(m_useQuantization);
+
+	btAssert(aabbMin.getX() > m_bvhAabbMin.getX());
+	btAssert(aabbMin.getY() > m_bvhAabbMin.getY());
+	btAssert(aabbMin.getZ() > m_bvhAabbMin.getZ());
+
+	btAssert(aabbMax.getX() < m_bvhAabbMax.getX());
+	btAssert(aabbMax.getY() < m_bvhAabbMax.getY());
+	btAssert(aabbMax.getZ() < m_bvhAabbMax.getZ());
+
+	///we should update all quantization values, using updateBvhNodes(meshInterface);
+	///but we only update chunks that overlap the given aabb
+	
+	unsigned short	quantizedQueryAabbMin[3];
+	unsigned short	quantizedQueryAabbMax[3];
+
+	quantize(&quantizedQueryAabbMin[0],aabbMin,0);
+	quantize(&quantizedQueryAabbMax[0],aabbMax,1);
+
+	int i;
+	for (i=0;i<this->m_SubtreeHeaders.size();i++)
+	{
+		btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i];
+
+		//PCK: unsigned instead of bool
+		unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax);
+		if (overlap != 0)
+		{
+			updateBvhNodes(meshInterface,subtree.m_rootNodeIndex,subtree.m_rootNodeIndex+subtree.m_subtreeSize,i);
+
+			subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]);
+		}
+	}
+	
+}
+
+void	btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index)
+{
+	(void)index;
+
+	btAssert(m_useQuantization);
+
+	int curNodeSubPart=-1;
+
+	//get access info to trianglemesh data
+		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;
+
+		btVector3	triangleVerts[3];
+		btVector3	aabbMin,aabbMax;
+		const btVector3& meshScaling = meshInterface->getScaling();
+		
+		int i;
+		for (i=endNode-1;i>=firstNode;i--)
+		{
+
+
+			btQuantizedBvhNode& curNode = m_quantizedContiguousNodes[i];
+			if (curNode.isLeafNode())
+			{
+				//recalc aabb from triangle data
+				int nodeSubPart = curNode.getPartId();
+				int nodeTriangleIndex = curNode.getTriangleIndex();
+				if (nodeSubPart != curNodeSubPart)
+				{
+					if (curNodeSubPart >= 0)
+						meshInterface->unLockReadOnlyVertexBase(curNodeSubPart);
+					meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,	type,stride,&indexbase,indexstride,numfaces,indicestype,nodeSubPart);
+
+					curNodeSubPart = nodeSubPart;
+					btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT);
+				}
+				//triangles->getLockedReadOnlyVertexIndexBase(vertexBase,numVerts,
+
+				unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*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(1e30),btScalar(1e30),btScalar(1e30));
+				aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30)); 
+				aabbMin.setMin(triangleVerts[0]);
+				aabbMax.setMax(triangleVerts[0]);
+				aabbMin.setMin(triangleVerts[1]);
+				aabbMax.setMax(triangleVerts[1]);
+				aabbMin.setMin(triangleVerts[2]);
+				aabbMax.setMax(triangleVerts[2]);
+
+				quantize(&curNode.m_quantizedAabbMin[0],aabbMin,0);
+				quantize(&curNode.m_quantizedAabbMax[0],aabbMax,1);
+				
+			} else
+			{
+				//combine aabb from both children
+
+				btQuantizedBvhNode* leftChildNode = &m_quantizedContiguousNodes[i+1];
+				
+				btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? &m_quantizedContiguousNodes[i+2] :
+					&m_quantizedContiguousNodes[i+1+leftChildNode->getEscapeIndex()];
+				
+
+				{
+					for (int i=0;i<3;i++)
+					{
+						curNode.m_quantizedAabbMin[i] = leftChildNode->m_quantizedAabbMin[i];
+						if (curNode.m_quantizedAabbMin[i]>rightChildNode->m_quantizedAabbMin[i])
+							curNode.m_quantizedAabbMin[i]=rightChildNode->m_quantizedAabbMin[i];
+
+						curNode.m_quantizedAabbMax[i] = leftChildNode->m_quantizedAabbMax[i];
+						if (curNode.m_quantizedAabbMax[i] < rightChildNode->m_quantizedAabbMax[i])
+							curNode.m_quantizedAabbMax[i] = rightChildNode->m_quantizedAabbMax[i];
+					}
+				}
+			}
+
+		}
+
+		if (curNodeSubPart >= 0)
+			meshInterface->unLockReadOnlyVertexBase(curNodeSubPart);
+
+		
+}
+
+///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place'
+btOptimizedBvh* btOptimizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian)
+{
+	btQuantizedBvh* bvh = btQuantizedBvh::deSerializeInPlace(i_alignedDataBuffer,i_dataBufferSize,i_swapEndian);
+	
+	//we don't add additional data so just do a static upcast
+	return static_cast<btOptimizedBvh*>(bvh);
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btOptimizedBvh.h	(revision 6952)
@@ -0,0 +1,63 @@
+/*
+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 OPTIMIZED_BVH_H
+#define OPTIMIZED_BVH_H
+
+#include "BulletCollision/BroadphaseCollision/btQuantizedBvh.h"
+
+class btStridingMeshInterface;
+
+
+///The btOptimizedBvh extends the btQuantizedBvh to create AABB tree for triangle meshes, through the btStridingMeshInterface.
+ATTRIBUTE_ALIGNED16(class) btOptimizedBvh : public btQuantizedBvh
+{
+	
+public:
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+protected:
+
+public:
+
+	btOptimizedBvh();
+
+	virtual ~btOptimizedBvh();
+
+	void	build(btStridingMeshInterface* triangles,bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax);
+
+	void	refit(btStridingMeshInterface* triangles,const btVector3& aabbMin,const btVector3& aabbMax);
+
+	void	refitPartial(btStridingMeshInterface* triangles,const btVector3& aabbMin, const btVector3& aabbMax);
+
+	void	updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index);
+
+	/// Data buffer MUST be 16 byte aligned
+	virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian)
+	{
+		return btQuantizedBvh::serialize(o_alignedDataBuffer,i_dataBufferSize,i_swapEndian);
+
+	}
+
+	///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place'
+	static btOptimizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian);
+
+
+};
+
+
+#endif //OPTIMIZED_BVH_H
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp	(revision 6952)
@@ -0,0 +1,185 @@
+/*
+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 "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h"
+
+btPolyhedralConvexShape::btPolyhedralConvexShape() :btConvexInternalShape(),
+m_localAabbMin(1,1,1),
+m_localAabbMax(-1,-1,-1),
+m_isLocalAabbValid(false),
+m_optionalHull(0)
+{
+
+}
+
+
+btVector3	btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const
+{
+	int i;
+	btVector3 supVec(0,0,0);
+
+	btScalar maxDot(btScalar(-1e30));
+
+	btVector3 vec = vec0;
+	btScalar lenSqr = vec.length2();
+	if (lenSqr < btScalar(0.0001))
+	{
+		vec.setValue(1,0,0);
+	} else
+	{
+		btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
+		vec *= rlen;
+	}
+
+	btVector3 vtx;
+	btScalar newDot;
+
+	for (i=0;i<getNumVertices();i++)
+	{
+		getVertex(i,vtx);
+		newDot = vec.dot(vtx);
+		if (newDot > maxDot)
+		{
+			maxDot = newDot;
+			supVec = vtx;
+		}
+	}
+
+	return supVec;
+
+}
+
+void	btPolyhedralConvexShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+	int i;
+
+	btVector3 vtx;
+	btScalar newDot;
+
+	for (i=0;i<numVectors;i++)
+	{
+		supportVerticesOut[i][3] = btScalar(-1e30);
+	}
+
+	for (int j=0;j<numVectors;j++)
+	{
+	
+		const btVector3& vec = vectors[j];
+
+		for (i=0;i<getNumVertices();i++)
+		{
+			getVertex(i,vtx);
+			newDot = vec.dot(vtx);
+			if (newDot > supportVerticesOut[j][3])
+			{
+				//WARNING: don't swap next lines, the w component would get overwritten!
+				supportVerticesOut[j] = vtx;
+				supportVerticesOut[j][3] = newDot;
+			}
+		}
+	}
+}
+
+
+
+void	btPolyhedralConvexShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+	//not yet, return box inertia
+
+	btScalar margin = getMargin();
+
+	btTransform ident;
+	ident.setIdentity();
+	btVector3 aabbMin,aabbMax;
+	getAabb(ident,aabbMin,aabbMax);
+	btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5);
+
+	btScalar lx=btScalar(2.)*(halfExtents.x()+margin);
+	btScalar ly=btScalar(2.)*(halfExtents.y()+margin);
+	btScalar lz=btScalar(2.)*(halfExtents.z()+margin);
+	const btScalar x2 = lx*lx;
+	const btScalar y2 = ly*ly;
+	const btScalar z2 = lz*lz;
+	const btScalar scaledmass = mass * btScalar(0.08333333);
+
+	inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
+
+}
+
+
+
+void btPolyhedralConvexShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	getNonvirtualAabb(trans,aabbMin,aabbMax,getMargin());
+}
+
+
+
+void	btPolyhedralConvexShape::setLocalScaling(const btVector3& scaling)
+{
+	btConvexInternalShape::setLocalScaling(scaling);
+	recalcLocalAabb();
+}
+
+void	btPolyhedralConvexShape::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/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h	(revision 6952)
@@ -0,0 +1,90 @@
+/*
+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 BU_SHAPE
+#define BU_SHAPE
+
+#include "LinearMath/btMatrix3x3.h"
+#include "LinearMath/btAabbUtil2.h"
+#include "btConvexInternalShape.h"
+
+
+///The btPolyhedralConvexShape is an internal interface class for polyhedral convex shapes.
+class btPolyhedralConvexShape : public btConvexInternalShape
+{
+
+protected:
+	btVector3	m_localAabbMin;
+	btVector3	m_localAabbMax;
+	bool		m_isLocalAabbValid;
+
+public:
+
+	btPolyhedralConvexShape();
+
+	//brute force implementations
+
+	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;
+
+
+	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);
+	}
+
+	
+	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;
+
+};
+
+#endif //BU_SHAPE
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp	(revision 6952)
@@ -0,0 +1,120 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 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 "btScaledBvhTriangleMeshShape.h"
+
+btScaledBvhTriangleMeshShape::btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling)
+:m_localScaling(localScaling),m_bvhTriMeshShape(childShape)
+{
+	m_shapeType = SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE;
+}
+
+btScaledBvhTriangleMeshShape::~btScaledBvhTriangleMeshShape()
+{
+}
+
+
+class btScaledTriangleCallback : public btTriangleCallback
+{
+	btTriangleCallback* m_originalCallback;
+
+	btVector3	m_localScaling;
+
+public:
+
+	btScaledTriangleCallback(btTriangleCallback* originalCallback,const btVector3& localScaling)
+		:m_originalCallback(originalCallback),
+		m_localScaling(localScaling)
+	{
+	}
+
+	virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
+	{
+		btVector3 newTriangle[3];
+		newTriangle[0] = triangle[0]*m_localScaling;
+		newTriangle[1] = triangle[1]*m_localScaling;
+		newTriangle[2] = triangle[2]*m_localScaling;
+		m_originalCallback->processTriangle(&newTriangle[0],partId,triangleIndex);
+	}
+};
+
+void	btScaledBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+	btScaledTriangleCallback scaledCallback(callback,m_localScaling);
+	
+	btVector3 invLocalScaling(1.f/m_localScaling.getX(),1.f/m_localScaling.getY(),1.f/m_localScaling.getZ());
+	btVector3 scaledAabbMin,scaledAabbMax;
+
+	///support negative scaling
+	scaledAabbMin[0] = m_localScaling.getX() >= 0. ? aabbMin[0] * invLocalScaling[0] : aabbMax[0] * invLocalScaling[0];
+	scaledAabbMin[1] = m_localScaling.getY() >= 0. ? aabbMin[1] * invLocalScaling[1] : aabbMax[1] * invLocalScaling[1];
+	scaledAabbMin[2] = m_localScaling.getZ() >= 0. ? aabbMin[2] * invLocalScaling[2] : aabbMax[2] * invLocalScaling[2];
+	
+	scaledAabbMax[0] = m_localScaling.getX() <= 0. ? aabbMin[0] * invLocalScaling[0] : aabbMax[0] * invLocalScaling[0];
+	scaledAabbMax[1] = m_localScaling.getY() <= 0. ? aabbMin[1] * invLocalScaling[1] : aabbMax[1] * invLocalScaling[1];
+	scaledAabbMax[2] = m_localScaling.getZ() <= 0. ? aabbMin[2] * invLocalScaling[2] : aabbMax[2] * invLocalScaling[2];
+	
+	
+	m_bvhTriMeshShape->processAllTriangles(&scaledCallback,scaledAabbMin,scaledAabbMax);
+}
+
+
+void	btScaledBvhTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	btVector3 localAabbMin = m_bvhTriMeshShape->getLocalAabbMin();
+	btVector3 localAabbMax = m_bvhTriMeshShape->getLocalAabbMax();
+
+	btVector3 tmpLocalAabbMin = localAabbMin * m_localScaling;
+	btVector3 tmpLocalAabbMax = localAabbMax * m_localScaling;
+
+	localAabbMin[0] = (m_localScaling.getX() >= 0.) ? tmpLocalAabbMin[0] : tmpLocalAabbMax[0];
+	localAabbMin[1] = (m_localScaling.getY() >= 0.) ? tmpLocalAabbMin[1] : tmpLocalAabbMax[1];
+	localAabbMin[2] = (m_localScaling.getZ() >= 0.) ? tmpLocalAabbMin[2] : tmpLocalAabbMax[2];
+	localAabbMax[0] = (m_localScaling.getX() <= 0.) ? tmpLocalAabbMin[0] : tmpLocalAabbMax[0];
+	localAabbMax[1] = (m_localScaling.getY() <= 0.) ? tmpLocalAabbMin[1] : tmpLocalAabbMax[1];
+	localAabbMax[2] = (m_localScaling.getZ() <= 0.) ? tmpLocalAabbMin[2] : tmpLocalAabbMax[2];
+
+	btVector3 localHalfExtents = btScalar(0.5)*(localAabbMax-localAabbMin);
+	btScalar margin = m_bvhTriMeshShape->getMargin();
+	localHalfExtents += btVector3(margin,margin,margin);
+	btVector3 localCenter = btScalar(0.5)*(localAabbMax+localAabbMin);
+	
+	btMatrix3x3 abs_b = trans.getBasis().absolute();  
+
+	btVector3 center = trans(localCenter);
+
+	btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
+		   abs_b[1].dot(localHalfExtents),
+		  abs_b[2].dot(localHalfExtents));
+	aabbMin = center - extent;
+	aabbMax = center + extent;
+
+}
+
+void	btScaledBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling)
+{
+	m_localScaling = scaling;
+}
+
+const btVector3& btScaledBvhTriangleMeshShape::getLocalScaling() const
+{
+	return m_localScaling;
+}
+
+void	btScaledBvhTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+	///don't make this a movable object!
+//	btAssert(0);
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h	(revision 6952)
@@ -0,0 +1,62 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 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 SCALED_BVH_TRIANGLE_MESH_SHAPE_H
+#define SCALED_BVH_TRIANGLE_MESH_SHAPE_H
+
+#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
+
+
+///The btScaledBvhTriangleMeshShape allows to instance a scaled version of an existing btBvhTriangleMeshShape.
+///Note that each btBvhTriangleMeshShape still can have its own local scaling, independent from this btScaledBvhTriangleMeshShape 'localScaling'
+ATTRIBUTE_ALIGNED16(class) btScaledBvhTriangleMeshShape : public btConcaveShape
+{
+	
+	
+	btVector3	m_localScaling;
+
+	btBvhTriangleMeshShape*	m_bvhTriMeshShape;
+
+public:
+
+
+	btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling);
+
+	virtual ~btScaledBvhTriangleMeshShape();
+
+
+	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
+	virtual void	setLocalScaling(const btVector3& scaling);
+	virtual const btVector3& getLocalScaling() const;
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
+	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+
+	btBvhTriangleMeshShape*	getChildShape()
+	{
+		return m_bvhTriMeshShape;
+	}
+
+	const btBvhTriangleMeshShape*	getChildShape() const
+	{
+		return m_bvhTriMeshShape;
+	}
+
+	//debugging
+	virtual const char*	getName()const {return "SCALEDBVHTRIANGLEMESH";}
+
+};
+
+#endif //BVH_TRIANGLE_MESH_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btShapeHull.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btShapeHull.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btShapeHull.cpp	(revision 6952)
@@ -0,0 +1,164 @@
+/*
+btbtShapeHull implemented by John McCutchan.
+
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.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 "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)
+{
+	m_shape = shape;
+	m_vertices.clear ();
+	m_indices.clear();
+	m_numIndices = 0;
+}
+
+btShapeHull::~btShapeHull ()
+{
+	m_indices.clear();	
+	m_vertices.clear ();
+}
+
+bool
+btShapeHull::buildHull (btScalar /*margin*/)
+{
+	int numSampleDirections = NUM_UNITSPHERE_POINTS;
+	{
+		int numPDA = m_shape->getNumPreferredPenetrationDirections();
+		if (numPDA)
+		{
+			for (int i=0;i<numPDA;i++)
+			{
+				btVector3 norm;
+				m_shape->getPreferredPenetrationDirection(i,norm);
+				btUnitSpherePoints[numSampleDirections] = norm;
+				numSampleDirections++;
+			}
+		}
+	}
+
+	btVector3 supportPoints[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2];
+	int i;
+	for (i = 0; i < numSampleDirections; i++)
+	{
+		supportPoints[i] = m_shape->localGetSupportingVertex(btUnitSpherePoints[i]);
+	}
+
+	HullDesc hd;
+	hd.mFlags = QF_TRIANGLES;
+	hd.mVcount = static_cast<unsigned int>(numSampleDirections);
+
+#ifdef BT_USE_DOUBLE_PRECISION
+	hd.mVertices = &supportPoints[0];
+	hd.mVertexStride = sizeof(btVector3);
+#else
+	hd.mVertices = &supportPoints[0];
+	hd.mVertexStride = sizeof (btVector3);
+#endif
+
+	HullLibrary hl;
+	HullResult hr;
+	if (hl.CreateConvexHull (hd, hr) == QE_FAIL)
+	{
+		return false;
+	}
+
+	m_vertices.resize (static_cast<int>(hr.mNumOutputVertices));
+
+
+	for (i = 0; i < static_cast<int>(hr.mNumOutputVertices); i++)
+	{
+		m_vertices[i] = hr.m_OutputVertices[i];
+	}
+	m_numIndices = hr.mNumIndices;
+	m_indices.resize(static_cast<int>(m_numIndices));
+	for (i = 0; i < static_cast<int>(m_numIndices); i++)
+	{
+		m_indices[i] = hr.m_Indices[i];
+	}
+
+	// free temporary hull result that we just copied
+	hl.ReleaseResult (hr);
+
+	return true;
+}
+
+int
+btShapeHull::numTriangles () const
+{
+	return static_cast<int>(m_numIndices / 3);
+}
+
+int
+btShapeHull::numVertices () const
+{
+	return m_vertices.size ();
+}
+
+int
+btShapeHull::numIndices () const
+{
+	return static_cast<int>(m_numIndices);
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btShapeHull.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btShapeHull.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btShapeHull.h	(revision 6952)
@@ -0,0 +1,56 @@
+/*
+btShapeHull implemented by John McCutchan.
+
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 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 _SHAPE_HULL_H
+#define _SHAPE_HULL_H
+
+#include "LinearMath/btAlignedObjectArray.h"
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+
+
+///The btShapeHull class takes a btConvexShape, builds a simplified convex hull using btConvexHull and provides triangle indices and vertices.
+///It can be useful for to simplify a complex convex object and for visualization of a non-polyhedral convex object.
+///It approximates the convex hull using the supporting vertex of 42 directions.
+class btShapeHull
+{
+public:
+	btShapeHull (const btConvexShape* shape);
+	~btShapeHull ();
+
+	bool buildHull (btScalar margin);
+
+	int numTriangles () const;
+	int numVertices () const;
+	int numIndices () const;
+
+	const btVector3* getVertexPointer() const
+	{
+		return &m_vertices[0];
+	}
+	const unsigned int* getIndexPointer() const
+	{
+		return &m_indices[0];
+	}
+
+protected:
+	btAlignedObjectArray<btVector3> m_vertices;
+	btAlignedObjectArray<unsigned int> m_indices;
+	unsigned int m_numIndices;
+	const btConvexShape* m_shape;
+};
+
+#endif //_SHAPE_HULL_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btSphereShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btSphereShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btSphereShape.cpp	(revision 6952)
@@ -0,0 +1,71 @@
+/*
+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 "btSphereShape.h"
+#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+
+#include "LinearMath/btQuaternion.h"
+
+btVector3	btSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
+{
+	(void)vec;
+	return btVector3(btScalar(0.),btScalar(0.),btScalar(0.));
+}
+
+void	btSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+	(void)vectors;
+
+	for (int i=0;i<numVectors;i++)
+	{
+		supportVerticesOut[i].setValue(btScalar(0.),btScalar(0.),btScalar(0.));
+	}
+}
+
+
+btVector3	btSphereShape::localGetSupportingVertex(const btVector3& vec)const
+{
+	btVector3 supVertex;
+	supVertex = localGetSupportingVertexWithoutMargin(vec);
+
+	btVector3 vecnorm = vec;
+	if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON))
+	{
+		vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.));
+	} 
+	vecnorm.normalize();
+	supVertex+= getMargin() * vecnorm;
+	return supVertex;
+}
+
+
+//broken due to scaling
+void btSphereShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	const btVector3& center = t.getOrigin();
+	btVector3 extent(getMargin(),getMargin(),getMargin());
+	aabbMin = center - extent;
+	aabbMax = center + extent;
+}
+
+
+
+void	btSphereShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+	btScalar elem = btScalar(0.4) * mass * getMargin()*getMargin();
+	inertia.setValue(elem,elem,elem);
+
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btSphereShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btSphereShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btSphereShape.h	(revision 6952)
@@ -0,0 +1,74 @@
+/*
+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 SPHERE_MINKOWSKI_H
+#define SPHERE_MINKOWSKI_H
+
+#include "btConvexInternalShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+
+///The btSphereShape implements an implicit sphere, centered around a local origin with radius.
+ATTRIBUTE_ALIGNED16(class) btSphereShape : public btConvexInternalShape
+
+{
+	
+public:
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	btSphereShape (btScalar radius) : btConvexInternalShape ()
+	{
+		m_shapeType = SPHERE_SHAPE_PROXYTYPE;
+		m_implicitShapeDimensions.setX(radius);
+		m_collisionMargin = radius;
+	}
+	
+	virtual btVector3	localGetSupportingVertex(const btVector3& vec)const;
+	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const;
+	//notice that the vectors should be unit length
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const;
+
+
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
+	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
+
+
+	btScalar	getRadius() const { return m_implicitShapeDimensions.getX() * m_localScaling.getX();}
+
+	void	setUnscaledRadius(btScalar	radius)
+	{
+		m_implicitShapeDimensions.setX(radius);
+		btConvexInternalShape::setMargin(radius);
+	}
+
+	//debugging
+	virtual const char*	getName()const {return "SPHERE";}
+
+	virtual void	setMargin(btScalar margin)
+	{
+		btConvexInternalShape::setMargin(margin);
+	}
+	virtual btScalar	getMargin() const
+	{
+		//to improve gjk behaviour, use radius+margin as the full margin, so never get into the penetration case
+		//this means, non-uniform scaling is not supported anymore
+		return getRadius();
+	}
+
+
+};
+
+
+#endif //SPHERE_MINKOWSKI_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btStaticPlaneShape.cpp	(revision 6952)
@@ -0,0 +1,107 @@
+/*
+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 "btStaticPlaneShape.h"
+
+#include "LinearMath/btTransformUtil.h"
+
+
+btStaticPlaneShape::btStaticPlaneShape(const btVector3& planeNormal,btScalar planeConstant)
+: btConcaveShape (), m_planeNormal(planeNormal.normalized()),
+m_planeConstant(planeConstant),
+m_localScaling(btScalar(0.),btScalar(0.),btScalar(0.))
+{
+	m_shapeType = STATIC_PLANE_PROXYTYPE;
+	//	btAssert( btFuzzyZero(m_planeNormal.length() - btScalar(1.)) );
+}
+
+
+btStaticPlaneShape::~btStaticPlaneShape()
+{
+}
+
+
+
+void btStaticPlaneShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	(void)t;
+	/*
+	btVector3 infvec (btScalar(1e30),btScalar(1e30),btScalar(1e30));
+
+	btVector3 center = m_planeNormal*m_planeConstant;
+	aabbMin = center + infvec*m_planeNormal;
+	aabbMax = aabbMin;
+	aabbMin.setMin(center - infvec*m_planeNormal);
+	aabbMax.setMax(center - infvec*m_planeNormal); 
+	*/
+
+	aabbMin.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
+	aabbMax.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+
+}
+
+
+
+
+void	btStaticPlaneShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+
+	btVector3 halfExtents = (aabbMax - aabbMin) * btScalar(0.5);
+	btScalar radius = halfExtents.length();
+	btVector3 center = (aabbMax + aabbMin) * btScalar(0.5);
+	
+	//this is where the triangles are generated, given AABB and plane equation (normal/constant)
+
+	btVector3 tangentDir0,tangentDir1;
+
+	//tangentDir0/tangentDir1 can be precalculated
+	btPlaneSpace1(m_planeNormal,tangentDir0,tangentDir1);
+
+	btVector3 supVertex0,supVertex1;
+
+	btVector3 projectedCenter = center - (m_planeNormal.dot(center) - m_planeConstant)*m_planeNormal;
+	
+	btVector3 triangle[3];
+	triangle[0] = projectedCenter + tangentDir0*radius + tangentDir1*radius;
+	triangle[1] = projectedCenter + tangentDir0*radius - tangentDir1*radius;
+	triangle[2] = projectedCenter - tangentDir0*radius - tangentDir1*radius;
+
+	callback->processTriangle(triangle,0,0);
+
+	triangle[0] = projectedCenter - tangentDir0*radius - tangentDir1*radius;
+	triangle[1] = projectedCenter - tangentDir0*radius + tangentDir1*radius;
+	triangle[2] = projectedCenter + tangentDir0*radius + tangentDir1*radius;
+
+	callback->processTriangle(triangle,0,1);
+
+}
+
+void	btStaticPlaneShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+	(void)mass;
+
+	//moving concave objects not supported
+	
+	inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
+}
+
+void	btStaticPlaneShape::setLocalScaling(const btVector3& scaling)
+{
+	m_localScaling = scaling;
+}
+const btVector3& btStaticPlaneShape::getLocalScaling() const
+{
+	return m_localScaling;
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btStaticPlaneShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btStaticPlaneShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btStaticPlaneShape.h	(revision 6952)
@@ -0,0 +1,64 @@
+/*
+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 STATIC_PLANE_SHAPE_H
+#define STATIC_PLANE_SHAPE_H
+
+#include "btConcaveShape.h"
+
+
+///The btStaticPlaneShape simulates an infinite non-moving (static) collision plane.
+class btStaticPlaneShape : public btConcaveShape
+{
+protected:
+	btVector3	m_localAabbMin;
+	btVector3	m_localAabbMax;
+	
+	btVector3	m_planeNormal;
+	btScalar      m_planeConstant;
+	btVector3	m_localScaling;
+
+public:
+	btStaticPlaneShape(const btVector3& planeNormal,btScalar planeConstant);
+
+	virtual ~btStaticPlaneShape();
+
+
+	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
+
+	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
+	virtual void	setLocalScaling(const btVector3& scaling);
+	virtual const btVector3& getLocalScaling() const;
+	
+	const btVector3&	getPlaneNormal() const
+	{
+		return	m_planeNormal;
+	}
+
+	const btScalar&	getPlaneConstant() const
+	{
+		return	m_planeConstant;
+	}
+
+	//debugging
+	virtual const char*	getName()const {return "STATICPLANE";}
+
+
+};
+
+#endif //STATIC_PLANE_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp	(revision 6952)
@@ -0,0 +1,124 @@
+/*
+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 "btStridingMeshInterface.h"
+
+btStridingMeshInterface::~btStridingMeshInterface()
+{
+
+}
+
+
+void	btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+	(void)aabbMin;
+	(void)aabbMax;
+	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];
+	btScalar* graphicsbase;
+
+	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++)
+	{
+		getLockedReadOnlyVertexIndexBase(&vertexbase,numverts,type,stride,&indexbase,indexstride,numtriangles,gfxindextype,part);
+		numtotalphysicsverts+=numtriangles*3; //upper bound
+
+		switch (gfxindextype)
+		{
+		case PHY_INTEGER:
+			{
+				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);
+				}
+				break;
+			}
+		default:
+			btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT));
+		}
+
+		unLockReadOnlyVertexBase(part);
+	}
+}
+
+void	btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax)
+{
+
+	struct	AabbCalculationCallback : public btInternalTriangleIndexCallback
+	{
+		btVector3	m_aabbMin;
+		btVector3	m_aabbMax;
+
+		AabbCalculationCallback()
+		{
+			m_aabbMin.setValue(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+			m_aabbMax.setValue(btScalar(-1e30),btScalar(-1e30),btScalar(-1e30));
+		}
+
+		virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex)
+		{
+			(void)partId;
+			(void)triangleIndex;
+
+			m_aabbMin.setMin(triangle[0]);
+			m_aabbMax.setMax(triangle[0]);
+			m_aabbMin.setMin(triangle[1]);
+			m_aabbMax.setMax(triangle[1]);
+			m_aabbMin.setMin(triangle[2]);
+			m_aabbMax.setMax(triangle[2]);
+		}
+	};
+
+		//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));
+	InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax);
+
+	aabbMin = aabbCallback.m_aabbMin;
+	aabbMax = aabbCallback.m_aabbMax;
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btStridingMeshInterface.h	(revision 6952)
@@ -0,0 +1,96 @@
+/*
+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 STRIDING_MESHINTERFACE_H
+#define STRIDING_MESHINTERFACE_H
+
+#include "LinearMath/btVector3.h"
+#include "btTriangleCallback.h"
+#include "btConcaveShape.h"
+
+
+
+///	The btStridingMeshInterface is the interface class for high performance generic access to triangle meshes, used in combination with btBvhTriangleMeshShape and some other collision shapes.
+/// Using index striding of 3*sizeof(integer) it can use triangle arrays, using index striding of 1*sizeof(integer) it can handle triangle strips.
+/// It allows for sharing graphics and collision meshes. Also it provides locking/unlocking of graphics meshes that are in gpu memory.
+class  btStridingMeshInterface
+{
+	protected:
+	
+		btVector3 m_scaling;
+
+	public:
+		btStridingMeshInterface() :m_scaling(btScalar(1.),btScalar(1.),btScalar(1.))
+		{
+
+		}
+
+		virtual ~btStridingMeshInterface();
+
+
+
+		virtual void	InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+
+		///brute force method to calculate aabb
+		void	calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax);
+
+		/// get read and write access to a subpart of a triangle mesh
+		/// this subpart has a continuous array of vertices and indices
+		/// in this way the mesh can be handled as chunks of memory with striding
+		/// very similar to OpenGL vertexarray support
+		/// make a call to unLockVertexBase when the read and write access is finished	
+		virtual void	getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0)=0;
+		
+		virtual void	getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const=0;
+	
+		/// unLockVertexBase finishes the access to a subpart of the triangle mesh
+		/// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished
+		virtual void	unLockVertexBase(int subpart)=0;
+
+		virtual void	unLockReadOnlyVertexBase(int subpart) const=0;
+
+
+		/// getNumSubParts returns the number of seperate subparts
+		/// each subpart has a continuous array of vertices and indices
+		virtual int		getNumSubParts() const=0;
+
+		virtual void	preallocateVertices(int numverts)=0;
+		virtual void	preallocateIndices(int numindices)=0;
+
+		virtual bool	hasPremadeAabb() const { return false; }
+		virtual void	setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const
+                {
+                        (void) aabbMin;
+                        (void) aabbMax;
+                }
+		virtual void	getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const
+        {
+            (void) aabbMin;
+            (void) aabbMax;
+        }
+
+		const btVector3&	getScaling() const {
+			return m_scaling;
+		}
+		void	setScaling(const btVector3& scaling)
+		{
+			m_scaling = scaling;
+		}
+
+	
+
+};
+
+#endif //STRIDING_MESHINTERFACE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.cpp	(revision 6952)
@@ -0,0 +1,200 @@
+
+/*
+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 "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 (),
+m_numVertices(0)
+{
+	m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE;
+	addVertex(pt0);
+	addVertex(pt1);
+}
+
+btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2) : btPolyhedralConvexShape (),
+m_numVertices(0)
+{
+	m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE;
+	addVertex(pt0);
+	addVertex(pt1);
+	addVertex(pt2);
+}
+
+btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2,const btVector3& pt3) : btPolyhedralConvexShape (),
+m_numVertices(0)
+{
+	m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE;
+	addVertex(pt0);
+	addVertex(pt1);
+	addVertex(pt2);
+	addVertex(pt3);
+}
+
+
+
+
+
+void btBU_Simplex1to4::addVertex(const btVector3& pt)
+{
+	m_vertices[m_numVertices++] = pt;
+
+	recalcLocalAabb();
+}
+
+
+int	btBU_Simplex1to4::getNumVertices() const
+{
+	return m_numVertices;
+}
+
+int btBU_Simplex1to4::getNumEdges() const
+{
+	//euler formula, F-E+V = 2, so E = F+V-2
+
+	switch (m_numVertices)
+	{
+	case 0:
+		return 0;
+	case 1: return 0;
+	case 2: return 1;
+	case 3: return 3;
+	case 4: return 6;
+
+
+	}
+
+	return 0;
+}
+
+void btBU_Simplex1to4::getEdge(int i,btVector3& pa,btVector3& pb) const
+{
+	
+    switch (m_numVertices)
+	{
+
+	case 2: 
+		pa = m_vertices[0];
+		pb = m_vertices[1];
+		break;
+	case 3:  
+		switch (i)
+		{
+		case 0:
+			pa = m_vertices[0];
+			pb = m_vertices[1];
+			break;
+		case 1:
+			pa = m_vertices[1];
+			pb = m_vertices[2];
+			break;
+		case 2:
+			pa = m_vertices[2];
+			pb = m_vertices[0];
+			break;
+
+		}
+		break;
+	case 4: 
+		switch (i)
+		{
+		case 0:
+			pa = m_vertices[0];
+			pb = m_vertices[1];
+			break;
+		case 1:
+			pa = m_vertices[1];
+			pb = m_vertices[2];
+			break;
+		case 2:
+			pa = m_vertices[2];
+			pb = m_vertices[0];
+			break;
+		case 3:
+			pa = m_vertices[0];
+			pb = m_vertices[3];
+			break;
+		case 4:
+			pa = m_vertices[1];
+			pb = m_vertices[3];
+			break;
+		case 5:
+			pa = m_vertices[2];
+			pb = m_vertices[3];
+			break;
+		}
+
+	}
+
+
+
+
+}
+
+void btBU_Simplex1to4::getVertex(int i,btVector3& vtx) const
+{
+	vtx = m_vertices[i];
+}
+
+int	btBU_Simplex1to4::getNumPlanes() const
+{
+	switch (m_numVertices)
+	{
+	case 0:
+			return 0;
+	case 1:
+			return 0;
+	case 2:
+			return 0;
+	case 3:
+			return 2;
+	case 4:
+			return 4;
+	default:
+		{
+		}
+	}
+	return 0;
+}
+
+
+void btBU_Simplex1to4::getPlane(btVector3&, btVector3& ,int ) const
+{
+	
+}
+
+int btBU_Simplex1to4::getIndex(int ) const
+{
+	return 0;
+}
+
+bool btBU_Simplex1to4::isInside(const btVector3& ,btScalar ) const
+{
+	return false;
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTetrahedronShape.h	(revision 6952)
@@ -0,0 +1,74 @@
+/*
+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 BU_SIMPLEX_1TO4_SHAPE
+#define BU_SIMPLEX_1TO4_SHAPE
+
+
+#include "btPolyhedralConvexShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+
+
+///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
+{
+protected:
+
+	int	m_numVertices;
+	btVector3	m_vertices[4];
+
+public:
+	btBU_Simplex1to4();
+
+	btBU_Simplex1to4(const btVector3& pt0);
+	btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1);
+	btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2);
+	btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2,const btVector3& pt3);
+
+    
+	void	reset()
+	{
+		m_numVertices = 0;
+	}
+	
+
+
+	void addVertex(const btVector3& pt);
+
+	//PolyhedralConvexShape interface
+
+	virtual int	getNumVertices() const;
+
+	virtual int getNumEdges() const;
+
+	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const;
+	
+	virtual void getVertex(int i,btVector3& vtx) const;
+
+	virtual int	getNumPlanes() const;
+
+	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i) const;
+
+	virtual int getIndex(int i) const;
+
+	virtual	bool isInside(const btVector3& pt,btScalar tolerance) const;
+
+
+	///getName is for debugging
+	virtual const char*	getName()const { return "btBU_Simplex1to4";}
+
+};
+
+#endif //BU_SIMPLEX_1TO4_SHAPE
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.cpp	(revision 6952)
@@ -0,0 +1,35 @@
+/*
+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 "btTriangleBuffer.h"
+
+
+
+
+
+
+
+void btTriangleBuffer::processTriangle(btVector3* triangle,int partId,int  triangleIndex)
+{
+		btTriangle	tri;
+		tri.m_vertex0 = triangle[0];
+		tri.m_vertex1 = triangle[1];
+		tri.m_vertex2 = triangle[2];
+		tri.m_partId = partId;
+		tri.m_triangleIndex = triangleIndex;
+			
+		m_triangleBuffer.push_back(tri);
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleBuffer.h	(revision 6952)
@@ -0,0 +1,69 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_TRIANGLE_BUFFER_H
+#define BT_TRIANGLE_BUFFER_H
+
+#include "btTriangleCallback.h"
+#include "LinearMath/btAlignedObjectArray.h"
+
+struct	btTriangle
+{
+	btVector3	m_vertex0;
+	btVector3	m_vertex1;
+	btVector3	m_vertex2;
+	int	m_partId;
+	int	m_triangleIndex;
+};
+
+///The btTriangleBuffer callback can be useful to collect and store overlapping triangles between AABB and concave objects that support 'processAllTriangles'
+///Example usage of this class:
+///			btTriangleBuffer	triBuf;
+///			concaveShape->processAllTriangles(&triBuf,aabbMin, aabbMax);
+///			for (int i=0;i<triBuf.getNumTriangles();i++)
+///			{
+///				const btTriangle& tri = triBuf.getTriangle(i);
+///				//do something useful here with the triangle
+///			}
+class btTriangleBuffer : public btTriangleCallback
+{
+
+	btAlignedObjectArray<btTriangle>	m_triangleBuffer;
+	
+public:
+
+
+	virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex);
+	
+	int	getNumTriangles() const
+	{
+		return int(m_triangleBuffer.size());
+	}
+	
+	const btTriangle&	getTriangle(int index) const
+	{
+		return m_triangleBuffer[index];
+	}
+
+	void	clearBuffer()
+	{
+		m_triangleBuffer.clear();
+	}
+	
+};
+
+
+#endif //BT_TRIANGLE_BUFFER_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleCallback.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleCallback.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleCallback.cpp	(revision 6952)
@@ -0,0 +1,28 @@
+/*
+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 "btTriangleCallback.h"
+
+btTriangleCallback::~btTriangleCallback()
+{
+
+}
+
+
+btInternalTriangleIndexCallback::~btInternalTriangleIndexCallback()
+{
+
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleCallback.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleCallback.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleCallback.h	(revision 6952)
@@ -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.
+*/
+
+#ifndef TRIANGLE_CALLBACK_H
+#define TRIANGLE_CALLBACK_H
+
+#include "LinearMath/btVector3.h"
+
+
+///The btTriangleCallback provides a callback for each overlapping triangle when calling processAllTriangles.
+///This callback is called by processAllTriangles for all btConcaveShape derived class, such as  btBvhTriangleMeshShape, btStaticPlaneShape and btHeightfieldTerrainShape.
+class btTriangleCallback
+{
+public:
+
+	virtual ~btTriangleCallback();
+	virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) = 0;
+};
+
+class btInternalTriangleIndexCallback
+{
+public:
+
+	virtual ~btInternalTriangleIndexCallback();
+	virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int  triangleIndex) = 0;
+};
+
+
+
+#endif //TRIANGLE_CALLBACK_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp	(revision 6952)
@@ -0,0 +1,99 @@
+/*
+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 "btTriangleIndexVertexArray.h"
+
+btTriangleIndexVertexArray::btTriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride)
+: m_hasAabb(0)
+{
+	btIndexedMesh mesh;
+
+	mesh.m_numTriangles = numTriangles;
+	mesh.m_triangleIndexBase = (const unsigned char *)triangleIndexBase;
+	mesh.m_triangleIndexStride = triangleIndexStride;
+	mesh.m_numVertices = numVertices;
+	mesh.m_vertexBase = (const unsigned char *)vertexBase;
+	mesh.m_vertexStride = vertexStride;
+
+	addIndexedMesh(mesh);
+
+}
+
+btTriangleIndexVertexArray::~btTriangleIndexVertexArray()
+{
+
+}
+
+void	btTriangleIndexVertexArray::getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart)
+{
+	btAssert(subpart< getNumSubParts() );
+
+	btIndexedMesh& mesh = m_indexedMeshes[subpart];
+
+	numverts = mesh.m_numVertices;
+	(*vertexbase) = (unsigned char *) mesh.m_vertexBase;
+	#ifdef BT_USE_DOUBLE_PRECISION
+	type = PHY_DOUBLE;
+	#else
+	type = PHY_FLOAT;
+	#endif
+	vertexStride = mesh.m_vertexStride;
+
+	numfaces = mesh.m_numTriangles;
+
+	(*indexbase) = (unsigned char *)mesh.m_triangleIndexBase;
+	indexstride = mesh.m_triangleIndexStride;
+	indicestype = mesh.m_indexType;
+}
+
+void	btTriangleIndexVertexArray::getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) const
+{
+	const btIndexedMesh& mesh = m_indexedMeshes[subpart];
+
+	numverts = mesh.m_numVertices;
+	(*vertexbase) = (const unsigned char *)mesh.m_vertexBase;
+	#ifdef BT_USE_DOUBLE_PRECISION
+	type = PHY_DOUBLE;
+	#else
+	type = PHY_FLOAT;
+	#endif
+	vertexStride = mesh.m_vertexStride;
+
+	numfaces = mesh.m_numTriangles;
+	(*indexbase) = (const unsigned char *)mesh.m_triangleIndexBase;
+	indexstride = mesh.m_triangleIndexStride;
+	indicestype = mesh.m_indexType;
+}
+
+bool	btTriangleIndexVertexArray::hasPremadeAabb() const
+{
+	return (m_hasAabb == 1);
+}
+
+
+void	btTriangleIndexVertexArray::setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const
+{
+	m_aabbMin = aabbMin;
+	m_aabbMax = aabbMax;
+	m_hasAabb = 1; // this is intentionally an int see notes in header
+}
+
+void	btTriangleIndexVertexArray::getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const
+{
+	*aabbMin = m_aabbMin;
+	*aabbMax = m_aabbMax;
+}
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h	(revision 6952)
@@ -0,0 +1,115 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_TRIANGLE_INDEX_VERTEX_ARRAY_H
+#define BT_TRIANGLE_INDEX_VERTEX_ARRAY_H
+
+#include "btStridingMeshInterface.h"
+#include "LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btScalar.h"
+
+
+///The btIndexedMesh indexes a single vertex and index array. Multiple btIndexedMesh objects can be passed into a btTriangleIndexVertexArray using addIndexedMesh.
+///Instead of the number of indices, we pass the number of triangles.
+ATTRIBUTE_ALIGNED16( struct)	btIndexedMesh
+{
+	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;
+}
+;
+
+
+typedef btAlignedObjectArray<btIndexedMesh>	IndexedMeshArray;
+
+///The btTriangleIndexVertexArray allows to access multiple triangle meshes, by indexing into existing triangle/index arrays.
+///Additional meshes can be added using addIndexedMesh
+///No duplcate is made of the vertex/index data, it only indexes into external vertex/index arrays.
+///So keep those arrays around during the lifetime of this btTriangleIndexVertexArray.
+ATTRIBUTE_ALIGNED16( class) btTriangleIndexVertexArray : public btStridingMeshInterface
+{
+protected:
+	IndexedMeshArray	m_indexedMeshes;
+	int m_pad[2];
+	mutable int m_hasAabb; // using int instead of bool to maintain alignment
+	mutable btVector3 m_aabbMin;
+	mutable btVector3 m_aabbMax;
+
+public:
+
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	btTriangleIndexVertexArray() : m_hasAabb(0)
+	{
+	}
+
+	virtual ~btTriangleIndexVertexArray();
+
+	//just to be backwards compatible
+	btTriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride);
+	
+	void	addIndexedMesh(const btIndexedMesh& mesh, PHY_ScalarType indexType = PHY_INTEGER)
+	{
+		m_indexedMeshes.push_back(mesh);
+		m_indexedMeshes[m_indexedMeshes.size()-1].m_indexType = indexType;
+	}
+	
+	
+	virtual void	getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0);
+
+	virtual void	getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const;
+
+	/// unLockVertexBase finishes the access to a subpart of the triangle mesh
+	/// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished
+	virtual void	unLockVertexBase(int subpart) {(void)subpart;}
+
+	virtual void	unLockReadOnlyVertexBase(int subpart) const {(void)subpart;}
+
+	/// getNumSubParts returns the number of seperate subparts
+	/// each subpart has a continuous array of vertices and indices
+	virtual int		getNumSubParts() const { 
+		return (int)m_indexedMeshes.size();
+	}
+
+	IndexedMeshArray&	getIndexedMeshArray()
+	{
+		return m_indexedMeshes;
+	}
+
+	const IndexedMeshArray&	getIndexedMeshArray() const
+	{
+		return m_indexedMeshes;
+	}
+
+	virtual void	preallocateVertices(int numverts){(void) numverts;}
+	virtual void	preallocateIndices(int numindices){(void) numindices;}
+
+	virtual bool	hasPremadeAabb() const;
+	virtual void	setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const;
+	virtual void	getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const;
+
+}
+;
+
+#endif //BT_TRIANGLE_INDEX_VERTEX_ARRAY_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp	(revision 6952)
@@ -0,0 +1,87 @@
+
+/*
+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.
+*/
+
+///This file was created by Alex Silverman
+
+#include "btTriangleIndexVertexMaterialArray.h"
+
+btTriangleIndexVertexMaterialArray::btTriangleIndexVertexMaterialArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,
+                                   int numVertices,btScalar* vertexBase,int vertexStride,
+                                   int numMaterials, unsigned char* materialBase, int materialStride,
+                                   int* triangleMaterialsBase, int materialIndexStride) :
+btTriangleIndexVertexArray(numTriangles, triangleIndexBase, triangleIndexStride, numVertices, vertexBase, vertexStride)
+{
+    btMaterialProperties mat;
+
+    mat.m_numMaterials = numMaterials;
+    mat.m_materialBase = materialBase;
+    mat.m_materialStride = materialStride;
+#ifdef BT_USE_DOUBLE_PRECISION
+    mat.m_materialType = PHY_DOUBLE;
+#else
+    mat.m_materialType = PHY_FLOAT;
+#endif
+
+    mat.m_numTriangles = numTriangles;
+    mat.m_triangleMaterialsBase = (unsigned char *)triangleMaterialsBase;
+    mat.m_triangleMaterialStride = materialIndexStride;
+    mat.m_triangleType = PHY_INTEGER;
+
+    addMaterialProperties(mat);
+}
+
+
+void btTriangleIndexVertexMaterialArray::getLockedMaterialBase(unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride,
+                                   unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart)
+{
+    btAssert(subpart< getNumSubParts() );
+
+    btMaterialProperties& mats = m_materials[subpart];
+
+    numMaterials = mats.m_numMaterials;
+    (*materialBase) = (unsigned char *) mats.m_materialBase;
+#ifdef BT_USE_DOUBLE_PRECISION
+    materialType = PHY_DOUBLE;
+#else
+    materialType = PHY_FLOAT;
+#endif
+    materialStride = mats.m_materialStride;
+
+    numTriangles = mats.m_numTriangles;
+    (*triangleMaterialBase) = (unsigned char *)mats.m_triangleMaterialsBase;
+    triangleMaterialStride = mats.m_triangleMaterialStride;
+    triangleType = mats.m_triangleType;
+}
+
+void btTriangleIndexVertexMaterialArray::getLockedReadOnlyMaterialBase(const unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride,
+                                           const unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart)
+{
+    btMaterialProperties& mats = m_materials[subpart];
+
+    numMaterials = mats.m_numMaterials;
+    (*materialBase) = (const unsigned char *) mats.m_materialBase;
+#ifdef BT_USE_DOUBLE_PRECISION
+    materialType = PHY_DOUBLE;
+#else
+    materialType = PHY_FLOAT;
+#endif
+    materialStride = mats.m_materialStride;
+
+    numTriangles = mats.m_numTriangles;
+    (*triangleMaterialBase) = (const unsigned char *)mats.m_triangleMaterialsBase;
+    triangleMaterialStride = mats.m_triangleMaterialStride;
+    triangleType = mats.m_triangleType;
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h	(revision 6952)
@@ -0,0 +1,84 @@
+/*
+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.
+*/
+
+///This file was created by Alex Silverman
+
+#ifndef BT_MULTIMATERIAL_TRIANGLE_INDEX_VERTEX_ARRAY_H
+#define BT_MULTIMATERIAL_TRIANGLE_INDEX_VERTEX_ARRAY_H
+
+#include "btTriangleIndexVertexArray.h"
+
+
+ATTRIBUTE_ALIGNED16( struct)	btMaterialProperties
+{
+    ///m_materialBase ==========> 2 btScalar values make up one material, friction then restitution
+    int m_numMaterials;
+    const unsigned char * m_materialBase;
+    int m_materialStride;
+    PHY_ScalarType m_materialType;
+    ///m_numTriangles <=========== This exists in the btIndexedMesh object for the same subpart, but since we're
+    ///                           padding the structure, it can be reproduced at no real cost
+    ///m_triangleMaterials =====> 1 integer value makes up one entry
+    ///                           eg: m_triangleMaterials[1] = 5; // This will set triangle 2 to use material 5
+    int m_numTriangles; 
+    const unsigned char * m_triangleMaterialsBase;
+    int m_triangleMaterialStride;
+    ///m_triangleType <========== Automatically set in addMaterialProperties
+    PHY_ScalarType m_triangleType;
+};
+
+typedef btAlignedObjectArray<btMaterialProperties>	MaterialArray;
+
+///Teh btTriangleIndexVertexMaterialArray is built on TriangleIndexVertexArray
+///The addition of a material array allows for the utilization of the partID and
+///triangleIndex that are returned in the ContactAddedCallback.  As with
+///TriangleIndexVertexArray, no duplicate is made of the material data, so it
+///is the users responsibility to maintain the array during the lifetime of the
+///TriangleIndexVertexMaterialArray.
+ATTRIBUTE_ALIGNED16(class) btTriangleIndexVertexMaterialArray : public btTriangleIndexVertexArray
+{
+protected:
+    MaterialArray       m_materials;
+		
+public:
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+    btTriangleIndexVertexMaterialArray()
+	{
+	}
+
+    btTriangleIndexVertexMaterialArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,
+        int numVertices,btScalar* vertexBase,int vertexStride,
+        int numMaterials, unsigned char* materialBase, int materialStride,
+        int* triangleMaterialsBase, int materialIndexStride);
+
+    virtual ~btTriangleIndexVertexMaterialArray() {}
+
+    void	addMaterialProperties(const btMaterialProperties& mat, PHY_ScalarType triangleType = PHY_INTEGER)
+    {
+        m_materials.push_back(mat);
+        m_materials[m_materials.size()-1].m_triangleType = triangleType;
+    }
+
+    virtual void getLockedMaterialBase(unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride,
+        unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType ,int subpart = 0);
+
+    virtual void getLockedReadOnlyMaterialBase(const unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride,
+        const unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart = 0);
+
+}
+;
+
+#endif //BT_MULTIMATERIAL_TRIANGLE_INDEX_VERTEX_ARRAY_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMesh.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMesh.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMesh.cpp	(revision 6952)
@@ -0,0 +1,139 @@
+/*
+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 "btTriangleMesh.h"
+
+
+
+btTriangleMesh::btTriangleMesh (bool use32bitIndices,bool use4componentVertices)
+:m_use32bitIndices(use32bitIndices),
+m_use4componentVertices(use4componentVertices),
+m_weldingThreshold(0.0)
+{
+	btIndexedMesh meshIndex;
+	meshIndex.m_numTriangles = 0;
+	meshIndex.m_numVertices = 0;
+	meshIndex.m_indexType = PHY_INTEGER;
+	meshIndex.m_triangleIndexBase = 0;
+	meshIndex.m_triangleIndexStride = 3*sizeof(int);
+	meshIndex.m_vertexBase = 0;
+	meshIndex.m_vertexStride = sizeof(btVector3);
+	m_indexedMeshes.push_back(meshIndex);
+
+	if (m_use32bitIndices)
+	{
+		m_indexedMeshes[0].m_numTriangles = m_32bitIndices.size()/3;
+		m_indexedMeshes[0].m_triangleIndexBase = 0;
+		m_indexedMeshes[0].m_indexType = PHY_INTEGER;
+		m_indexedMeshes[0].m_triangleIndexStride = 3*sizeof(int);
+	} else
+	{
+		m_indexedMeshes[0].m_numTriangles = m_16bitIndices.size()/3;
+		m_indexedMeshes[0].m_triangleIndexBase = 0;
+		m_indexedMeshes[0].m_indexType = PHY_SHORT;
+		m_indexedMeshes[0].m_triangleIndexStride = 3*sizeof(short int);
+	}
+
+	if (m_use4componentVertices)
+	{
+		m_indexedMeshes[0].m_numVertices = m_4componentVertices.size();
+		m_indexedMeshes[0].m_vertexBase = 0;
+		m_indexedMeshes[0].m_vertexStride = sizeof(btVector3);
+	} else
+	{
+		m_indexedMeshes[0].m_numVertices = m_3componentVertices.size()/3;
+		m_indexedMeshes[0].m_vertexBase = 0;
+		m_indexedMeshes[0].m_vertexStride = 3*sizeof(btScalar);
+	}
+
+
+}
+
+void	btTriangleMesh::addIndex(int index)
+{
+	if (m_use32bitIndices)
+	{
+		m_32bitIndices.push_back(index);
+		m_indexedMeshes[0].m_triangleIndexBase = (unsigned char*) &m_32bitIndices[0];
+	} else
+	{
+		m_16bitIndices.push_back(index);
+		m_indexedMeshes[0].m_triangleIndexBase = (unsigned char*) &m_16bitIndices[0];
+	}
+}
+
+
+int	btTriangleMesh::findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices)
+{
+	//return index of new/existing vertex
+	///@todo: could use acceleration structure for this
+	if (m_use4componentVertices)
+	{
+		if (removeDuplicateVertices)
+			{
+			for (int i=0;i< m_4componentVertices.size();i++)
+			{
+				if ((m_4componentVertices[i]-vertex).length2() <= m_weldingThreshold)
+				{
+					return i;
+				}
+			}
+		}
+		m_indexedMeshes[0].m_numVertices++;
+		m_4componentVertices.push_back(vertex);
+		m_indexedMeshes[0].m_vertexBase = (unsigned char*)&m_4componentVertices[0];
+
+		return m_4componentVertices.size()-1;
+		
+	} else
+	{
+		
+		if (removeDuplicateVertices)
+		{
+			for (int i=0;i< m_3componentVertices.size();i+=3)
+			{
+				btVector3 vtx(m_3componentVertices[i],m_3componentVertices[i+1],m_3componentVertices[i+2]);
+				if ((vtx-vertex).length2() <= m_weldingThreshold)
+				{
+					return i/3;
+				}
+			}
+	}
+		m_3componentVertices.push_back((float)vertex.getX());
+		m_3componentVertices.push_back((float)vertex.getY());
+		m_3componentVertices.push_back((float)vertex.getZ());
+		m_indexedMeshes[0].m_numVertices++;
+		m_indexedMeshes[0].m_vertexBase = (unsigned char*)&m_3componentVertices[0];
+		return (m_3componentVertices.size()/3)-1;
+	}
+
+}
+		
+void	btTriangleMesh::addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2,bool removeDuplicateVertices)
+{
+	m_indexedMeshes[0].m_numTriangles++;
+	addIndex(findOrAddVertex(vertex0,removeDuplicateVertices));
+	addIndex(findOrAddVertex(vertex1,removeDuplicateVertices));
+	addIndex(findOrAddVertex(vertex2,removeDuplicateVertices));
+}
+
+int btTriangleMesh::getNumTriangles() const
+{
+	if (m_use32bitIndices)
+	{
+		return m_32bitIndices.size() / 3;
+	}
+	return m_16bitIndices.size() / 3;
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMesh.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMesh.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMesh.h	(revision 6952)
@@ -0,0 +1,69 @@
+/*
+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 TRIANGLE_MESH_H
+#define TRIANGLE_MESH_H
+
+#include "btTriangleIndexVertexArray.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btAlignedObjectArray.h"
+
+///The btTriangleMesh class is a convenience class derived from btTriangleIndexVertexArray, that provides storage for a concave triangle mesh. It can be used as data for the btBvhTriangleMeshShape.
+///It allows either 32bit or 16bit indices, and 4 (x-y-z-w) or 3 (x-y-z) component vertices.
+///If you want to share triangle/index data between graphics mesh and collision mesh (btBvhTriangleMeshShape), you can directly use btTriangleIndexVertexArray or derive your own class from btStridingMeshInterface.
+///Performance of btTriangleMesh and btTriangleIndexVertexArray used in a btBvhTriangleMeshShape is the same.
+class btTriangleMesh : public btTriangleIndexVertexArray
+{
+	btAlignedObjectArray<btVector3>	m_4componentVertices;
+	btAlignedObjectArray<float>		m_3componentVertices;
+
+	btAlignedObjectArray<unsigned int>		m_32bitIndices;
+	btAlignedObjectArray<unsigned short int>		m_16bitIndices;
+	bool	m_use32bitIndices;
+	bool	m_use4componentVertices;
+	
+
+	public:
+		btScalar	m_weldingThreshold;
+
+		btTriangleMesh (bool use32bitIndices=true,bool use4componentVertices=true);
+
+		int		findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices);
+		void	addIndex(int index);
+
+		bool	getUse32bitIndices() const
+		{
+			return m_use32bitIndices;
+		}
+
+		bool	getUse4componentVertices() const
+		{
+			return m_use4componentVertices;
+		}
+		///By default addTriangle won't search for duplicate vertices, because the search is very slow for large triangle meshes.
+		///In general it is better to directly use btTriangleIndexVertexArray instead.
+		void	addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2, bool removeDuplicateVertices=false);
+		
+		int getNumTriangles() const;
+
+		virtual void	preallocateVertices(int numverts){(void) numverts;}
+		virtual void	preallocateIndices(int numindices){(void) numindices;}
+
+		
+};
+
+#endif //TRIANGLE_MESH_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp	(revision 6952)
@@ -0,0 +1,209 @@
+/*
+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 "btTriangleMeshShape.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btQuaternion.h"
+#include "btStridingMeshInterface.h"
+#include "LinearMath/btAabbUtil2.h"
+#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+
+
+btTriangleMeshShape::btTriangleMeshShape(btStridingMeshInterface* meshInterface)
+: btConcaveShape (), m_meshInterface(meshInterface)
+{
+	m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE;
+	if(meshInterface->hasPremadeAabb())
+	{
+		meshInterface->getPremadeAabb(&m_localAabbMin, &m_localAabbMax);
+	}
+	else
+	{
+		recalcLocalAabb();
+	}
+}
+
+
+btTriangleMeshShape::~btTriangleMeshShape()
+{
+		
+}
+
+
+
+
+void btTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const
+{
+
+	btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin);
+	localHalfExtents += btVector3(getMargin(),getMargin(),getMargin());
+	btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin);
+	
+	btMatrix3x3 abs_b = trans.getBasis().absolute();  
+
+	btVector3 center = trans(localCenter);
+
+	btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
+		   abs_b[1].dot(localHalfExtents),
+		  abs_b[2].dot(localHalfExtents));
+	aabbMin = center - extent;
+	aabbMax = center + extent;
+
+
+}
+
+void	btTriangleMeshShape::recalcLocalAabb()
+{
+	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;
+	}
+}
+
+
+
+class SupportVertexCallback : public btTriangleCallback
+{
+
+	btVector3 m_supportVertexLocal;
+public:
+
+	btTransform	m_worldTrans;
+	btScalar m_maxDot;
+	btVector3 m_supportVecLocal;
+
+	SupportVertexCallback(const btVector3& supportVecWorld,const btTransform& trans)
+		: m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), m_worldTrans(trans) ,m_maxDot(btScalar(-1e30))
+		
+	{
+		m_supportVecLocal = supportVecWorld * m_worldTrans.getBasis();
+	}
+
+	virtual void processTriangle( btVector3* triangle,int partId, int triangleIndex)
+	{
+		(void)partId;
+		(void)triangleIndex;
+		for (int i=0;i<3;i++)
+		{
+			btScalar dot = m_supportVecLocal.dot(triangle[i]);
+			if (dot > m_maxDot)
+			{
+				m_maxDot = dot;
+				m_supportVertexLocal = triangle[i];
+			}
+		}
+	}
+
+	btVector3 GetSupportVertexWorldSpace()
+	{
+		return m_worldTrans(m_supportVertexLocal);
+	}
+
+	btVector3	GetSupportVertexLocal()
+	{
+		return m_supportVertexLocal;
+	}
+
+};
+
+	
+void btTriangleMeshShape::setLocalScaling(const btVector3& scaling)
+{
+	m_meshInterface->setScaling(scaling);
+	recalcLocalAabb();
+}
+
+const btVector3& btTriangleMeshShape::getLocalScaling() const
+{
+	return m_meshInterface->getScaling();
+}
+
+
+
+
+
+
+//#define DEBUG_TRIANGLE_MESH
+
+
+
+void	btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+		struct FilteredCallback : public btInternalTriangleIndexCallback
+	{
+		btTriangleCallback* m_callback;
+		btVector3 m_aabbMin;
+		btVector3 m_aabbMax;
+
+		FilteredCallback(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax)
+			:m_callback(callback),
+			m_aabbMin(aabbMin),
+			m_aabbMax(aabbMax)
+		{
+		}
+
+		virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex)
+		{
+			if (TestTriangleAgainstAabb2(&triangle[0],m_aabbMin,m_aabbMax))
+			{
+				//check aabb in triangle-space, before doing this
+				m_callback->processTriangle(triangle,partId,triangleIndex);
+			}
+			
+		}
+
+	};
+
+	FilteredCallback filterCallback(callback,aabbMin,aabbMax);
+
+	m_meshInterface->InternalProcessAllTriangles(&filterCallback,aabbMin,aabbMax);
+}
+
+
+
+
+
+void	btTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+	(void)mass;
+	//moving concave objects not supported
+	btAssert(0);
+	inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
+}
+
+
+btVector3 btTriangleMeshShape::localGetSupportingVertex(const btVector3& vec) const
+{
+	btVector3 supportVertex;
+
+	btTransform ident;
+	ident.setIdentity();
+
+	SupportVertexCallback supportCallback(vec,ident);
+
+	btVector3 aabbMax(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+	
+	processAllTriangles(&supportCallback,-aabbMax,aabbMax);
+		
+	supportVertex = supportCallback.GetSupportVertexLocal();
+
+	return supportVertex;
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleMeshShape.h	(revision 6952)
@@ -0,0 +1,85 @@
+/*
+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 TRIANGLE_MESH_SHAPE_H
+#define TRIANGLE_MESH_SHAPE_H
+
+#include "btConcaveShape.h"
+#include "btStridingMeshInterface.h"
+
+
+///The btTriangleMeshShape is an internal concave triangle mesh interface. Don't use this class directly, use btBvhTriangleMeshShape instead.
+class btTriangleMeshShape : public btConcaveShape
+{
+protected:
+	btVector3	m_localAabbMin;
+	btVector3	m_localAabbMax;
+	btStridingMeshInterface* m_meshInterface;
+
+	///btTriangleMeshShape constructor has been disabled/protected, so that users will not mistakenly use this class.
+	///Don't use btTriangleMeshShape but use btBvhTriangleMeshShape instead!
+	btTriangleMeshShape(btStridingMeshInterface* meshInterface);
+
+public:
+
+	virtual ~btTriangleMeshShape();
+
+	virtual btVector3 localGetSupportingVertex(const btVector3& vec) const;
+
+	virtual btVector3	localGetSupportingVertexWithoutMargin(const btVector3& vec)const
+	{
+		btAssert(0);
+		return localGetSupportingVertex(vec);
+	}
+
+	void	recalcLocalAabb();
+
+	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const;
+
+	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
+	virtual void	setLocalScaling(const btVector3& scaling);
+	virtual const btVector3& getLocalScaling() const;
+	
+	btStridingMeshInterface* getMeshInterface()
+	{
+		return m_meshInterface;
+	}
+
+	const btStridingMeshInterface* getMeshInterface() const
+	{
+		return m_meshInterface;
+	}
+
+	const btVector3& getLocalAabbMin() const
+	{
+		return m_localAabbMin;
+	}
+	const btVector3& getLocalAabbMax() const
+	{
+		return m_localAabbMax;
+	}
+
+
+
+	//debugging
+	virtual const char*	getName()const {return "TRIANGLEMESH";}
+
+
+};
+
+#endif //TRIANGLE_MESH_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btTriangleShape.h	(revision 6952)
@@ -0,0 +1,174 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef OBB_TRIANGLE_MINKOWSKI_H
+#define OBB_TRIANGLE_MINKOWSKI_H
+
+#include "btConvexShape.h"
+#include "btBoxShape.h"
+
+class btTriangleShape : public btPolyhedralConvexShape
+{
+
+
+public:
+
+	btVector3	m_vertices1[3];
+
+	virtual int getNumVertices() const
+	{
+		return 3;
+	}
+
+	const btVector3& getVertexPtr(int index) const
+	{
+		return m_vertices1[index];
+	}
+	virtual void getVertex(int index,btVector3& vert) const
+	{
+		vert = m_vertices1[index];
+	}
+
+	virtual int getNumEdges() const
+	{
+		return 3;
+	}
+	
+	virtual void getEdge(int i,btVector3& pa,btVector3& pb) const
+	{
+		getVertex(i,pa);
+		getVertex((i+1)%3,pb);
+	}
+
+
+	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax)const 
+	{
+//		btAssert(0);
+		getAabbSlow(t,aabbMin,aabbMax);
+	}
+
+	btVector3 localGetSupportingVertexWithoutMargin(const btVector3& dir)const 
+	{
+		btVector3 dots(dir.dot(m_vertices1[0]), dir.dot(m_vertices1[1]), dir.dot(m_vertices1[2]));
+	  	return m_vertices1[dots.maxAxis()];
+
+	}
+
+	virtual void	batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+	{
+		for (int i=0;i<numVectors;i++)
+		{
+			const btVector3& dir = vectors[i];
+			btVector3 dots(dir.dot(m_vertices1[0]), dir.dot(m_vertices1[1]), dir.dot(m_vertices1[2]));
+  			supportVerticesOut[i] = m_vertices1[dots.maxAxis()];
+		}
+
+	}
+
+
+
+	btTriangleShape(const btVector3& p0,const btVector3& p1,const btVector3& p2) : btPolyhedralConvexShape ()
+    {
+		m_shapeType = TRIANGLE_SHAPE_PROXYTYPE;
+        m_vertices1[0] = p0;
+        m_vertices1[1] = p1;
+        m_vertices1[2] = p2;
+    }
+
+
+	virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i) const
+	{
+		getPlaneEquation(i,planeNormal,planeSupport);
+	}
+
+	virtual int	getNumPlanes() const
+	{
+		return 1;
+	}
+
+	void calcNormal(btVector3& normal) const
+	{
+		normal = (m_vertices1[1]-m_vertices1[0]).cross(m_vertices1[2]-m_vertices1[0]);
+		normal.normalize();
+	}
+
+	virtual void getPlaneEquation(int i, btVector3& planeNormal,btVector3& planeSupport) const
+	{
+		(void)i;
+		calcNormal(planeNormal);
+		planeSupport = m_vertices1[0];
+	}
+
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const
+	{
+		(void)mass;
+		btAssert(0);
+		inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
+	}
+
+		virtual	bool isInside(const btVector3& pt,btScalar tolerance) const
+	{
+		btVector3 normal;
+		calcNormal(normal);
+		//distance to plane
+		btScalar dist = pt.dot(normal);
+		btScalar planeconst = m_vertices1[0].dot(normal);
+		dist -= planeconst;
+		if (dist >= -tolerance && dist <= tolerance)
+		{
+			//inside check on edge-planes
+			int i;
+			for (i=0;i<3;i++)
+			{
+				btVector3 pa,pb;
+				getEdge(i,pa,pb);
+				btVector3 edge = pb-pa;
+				btVector3 edgeNormal = edge.cross(normal);
+				edgeNormal.normalize();
+				btScalar dist = pt.dot( edgeNormal);
+				btScalar edgeConst = pa.dot(edgeNormal);
+				dist -= edgeConst;
+				if (dist < -tolerance)
+					return false;
+			}
+			
+			return true;
+		}
+
+		return false;
+	}
+		//debugging
+		virtual const char*	getName()const
+		{
+			return "Triangle";
+		}
+
+		virtual int		getNumPreferredPenetrationDirections() const
+		{
+			return 2;
+		}
+		
+		virtual void	getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
+		{
+			calcNormal(penetrationVector);
+			if (index)
+				penetrationVector *= btScalar(-1.);
+		}
+
+
+};
+
+#endif //OBB_TRIANGLE_MINKOWSKI_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btUniformScalingShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btUniformScalingShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btUniformScalingShape.cpp	(revision 6952)
@@ -0,0 +1,115 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2007 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 "btUniformScalingShape.h"
+
+btUniformScalingShape::btUniformScalingShape(	btConvexShape* convexChildShape,btScalar uniformScalingFactor):
+btConvexShape (), m_childConvexShape(convexChildShape),
+m_uniformScalingFactor(uniformScalingFactor)
+{
+	m_shapeType = UNIFORM_SCALING_SHAPE_PROXYTYPE;
+}
+	
+btUniformScalingShape::~btUniformScalingShape()
+{
+}
+	
+
+btVector3	btUniformScalingShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const
+{
+	btVector3 tmpVertex;
+	tmpVertex = m_childConvexShape->localGetSupportingVertexWithoutMargin(vec);
+	return tmpVertex*m_uniformScalingFactor;
+}
+
+void	btUniformScalingShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const
+{
+	m_childConvexShape->batchedUnitVectorGetSupportingVertexWithoutMargin(vectors,supportVerticesOut,numVectors);
+	int i;
+	for (i=0;i<numVectors;i++)
+	{
+		supportVerticesOut[i] = supportVerticesOut[i] * m_uniformScalingFactor;
+	}
+}
+
+
+btVector3	btUniformScalingShape::localGetSupportingVertex(const btVector3& vec)const
+{
+	btVector3 tmpVertex;
+	tmpVertex = m_childConvexShape->localGetSupportingVertex(vec);
+	return tmpVertex*m_uniformScalingFactor;
+}
+
+
+void	btUniformScalingShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+
+	///this linear upscaling is not realistic, but we don't deal with large mass ratios...
+	btVector3 tmpInertia;
+	m_childConvexShape->calculateLocalInertia(mass,tmpInertia);
+	inertia = tmpInertia * m_uniformScalingFactor;
+}
+
+
+	///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
+void btUniformScalingShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	m_childConvexShape->getAabb(t,aabbMin,aabbMax);
+	btVector3 aabbCenter = (aabbMax+aabbMin)*btScalar(0.5);
+	btVector3 scaledAabbHalfExtends = (aabbMax-aabbMin)*btScalar(0.5)*m_uniformScalingFactor;
+
+	aabbMin = aabbCenter - scaledAabbHalfExtends;
+	aabbMax = aabbCenter + scaledAabbHalfExtends;
+
+}
+
+void btUniformScalingShape::getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+{
+	m_childConvexShape->getAabbSlow(t,aabbMin,aabbMax);
+	btVector3 aabbCenter = (aabbMax+aabbMin)*btScalar(0.5);
+	btVector3 scaledAabbHalfExtends = (aabbMax-aabbMin)*btScalar(0.5)*m_uniformScalingFactor;
+
+	aabbMin = aabbCenter - scaledAabbHalfExtends;
+	aabbMax = aabbCenter + scaledAabbHalfExtends;
+}
+
+void	btUniformScalingShape::setLocalScaling(const btVector3& scaling) 
+{
+	m_childConvexShape->setLocalScaling(scaling);
+}
+
+const btVector3& btUniformScalingShape::getLocalScaling() const
+{
+	return m_childConvexShape->getLocalScaling();
+}
+
+void	btUniformScalingShape::setMargin(btScalar margin)
+{
+	m_childConvexShape->setMargin(margin);
+}
+btScalar	btUniformScalingShape::getMargin() const
+{
+	return m_childConvexShape->getMargin() * m_uniformScalingFactor;
+}
+
+int		btUniformScalingShape::getNumPreferredPenetrationDirections() const
+{
+	return m_childConvexShape->getNumPreferredPenetrationDirections();
+}
+	
+void	btUniformScalingShape::getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const
+{
+	m_childConvexShape->getPreferredPenetrationDirection(index,penetrationVector);
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btUniformScalingShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btUniformScalingShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/CollisionShapes/btUniformScalingShape.h	(revision 6952)
@@ -0,0 +1,87 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_UNIFORM_SCALING_SHAPE_H
+#define BT_UNIFORM_SCALING_SHAPE_H
+
+#include "btConvexShape.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types
+
+///The btUniformScalingShape allows to re-use uniform scaled instances of btConvexShape in a memory efficient way.
+///Istead of using btUniformScalingShape, it is better to use the non-uniform setLocalScaling method on convex shapes that implement it.
+class btUniformScalingShape : public btConvexShape
+{
+	btConvexShape*	m_childConvexShape;
+
+	btScalar	m_uniformScalingFactor;
+	
+	public:
+	
+	btUniformScalingShape(	btConvexShape* convexChildShape, btScalar uniformScalingFactor);
+	
+	virtual ~btUniformScalingShape();
+	
+	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;
+
+	btScalar	getUniformScalingFactor() const
+	{
+		return m_uniformScalingFactor;
+	}
+
+	btConvexShape*	getChildShape() 
+	{
+		return m_childConvexShape;
+	}
+
+	const btConvexShape*	getChildShape() const
+	{
+		return m_childConvexShape;
+	}
+
+	virtual const char*	getName()const 
+	{
+		return "UniformScalingShape";
+	}
+	
+
+
+	///////////////////////////
+
+
+	///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_UNIFORM_SCALING_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btBoxCollision.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btBoxCollision.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btBoxCollision.h	(revision 6952)
@@ -0,0 +1,647 @@
+#ifndef BT_BOX_COLLISION_H_INCLUDED
+#define BT_BOX_COLLISION_H_INCLUDED
+
+/*! \file gim_box_collision.h
+\author Francisco Len Nßjera
+*/
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 "LinearMath/btTransform.h"
+
+
+///Swap numbers
+#define BT_SWAP_NUMBERS(a,b){ \
+    a = a+b; \
+    b = a-b; \
+    a = a-b; \
+}\
+
+
+#define BT_MAX(a,b) (a<b?b:a)
+#define BT_MIN(a,b) (a>b?b:a)
+
+#define BT_GREATER(x, y)	btFabs(x) > (y)
+
+#define BT_MAX3(a,b,c) BT_MAX(a,BT_MAX(b,c))
+#define BT_MIN3(a,b,c) BT_MIN(a,BT_MIN(b,c))
+
+
+
+
+
+
+enum eBT_PLANE_INTERSECTION_TYPE
+{
+	BT_CONST_BACK_PLANE = 0,
+	BT_CONST_COLLIDE_PLANE,
+	BT_CONST_FRONT_PLANE
+};
+
+//SIMD_FORCE_INLINE bool test_cross_edge_box(
+//	const btVector3 & edge,
+//	const btVector3 & absolute_edge,
+//	const btVector3 & pointa,
+//	const btVector3 & pointb, const btVector3 & extend,
+//	int dir_index0,
+//	int dir_index1
+//	int component_index0,
+//	int component_index1)
+//{
+//	// dir coords are -z and y
+//
+//	const btScalar dir0 = -edge[dir_index0];
+//	const btScalar dir1 = edge[dir_index1];
+//	btScalar pmin = pointa[component_index0]*dir0 + pointa[component_index1]*dir1;
+//	btScalar pmax = pointb[component_index0]*dir0 + pointb[component_index1]*dir1;
+//	//find minmax
+//	if(pmin>pmax)
+//	{
+//		BT_SWAP_NUMBERS(pmin,pmax);
+//	}
+//	//find extends
+//	const btScalar rad = extend[component_index0] * absolute_edge[dir_index0] +
+//					extend[component_index1] * absolute_edge[dir_index1];
+//
+//	if(pmin>rad || -rad>pmax) return false;
+//	return true;
+//}
+//
+//SIMD_FORCE_INLINE bool test_cross_edge_box_X_axis(
+//	const btVector3 & edge,
+//	const btVector3 & absolute_edge,
+//	const btVector3 & pointa,
+//	const btVector3 & pointb, btVector3 & extend)
+//{
+//
+//	return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,2,1,1,2);
+//}
+//
+//
+//SIMD_FORCE_INLINE bool test_cross_edge_box_Y_axis(
+//	const btVector3 & edge,
+//	const btVector3 & absolute_edge,
+//	const btVector3 & pointa,
+//	const btVector3 & pointb, btVector3 & extend)
+//{
+//
+//	return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,0,2,2,0);
+//}
+//
+//SIMD_FORCE_INLINE bool test_cross_edge_box_Z_axis(
+//	const btVector3 & edge,
+//	const btVector3 & absolute_edge,
+//	const btVector3 & pointa,
+//	const btVector3 & pointb, btVector3 & extend)
+//{
+//
+//	return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,1,0,0,1);
+//}
+
+
+#define TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,i_dir_0,i_dir_1,i_comp_0,i_comp_1)\
+{\
+	const btScalar dir0 = -edge[i_dir_0];\
+	const btScalar dir1 = edge[i_dir_1];\
+	btScalar pmin = pointa[i_comp_0]*dir0 + pointa[i_comp_1]*dir1;\
+	btScalar pmax = pointb[i_comp_0]*dir0 + pointb[i_comp_1]*dir1;\
+	if(pmin>pmax)\
+	{\
+		BT_SWAP_NUMBERS(pmin,pmax); \
+	}\
+	const btScalar abs_dir0 = absolute_edge[i_dir_0];\
+	const btScalar abs_dir1 = absolute_edge[i_dir_1];\
+	const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1;\
+	if(pmin>rad || -rad>pmax) return false;\
+}\
+
+
+#define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
+{\
+	TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,2,1,1,2);\
+}\
+
+#define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
+{\
+	TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,0,2,2,0);\
+}\
+
+#define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
+{\
+	TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,1,0,0,1);\
+}\
+
+
+//! Returns the dot product between a vec3f and the col of a matrix
+SIMD_FORCE_INLINE btScalar bt_mat3_dot_col(
+const btMatrix3x3 & mat, const btVector3 & vec3, int colindex)
+{
+	return vec3[0]*mat[0][colindex] + vec3[1]*mat[1][colindex] + vec3[2]*mat[2][colindex];
+}
+
+
+//!  Class for transforming a model1 to the space of model0
+ATTRIBUTE_ALIGNED16	(class) BT_BOX_BOX_TRANSFORM_CACHE
+{
+public:
+    btVector3  m_T1to0;//!< Transforms translation of model1 to model 0
+	btMatrix3x3 m_R1to0;//!< Transforms Rotation of model1 to model 0, equal  to R0' * R1
+	btMatrix3x3 m_AR;//!< Absolute value of m_R1to0
+
+	SIMD_FORCE_INLINE void calc_absolute_matrix()
+	{
+//		static const btVector3 vepsi(1e-6f,1e-6f,1e-6f);
+//		m_AR[0] = vepsi + m_R1to0[0].absolute();
+//		m_AR[1] = vepsi + m_R1to0[1].absolute();
+//		m_AR[2] = vepsi + m_R1to0[2].absolute();
+
+		int i,j;
+
+        for(i=0;i<3;i++)
+        {
+            for(j=0;j<3;j++ )
+            {
+            	m_AR[i][j] = 1e-6f + btFabs(m_R1to0[i][j]);
+            }
+        }
+
+	}
+
+	BT_BOX_BOX_TRANSFORM_CACHE()
+	{
+	}
+
+
+
+	//! Calc the transformation relative  1 to 0. Inverts matrics by transposing
+	SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform & trans0,const btTransform & trans1)
+	{
+
+		btTransform temp_trans = trans0.inverse();
+		temp_trans = temp_trans * trans1;
+
+		m_T1to0 = temp_trans.getOrigin();
+		m_R1to0 = temp_trans.getBasis();
+
+
+		calc_absolute_matrix();
+	}
+
+	//! Calcs the full invertion of the matrices. Useful for scaling matrices
+	SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform & trans0,const btTransform & trans1)
+	{
+		m_R1to0 = trans0.getBasis().inverse();
+		m_T1to0 = m_R1to0 * (-trans0.getOrigin());
+
+		m_T1to0 += m_R1to0*trans1.getOrigin();
+		m_R1to0 *= trans1.getBasis();
+
+		calc_absolute_matrix();
+	}
+
+	SIMD_FORCE_INLINE btVector3 transform(const btVector3 & point) const
+	{
+		return btVector3(m_R1to0[0].dot(point) + m_T1to0.x(),
+			m_R1to0[1].dot(point) + m_T1to0.y(),
+			m_R1to0[2].dot(point) + m_T1to0.z());
+	}
+};
+
+
+#define BOX_PLANE_EPSILON 0.000001f
+
+//! Axis aligned box
+ATTRIBUTE_ALIGNED16	(class) btAABB
+{
+public:
+	btVector3 m_min;
+	btVector3 m_max;
+
+	btAABB()
+	{}
+
+
+	btAABB(const btVector3 & V1,
+			 const btVector3 & V2,
+			 const btVector3 & V3)
+	{
+		m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]);
+		m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]);
+		m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]);
+
+		m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]);
+		m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]);
+		m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]);
+	}
+
+	btAABB(const btVector3 & V1,
+			 const btVector3 & V2,
+			 const btVector3 & V3,
+			 btScalar margin)
+	{
+		m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]);
+		m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]);
+		m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]);
+
+		m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]);
+		m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]);
+		m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]);
+
+		m_min[0] -= margin;
+		m_min[1] -= margin;
+		m_min[2] -= margin;
+		m_max[0] += margin;
+		m_max[1] += margin;
+		m_max[2] += margin;
+	}
+
+	btAABB(const btAABB &other):
+		m_min(other.m_min),m_max(other.m_max)
+	{
+	}
+
+	btAABB(const btAABB &other,btScalar margin ):
+		m_min(other.m_min),m_max(other.m_max)
+	{
+		m_min[0] -= margin;
+		m_min[1] -= margin;
+		m_min[2] -= margin;
+		m_max[0] += margin;
+		m_max[1] += margin;
+		m_max[2] += margin;
+	}
+
+	SIMD_FORCE_INLINE void invalidate()
+	{
+		m_min[0] = SIMD_INFINITY;
+		m_min[1] = SIMD_INFINITY;
+		m_min[2] = SIMD_INFINITY;
+		m_max[0] = -SIMD_INFINITY;
+		m_max[1] = -SIMD_INFINITY;
+		m_max[2] = -SIMD_INFINITY;
+	}
+
+	SIMD_FORCE_INLINE void increment_margin(btScalar margin)
+	{
+		m_min[0] -= margin;
+		m_min[1] -= margin;
+		m_min[2] -= margin;
+		m_max[0] += margin;
+		m_max[1] += margin;
+		m_max[2] += margin;
+	}
+
+	SIMD_FORCE_INLINE void copy_with_margin(const btAABB &other, btScalar margin)
+	{
+		m_min[0] = other.m_min[0] - margin;
+		m_min[1] = other.m_min[1] - margin;
+		m_min[2] = other.m_min[2] - margin;
+
+		m_max[0] = other.m_max[0] + margin;
+		m_max[1] = other.m_max[1] + margin;
+		m_max[2] = other.m_max[2] + margin;
+	}
+
+	template<typename CLASS_POINT>
+	SIMD_FORCE_INLINE void calc_from_triangle(
+							const CLASS_POINT & V1,
+							const CLASS_POINT & V2,
+							const CLASS_POINT & V3)
+	{
+		m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]);
+		m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]);
+		m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]);
+
+		m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]);
+		m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]);
+		m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]);
+	}
+
+	template<typename CLASS_POINT>
+	SIMD_FORCE_INLINE void calc_from_triangle_margin(
+							const CLASS_POINT & V1,
+							const CLASS_POINT & V2,
+							const CLASS_POINT & V3, btScalar margin)
+	{
+		m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]);
+		m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]);
+		m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]);
+
+		m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]);
+		m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]);
+		m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]);
+
+		m_min[0] -= margin;
+		m_min[1] -= margin;
+		m_min[2] -= margin;
+		m_max[0] += margin;
+		m_max[1] += margin;
+		m_max[2] += margin;
+	}
+
+	//! Apply a transform to an AABB
+	SIMD_FORCE_INLINE void appy_transform(const btTransform & trans)
+	{
+		btVector3 center = (m_max+m_min)*0.5f;
+		btVector3 extends = m_max - center;
+		// Compute new center
+		center = trans(center);
+
+		btVector3 textends(extends.dot(trans.getBasis().getRow(0).absolute()),
+ 				 extends.dot(trans.getBasis().getRow(1).absolute()),
+				 extends.dot(trans.getBasis().getRow(2).absolute()));
+
+		m_min = center - textends;
+		m_max = center + textends;
+	}
+
+
+	//! Apply a transform to an AABB
+	SIMD_FORCE_INLINE void appy_transform_trans_cache(const BT_BOX_BOX_TRANSFORM_CACHE & trans)
+	{
+		btVector3 center = (m_max+m_min)*0.5f;
+		btVector3 extends = m_max - center;
+		// Compute new center
+		center = trans.transform(center);
+
+		btVector3 textends(extends.dot(trans.m_R1to0.getRow(0).absolute()),
+ 				 extends.dot(trans.m_R1to0.getRow(1).absolute()),
+				 extends.dot(trans.m_R1to0.getRow(2).absolute()));
+
+		m_min = center - textends;
+		m_max = center + textends;
+	}
+
+	//! Merges a Box
+	SIMD_FORCE_INLINE void merge(const btAABB & box)
+	{
+		m_min[0] = BT_MIN(m_min[0],box.m_min[0]);
+		m_min[1] = BT_MIN(m_min[1],box.m_min[1]);
+		m_min[2] = BT_MIN(m_min[2],box.m_min[2]);
+
+		m_max[0] = BT_MAX(m_max[0],box.m_max[0]);
+		m_max[1] = BT_MAX(m_max[1],box.m_max[1]);
+		m_max[2] = BT_MAX(m_max[2],box.m_max[2]);
+	}
+
+	//! Merges a point
+	template<typename CLASS_POINT>
+	SIMD_FORCE_INLINE void merge_point(const CLASS_POINT & point)
+	{
+		m_min[0] = BT_MIN(m_min[0],point[0]);
+		m_min[1] = BT_MIN(m_min[1],point[1]);
+		m_min[2] = BT_MIN(m_min[2],point[2]);
+
+		m_max[0] = BT_MAX(m_max[0],point[0]);
+		m_max[1] = BT_MAX(m_max[1],point[1]);
+		m_max[2] = BT_MAX(m_max[2],point[2]);
+	}
+
+	//! Gets the extend and center
+	SIMD_FORCE_INLINE void get_center_extend(btVector3 & center,btVector3 & extend)  const
+	{
+		center = (m_max+m_min)*0.5f;
+		extend = m_max - center;
+	}
+
+	//! Finds the intersecting box between this box and the other.
+	SIMD_FORCE_INLINE void find_intersection(const btAABB & other, btAABB & intersection)  const
+	{
+		intersection.m_min[0] = BT_MAX(other.m_min[0],m_min[0]);
+		intersection.m_min[1] = BT_MAX(other.m_min[1],m_min[1]);
+		intersection.m_min[2] = BT_MAX(other.m_min[2],m_min[2]);
+
+		intersection.m_max[0] = BT_MIN(other.m_max[0],m_max[0]);
+		intersection.m_max[1] = BT_MIN(other.m_max[1],m_max[1]);
+		intersection.m_max[2] = BT_MIN(other.m_max[2],m_max[2]);
+	}
+
+
+	SIMD_FORCE_INLINE bool has_collision(const btAABB & other) const
+	{
+		if(m_min[0] > other.m_max[0] ||
+		   m_max[0] < other.m_min[0] ||
+		   m_min[1] > other.m_max[1] ||
+		   m_max[1] < other.m_min[1] ||
+		   m_min[2] > other.m_max[2] ||
+		   m_max[2] < other.m_min[2])
+		{
+			return false;
+		}
+		return true;
+	}
+
+	/*! \brief Finds the Ray intersection parameter.
+	\param aabb Aligned box
+	\param vorigin A vec3f with the origin of the ray
+	\param vdir A vec3f with the direction of the ray
+	*/
+	SIMD_FORCE_INLINE bool collide_ray(const btVector3 & vorigin,const btVector3 & vdir)  const
+	{
+		btVector3 extents,center;
+		this->get_center_extend(center,extents);;
+
+		btScalar Dx = vorigin[0] - center[0];
+		if(BT_GREATER(Dx, extents[0]) && Dx*vdir[0]>=0.0f)	return false;
+		btScalar Dy = vorigin[1] - center[1];
+		if(BT_GREATER(Dy, extents[1]) && Dy*vdir[1]>=0.0f)	return false;
+		btScalar Dz = vorigin[2] - center[2];
+		if(BT_GREATER(Dz, extents[2]) && Dz*vdir[2]>=0.0f)	return false;
+
+
+		btScalar f = vdir[1] * Dz - vdir[2] * Dy;
+		if(btFabs(f) > extents[1]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[1])) return false;
+		f = vdir[2] * Dx - vdir[0] * Dz;
+		if(btFabs(f) > extents[0]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[0]))return false;
+		f = vdir[0] * Dy - vdir[1] * Dx;
+		if(btFabs(f) > extents[0]*btFabs(vdir[1]) + extents[1]*btFabs(vdir[0]))return false;
+		return true;
+	}
+
+
+	SIMD_FORCE_INLINE void projection_interval(const btVector3 & direction, btScalar &vmin, btScalar &vmax) const
+	{
+		btVector3 center = (m_max+m_min)*0.5f;
+		btVector3 extend = m_max-center;
+
+		btScalar _fOrigin =  direction.dot(center);
+		btScalar _fMaximumExtent = extend.dot(direction.absolute());
+		vmin = _fOrigin - _fMaximumExtent;
+		vmax = _fOrigin + _fMaximumExtent;
+	}
+
+	SIMD_FORCE_INLINE eBT_PLANE_INTERSECTION_TYPE plane_classify(const btVector4 &plane) const
+	{
+		btScalar _fmin,_fmax;
+		this->projection_interval(plane,_fmin,_fmax);
+
+		if(plane[3] > _fmax + BOX_PLANE_EPSILON)
+		{
+			return BT_CONST_BACK_PLANE; // 0
+		}
+
+		if(plane[3]+BOX_PLANE_EPSILON >=_fmin)
+		{
+			return BT_CONST_COLLIDE_PLANE; //1
+		}
+		return BT_CONST_FRONT_PLANE;//2
+	}
+
+	SIMD_FORCE_INLINE bool overlapping_trans_conservative(const btAABB & box, btTransform & trans1_to_0) const
+	{
+		btAABB tbox = box;
+		tbox.appy_transform(trans1_to_0);
+		return has_collision(tbox);
+	}
+
+	SIMD_FORCE_INLINE bool overlapping_trans_conservative2(const btAABB & box,
+		const BT_BOX_BOX_TRANSFORM_CACHE & trans1_to_0) const
+	{
+		btAABB tbox = box;
+		tbox.appy_transform_trans_cache(trans1_to_0);
+		return has_collision(tbox);
+	}
+
+	//! transcache is the transformation cache from box to this AABB
+	SIMD_FORCE_INLINE bool overlapping_trans_cache(
+		const btAABB & box,const BT_BOX_BOX_TRANSFORM_CACHE & transcache, bool fulltest) const
+	{
+
+		//Taken from OPCODE
+		btVector3 ea,eb;//extends
+		btVector3 ca,cb;//extends
+		get_center_extend(ca,ea);
+		box.get_center_extend(cb,eb);
+
+
+		btVector3 T;
+		btScalar t,t2;
+		int i;
+
+		// Class I : A's basis vectors
+		for(i=0;i<3;i++)
+		{
+			T[i] =  transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i];
+			t = transcache.m_AR[i].dot(eb) + ea[i];
+			if(BT_GREATER(T[i], t))	return false;
+		}
+		// Class II : B's basis vectors
+		for(i=0;i<3;i++)
+		{
+			t = bt_mat3_dot_col(transcache.m_R1to0,T,i);
+			t2 = bt_mat3_dot_col(transcache.m_AR,ea,i) + eb[i];
+			if(BT_GREATER(t,t2))	return false;
+		}
+		// Class III : 9 cross products
+		if(fulltest)
+		{
+			int j,m,n,o,p,q,r;
+			for(i=0;i<3;i++)
+			{
+				m = (i+1)%3;
+				n = (i+2)%3;
+				o = i==0?1:0;
+				p = i==2?1:2;
+				for(j=0;j<3;j++)
+				{
+					q = j==2?1:2;
+					r = j==0?1:0;
+					t = T[n]*transcache.m_R1to0[m][j] - T[m]*transcache.m_R1to0[n][j];
+					t2 = ea[o]*transcache.m_AR[p][j] + ea[p]*transcache.m_AR[o][j] +
+						eb[r]*transcache.m_AR[i][q] + eb[q]*transcache.m_AR[i][r];
+					if(BT_GREATER(t,t2))	return false;
+				}
+			}
+		}
+		return true;
+	}
+
+	//! Simple test for planes.
+	SIMD_FORCE_INLINE bool collide_plane(
+		const btVector4 & plane) const
+	{
+		eBT_PLANE_INTERSECTION_TYPE classify = plane_classify(plane);
+		return (classify == BT_CONST_COLLIDE_PLANE);
+	}
+
+	//! test for a triangle, with edges
+	SIMD_FORCE_INLINE bool collide_triangle_exact(
+		const btVector3 & p1,
+		const btVector3 & p2,
+		const btVector3 & p3,
+		const btVector4 & triangle_plane) const
+	{
+		if(!collide_plane(triangle_plane)) return false;
+
+		btVector3 center,extends;
+		this->get_center_extend(center,extends);
+
+		const btVector3 v1(p1 - center);
+		const btVector3 v2(p2 - center);
+		const btVector3 v3(p3 - center);
+
+		//First axis
+		btVector3 diff(v2 - v1);
+		btVector3 abs_diff = diff.absolute();
+		//Test With X axis
+		TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v1,v3,extends);
+		//Test With Y axis
+		TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v1,v3,extends);
+		//Test With Z axis
+		TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v1,v3,extends);
+
+
+		diff = v3 - v2;
+		abs_diff = diff.absolute();
+		//Test With X axis
+		TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v2,v1,extends);
+		//Test With Y axis
+		TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v2,v1,extends);
+		//Test With Z axis
+		TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v2,v1,extends);
+
+		diff = v1 - v3;
+		abs_diff = diff.absolute();
+		//Test With X axis
+		TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v3,v2,extends);
+		//Test With Y axis
+		TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v3,v2,extends);
+		//Test With Z axis
+		TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v3,v2,extends);
+
+		return true;
+	}
+};
+
+
+//! Compairison of transformation objects
+SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform & t1,const btTransform & t2)
+{
+	if(!(t1.getOrigin() == t2.getOrigin()) ) return false;
+
+	if(!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0)) ) return false;
+	if(!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1)) ) return false;
+	if(!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2)) ) return false;
+	return true;
+}
+
+
+
+#endif // GIM_BOX_COLLISION_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btClipPolygon.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btClipPolygon.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btClipPolygon.h	(revision 6952)
@@ -0,0 +1,182 @@
+#ifndef BT_CLIP_POLYGON_H_INCLUDED
+#define BT_CLIP_POLYGON_H_INCLUDED
+
+/*! \file btClipPolygon.h
+\author Francisco Len Nßjera
+*/
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 "LinearMath/btTransform.h"
+#include "LinearMath/btGeometryUtil.h"
+
+
+SIMD_FORCE_INLINE btScalar bt_distance_point_plane(const btVector4 & plane,const btVector3 &point)
+{
+	return point.dot(plane) - plane[3];
+}
+
+/*! Vector blending
+Takes two vectors a, b, blends them together*/
+SIMD_FORCE_INLINE void bt_vec_blend(btVector3 &vr, const btVector3 &va,const btVector3 &vb, btScalar blend_factor)
+{
+	vr = (1-blend_factor)*va + blend_factor*vb;
+}
+
+//! This function calcs the distance from a 3D plane
+SIMD_FORCE_INLINE void bt_plane_clip_polygon_collect(
+						const btVector3 & point0,
+						const btVector3 & point1,
+						btScalar dist0,
+						btScalar dist1,
+						btVector3 * clipped,
+						int & clipped_count)
+{
+	bool _prevclassif = (dist0>SIMD_EPSILON);
+	bool _classif = (dist1>SIMD_EPSILON);
+	if(_classif!=_prevclassif)
+	{
+		btScalar blendfactor = -dist0/(dist1-dist0);
+		bt_vec_blend(clipped[clipped_count],point0,point1,blendfactor);
+		clipped_count++;
+	}
+	if(!_classif)
+	{
+		clipped[clipped_count] = point1;
+		clipped_count++;
+	}
+}
+
+
+//! Clips a polygon by a plane
+/*!
+*\return The count of the clipped counts
+*/
+SIMD_FORCE_INLINE int bt_plane_clip_polygon(
+						const btVector4 & plane,
+						const btVector3 * polygon_points,
+						int polygon_point_count,
+						btVector3 * clipped)
+{
+    int clipped_count = 0;
+
+
+    //clip first point
+	btScalar firstdist = bt_distance_point_plane(plane,polygon_points[0]);;
+	if(!(firstdist>SIMD_EPSILON))
+	{
+		clipped[clipped_count] = polygon_points[0];
+		clipped_count++;
+	}
+
+	btScalar olddist = firstdist;
+	for(int i=1;i<polygon_point_count;i++)
+	{
+		btScalar dist = bt_distance_point_plane(plane,polygon_points[i]);
+
+		bt_plane_clip_polygon_collect(
+						polygon_points[i-1],polygon_points[i],
+						olddist,
+						dist,
+						clipped,
+						clipped_count);
+
+
+		olddist = dist;
+	}
+
+	//RETURN TO FIRST  point
+
+	bt_plane_clip_polygon_collect(
+					polygon_points[polygon_point_count-1],polygon_points[0],
+					olddist,
+					firstdist,
+					clipped,
+					clipped_count);
+
+	return clipped_count;
+}
+
+//! Clips a polygon by a plane
+/*!
+*\param clipped must be an array of 16 points.
+*\return The count of the clipped counts
+*/
+SIMD_FORCE_INLINE int bt_plane_clip_triangle(
+						const btVector4 & plane,
+						const btVector3 & point0,
+						const btVector3 & point1,
+						const btVector3& point2,
+						btVector3 * clipped // an allocated array of 16 points at least
+						)
+{
+    int clipped_count = 0;
+
+    //clip first point0
+	btScalar firstdist = bt_distance_point_plane(plane,point0);;
+	if(!(firstdist>SIMD_EPSILON))
+	{
+		clipped[clipped_count] = point0;
+		clipped_count++;
+	}
+
+	// point 1
+	btScalar olddist = firstdist;
+	btScalar dist = bt_distance_point_plane(plane,point1);
+
+	bt_plane_clip_polygon_collect(
+					point0,point1,
+					olddist,
+					dist,
+					clipped,
+					clipped_count);
+
+	olddist = dist;
+
+
+	// point 2
+	dist = bt_distance_point_plane(plane,point2);
+
+	bt_plane_clip_polygon_collect(
+					point1,point2,
+					olddist,
+					dist,
+					clipped,
+					clipped_count);
+	olddist = dist;
+
+
+
+	//RETURN TO FIRST  point0
+	bt_plane_clip_polygon_collect(
+					point2,point0,
+					olddist,
+					firstdist,
+					clipped,
+					clipped_count);
+
+	return clipped_count;
+}
+
+
+
+
+
+#endif // GIM_TRI_COLLISION_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btContactProcessing.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btContactProcessing.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btContactProcessing.cpp	(revision 6952)
@@ -0,0 +1,181 @@
+
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 "btContactProcessing.h"
+
+#define MAX_COINCIDENT 8
+
+struct CONTACT_KEY_TOKEN
+{
+	unsigned int m_key;
+	int m_value;
+	CONTACT_KEY_TOKEN()
+    {
+    }
+
+    CONTACT_KEY_TOKEN(unsigned int key,int token)
+    {
+    	m_key = key;
+    	m_value =  token;
+    }
+
+    CONTACT_KEY_TOKEN(const CONTACT_KEY_TOKEN& rtoken)
+    {
+    	m_key = rtoken.m_key;
+    	m_value = rtoken.m_value;
+    }
+
+    inline bool operator <(const CONTACT_KEY_TOKEN& other) const
+	{
+		return (m_key < other.m_key);
+	}
+
+	inline bool operator >(const CONTACT_KEY_TOKEN& other) const
+	{
+		return (m_key > other.m_key);
+	}
+
+};
+
+class CONTACT_KEY_TOKEN_COMP
+{
+	public:
+
+		bool operator() ( const CONTACT_KEY_TOKEN& a, const CONTACT_KEY_TOKEN& b )
+		{
+			return ( a < b );
+		}
+};
+
+
+void btContactArray::merge_contacts(
+	const btContactArray & contacts, bool normal_contact_average)
+{
+	clear();
+
+	int i;
+	if(contacts.size()==0) return;
+
+
+	if(contacts.size()==1)
+	{
+		push_back(contacts[0]);
+		return;
+	}
+
+	btAlignedObjectArray<CONTACT_KEY_TOKEN> keycontacts;
+
+	keycontacts.reserve(contacts.size());
+
+	//fill key contacts
+
+	for ( i = 0;i<contacts.size() ;i++ )
+	{
+		keycontacts.push_back(CONTACT_KEY_TOKEN(contacts[i].calc_key_contact(),i));
+	}
+
+	//sort keys
+	keycontacts.quickSort(CONTACT_KEY_TOKEN_COMP());
+
+	// Merge contacts
+	int coincident_count=0;
+	btVector3 coincident_normals[MAX_COINCIDENT];
+
+	unsigned int last_key = keycontacts[0].m_key;
+	unsigned int key = 0;
+
+	push_back(contacts[keycontacts[0].m_value]);
+
+	GIM_CONTACT * pcontact = &(*this)[0];
+
+	for( i=1;i<keycontacts.size();i++)
+	{
+	    key = keycontacts[i].m_key;
+		const GIM_CONTACT * scontact = &contacts[keycontacts[i].m_value];
+
+		if(last_key ==  key)//same points
+		{
+			//merge contact
+			if(pcontact->m_depth - CONTACT_DIFF_EPSILON > scontact->m_depth)//)
+			{
+				*pcontact = *scontact;
+                coincident_count = 0;
+			}
+			else if(normal_contact_average)
+			{
+				if(btFabs(pcontact->m_depth - scontact->m_depth)<CONTACT_DIFF_EPSILON)
+                {
+                    if(coincident_count<MAX_COINCIDENT)
+                    {
+                    	coincident_normals[coincident_count] = scontact->m_normal;
+                        coincident_count++;
+                    }
+                }
+			}
+		}
+		else
+		{//add new contact
+
+		    if(normal_contact_average && coincident_count>0)
+		    {
+		    	pcontact->interpolate_normals(coincident_normals,coincident_count);
+		        coincident_count = 0;
+		    }
+
+		    push_back(*scontact);
+		    pcontact = &(*this)[this->size()-1];
+        }
+		last_key = key;
+	}
+}
+
+void btContactArray::merge_contacts_unique(const btContactArray & contacts)
+{
+	clear();
+
+	if(contacts.size()==0) return;
+
+	if(contacts.size()==1)
+	{
+		push_back(contacts[0]);
+		return;
+	}
+
+	GIM_CONTACT average_contact = contacts[0];
+
+	for (int i=1;i<contacts.size() ;i++ )
+	{
+		average_contact.m_point += contacts[i].m_point;
+		average_contact.m_normal += contacts[i].m_normal * contacts[i].m_depth;
+	}
+
+	//divide
+	btScalar divide_average = 1.0f/((btScalar)contacts.size());
+
+	average_contact.m_point *= divide_average;
+
+	average_contact.m_normal *= divide_average;
+
+	average_contact.m_depth = average_contact.m_normal.length();
+
+	average_contact.m_normal /= average_contact.m_depth;
+
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btContactProcessing.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btContactProcessing.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btContactProcessing.h	(revision 6952)
@@ -0,0 +1,145 @@
+#ifndef BT_CONTACT_H_INCLUDED
+#define BT_CONTACT_H_INCLUDED
+
+/*! \file gim_contact.h
+\author Francisco Len Nßjera
+*/
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 "LinearMath/btTransform.h"
+#include "LinearMath/btAlignedObjectArray.h"
+#include "btTriangleShapeEx.h"
+
+
+
+/**
+Configuration var for applying interpolation of  contact normals
+*/
+#define NORMAL_CONTACT_AVERAGE 1
+
+#define CONTACT_DIFF_EPSILON 0.00001f
+
+///The GIM_CONTACT is an internal GIMPACT structure, similar to btManifoldPoint.
+///@todo: remove and replace GIM_CONTACT by btManifoldPoint.
+class GIM_CONTACT
+{
+public:
+    btVector3 m_point;
+    btVector3 m_normal;
+    btScalar m_depth;//Positive value indicates interpenetration
+    btScalar m_distance;//Padding not for use
+    int m_feature1;//Face number
+    int m_feature2;//Face number
+public:
+    GIM_CONTACT()
+    {
+    }
+
+    GIM_CONTACT(const GIM_CONTACT & contact):
+				m_point(contact.m_point),
+				m_normal(contact.m_normal),
+				m_depth(contact.m_depth),
+				m_feature1(contact.m_feature1),
+				m_feature2(contact.m_feature2)
+    {
+    }
+
+    GIM_CONTACT(const btVector3 &point,const btVector3 & normal,
+    	 			btScalar depth, int feature1, int feature2):
+				m_point(point),
+				m_normal(normal),
+				m_depth(depth),
+				m_feature1(feature1),
+				m_feature2(feature2)
+    {
+    }
+
+	//! Calcs key for coord classification
+    SIMD_FORCE_INLINE unsigned int calc_key_contact() const
+    {
+    	int _coords[] = {
+    		(int)(m_point[0]*1000.0f+1.0f),
+    		(int)(m_point[1]*1333.0f),
+    		(int)(m_point[2]*2133.0f+3.0f)};
+		unsigned int _hash=0;
+		unsigned int *_uitmp = (unsigned int *)(&_coords[0]);
+		_hash = *_uitmp;
+		_uitmp++;
+		_hash += (*_uitmp)<<4;
+		_uitmp++;
+		_hash += (*_uitmp)<<8;
+		return _hash;
+    }
+
+    SIMD_FORCE_INLINE void interpolate_normals( btVector3 * normals,int normal_count)
+    {
+    	btVector3 vec_sum(m_normal);
+		for(int i=0;i<normal_count;i++)
+		{
+			vec_sum += normals[i];
+		}
+
+		btScalar vec_sum_len = vec_sum.length2();
+		if(vec_sum_len <CONTACT_DIFF_EPSILON) return;
+
+		//GIM_INV_SQRT(vec_sum_len,vec_sum_len); // 1/sqrt(vec_sum_len)
+
+		m_normal = vec_sum/btSqrt(vec_sum_len);
+    }
+
+};
+
+
+class btContactArray:public btAlignedObjectArray<GIM_CONTACT>
+{
+public:
+	btContactArray()
+	{
+		reserve(64);
+	}
+
+	SIMD_FORCE_INLINE void push_contact(
+		const btVector3 &point,const btVector3 & normal,
+		btScalar depth, int feature1, int feature2)
+	{
+		push_back( GIM_CONTACT(point,normal,depth,feature1,feature2) );
+	}
+
+	SIMD_FORCE_INLINE void push_triangle_contacts(
+		const GIM_TRIANGLE_CONTACT & tricontact,
+		int feature1,int feature2)
+	{
+		for(int i = 0;i<tricontact.m_point_count ;i++ )
+		{
+			push_contact(
+				tricontact.m_points[i],
+				tricontact.m_separating_normal,
+				tricontact.m_penetration_depth,feature1,feature2);
+		}
+	}
+
+	void merge_contacts(const btContactArray & contacts, bool normal_contact_average = true);
+
+	void merge_contacts_unique(const btContactArray & contacts);
+};
+
+
+#endif // GIM_CONTACT_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactBvh.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactBvh.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactBvh.cpp	(revision 6952)
@@ -0,0 +1,498 @@
+/*! \file gim_box_set.h
+\author Francisco Len Nßjera
+*/
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 "btGImpactBvh.h"
+#include "LinearMath/btQuickprof.h"
+
+#ifdef TRI_COLLISION_PROFILING
+
+btClock g_tree_clock;
+
+float g_accum_tree_collision_time = 0;
+int g_count_traversing = 0;
+
+
+void bt_begin_gim02_tree_time()
+{
+	g_tree_clock.reset();
+}
+
+void bt_end_gim02_tree_time()
+{
+	g_accum_tree_collision_time += g_tree_clock.getTimeMicroseconds();
+	g_count_traversing++;
+}
+
+//! Gets the average time in miliseconds of tree collisions
+float btGImpactBvh::getAverageTreeCollisionTime()
+{
+	if(g_count_traversing == 0) return 0;
+
+	float avgtime = g_accum_tree_collision_time;
+	avgtime /= (float)g_count_traversing;
+
+	g_accum_tree_collision_time = 0;
+	g_count_traversing = 0;
+	return avgtime;
+
+//	float avgtime = g_count_traversing;
+//	g_count_traversing = 0;
+//	return avgtime;
+
+}
+
+#endif //TRI_COLLISION_PROFILING
+
+/////////////////////// btBvhTree /////////////////////////////////
+
+int btBvhTree::_calc_splitting_axis(
+	GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,  int endIndex)
+{
+
+	int i;
+
+	btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
+	btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.));
+	int numIndices = endIndex-startIndex;
+
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
+					 primitive_boxes[i].m_bound.m_min);
+		means+=center;
+	}
+	means *= (btScalar(1.)/(btScalar)numIndices);
+
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
+					 primitive_boxes[i].m_bound.m_min);
+		btVector3 diff2 = center-means;
+		diff2 = diff2 * diff2;
+		variance += diff2;
+	}
+	variance *= (btScalar(1.)/	((btScalar)numIndices-1)	);
+
+	return variance.maxAxis();
+}
+
+
+int btBvhTree::_sort_and_calc_splitting_index(
+	GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,
+	int endIndex, int splitAxis)
+{
+	int i;
+	int splitIndex =startIndex;
+	int numIndices = endIndex - startIndex;
+
+	// average of centers
+	btScalar splitValue = 0.0f;
+
+	btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
+					 primitive_boxes[i].m_bound.m_min);
+		means+=center;
+	}
+	means *= (btScalar(1.)/(btScalar)numIndices);
+
+	splitValue = means[splitAxis];
+
+
+	//sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
+					 primitive_boxes[i].m_bound.m_min);
+		if (center[splitAxis] > splitValue)
+		{
+			//swap
+			primitive_boxes.swap(i,splitIndex);
+			//swapLeafNodes(i,splitIndex);
+			splitIndex++;
+		}
+	}
+
+	//if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex
+	//otherwise the tree-building might fail due to stack-overflows in certain cases.
+	//unbalanced1 is unsafe: it can cause stack overflows
+	//bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1)));
+
+	//unbalanced2 should work too: always use center (perfect balanced trees)
+	//bool unbalanced2 = true;
+
+	//this should be safe too:
+	int rangeBalancedIndices = numIndices/3;
+	bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices)));
+
+	if (unbalanced)
+	{
+		splitIndex = startIndex+ (numIndices>>1);
+	}
+
+	btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex))));
+
+	return splitIndex;
+
+}
+
+
+void btBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,  int endIndex)
+{
+	int curIndex = m_num_nodes;
+	m_num_nodes++;
+
+	btAssert((endIndex-startIndex)>0);
+
+	if ((endIndex-startIndex)==1)
+	{
+	    //We have a leaf node
+	    setNodeBound(curIndex,primitive_boxes[startIndex].m_bound);
+		m_node_array[curIndex].setDataIndex(primitive_boxes[startIndex].m_data);
+
+		return;
+	}
+	//calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
+
+	//split axis
+	int splitIndex = _calc_splitting_axis(primitive_boxes,startIndex,endIndex);
+
+	splitIndex = _sort_and_calc_splitting_index(
+			primitive_boxes,startIndex,endIndex,
+			splitIndex//split axis
+			);
+
+
+	//calc this node bounding box
+
+	btAABB node_bound;
+	node_bound.invalidate();
+
+	for (int i=startIndex;i<endIndex;i++)
+	{
+		node_bound.merge(primitive_boxes[i].m_bound);
+	}
+
+	setNodeBound(curIndex,node_bound);
+
+
+	//build left branch
+	_build_sub_tree(primitive_boxes, startIndex, splitIndex );
+
+
+	//build right branch
+	 _build_sub_tree(primitive_boxes, splitIndex ,endIndex);
+
+	m_node_array[curIndex].setEscapeIndex(m_num_nodes - curIndex);
+
+
+}
+
+//! stackless build tree
+void btBvhTree::build_tree(
+	GIM_BVH_DATA_ARRAY & primitive_boxes)
+{
+	// initialize node count to 0
+	m_num_nodes = 0;
+	// allocate nodes
+	m_node_array.resize(primitive_boxes.size()*2);
+
+	_build_sub_tree(primitive_boxes, 0, primitive_boxes.size());
+}
+
+////////////////////////////////////class btGImpactBvh
+
+void btGImpactBvh::refit()
+{
+	int nodecount = getNodeCount();
+	while(nodecount--)
+	{
+		if(isLeafNode(nodecount))
+		{
+			btAABB leafbox;
+			m_primitive_manager->get_primitive_box(getNodeData(nodecount),leafbox);
+			setNodeBound(nodecount,leafbox);
+		}
+		else
+		{
+			//const GIM_BVH_TREE_NODE * nodepointer = get_node_pointer(nodecount);
+			//get left bound
+			btAABB bound;
+			bound.invalidate();
+
+			btAABB temp_box;
+
+			int child_node = getLeftNode(nodecount);
+			if(child_node)
+			{
+				getNodeBound(child_node,temp_box);
+				bound.merge(temp_box);
+			}
+
+			child_node = getRightNode(nodecount);
+			if(child_node)
+			{
+				getNodeBound(child_node,temp_box);
+				bound.merge(temp_box);
+			}
+
+			setNodeBound(nodecount,bound);
+		}
+	}
+}
+
+//! this rebuild the entire set
+void btGImpactBvh::buildSet()
+{
+	//obtain primitive boxes
+	GIM_BVH_DATA_ARRAY primitive_boxes;
+	primitive_boxes.resize(m_primitive_manager->get_primitive_count());
+
+	for (int i = 0;i<primitive_boxes.size() ;i++ )
+	{
+		 m_primitive_manager->get_primitive_box(i,primitive_boxes[i].m_bound);
+		 primitive_boxes[i].m_data = i;
+	}
+
+	m_box_tree.build_tree(primitive_boxes);
+}
+
+//! returns the indices of the primitives in the m_primitive_manager
+bool btGImpactBvh::boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const
+{
+	int curIndex = 0;
+	int numNodes = getNodeCount();
+
+	while (curIndex < numNodes)
+	{
+		btAABB bound;
+		getNodeBound(curIndex,bound);
+
+		//catch bugs in tree data
+
+		bool aabbOverlap = bound.has_collision(box);
+		bool isleafnode = isLeafNode(curIndex);
+
+		if (isleafnode && aabbOverlap)
+		{
+			collided_results.push_back(getNodeData(curIndex));
+		}
+
+		if (aabbOverlap || isleafnode)
+		{
+			//next subnode
+			curIndex++;
+		}
+		else
+		{
+			//skip node
+			curIndex+= getEscapeNodeIndex(curIndex);
+		}
+	}
+	if(collided_results.size()>0) return true;
+	return false;
+}
+
+
+
+//! returns the indices of the primitives in the m_primitive_manager
+bool btGImpactBvh::rayQuery(
+	const btVector3 & ray_dir,const btVector3 & ray_origin ,
+	btAlignedObjectArray<int> & collided_results) const
+{
+	int curIndex = 0;
+	int numNodes = getNodeCount();
+
+	while (curIndex < numNodes)
+	{
+		btAABB bound;
+		getNodeBound(curIndex,bound);
+
+		//catch bugs in tree data
+
+		bool aabbOverlap = bound.collide_ray(ray_origin,ray_dir);
+		bool isleafnode = isLeafNode(curIndex);
+
+		if (isleafnode && aabbOverlap)
+		{
+			collided_results.push_back(getNodeData( curIndex));
+		}
+
+		if (aabbOverlap || isleafnode)
+		{
+			//next subnode
+			curIndex++;
+		}
+		else
+		{
+			//skip node
+			curIndex+= getEscapeNodeIndex(curIndex);
+		}
+	}
+	if(collided_results.size()>0) return true;
+	return false;
+}
+
+
+SIMD_FORCE_INLINE bool _node_collision(
+	btGImpactBvh * boxset0, btGImpactBvh * boxset1,
+	const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0,
+	int node0 ,int node1, bool complete_primitive_tests)
+{
+	btAABB box0;
+	boxset0->getNodeBound(node0,box0);
+	btAABB box1;
+	boxset1->getNodeBound(node1,box1);
+
+	return box0.overlapping_trans_cache(box1,trans_cache_1to0,complete_primitive_tests );
+//	box1.appy_transform_trans_cache(trans_cache_1to0);
+//	return box0.has_collision(box1);
+
+}
+
+
+//stackless recursive collision routine
+static void _find_collision_pairs_recursive(
+	btGImpactBvh * boxset0, btGImpactBvh * boxset1,
+	btPairSet * collision_pairs,
+	const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0,
+	int node0, int node1, bool complete_primitive_tests)
+{
+
+
+
+	if( _node_collision(
+		boxset0,boxset1,trans_cache_1to0,
+		node0,node1,complete_primitive_tests) ==false) return;//avoid colliding internal nodes
+
+	if(boxset0->isLeafNode(node0))
+	{
+		if(boxset1->isLeafNode(node1))
+		{
+			// collision result
+			collision_pairs->push_pair(
+				boxset0->getNodeData(node0),boxset1->getNodeData(node1));
+			return;
+		}
+		else
+		{
+
+			//collide left recursive
+
+			_find_collision_pairs_recursive(
+								boxset0,boxset1,
+								collision_pairs,trans_cache_1to0,
+								node0,boxset1->getLeftNode(node1),false);
+
+			//collide right recursive
+			_find_collision_pairs_recursive(
+								boxset0,boxset1,
+								collision_pairs,trans_cache_1to0,
+								node0,boxset1->getRightNode(node1),false);
+
+
+		}
+	}
+	else
+	{
+		if(boxset1->isLeafNode(node1))
+		{
+
+			//collide left recursive
+			_find_collision_pairs_recursive(
+								boxset0,boxset1,
+								collision_pairs,trans_cache_1to0,
+								boxset0->getLeftNode(node0),node1,false);
+
+
+			//collide right recursive
+
+			_find_collision_pairs_recursive(
+								boxset0,boxset1,
+								collision_pairs,trans_cache_1to0,
+								boxset0->getRightNode(node0),node1,false);
+
+
+		}
+		else
+		{
+			//collide left0 left1
+
+
+
+			_find_collision_pairs_recursive(
+				boxset0,boxset1,
+				collision_pairs,trans_cache_1to0,
+				boxset0->getLeftNode(node0),boxset1->getLeftNode(node1),false);
+
+			//collide left0 right1
+
+			_find_collision_pairs_recursive(
+				boxset0,boxset1,
+				collision_pairs,trans_cache_1to0,
+				boxset0->getLeftNode(node0),boxset1->getRightNode(node1),false);
+
+
+			//collide right0 left1
+
+			_find_collision_pairs_recursive(
+				boxset0,boxset1,
+				collision_pairs,trans_cache_1to0,
+				boxset0->getRightNode(node0),boxset1->getLeftNode(node1),false);
+
+			//collide right0 right1
+
+			_find_collision_pairs_recursive(
+				boxset0,boxset1,
+				collision_pairs,trans_cache_1to0,
+				boxset0->getRightNode(node0),boxset1->getRightNode(node1),false);
+
+		}// else if node1 is not a leaf
+	}// else if node0 is not a leaf
+}
+
+
+void btGImpactBvh::find_collision(btGImpactBvh * boxset0, const btTransform & trans0,
+		btGImpactBvh * boxset1, const btTransform & trans1,
+		btPairSet & collision_pairs)
+{
+
+	if(boxset0->getNodeCount()==0 || boxset1->getNodeCount()==0 ) return;
+
+	BT_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0;
+
+	trans_cache_1to0.calc_from_homogenic(trans0,trans1);
+
+#ifdef TRI_COLLISION_PROFILING
+	bt_begin_gim02_tree_time();
+#endif //TRI_COLLISION_PROFILING
+
+	_find_collision_pairs_recursive(
+		boxset0,boxset1,
+		&collision_pairs,trans_cache_1to0,0,0,true);
+#ifdef TRI_COLLISION_PROFILING
+	bt_end_gim02_tree_time();
+#endif //TRI_COLLISION_PROFILING
+
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactBvh.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactBvh.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactBvh.h	(revision 6952)
@@ -0,0 +1,394 @@
+#ifndef GIM_BOX_SET_H_INCLUDED
+#define GIM_BOX_SET_H_INCLUDED
+
+/*! \file gim_box_set.h
+\author Francisco Len Nßjera
+*/
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 "LinearMath/btAlignedObjectArray.h"
+
+#include "btBoxCollision.h"
+#include "btTriangleShapeEx.h"
+
+
+
+
+
+//! Overlapping pair
+struct GIM_PAIR
+{
+    int m_index1;
+    int m_index2;
+    GIM_PAIR()
+    {}
+
+    GIM_PAIR(const GIM_PAIR & p)
+    {
+    	m_index1 = p.m_index1;
+    	m_index2 = p.m_index2;
+	}
+
+	GIM_PAIR(int index1, int index2)
+    {
+    	m_index1 = index1;
+    	m_index2 = index2;
+	}
+};
+
+//! A pairset array
+class btPairSet: public btAlignedObjectArray<GIM_PAIR>
+{
+public:
+	btPairSet()
+	{
+		reserve(32);
+	}
+	inline void push_pair(int index1,int index2)
+	{
+		push_back(GIM_PAIR(index1,index2));
+	}
+
+	inline void push_pair_inv(int index1,int index2)
+	{
+		push_back(GIM_PAIR(index2,index1));
+	}
+};
+
+
+///GIM_BVH_DATA is an internal GIMPACT collision structure to contain axis aligned bounding box
+struct GIM_BVH_DATA
+{
+	btAABB m_bound;
+	int m_data;
+};
+
+//! Node Structure for trees
+class GIM_BVH_TREE_NODE
+{
+public:
+	btAABB m_bound;
+protected:
+	int	m_escapeIndexOrDataIndex;
+public:
+	GIM_BVH_TREE_NODE()
+	{
+		m_escapeIndexOrDataIndex = 0;
+	}
+
+	SIMD_FORCE_INLINE bool isLeafNode() const
+	{
+		//skipindex is negative (internal node), triangleindex >=0 (leafnode)
+		return (m_escapeIndexOrDataIndex>=0);
+	}
+
+	SIMD_FORCE_INLINE int getEscapeIndex() const
+	{
+		//btAssert(m_escapeIndexOrDataIndex < 0);
+		return -m_escapeIndexOrDataIndex;
+	}
+
+	SIMD_FORCE_INLINE void setEscapeIndex(int index)
+	{
+		m_escapeIndexOrDataIndex = -index;
+	}
+
+	SIMD_FORCE_INLINE int getDataIndex() const
+	{
+		//btAssert(m_escapeIndexOrDataIndex >= 0);
+
+		return m_escapeIndexOrDataIndex;
+	}
+
+	SIMD_FORCE_INLINE void setDataIndex(int index)
+	{
+		m_escapeIndexOrDataIndex = index;
+	}
+
+};
+
+
+class GIM_BVH_DATA_ARRAY:public btAlignedObjectArray<GIM_BVH_DATA>
+{
+};
+
+
+class GIM_BVH_TREE_NODE_ARRAY:public btAlignedObjectArray<GIM_BVH_TREE_NODE>
+{
+};
+
+
+
+
+//! Basic Box tree structure
+class btBvhTree
+{
+protected:
+	int m_num_nodes;
+	GIM_BVH_TREE_NODE_ARRAY m_node_array;
+protected:
+	int _sort_and_calc_splitting_index(
+		GIM_BVH_DATA_ARRAY & primitive_boxes,
+		 int startIndex,  int endIndex, int splitAxis);
+
+	int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,  int endIndex);
+
+	void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,  int endIndex);
+public:
+	btBvhTree()
+	{
+		m_num_nodes = 0;
+	}
+
+	//! prototype functions for box tree management
+	//!@{
+	void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes);
+
+	SIMD_FORCE_INLINE void clearNodes()
+	{
+		m_node_array.clear();
+		m_num_nodes = 0;
+	}
+
+	//! node count
+	SIMD_FORCE_INLINE int getNodeCount() const
+	{
+		return m_num_nodes;
+	}
+
+	//! tells if the node is a leaf
+	SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const
+	{
+		return m_node_array[nodeindex].isLeafNode();
+	}
+
+	SIMD_FORCE_INLINE int getNodeData(int nodeindex) const
+	{
+		return m_node_array[nodeindex].getDataIndex();
+	}
+
+	SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const
+	{
+		bound = m_node_array[nodeindex].m_bound;
+	}
+
+	SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
+	{
+		m_node_array[nodeindex].m_bound = bound;
+	}
+
+	SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
+	{
+		return nodeindex+1;
+	}
+
+	SIMD_FORCE_INLINE int getRightNode(int nodeindex) const
+	{
+		if(m_node_array[nodeindex+1].isLeafNode()) return nodeindex+2;
+		return nodeindex+1 + m_node_array[nodeindex+1].getEscapeIndex();
+	}
+
+	SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const
+	{
+		return m_node_array[nodeindex].getEscapeIndex();
+	}
+
+	SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE * get_node_pointer(int index = 0) const
+	{
+		return &m_node_array[index];
+	}
+
+	//!@}
+};
+
+
+//! Prototype Base class for primitive classification
+/*!
+This class is a wrapper for primitive collections.
+This tells relevant info for the Bounding Box set classes, which take care of space classification.
+This class can manage Compound shapes and trimeshes, and if it is managing trimesh then the  Hierarchy Bounding Box classes will take advantage of primitive Vs Box overlapping tests for getting optimal results and less Per Box compairisons.
+*/
+class btPrimitiveManagerBase
+{
+public:
+
+	//! determines if this manager consist on only triangles, which special case will be optimized
+	virtual bool is_trimesh() const = 0;
+	virtual int get_primitive_count() const = 0;
+	virtual void get_primitive_box(int prim_index ,btAABB & primbox) const = 0;
+	//! retrieves only the points of the triangle, and the collision margin
+	virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const= 0;
+};
+
+
+//! Structure for containing Boxes
+/*!
+This class offers an structure for managing a box tree of primitives.
+Requires a Primitive prototype (like btPrimitiveManagerBase )
+*/
+class btGImpactBvh
+{
+protected:
+	btBvhTree m_box_tree;
+	btPrimitiveManagerBase * m_primitive_manager;
+
+protected:
+	//stackless refit
+	void refit();
+public:
+
+	//! this constructor doesn't build the tree. you must call	buildSet
+	btGImpactBvh()
+	{
+		m_primitive_manager = NULL;
+	}
+
+	//! this constructor doesn't build the tree. you must call	buildSet
+	btGImpactBvh(btPrimitiveManagerBase * primitive_manager)
+	{
+		m_primitive_manager = primitive_manager;
+	}
+
+	SIMD_FORCE_INLINE btAABB getGlobalBox()  const
+	{
+		btAABB totalbox;
+		getNodeBound(0, totalbox);
+		return totalbox;
+	}
+
+	SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase * primitive_manager)
+	{
+		m_primitive_manager = primitive_manager;
+	}
+
+	SIMD_FORCE_INLINE btPrimitiveManagerBase * getPrimitiveManager() const
+	{
+		return m_primitive_manager;
+	}
+
+
+//! node manager prototype functions
+///@{
+
+	//! this attemps to refit the box set.
+	SIMD_FORCE_INLINE void update()
+	{
+		refit();
+	}
+
+	//! this rebuild the entire set
+	void buildSet();
+
+	//! returns the indices of the primitives in the m_primitive_manager
+	bool boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const;
+
+	//! returns the indices of the primitives in the m_primitive_manager
+	SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB & box,
+		 const btTransform & transform, btAlignedObjectArray<int> & collided_results) const
+	{
+		btAABB transbox=box;
+		transbox.appy_transform(transform);
+		return boxQuery(transbox,collided_results);
+	}
+
+	//! returns the indices of the primitives in the m_primitive_manager
+	bool rayQuery(
+		const btVector3 & ray_dir,const btVector3 & ray_origin ,
+		btAlignedObjectArray<int> & collided_results) const;
+
+	//! tells if this set has hierarcht
+	SIMD_FORCE_INLINE bool hasHierarchy() const
+	{
+		return true;
+	}
+
+	//! tells if this set is a trimesh
+	SIMD_FORCE_INLINE bool isTrimesh()  const
+	{
+		return m_primitive_manager->is_trimesh();
+	}
+
+	//! node count
+	SIMD_FORCE_INLINE int getNodeCount() const
+	{
+		return m_box_tree.getNodeCount();
+	}
+
+	//! tells if the node is a leaf
+	SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const
+	{
+		return m_box_tree.isLeafNode(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE int getNodeData(int nodeindex) const
+	{
+		return m_box_tree.getNodeData(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound)  const
+	{
+		m_box_tree.getNodeBound(nodeindex, bound);
+	}
+
+	SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
+	{
+		m_box_tree.setNodeBound(nodeindex, bound);
+	}
+
+
+	SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
+	{
+		return m_box_tree.getLeftNode(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE int getRightNode(int nodeindex) const
+	{
+		return m_box_tree.getRightNode(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const
+	{
+		return m_box_tree.getEscapeNodeIndex(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex,btPrimitiveTriangle & triangle) const
+	{
+		m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex),triangle);
+	}
+
+
+	SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE * get_node_pointer(int index = 0) const
+	{
+		return m_box_tree.get_node_pointer(index);
+	}
+
+
+	static float getAverageTreeCollisionTime();
+
+
+	static void find_collision(btGImpactBvh * boxset1, const btTransform & trans1,
+		btGImpactBvh * boxset2, const btTransform & trans2,
+		btPairSet & collision_pairs);
+};
+
+
+#endif // GIM_BOXPRUNING_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp	(revision 6952)
@@ -0,0 +1,897 @@
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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.
+*/
+/*
+Author: Francisco Len Nßjera
+Concave-Concave Collision
+
+*/
+
+#include "BulletCollision/CollisionDispatch/btManifoldResult.h"
+#include "LinearMath/btIDebugDraw.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+#include "BulletCollision/CollisionShapes/btBoxShape.h"
+#include "btGImpactCollisionAlgorithm.h"
+#include "btContactProcessing.h"
+#include "LinearMath/btQuickprof.h"
+
+
+//! Class for accessing the plane equation
+class btPlaneShape : public btStaticPlaneShape
+{
+public:
+
+	btPlaneShape(const btVector3& v, float f)
+		:btStaticPlaneShape(v,f)
+	{
+	}
+
+	void get_plane_equation(btVector4 &equation)
+	{
+		equation[0] = m_planeNormal[0];
+		equation[1] = m_planeNormal[1];
+		equation[2] = m_planeNormal[2];
+		equation[3] = m_planeConstant;
+	}
+
+
+	void get_plane_equation_transformed(const btTransform & trans,btVector4 &equation)
+	{
+		equation[0] = trans.getBasis().getRow(0).dot(m_planeNormal);
+		equation[1] = trans.getBasis().getRow(1).dot(m_planeNormal);
+		equation[2] = trans.getBasis().getRow(2).dot(m_planeNormal);
+		equation[3] = trans.getOrigin().dot(m_planeNormal) + m_planeConstant;
+	}
+};
+
+
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+#ifdef TRI_COLLISION_PROFILING
+
+btClock g_triangle_clock;
+
+float g_accum_triangle_collision_time = 0;
+int g_count_triangle_collision = 0;
+
+void bt_begin_gim02_tri_time()
+{
+	g_triangle_clock.reset();
+}
+
+void bt_end_gim02_tri_time()
+{
+	g_accum_triangle_collision_time += g_triangle_clock.getTimeMicroseconds();
+	g_count_triangle_collision++;
+}
+#endif //TRI_COLLISION_PROFILING
+//! Retrieving shapes shapes
+/*!
+Declared here due of insuficent space on Pool allocators
+*/
+//!@{
+class GIM_ShapeRetriever
+{
+public:
+	btGImpactShapeInterface * m_gim_shape;
+	btTriangleShapeEx m_trishape;
+	btTetrahedronShapeEx m_tetrashape;
+
+public:
+	class ChildShapeRetriever
+	{
+	public:
+		GIM_ShapeRetriever * m_parent;
+		virtual btCollisionShape * getChildShape(int index)
+		{
+			return m_parent->m_gim_shape->getChildShape(index);
+		}
+	};
+
+	class TriangleShapeRetriever:public ChildShapeRetriever
+	{
+	public:
+
+		virtual btCollisionShape * getChildShape(int index)
+		{
+			m_parent->m_gim_shape->getBulletTriangle(index,m_parent->m_trishape);
+			return &m_parent->m_trishape;
+		}
+	};
+
+	class TetraShapeRetriever:public ChildShapeRetriever
+	{
+	public:
+
+		virtual btCollisionShape * getChildShape(int index)
+		{
+			m_parent->m_gim_shape->getBulletTetrahedron(index,m_parent->m_tetrashape);
+			return &m_parent->m_tetrashape;
+		}
+	};
+public:
+	ChildShapeRetriever m_child_retriever;
+	TriangleShapeRetriever m_tri_retriever;
+	TetraShapeRetriever  m_tetra_retriever;
+	ChildShapeRetriever * m_current_retriever;
+
+	GIM_ShapeRetriever(btGImpactShapeInterface * gim_shape)
+	{
+		m_gim_shape = gim_shape;
+		//select retriever
+		if(m_gim_shape->needsRetrieveTriangles())
+		{
+			m_current_retriever = &m_tri_retriever;
+		}
+		else if(m_gim_shape->needsRetrieveTetrahedrons())
+		{
+			m_current_retriever = &m_tetra_retriever;
+		}
+		else
+		{
+			m_current_retriever = &m_child_retriever;
+		}
+
+		m_current_retriever->m_parent = this;
+	}
+
+	btCollisionShape * getChildShape(int index)
+	{
+		return m_current_retriever->getChildShape(index);
+	}
+
+
+};
+
+
+
+//!@}
+
+
+#ifdef TRI_COLLISION_PROFILING
+
+//! Gets the average time in miliseconds of tree collisions
+float btGImpactCollisionAlgorithm::getAverageTreeCollisionTime()
+{
+	return btGImpactBoxSet::getAverageTreeCollisionTime();
+
+}
+
+//! Gets the average time in miliseconds of triangle collisions
+float btGImpactCollisionAlgorithm::getAverageTriangleCollisionTime()
+{
+	if(g_count_triangle_collision == 0) return 0;
+
+	float avgtime = g_accum_triangle_collision_time;
+	avgtime /= (float)g_count_triangle_collision;
+
+	g_accum_triangle_collision_time = 0;
+	g_count_triangle_collision = 0;
+
+	return avgtime;
+}
+
+#endif //TRI_COLLISION_PROFILING
+
+
+
+btGImpactCollisionAlgorithm::btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+: btActivatingCollisionAlgorithm(ci,body0,body1)
+{
+	m_manifoldPtr = NULL;
+	m_convex_algorithm = NULL;
+}
+
+btGImpactCollisionAlgorithm::~btGImpactCollisionAlgorithm()
+{
+	clearCache();
+}
+
+
+
+
+
+void btGImpactCollisionAlgorithm::addContactPoint(btCollisionObject * body0,
+				btCollisionObject * body1,
+				const btVector3 & point,
+				const btVector3 & normal,
+				btScalar distance)
+{
+	m_resultOut->setShapeIdentifiers(m_part0,m_triface0,m_part1,m_triface1);
+	checkManifold(body0,body1);
+	m_resultOut->addContactPoint(normal,point,distance);
+}
+
+
+void btGImpactCollisionAlgorithm::shape_vs_shape_collision(
+					  btCollisionObject * body0,
+					  btCollisionObject * body1,
+					  btCollisionShape * shape0,
+					  btCollisionShape * shape1)
+{
+
+	btCollisionShape* tmpShape0 = body0->getCollisionShape();
+	btCollisionShape* tmpShape1 = body1->getCollisionShape();
+	
+	body0->internalSetTemporaryCollisionShape(shape0);
+	body1->internalSetTemporaryCollisionShape(shape1);
+
+	{
+		btCollisionAlgorithm* algor = newAlgorithm(body0,body1);
+		// post :	checkManifold is called
+
+		m_resultOut->setShapeIdentifiers(m_part0,m_triface0,m_part1,m_triface1);
+
+		algor->processCollision(body0,body1,*m_dispatchInfo,m_resultOut);
+
+		algor->~btCollisionAlgorithm();
+		m_dispatcher->freeCollisionAlgorithm(algor);
+	}
+
+	body0->internalSetTemporaryCollisionShape(tmpShape0);
+	body1->internalSetTemporaryCollisionShape(tmpShape1);
+}
+
+void btGImpactCollisionAlgorithm::convex_vs_convex_collision(
+					  btCollisionObject * body0,
+					  btCollisionObject * body1,
+					  btCollisionShape * shape0,
+					  btCollisionShape * shape1)
+{
+
+	btCollisionShape* tmpShape0 = body0->getCollisionShape();
+	btCollisionShape* tmpShape1 = body1->getCollisionShape();
+	
+	body0->internalSetTemporaryCollisionShape(shape0);
+	body1->internalSetTemporaryCollisionShape(shape1);
+
+
+	m_resultOut->setShapeIdentifiers(m_part0,m_triface0,m_part1,m_triface1);
+
+	checkConvexAlgorithm(body0,body1);
+	m_convex_algorithm->processCollision(body0,body1,*m_dispatchInfo,m_resultOut);
+
+	body0->internalSetTemporaryCollisionShape(tmpShape0);
+	body1->internalSetTemporaryCollisionShape(tmpShape1);
+
+}
+
+
+
+
+void btGImpactCollisionAlgorithm::gimpact_vs_gimpact_find_pairs(
+					  const btTransform & trans0,
+					  const btTransform & trans1,
+					  btGImpactShapeInterface * shape0,
+					  btGImpactShapeInterface * shape1,btPairSet & pairset)
+{
+	if(shape0->hasBoxSet() && shape1->hasBoxSet())
+	{
+		btGImpactBoxSet::find_collision(shape0->getBoxSet(),trans0,shape1->getBoxSet(),trans1,pairset);
+	}
+	else
+	{
+		btAABB boxshape0;
+		btAABB boxshape1;
+		int i = shape0->getNumChildShapes();
+
+		while(i--)
+		{
+			shape0->getChildAabb(i,trans0,boxshape0.m_min,boxshape0.m_max);
+
+			int j = shape1->getNumChildShapes();
+			while(j--)
+			{
+				shape1->getChildAabb(i,trans1,boxshape1.m_min,boxshape1.m_max);
+
+				if(boxshape1.has_collision(boxshape0))
+				{
+					pairset.push_pair(i,j);
+				}
+			}
+		}
+	}
+
+
+}
+
+
+void btGImpactCollisionAlgorithm::gimpact_vs_shape_find_pairs(
+					  const btTransform & trans0,
+					  const btTransform & trans1,
+					  btGImpactShapeInterface * shape0,
+					  btCollisionShape * shape1,
+					  btAlignedObjectArray<int> & collided_primitives)
+{
+
+	btAABB boxshape;
+
+
+	if(shape0->hasBoxSet())
+	{
+		btTransform trans1to0 = trans0.inverse();
+		trans1to0 *= trans1;
+
+		shape1->getAabb(trans1to0,boxshape.m_min,boxshape.m_max);
+
+		shape0->getBoxSet()->boxQuery(boxshape, collided_primitives);
+	}
+	else
+	{
+		shape1->getAabb(trans1,boxshape.m_min,boxshape.m_max);
+
+		btAABB boxshape0;
+		int i = shape0->getNumChildShapes();
+
+		while(i--)
+		{
+			shape0->getChildAabb(i,trans0,boxshape0.m_min,boxshape0.m_max);
+
+			if(boxshape.has_collision(boxshape0))
+			{
+				collided_primitives.push_back(i);
+			}
+		}
+
+	}
+
+}
+
+
+void btGImpactCollisionAlgorithm::collide_gjk_triangles(btCollisionObject * body0,
+				  btCollisionObject * body1,
+				  btGImpactMeshShapePart * shape0,
+				  btGImpactMeshShapePart * shape1,
+				  const int * pairs, int pair_count)
+{
+	btTriangleShapeEx tri0;
+	btTriangleShapeEx tri1;
+
+	shape0->lockChildShapes();
+	shape1->lockChildShapes();
+
+	const int * pair_pointer = pairs;
+
+	while(pair_count--)
+	{
+
+		m_triface0 = *(pair_pointer);
+		m_triface1 = *(pair_pointer+1);
+		pair_pointer+=2;
+
+
+
+		shape0->getBulletTriangle(m_triface0,tri0);
+		shape1->getBulletTriangle(m_triface1,tri1);
+
+
+		//collide two convex shapes
+		if(tri0.overlap_test_conservative(tri1))
+		{
+			convex_vs_convex_collision(body0,body1,&tri0,&tri1);
+		}
+
+	}
+
+	shape0->unlockChildShapes();
+	shape1->unlockChildShapes();
+}
+
+void btGImpactCollisionAlgorithm::collide_sat_triangles(btCollisionObject * body0,
+					  btCollisionObject * body1,
+					  btGImpactMeshShapePart * shape0,
+					  btGImpactMeshShapePart * shape1,
+					  const int * pairs, int pair_count)
+{
+	btTransform orgtrans0 = body0->getWorldTransform();
+	btTransform orgtrans1 = body1->getWorldTransform();
+
+	btPrimitiveTriangle ptri0;
+	btPrimitiveTriangle ptri1;
+	GIM_TRIANGLE_CONTACT contact_data;
+
+	shape0->lockChildShapes();
+	shape1->lockChildShapes();
+
+	const int * pair_pointer = pairs;
+
+	while(pair_count--)
+	{
+
+		m_triface0 = *(pair_pointer);
+		m_triface1 = *(pair_pointer+1);
+		pair_pointer+=2;
+
+
+		shape0->getPrimitiveTriangle(m_triface0,ptri0);
+		shape1->getPrimitiveTriangle(m_triface1,ptri1);
+
+		#ifdef TRI_COLLISION_PROFILING
+		bt_begin_gim02_tri_time();
+		#endif
+
+		ptri0.applyTransform(orgtrans0);
+		ptri1.applyTransform(orgtrans1);
+
+
+		//build planes
+		ptri0.buildTriPlane();
+		ptri1.buildTriPlane();
+		// test conservative
+
+
+
+		if(ptri0.overlap_test_conservative(ptri1))
+		{
+			if(ptri0.find_triangle_collision_clip_method(ptri1,contact_data))
+			{
+
+				int j = contact_data.m_point_count;
+				while(j--)
+				{
+
+					addContactPoint(body0, body1,
+								contact_data.m_points[j],
+								contact_data.m_separating_normal,
+								-contact_data.m_penetration_depth);
+				}
+			}
+		}
+
+		#ifdef TRI_COLLISION_PROFILING
+		bt_end_gim02_tri_time();
+		#endif
+
+	}
+
+	shape0->unlockChildShapes();
+	shape1->unlockChildShapes();
+
+}
+
+
+void btGImpactCollisionAlgorithm::gimpact_vs_gimpact(
+						btCollisionObject * body0,
+					   	btCollisionObject * body1,
+					  	btGImpactShapeInterface * shape0,
+					  	btGImpactShapeInterface * shape1)
+{
+
+	if(shape0->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE)
+	{
+		btGImpactMeshShape * meshshape0 = static_cast<btGImpactMeshShape *>(shape0);
+		m_part0 = meshshape0->getMeshPartCount();
+
+		while(m_part0--)
+		{
+			gimpact_vs_gimpact(body0,body1,meshshape0->getMeshPart(m_part0),shape1);
+		}
+
+		return;
+	}
+
+	if(shape1->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE)
+	{
+		btGImpactMeshShape * meshshape1 = static_cast<btGImpactMeshShape *>(shape1);
+		m_part1 = meshshape1->getMeshPartCount();
+
+		while(m_part1--)
+		{
+
+			gimpact_vs_gimpact(body0,body1,shape0,meshshape1->getMeshPart(m_part1));
+
+		}
+
+		return;
+	}
+
+
+	btTransform orgtrans0 = body0->getWorldTransform();
+	btTransform orgtrans1 = body1->getWorldTransform();
+
+	btPairSet pairset;
+
+	gimpact_vs_gimpact_find_pairs(orgtrans0,orgtrans1,shape0,shape1,pairset);
+
+	if(pairset.size()== 0) return;
+
+	if(shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART &&
+		shape1->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART)
+	{
+		btGImpactMeshShapePart * shapepart0 = static_cast<btGImpactMeshShapePart * >(shape0);
+		btGImpactMeshShapePart * shapepart1 = static_cast<btGImpactMeshShapePart * >(shape1);
+		//specialized function
+		#ifdef BULLET_TRIANGLE_COLLISION
+		collide_gjk_triangles(body0,body1,shapepart0,shapepart1,&pairset[0].m_index1,pairset.size());
+		#else
+		collide_sat_triangles(body0,body1,shapepart0,shapepart1,&pairset[0].m_index1,pairset.size());
+		#endif
+
+		return;
+	}
+
+	//general function
+
+	shape0->lockChildShapes();
+	shape1->lockChildShapes();
+
+	GIM_ShapeRetriever retriever0(shape0);
+	GIM_ShapeRetriever retriever1(shape1);
+
+	bool child_has_transform0 = shape0->childrenHasTransform();
+	bool child_has_transform1 = shape1->childrenHasTransform();
+
+	int i = pairset.size();
+	while(i--)
+	{
+		GIM_PAIR * pair = &pairset[i];
+		m_triface0 = pair->m_index1;
+		m_triface1 = pair->m_index2;
+		btCollisionShape * colshape0 = retriever0.getChildShape(m_triface0);
+		btCollisionShape * colshape1 = retriever1.getChildShape(m_triface1);
+
+		if(child_has_transform0)
+		{
+			body0->setWorldTransform(orgtrans0*shape0->getChildTransform(m_triface0));
+		}
+
+		if(child_has_transform1)
+		{
+			body1->setWorldTransform(orgtrans1*shape1->getChildTransform(m_triface1));
+		}
+
+		//collide two convex shapes
+		convex_vs_convex_collision(body0,body1,colshape0,colshape1);
+
+
+		if(child_has_transform0)
+		{
+			body0->setWorldTransform(orgtrans0);
+		}
+
+		if(child_has_transform1)
+		{
+			body1->setWorldTransform(orgtrans1);
+		}
+
+	}
+
+	shape0->unlockChildShapes();
+	shape1->unlockChildShapes();
+}
+
+void btGImpactCollisionAlgorithm::gimpact_vs_shape(btCollisionObject * body0,
+				  btCollisionObject * body1,
+				  btGImpactShapeInterface * shape0,
+				  btCollisionShape * shape1,bool swapped)
+{
+	if(shape0->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE)
+	{
+		btGImpactMeshShape * meshshape0 = static_cast<btGImpactMeshShape *>(shape0);
+		int& part = swapped ? m_part1 : m_part0;
+		part = meshshape0->getMeshPartCount();
+
+		while(part--)
+		{
+
+			gimpact_vs_shape(body0,
+				  body1,
+				  meshshape0->getMeshPart(part),
+				  shape1,swapped);
+
+		}
+
+		return;
+	}
+
+	#ifdef GIMPACT_VS_PLANE_COLLISION
+	if(shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART &&
+		shape1->getShapeType() == STATIC_PLANE_PROXYTYPE)
+	{
+		btGImpactMeshShapePart * shapepart = static_cast<btGImpactMeshShapePart *>(shape0);
+		btStaticPlaneShape * planeshape = static_cast<btStaticPlaneShape * >(shape1);
+		gimpacttrimeshpart_vs_plane_collision(body0,body1,shapepart,planeshape,swapped);
+		return;
+	}
+
+	#endif
+
+
+
+	if(shape1->isCompound())
+	{
+		btCompoundShape * compoundshape = static_cast<btCompoundShape *>(shape1);
+		gimpact_vs_compoundshape(body0,body1,shape0,compoundshape,swapped);
+		return;
+	}
+	else if(shape1->isConcave())
+	{
+		btConcaveShape * concaveshape = static_cast<btConcaveShape *>(shape1);
+		gimpact_vs_concave(body0,body1,shape0,concaveshape,swapped);
+		return;
+	}
+
+
+	btTransform orgtrans0 = body0->getWorldTransform();
+
+	btTransform orgtrans1 = body1->getWorldTransform();
+
+	btAlignedObjectArray<int> collided_results;
+
+	gimpact_vs_shape_find_pairs(orgtrans0,orgtrans1,shape0,shape1,collided_results);
+
+	if(collided_results.size() == 0) return;
+
+
+	shape0->lockChildShapes();
+
+	GIM_ShapeRetriever retriever0(shape0);
+
+
+	bool child_has_transform0 = shape0->childrenHasTransform();
+
+
+	int i = collided_results.size();
+
+	while(i--)
+	{
+		int child_index = collided_results[i];
+        if(swapped)
+    		m_triface1 = child_index;
+        else
+            m_triface0 = child_index;
+
+		btCollisionShape * colshape0 = retriever0.getChildShape(child_index);
+
+		if(child_has_transform0)
+		{
+			body0->setWorldTransform(orgtrans0*shape0->getChildTransform(child_index));
+		}
+
+		//collide two shapes
+		if(swapped)
+		{
+			shape_vs_shape_collision(body1,body0,shape1,colshape0);
+		}
+		else
+		{
+			shape_vs_shape_collision(body0,body1,colshape0,shape1);
+		}
+
+		//restore transforms
+		if(child_has_transform0)
+		{
+			body0->setWorldTransform(orgtrans0);
+		}
+
+	}
+
+	shape0->unlockChildShapes();
+
+}
+
+void btGImpactCollisionAlgorithm::gimpact_vs_compoundshape(btCollisionObject * body0,
+				  btCollisionObject * body1,
+				  btGImpactShapeInterface * shape0,
+				  btCompoundShape * shape1,bool swapped)
+{
+	btTransform orgtrans1 = body1->getWorldTransform();
+
+	int i = shape1->getNumChildShapes();
+	while(i--)
+	{
+
+		btCollisionShape * colshape1 = shape1->getChildShape(i);
+		btTransform childtrans1 = orgtrans1*shape1->getChildTransform(i);
+
+		body1->setWorldTransform(childtrans1);
+
+		//collide child shape
+		gimpact_vs_shape(body0, body1,
+					  shape0,colshape1,swapped);
+
+
+		//restore transforms
+		body1->setWorldTransform(orgtrans1);
+	}
+}
+
+void btGImpactCollisionAlgorithm::gimpacttrimeshpart_vs_plane_collision(
+					  btCollisionObject * body0,
+					  btCollisionObject * body1,
+					  btGImpactMeshShapePart * shape0,
+					  btStaticPlaneShape * shape1,bool swapped)
+{
+
+
+	btTransform orgtrans0 = body0->getWorldTransform();
+	btTransform orgtrans1 = body1->getWorldTransform();
+
+	btPlaneShape * planeshape = static_cast<btPlaneShape *>(shape1);
+	btVector4 plane;
+	planeshape->get_plane_equation_transformed(orgtrans1,plane);
+
+	//test box against plane
+
+	btAABB tribox;
+	shape0->getAabb(orgtrans0,tribox.m_min,tribox.m_max);
+	tribox.increment_margin(planeshape->getMargin());
+
+	if( tribox.plane_classify(plane)!= BT_CONST_COLLIDE_PLANE) return;
+
+	shape0->lockChildShapes();
+
+	btScalar margin = shape0->getMargin() + planeshape->getMargin();
+
+	btVector3 vertex;
+	int vi = shape0->getVertexCount();
+	while(vi--)
+	{
+		shape0->getVertex(vi,vertex);
+		vertex = orgtrans0(vertex);
+
+		btScalar distance = vertex.dot(plane) - plane[3] - margin;
+
+		if(distance<0.0)//add contact
+		{
+			if(swapped)
+			{
+				addContactPoint(body1, body0,
+					vertex,
+					-plane,
+					distance);
+			}
+			else
+			{
+				addContactPoint(body0, body1,
+					vertex,
+					plane,
+					distance);
+			}
+		}
+	}
+
+	shape0->unlockChildShapes();
+}
+
+
+
+
+class btGImpactTriangleCallback: public btTriangleCallback
+{
+public:
+	btGImpactCollisionAlgorithm * algorithm;
+	btCollisionObject * body0;
+	btCollisionObject * body1;
+	btGImpactShapeInterface * gimpactshape0;
+	bool swapped;
+	btScalar margin;
+
+	virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex)
+	{
+		btTriangleShapeEx tri1(triangle[0],triangle[1],triangle[2]);
+		tri1.setMargin(margin);
+        if(swapped)
+        {
+            algorithm->setPart0(partId);
+            algorithm->setFace0(triangleIndex);
+        }
+        else
+        {
+            algorithm->setPart1(partId);
+            algorithm->setFace1(triangleIndex);
+        }
+		algorithm->gimpact_vs_shape(
+							body0,body1,gimpactshape0,&tri1,swapped);
+	}
+};
+
+
+
+
+void btGImpactCollisionAlgorithm::gimpact_vs_concave(
+				  btCollisionObject * body0,
+				  btCollisionObject * body1,
+				  btGImpactShapeInterface * shape0,
+				  btConcaveShape * shape1,bool swapped)
+{
+	//create the callback
+	btGImpactTriangleCallback tricallback;
+	tricallback.algorithm = this;
+	tricallback.body0 = body0;
+	tricallback.body1 = body1;
+	tricallback.gimpactshape0 = shape0;
+	tricallback.swapped = swapped;
+	tricallback.margin = shape1->getMargin();
+
+	//getting the trimesh AABB
+	btTransform gimpactInConcaveSpace;
+
+	gimpactInConcaveSpace = body1->getWorldTransform().inverse() * body0->getWorldTransform();
+
+	btVector3 minAABB,maxAABB;
+	shape0->getAabb(gimpactInConcaveSpace,minAABB,maxAABB);
+
+	shape1->processAllTriangles(&tricallback,minAABB,maxAABB);
+
+}
+
+
+
+void btGImpactCollisionAlgorithm::processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+    clearCache();
+
+    m_resultOut = resultOut;
+	m_dispatchInfo = &dispatchInfo;
+    btGImpactShapeInterface * gimpactshape0;
+    btGImpactShapeInterface * gimpactshape1;
+
+	if (body0->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE)
+	{
+		gimpactshape0 = static_cast<btGImpactShapeInterface *>(body0->getCollisionShape());
+
+		if( body1->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE )
+		{
+			gimpactshape1 = static_cast<btGImpactShapeInterface *>(body1->getCollisionShape());
+
+			gimpact_vs_gimpact(body0,body1,gimpactshape0,gimpactshape1);
+		}
+		else
+		{
+			gimpact_vs_shape(body0,body1,gimpactshape0,body1->getCollisionShape(),false);
+		}
+
+	}
+	else if (body1->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE )
+	{
+		gimpactshape1 = static_cast<btGImpactShapeInterface *>(body1->getCollisionShape());
+
+		gimpact_vs_shape(body1,body0,gimpactshape1,body0->getCollisionShape(),true);
+	}
+}
+
+
+btScalar btGImpactCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut)
+{
+	return 1.f;
+
+}
+
+///////////////////////////////////// REGISTERING ALGORITHM //////////////////////////////////////////////
+
+btGImpactCollisionAlgorithm::CreateFunc g_gimpact_cf;
+
+//! Use this function for register the algorithm externally
+void btGImpactCollisionAlgorithm::registerAlgorithm(btCollisionDispatcher * dispatcher)
+{
+
+	int i;
+
+	for ( i = 0;i < MAX_BROADPHASE_COLLISION_TYPES ;i++ )
+	{
+		dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,i ,&g_gimpact_cf);
+	}
+
+	for ( i = 0;i < MAX_BROADPHASE_COLLISION_TYPES ;i++ )
+	{
+		dispatcher->registerCollisionCreateFunc(i,GIMPACT_SHAPE_PROXYTYPE ,&g_gimpact_cf);
+	}
+
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h	(revision 6952)
@@ -0,0 +1,306 @@
+/*! \file btGImpactShape.h
+\author Francisco Len Nßjera
+*/
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 BVH_CONCAVE_COLLISION_ALGORITHM_H
+#define BVH_CONCAVE_COLLISION_ALGORITHM_H
+
+#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h"
+#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+class btDispatcher;
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+
+#include "LinearMath/btAlignedObjectArray.h"
+
+#include "btGImpactShape.h"
+#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
+#include "BulletCollision/CollisionShapes/btCompoundShape.h"
+#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h"
+#include "LinearMath/btIDebugDraw.h"
+
+
+
+//! Collision Algorithm for GImpact Shapes
+/*!
+For register this algorithm in Bullet, proceed as following:
+ \code
+btCollisionDispatcher * dispatcher = static_cast<btCollisionDispatcher *>(m_dynamicsWorld ->getDispatcher());
+btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher);
+ \endcode
+*/
+class btGImpactCollisionAlgorithm : public btActivatingCollisionAlgorithm
+{
+protected:
+	btCollisionAlgorithm * m_convex_algorithm;
+    btPersistentManifold * m_manifoldPtr;
+	btManifoldResult* m_resultOut;
+	const btDispatcherInfo * m_dispatchInfo;
+	int m_triface0;
+	int m_part0;
+	int m_triface1;
+	int m_part1;
+
+
+	//! Creates a new contact point
+	SIMD_FORCE_INLINE btPersistentManifold* newContactManifold(btCollisionObject* body0,btCollisionObject* body1)
+	{
+		m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1);
+		return m_manifoldPtr;
+	}
+
+	SIMD_FORCE_INLINE void destroyConvexAlgorithm()
+	{
+		if(m_convex_algorithm)
+		{
+			m_convex_algorithm->~btCollisionAlgorithm();
+			m_dispatcher->freeCollisionAlgorithm( m_convex_algorithm);
+			m_convex_algorithm = NULL;
+		}
+	}
+
+	SIMD_FORCE_INLINE void destroyContactManifolds()
+	{
+		if(m_manifoldPtr == NULL) return;
+		m_dispatcher->releaseManifold(m_manifoldPtr);
+		m_manifoldPtr = NULL;
+	}
+
+	SIMD_FORCE_INLINE void clearCache()
+	{
+		destroyContactManifolds();
+		destroyConvexAlgorithm();
+
+		m_triface0 = -1;
+		m_part0 = -1;
+		m_triface1 = -1;
+		m_part1 = -1;
+	}
+
+	SIMD_FORCE_INLINE btPersistentManifold* getLastManifold()
+	{
+		return m_manifoldPtr;
+	}
+
+
+	// Call before process collision
+	SIMD_FORCE_INLINE void checkManifold(btCollisionObject* body0,btCollisionObject* body1)
+	{
+		if(getLastManifold() == 0)
+		{
+			newContactManifold(body0,body1);
+		}
+
+		m_resultOut->setPersistentManifold(getLastManifold());
+	}
+
+	// Call before process collision
+	SIMD_FORCE_INLINE btCollisionAlgorithm * newAlgorithm(btCollisionObject* body0,btCollisionObject* body1)
+	{
+		checkManifold(body0,body1);
+
+		btCollisionAlgorithm * convex_algorithm = m_dispatcher->findAlgorithm(
+				body0,body1,getLastManifold());
+		return convex_algorithm ;
+	}
+
+	// Call before process collision
+	SIMD_FORCE_INLINE void checkConvexAlgorithm(btCollisionObject* body0,btCollisionObject* body1)
+	{
+		if(m_convex_algorithm) return;
+		m_convex_algorithm = newAlgorithm(body0,body1);
+	}
+
+
+
+
+	void addContactPoint(btCollisionObject * body0,
+					btCollisionObject * body1,
+					const btVector3 & point,
+					const btVector3 & normal,
+					btScalar distance);
+
+//! Collision routines
+//!@{
+
+	void collide_gjk_triangles(btCollisionObject * body0,
+				  btCollisionObject * body1,
+				  btGImpactMeshShapePart * shape0,
+				  btGImpactMeshShapePart * shape1,
+				  const int * pairs, int pair_count);
+
+	void collide_sat_triangles(btCollisionObject * body0,
+					  btCollisionObject * body1,
+					  btGImpactMeshShapePart * shape0,
+					  btGImpactMeshShapePart * shape1,
+					  const int * pairs, int pair_count);
+
+
+
+
+	void shape_vs_shape_collision(
+					  btCollisionObject * body0,
+					  btCollisionObject * body1,
+					  btCollisionShape * shape0,
+					  btCollisionShape * shape1);
+
+	void convex_vs_convex_collision(btCollisionObject * body0,
+					  btCollisionObject * body1,
+					  btCollisionShape * shape0,
+					  btCollisionShape * shape1);
+
+
+
+	void gimpact_vs_gimpact_find_pairs(
+					  const btTransform & trans0,
+					  const btTransform & trans1,
+					  btGImpactShapeInterface * shape0,
+					  btGImpactShapeInterface * shape1,btPairSet & pairset);
+
+	void gimpact_vs_shape_find_pairs(
+					  const btTransform & trans0,
+					  const btTransform & trans1,
+					  btGImpactShapeInterface * shape0,
+					  btCollisionShape * shape1,
+					  btAlignedObjectArray<int> & collided_primitives);
+
+
+	void gimpacttrimeshpart_vs_plane_collision(
+					  btCollisionObject * body0,
+					  btCollisionObject * body1,
+					  btGImpactMeshShapePart * shape0,
+					  btStaticPlaneShape * shape1,bool swapped);
+
+
+public:
+
+	btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
+
+	virtual ~btGImpactCollisionAlgorithm();
+
+	virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+	btScalar	calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
+
+	virtual	void	getAllContactManifolds(btManifoldArray&	manifoldArray)
+	{
+		if (m_manifoldPtr)
+			manifoldArray.push_back(m_manifoldPtr);
+	}
+
+
+	struct CreateFunc :public 	btCollisionAlgorithmCreateFunc
+	{
+		virtual	btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
+		{
+			void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btGImpactCollisionAlgorithm));
+			return new(mem) btGImpactCollisionAlgorithm(ci,body0,body1);
+		}
+	};
+
+	//! Use this function for register the algorithm externally
+	static void registerAlgorithm(btCollisionDispatcher * dispatcher);
+
+	//! Gets the average time in miliseconds of tree collisions
+	static float getAverageTreeCollisionTime();
+
+	//! Gets the average time in miliseconds of triangle collisions
+	static float getAverageTriangleCollisionTime();
+
+
+	//! Collides two gimpact shapes
+	/*!
+	\pre shape0 and shape1 couldn't be btGImpactMeshShape objects
+	*/
+
+
+	void gimpact_vs_gimpact(btCollisionObject * body0,
+					  btCollisionObject * body1,
+					  btGImpactShapeInterface * shape0,
+					  btGImpactShapeInterface * shape1);
+
+	void gimpact_vs_shape(btCollisionObject * body0,
+					  btCollisionObject * body1,
+					  btGImpactShapeInterface * shape0,
+					  btCollisionShape * shape1,bool swapped);
+
+	void gimpact_vs_compoundshape(btCollisionObject * body0,
+					  btCollisionObject * body1,
+					  btGImpactShapeInterface * shape0,
+					  btCompoundShape * shape1,bool swapped);
+
+	void gimpact_vs_concave(
+					  btCollisionObject * body0,
+					  btCollisionObject * body1,
+					  btGImpactShapeInterface * shape0,
+					  btConcaveShape * shape1,bool swapped);
+
+
+
+
+		/// Accessor/Mutator pairs for Part and triangleID
+    void 	setFace0(int value) 
+    { 
+    	m_triface0 = value; 
+    }
+    int getFace0() 
+    { 
+    	return m_triface0; 
+    }
+    void setFace1(int value) 
+    { 
+    	m_triface1 = value; 
+    }
+    int getFace1() 
+    { 
+    	return m_triface1; 
+    }
+    void setPart0(int value) 
+    { 
+    	m_part0 = value; 
+    }
+    int getPart0() 
+    { 
+    	return m_part0; 
+    }
+    void setPart1(int value) 
+    { 
+    	m_part1 = value; 
+		}
+    int getPart1() 
+    { 
+    	return m_part1; 
+    }
+
+};
+
+
+//algorithm details
+//#define BULLET_TRIANGLE_COLLISION 1
+#define GIMPACT_VS_PLANE_COLLISION 1
+
+
+
+#endif //BVH_CONCAVE_COLLISION_ALGORITHM_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactMassUtil.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactMassUtil.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactMassUtil.h	(revision 6952)
@@ -0,0 +1,60 @@
+/*! \file btGImpactMassUtil.h
+\author Francisco Len Nßjera
+*/
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 GIMPACT_MASS_UTIL_H
+#define GIMPACT_MASS_UTIL_H
+
+#include "LinearMath/btTransform.h"
+
+
+
+SIMD_FORCE_INLINE btVector3 gim_inertia_add_transformed(
+	const btVector3 & source_inertia, const btVector3 & added_inertia, const btTransform & transform)
+{
+	btMatrix3x3  rotatedTensor = transform.getBasis().scaled(added_inertia) * transform.getBasis().transpose();
+
+	btScalar x2 = transform.getOrigin()[0];
+	x2*= x2;
+	btScalar y2 = transform.getOrigin()[1];
+	y2*= y2;
+	btScalar z2 = transform.getOrigin()[2];
+	z2*= z2;
+
+	btScalar ix = rotatedTensor[0][0]*(y2+z2);
+	btScalar iy = rotatedTensor[1][1]*(x2+z2);
+	btScalar iz = rotatedTensor[2][2]*(x2+y2);
+
+	return btVector3(source_inertia[0]+ix,source_inertia[1]+iy,source_inertia[2] + iz);
+}
+
+SIMD_FORCE_INLINE btVector3 gim_get_point_inertia(const btVector3 & point, btScalar mass)
+{
+	btScalar x2 = point[0]*point[0];
+	btScalar y2 = point[1]*point[1];
+	btScalar z2 = point[2]*point[2];
+	return btVector3(mass*(y2+z2),mass*(x2+z2),mass*(x2+y2));
+}
+
+
+#endif //GIMPACT_MESH_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp	(revision 6952)
@@ -0,0 +1,528 @@
+/*! \file gim_box_set.h
+\author Francisco Len Nßjera
+*/
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 "btGImpactQuantizedBvh.h"
+#include "LinearMath/btQuickprof.h"
+
+#ifdef TRI_COLLISION_PROFILING
+btClock g_q_tree_clock;
+
+
+float g_q_accum_tree_collision_time = 0;
+int g_q_count_traversing = 0;
+
+
+void bt_begin_gim02_q_tree_time()
+{
+	g_q_tree_clock.reset();
+}
+
+void bt_end_gim02_q_tree_time()
+{
+	g_q_accum_tree_collision_time += g_q_tree_clock.getTimeMicroseconds();
+	g_q_count_traversing++;
+}
+
+
+//! Gets the average time in miliseconds of tree collisions
+float btGImpactQuantizedBvh::getAverageTreeCollisionTime()
+{
+	if(g_q_count_traversing == 0) return 0;
+
+	float avgtime = g_q_accum_tree_collision_time;
+	avgtime /= (float)g_q_count_traversing;
+
+	g_q_accum_tree_collision_time = 0;
+	g_q_count_traversing = 0;
+	return avgtime;
+
+//	float avgtime = g_q_count_traversing;
+//	g_q_count_traversing = 0;
+//	return avgtime;
+
+}
+
+#endif //TRI_COLLISION_PROFILING
+
+/////////////////////// btQuantizedBvhTree /////////////////////////////////
+
+void btQuantizedBvhTree::calc_quantization(
+	GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin)
+{
+	//calc globa box
+	btAABB global_bound;
+	global_bound.invalidate();
+
+	for (int i=0;i<primitive_boxes.size() ;i++ )
+	{
+		global_bound.merge(primitive_boxes[i].m_bound);
+	}
+
+	bt_calc_quantization_parameters(
+		m_global_bound.m_min,m_global_bound.m_max,m_bvhQuantization,global_bound.m_min,global_bound.m_max,boundMargin);
+
+}
+
+
+
+int btQuantizedBvhTree::_calc_splitting_axis(
+	GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,  int endIndex)
+{
+
+	int i;
+
+	btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
+	btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.));
+	int numIndices = endIndex-startIndex;
+
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
+					 primitive_boxes[i].m_bound.m_min);
+		means+=center;
+	}
+	means *= (btScalar(1.)/(btScalar)numIndices);
+
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
+					 primitive_boxes[i].m_bound.m_min);
+		btVector3 diff2 = center-means;
+		diff2 = diff2 * diff2;
+		variance += diff2;
+	}
+	variance *= (btScalar(1.)/	((btScalar)numIndices-1)	);
+
+	return variance.maxAxis();
+}
+
+
+int btQuantizedBvhTree::_sort_and_calc_splitting_index(
+	GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,
+	int endIndex, int splitAxis)
+{
+	int i;
+	int splitIndex =startIndex;
+	int numIndices = endIndex - startIndex;
+
+	// average of centers
+	btScalar splitValue = 0.0f;
+
+	btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
+					 primitive_boxes[i].m_bound.m_min);
+		means+=center;
+	}
+	means *= (btScalar(1.)/(btScalar)numIndices);
+
+	splitValue = means[splitAxis];
+
+
+	//sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
+					 primitive_boxes[i].m_bound.m_min);
+		if (center[splitAxis] > splitValue)
+		{
+			//swap
+			primitive_boxes.swap(i,splitIndex);
+			//swapLeafNodes(i,splitIndex);
+			splitIndex++;
+		}
+	}
+
+	//if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex
+	//otherwise the tree-building might fail due to stack-overflows in certain cases.
+	//unbalanced1 is unsafe: it can cause stack overflows
+	//bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1)));
+
+	//unbalanced2 should work too: always use center (perfect balanced trees)
+	//bool unbalanced2 = true;
+
+	//this should be safe too:
+	int rangeBalancedIndices = numIndices/3;
+	bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices)));
+
+	if (unbalanced)
+	{
+		splitIndex = startIndex+ (numIndices>>1);
+	}
+
+	btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex))));
+
+	return splitIndex;
+
+}
+
+
+void btQuantizedBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,  int endIndex)
+{
+	int curIndex = m_num_nodes;
+	m_num_nodes++;
+
+	btAssert((endIndex-startIndex)>0);
+
+	if ((endIndex-startIndex)==1)
+	{
+	    //We have a leaf node
+	    setNodeBound(curIndex,primitive_boxes[startIndex].m_bound);
+		m_node_array[curIndex].setDataIndex(primitive_boxes[startIndex].m_data);
+
+		return;
+	}
+	//calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
+
+	//split axis
+	int splitIndex = _calc_splitting_axis(primitive_boxes,startIndex,endIndex);
+
+	splitIndex = _sort_and_calc_splitting_index(
+			primitive_boxes,startIndex,endIndex,
+			splitIndex//split axis
+			);
+
+
+	//calc this node bounding box
+
+	btAABB node_bound;
+	node_bound.invalidate();
+
+	for (int i=startIndex;i<endIndex;i++)
+	{
+		node_bound.merge(primitive_boxes[i].m_bound);
+	}
+
+	setNodeBound(curIndex,node_bound);
+
+
+	//build left branch
+	_build_sub_tree(primitive_boxes, startIndex, splitIndex );
+
+
+	//build right branch
+	 _build_sub_tree(primitive_boxes, splitIndex ,endIndex);
+
+	m_node_array[curIndex].setEscapeIndex(m_num_nodes - curIndex);
+
+
+}
+
+//! stackless build tree
+void btQuantizedBvhTree::build_tree(
+	GIM_BVH_DATA_ARRAY & primitive_boxes)
+{
+	calc_quantization(primitive_boxes);
+	// initialize node count to 0
+	m_num_nodes = 0;
+	// allocate nodes
+	m_node_array.resize(primitive_boxes.size()*2);
+
+	_build_sub_tree(primitive_boxes, 0, primitive_boxes.size());
+}
+
+////////////////////////////////////class btGImpactQuantizedBvh
+
+void btGImpactQuantizedBvh::refit()
+{
+	int nodecount = getNodeCount();
+	while(nodecount--)
+	{
+		if(isLeafNode(nodecount))
+		{
+			btAABB leafbox;
+			m_primitive_manager->get_primitive_box(getNodeData(nodecount),leafbox);
+			setNodeBound(nodecount,leafbox);
+		}
+		else
+		{
+			//const GIM_BVH_TREE_NODE * nodepointer = get_node_pointer(nodecount);
+			//get left bound
+			btAABB bound;
+			bound.invalidate();
+
+			btAABB temp_box;
+
+			int child_node = getLeftNode(nodecount);
+			if(child_node)
+			{
+				getNodeBound(child_node,temp_box);
+				bound.merge(temp_box);
+			}
+
+			child_node = getRightNode(nodecount);
+			if(child_node)
+			{
+				getNodeBound(child_node,temp_box);
+				bound.merge(temp_box);
+			}
+
+			setNodeBound(nodecount,bound);
+		}
+	}
+}
+
+//! this rebuild the entire set
+void btGImpactQuantizedBvh::buildSet()
+{
+	//obtain primitive boxes
+	GIM_BVH_DATA_ARRAY primitive_boxes;
+	primitive_boxes.resize(m_primitive_manager->get_primitive_count());
+
+	for (int i = 0;i<primitive_boxes.size() ;i++ )
+	{
+		 m_primitive_manager->get_primitive_box(i,primitive_boxes[i].m_bound);
+		 primitive_boxes[i].m_data = i;
+	}
+
+	m_box_tree.build_tree(primitive_boxes);
+}
+
+//! returns the indices of the primitives in the m_primitive_manager
+bool btGImpactQuantizedBvh::boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const
+{
+	int curIndex = 0;
+	int numNodes = getNodeCount();
+
+	//quantize box
+
+	unsigned short quantizedMin[3];
+	unsigned short quantizedMax[3];
+
+	m_box_tree.quantizePoint(quantizedMin,box.m_min);
+	m_box_tree.quantizePoint(quantizedMax,box.m_max);
+
+
+	while (curIndex < numNodes)
+	{
+
+		//catch bugs in tree data
+
+		bool aabbOverlap = m_box_tree.testQuantizedBoxOverlapp(curIndex, quantizedMin,quantizedMax);
+		bool isleafnode = isLeafNode(curIndex);
+
+		if (isleafnode && aabbOverlap)
+		{
+			collided_results.push_back(getNodeData(curIndex));
+		}
+
+		if (aabbOverlap || isleafnode)
+		{
+			//next subnode
+			curIndex++;
+		}
+		else
+		{
+			//skip node
+			curIndex+= getEscapeNodeIndex(curIndex);
+		}
+	}
+	if(collided_results.size()>0) return true;
+	return false;
+}
+
+
+
+//! returns the indices of the primitives in the m_primitive_manager
+bool btGImpactQuantizedBvh::rayQuery(
+	const btVector3 & ray_dir,const btVector3 & ray_origin ,
+	btAlignedObjectArray<int> & collided_results) const
+{
+	int curIndex = 0;
+	int numNodes = getNodeCount();
+
+	while (curIndex < numNodes)
+	{
+		btAABB bound;
+		getNodeBound(curIndex,bound);
+
+		//catch bugs in tree data
+
+		bool aabbOverlap = bound.collide_ray(ray_origin,ray_dir);
+		bool isleafnode = isLeafNode(curIndex);
+
+		if (isleafnode && aabbOverlap)
+		{
+			collided_results.push_back(getNodeData( curIndex));
+		}
+
+		if (aabbOverlap || isleafnode)
+		{
+			//next subnode
+			curIndex++;
+		}
+		else
+		{
+			//skip node
+			curIndex+= getEscapeNodeIndex(curIndex);
+		}
+	}
+	if(collided_results.size()>0) return true;
+	return false;
+}
+
+
+SIMD_FORCE_INLINE bool _quantized_node_collision(
+	btGImpactQuantizedBvh * boxset0, btGImpactQuantizedBvh * boxset1,
+	const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0,
+	int node0 ,int node1, bool complete_primitive_tests)
+{
+	btAABB box0;
+	boxset0->getNodeBound(node0,box0);
+	btAABB box1;
+	boxset1->getNodeBound(node1,box1);
+
+	return box0.overlapping_trans_cache(box1,trans_cache_1to0,complete_primitive_tests );
+//	box1.appy_transform_trans_cache(trans_cache_1to0);
+//	return box0.has_collision(box1);
+
+}
+
+
+//stackless recursive collision routine
+static void _find_quantized_collision_pairs_recursive(
+	btGImpactQuantizedBvh * boxset0, btGImpactQuantizedBvh * boxset1,
+	btPairSet * collision_pairs,
+	const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0,
+	int node0, int node1, bool complete_primitive_tests)
+{
+
+
+
+	if( _quantized_node_collision(
+		boxset0,boxset1,trans_cache_1to0,
+		node0,node1,complete_primitive_tests) ==false) return;//avoid colliding internal nodes
+
+	if(boxset0->isLeafNode(node0))
+	{
+		if(boxset1->isLeafNode(node1))
+		{
+			// collision result
+			collision_pairs->push_pair(
+				boxset0->getNodeData(node0),boxset1->getNodeData(node1));
+			return;
+		}
+		else
+		{
+
+			//collide left recursive
+
+			_find_quantized_collision_pairs_recursive(
+								boxset0,boxset1,
+								collision_pairs,trans_cache_1to0,
+								node0,boxset1->getLeftNode(node1),false);
+
+			//collide right recursive
+			_find_quantized_collision_pairs_recursive(
+								boxset0,boxset1,
+								collision_pairs,trans_cache_1to0,
+								node0,boxset1->getRightNode(node1),false);
+
+
+		}
+	}
+	else
+	{
+		if(boxset1->isLeafNode(node1))
+		{
+
+			//collide left recursive
+			_find_quantized_collision_pairs_recursive(
+								boxset0,boxset1,
+								collision_pairs,trans_cache_1to0,
+								boxset0->getLeftNode(node0),node1,false);
+
+
+			//collide right recursive
+
+			_find_quantized_collision_pairs_recursive(
+								boxset0,boxset1,
+								collision_pairs,trans_cache_1to0,
+								boxset0->getRightNode(node0),node1,false);
+
+
+		}
+		else
+		{
+			//collide left0 left1
+
+
+
+			_find_quantized_collision_pairs_recursive(
+				boxset0,boxset1,
+				collision_pairs,trans_cache_1to0,
+				boxset0->getLeftNode(node0),boxset1->getLeftNode(node1),false);
+
+			//collide left0 right1
+
+			_find_quantized_collision_pairs_recursive(
+				boxset0,boxset1,
+				collision_pairs,trans_cache_1to0,
+				boxset0->getLeftNode(node0),boxset1->getRightNode(node1),false);
+
+
+			//collide right0 left1
+
+			_find_quantized_collision_pairs_recursive(
+				boxset0,boxset1,
+				collision_pairs,trans_cache_1to0,
+				boxset0->getRightNode(node0),boxset1->getLeftNode(node1),false);
+
+			//collide right0 right1
+
+			_find_quantized_collision_pairs_recursive(
+				boxset0,boxset1,
+				collision_pairs,trans_cache_1to0,
+				boxset0->getRightNode(node0),boxset1->getRightNode(node1),false);
+
+		}// else if node1 is not a leaf
+	}// else if node0 is not a leaf
+}
+
+
+void btGImpactQuantizedBvh::find_collision(btGImpactQuantizedBvh * boxset0, const btTransform & trans0,
+		btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
+		btPairSet & collision_pairs)
+{
+
+	if(boxset0->getNodeCount()==0 || boxset1->getNodeCount()==0 ) return;
+
+	BT_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0;
+
+	trans_cache_1to0.calc_from_homogenic(trans0,trans1);
+
+#ifdef TRI_COLLISION_PROFILING
+	bt_begin_gim02_q_tree_time();
+#endif //TRI_COLLISION_PROFILING
+
+	_find_quantized_collision_pairs_recursive(
+		boxset0,boxset1,
+		&collision_pairs,trans_cache_1to0,0,0,true);
+#ifdef TRI_COLLISION_PROFILING
+	bt_end_gim02_q_tree_time();
+#endif //TRI_COLLISION_PROFILING
+
+}
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactQuantizedBvh.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactQuantizedBvh.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactQuantizedBvh.h	(revision 6952)
@@ -0,0 +1,372 @@
+#ifndef GIM_QUANTIZED_SET_H_INCLUDED
+#define GIM_QUANTIZED_SET_H_INCLUDED
+
+/*! \file btGImpactQuantizedBvh.h
+\author Francisco Len Nßjera
+*/
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 "btGImpactBvh.h"
+#include "btQuantization.h"
+
+
+
+
+
+///btQuantizedBvhNode is a compressed aabb node, 16 bytes.
+///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range).
+ATTRIBUTE_ALIGNED16	(struct) BT_QUANTIZED_BVH_NODE
+{
+	//12 bytes
+	unsigned short int	m_quantizedAabbMin[3];
+	unsigned short int	m_quantizedAabbMax[3];
+	//4 bytes
+	int	m_escapeIndexOrDataIndex;
+
+	BT_QUANTIZED_BVH_NODE()
+	{
+		m_escapeIndexOrDataIndex = 0;
+	}
+
+	SIMD_FORCE_INLINE bool isLeafNode() const
+	{
+		//skipindex is negative (internal node), triangleindex >=0 (leafnode)
+		return (m_escapeIndexOrDataIndex>=0);
+	}
+
+	SIMD_FORCE_INLINE int getEscapeIndex() const
+	{
+		//btAssert(m_escapeIndexOrDataIndex < 0);
+		return -m_escapeIndexOrDataIndex;
+	}
+
+	SIMD_FORCE_INLINE void setEscapeIndex(int index)
+	{
+		m_escapeIndexOrDataIndex = -index;
+	}
+
+	SIMD_FORCE_INLINE int getDataIndex() const
+	{
+		//btAssert(m_escapeIndexOrDataIndex >= 0);
+
+		return m_escapeIndexOrDataIndex;
+	}
+
+	SIMD_FORCE_INLINE void setDataIndex(int index)
+	{
+		m_escapeIndexOrDataIndex = index;
+	}
+
+	SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp(
+		unsigned short * quantizedMin,unsigned short * quantizedMax) const
+	{
+		if(m_quantizedAabbMin[0] > quantizedMax[0] ||
+		   m_quantizedAabbMax[0] < quantizedMin[0] ||
+		   m_quantizedAabbMin[1] > quantizedMax[1] ||
+		   m_quantizedAabbMax[1] < quantizedMin[1] ||
+		   m_quantizedAabbMin[2] > quantizedMax[2] ||
+		   m_quantizedAabbMax[2] < quantizedMin[2])
+		{
+			return false;
+		}
+		return true;
+	}
+
+};
+
+
+
+class GIM_QUANTIZED_BVH_NODE_ARRAY:public btAlignedObjectArray<BT_QUANTIZED_BVH_NODE>
+{
+};
+
+
+
+
+//! Basic Box tree structure
+class btQuantizedBvhTree
+{
+protected:
+	int m_num_nodes;
+	GIM_QUANTIZED_BVH_NODE_ARRAY m_node_array;
+	btAABB m_global_bound;
+	btVector3 m_bvhQuantization;
+protected:
+	void calc_quantization(GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin = btScalar(1.0) );
+
+	int _sort_and_calc_splitting_index(
+		GIM_BVH_DATA_ARRAY & primitive_boxes,
+		 int startIndex,  int endIndex, int splitAxis);
+
+	int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,  int endIndex);
+
+	void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex,  int endIndex);
+public:
+	btQuantizedBvhTree()
+	{
+		m_num_nodes = 0;
+	}
+
+	//! prototype functions for box tree management
+	//!@{
+	void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes);
+
+	SIMD_FORCE_INLINE void quantizePoint(
+		unsigned short * quantizedpoint, const btVector3 & point) const
+	{
+		bt_quantize_clamp(quantizedpoint,point,m_global_bound.m_min,m_global_bound.m_max,m_bvhQuantization);
+	}
+
+
+	SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp(
+		int node_index,
+		unsigned short * quantizedMin,unsigned short * quantizedMax) const
+	{
+		return m_node_array[node_index].testQuantizedBoxOverlapp(quantizedMin,quantizedMax);
+	}
+
+	SIMD_FORCE_INLINE void clearNodes()
+	{
+		m_node_array.clear();
+		m_num_nodes = 0;
+	}
+
+	//! node count
+	SIMD_FORCE_INLINE int getNodeCount() const
+	{
+		return m_num_nodes;
+	}
+
+	//! tells if the node is a leaf
+	SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const
+	{
+		return m_node_array[nodeindex].isLeafNode();
+	}
+
+	SIMD_FORCE_INLINE int getNodeData(int nodeindex) const
+	{
+		return m_node_array[nodeindex].getDataIndex();
+	}
+
+	SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const
+	{
+		bound.m_min = bt_unquantize(
+			m_node_array[nodeindex].m_quantizedAabbMin,
+			m_global_bound.m_min,m_bvhQuantization);
+
+		bound.m_max = bt_unquantize(
+			m_node_array[nodeindex].m_quantizedAabbMax,
+			m_global_bound.m_min,m_bvhQuantization);
+	}
+
+	SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
+	{
+		bt_quantize_clamp(	m_node_array[nodeindex].m_quantizedAabbMin,
+							bound.m_min,
+							m_global_bound.m_min,
+							m_global_bound.m_max,
+							m_bvhQuantization);
+
+		bt_quantize_clamp(	m_node_array[nodeindex].m_quantizedAabbMax,
+							bound.m_max,
+							m_global_bound.m_min,
+							m_global_bound.m_max,
+							m_bvhQuantization);
+	}
+
+	SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
+	{
+		return nodeindex+1;
+	}
+
+	SIMD_FORCE_INLINE int getRightNode(int nodeindex) const
+	{
+		if(m_node_array[nodeindex+1].isLeafNode()) return nodeindex+2;
+		return nodeindex+1 + m_node_array[nodeindex+1].getEscapeIndex();
+	}
+
+	SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const
+	{
+		return m_node_array[nodeindex].getEscapeIndex();
+	}
+
+	SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const
+	{
+		return &m_node_array[index];
+	}
+
+	//!@}
+};
+
+
+
+//! Structure for containing Boxes
+/*!
+This class offers an structure for managing a box tree of primitives.
+Requires a Primitive prototype (like btPrimitiveManagerBase )
+*/
+class btGImpactQuantizedBvh
+{
+protected:
+	btQuantizedBvhTree m_box_tree;
+	btPrimitiveManagerBase * m_primitive_manager;
+
+protected:
+	//stackless refit
+	void refit();
+public:
+
+	//! this constructor doesn't build the tree. you must call	buildSet
+	btGImpactQuantizedBvh()
+	{
+		m_primitive_manager = NULL;
+	}
+
+	//! this constructor doesn't build the tree. you must call	buildSet
+	btGImpactQuantizedBvh(btPrimitiveManagerBase * primitive_manager)
+	{
+		m_primitive_manager = primitive_manager;
+	}
+
+	SIMD_FORCE_INLINE btAABB getGlobalBox()  const
+	{
+		btAABB totalbox;
+		getNodeBound(0, totalbox);
+		return totalbox;
+	}
+
+	SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase * primitive_manager)
+	{
+		m_primitive_manager = primitive_manager;
+	}
+
+	SIMD_FORCE_INLINE btPrimitiveManagerBase * getPrimitiveManager() const
+	{
+		return m_primitive_manager;
+	}
+
+
+//! node manager prototype functions
+///@{
+
+	//! this attemps to refit the box set.
+	SIMD_FORCE_INLINE void update()
+	{
+		refit();
+	}
+
+	//! this rebuild the entire set
+	void buildSet();
+
+	//! returns the indices of the primitives in the m_primitive_manager
+	bool boxQuery(const btAABB & box, btAlignedObjectArray<int> & collided_results) const;
+
+	//! returns the indices of the primitives in the m_primitive_manager
+	SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB & box,
+		 const btTransform & transform, btAlignedObjectArray<int> & collided_results) const
+	{
+		btAABB transbox=box;
+		transbox.appy_transform(transform);
+		return boxQuery(transbox,collided_results);
+	}
+
+	//! returns the indices of the primitives in the m_primitive_manager
+	bool rayQuery(
+		const btVector3 & ray_dir,const btVector3 & ray_origin ,
+		btAlignedObjectArray<int> & collided_results) const;
+
+	//! tells if this set has hierarcht
+	SIMD_FORCE_INLINE bool hasHierarchy() const
+	{
+		return true;
+	}
+
+	//! tells if this set is a trimesh
+	SIMD_FORCE_INLINE bool isTrimesh()  const
+	{
+		return m_primitive_manager->is_trimesh();
+	}
+
+	//! node count
+	SIMD_FORCE_INLINE int getNodeCount() const
+	{
+		return m_box_tree.getNodeCount();
+	}
+
+	//! tells if the node is a leaf
+	SIMD_FORCE_INLINE bool isLeafNode(int nodeindex) const
+	{
+		return m_box_tree.isLeafNode(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE int getNodeData(int nodeindex) const
+	{
+		return m_box_tree.getNodeData(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound)  const
+	{
+		m_box_tree.getNodeBound(nodeindex, bound);
+	}
+
+	SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound)
+	{
+		m_box_tree.setNodeBound(nodeindex, bound);
+	}
+
+
+	SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const
+	{
+		return m_box_tree.getLeftNode(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE int getRightNode(int nodeindex) const
+	{
+		return m_box_tree.getRightNode(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const
+	{
+		return m_box_tree.getEscapeNodeIndex(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex,btPrimitiveTriangle & triangle) const
+	{
+		m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex),triangle);
+	}
+
+
+	SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const
+	{
+		return m_box_tree.get_node_pointer(index);
+	}
+
+
+	static float getAverageTreeCollisionTime();
+
+
+	static void find_collision(btGImpactQuantizedBvh * boxset1, const btTransform & trans1,
+		btGImpactQuantizedBvh * boxset2, const btTransform & trans2,
+		btPairSet & collision_pairs);
+};
+
+
+#endif // GIM_BOXPRUNING_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactShape.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactShape.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactShape.cpp	(revision 6952)
@@ -0,0 +1,183 @@
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 "btGImpactShape.h"
+#include "btGImpactMassUtil.h"
+
+
+#define CALC_EXACT_INERTIA 1
+
+void btGImpactCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+	lockChildShapes();
+#ifdef CALC_EXACT_INERTIA
+	inertia.setValue(0.f,0.f,0.f);
+
+	int i = this->getNumChildShapes();
+	btScalar shapemass = mass/btScalar(i);
+
+	while(i--)
+	{
+		btVector3 temp_inertia;
+		m_childShapes[i]->calculateLocalInertia(shapemass,temp_inertia);
+		if(childrenHasTransform())
+		{
+			inertia = gim_inertia_add_transformed( inertia,temp_inertia,m_childTransforms[i]);
+		}
+		else
+		{
+			inertia = gim_inertia_add_transformed( inertia,temp_inertia,btTransform::getIdentity());
+		}
+
+	}
+
+#else
+
+	// Calc box inertia
+
+	btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
+	btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
+	btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
+	const btScalar x2 = lx*lx;
+	const btScalar y2 = ly*ly;
+	const btScalar z2 = lz*lz;
+	const btScalar scaledmass = mass * btScalar(0.08333333);
+
+	inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
+
+#endif
+	unlockChildShapes();
+}
+
+
+
+void btGImpactMeshShapePart::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+	lockChildShapes();
+
+
+#ifdef CALC_EXACT_INERTIA
+	inertia.setValue(0.f,0.f,0.f);
+
+	int i = this->getVertexCount();
+	btScalar pointmass = mass/btScalar(i);
+
+	while(i--)
+	{
+		btVector3 pointintertia;
+		this->getVertex(i,pointintertia);
+		pointintertia = gim_get_point_inertia(pointintertia,pointmass);
+		inertia+=pointintertia;
+	}
+
+#else
+
+	// Calc box inertia
+
+	btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
+	btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
+	btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
+	const btScalar x2 = lx*lx;
+	const btScalar y2 = ly*ly;
+	const btScalar z2 = lz*lz;
+	const btScalar scaledmass = mass * btScalar(0.08333333);
+
+	inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
+
+#endif
+
+	unlockChildShapes();
+}
+
+void btGImpactMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const
+{
+
+#ifdef CALC_EXACT_INERTIA
+	inertia.setValue(0.f,0.f,0.f);
+
+	int i = this->getMeshPartCount();
+	btScalar partmass = mass/btScalar(i);
+
+	while(i--)
+	{
+		btVector3 partinertia;
+		getMeshPart(i)->calculateLocalInertia(partmass,partinertia);
+		inertia+=partinertia;
+	}
+
+#else
+
+	// Calc box inertia
+
+	btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0];
+	btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1];
+	btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2];
+	const btScalar x2 = lx*lx;
+	const btScalar y2 = ly*ly;
+	const btScalar z2 = lz*lz;
+	const btScalar scaledmass = mass * btScalar(0.08333333);
+
+	inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2));
+
+#endif
+}
+
+void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const
+{
+}
+
+
+void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+	lockChildShapes();
+	btAABB box;
+	box.m_min = aabbMin;
+	box.m_max = aabbMax;
+
+	btAlignedObjectArray<int> collided;
+	m_box_set.boxQuery(box,collided);
+
+	if(collided.size()==0)
+	{
+		unlockChildShapes();
+		return;
+	}
+
+	int part = (int)getPart();
+	btPrimitiveTriangle triangle;
+	int i = collided.size();
+	while(i--)
+	{
+		this->getPrimitiveTriangle(collided[i],triangle);
+		callback->processTriangle(triangle.m_vertices,part,collided[i]);
+	}
+	unlockChildShapes();
+
+}
+
+void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
+{
+	int i = m_mesh_parts.size();
+	while(i--)
+	{
+		m_mesh_parts[i]->processAllTriangles(callback,aabbMin,aabbMax);
+	}
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactShape.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactShape.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGImpactShape.h	(revision 6952)
@@ -0,0 +1,1122 @@
+/*! \file btGImpactShape.h
+\author Francisco Len Nßjera
+*/
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 GIMPACT_SHAPE_H
+#define GIMPACT_SHAPE_H
+
+#include "BulletCollision/CollisionShapes/btCollisionShape.h"
+#include "BulletCollision/CollisionShapes/btTriangleShape.h"
+#include "BulletCollision/CollisionShapes/btStridingMeshInterface.h"
+#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
+#include "BulletCollision/CollisionShapes/btConcaveShape.h"
+#include "BulletCollision/CollisionShapes/btTetrahedronShape.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btMatrix3x3.h"
+#include "LinearMath/btAlignedObjectArray.h"
+
+#include "btGImpactQuantizedBvh.h" // box tree class
+
+
+//! declare Quantized trees, (you can change to float based trees)
+typedef btGImpactQuantizedBvh btGImpactBoxSet;
+
+enum eGIMPACT_SHAPE_TYPE
+{
+	CONST_GIMPACT_COMPOUND_SHAPE = 0,
+	CONST_GIMPACT_TRIMESH_SHAPE_PART,
+	CONST_GIMPACT_TRIMESH_SHAPE
+};
+
+
+//! Helper class for tetrahedrons
+class btTetrahedronShapeEx:public btBU_Simplex1to4
+{
+public:
+	btTetrahedronShapeEx()
+	{
+		m_numVertices = 4;
+	}
+
+
+	SIMD_FORCE_INLINE void setVertices(
+		const btVector3 & v0,const btVector3 & v1,
+		const btVector3 & v2,const btVector3 & v3)
+	{
+		m_vertices[0] = v0;
+		m_vertices[1] = v1;
+		m_vertices[2] = v2;
+		m_vertices[3] = v3;
+		recalcLocalAabb();
+	}
+};
+
+
+//! Base class for gimpact shapes
+class btGImpactShapeInterface : public btConcaveShape
+{
+protected:
+    btAABB m_localAABB;
+    bool m_needs_update;
+    btVector3  localScaling;
+    btGImpactBoxSet m_box_set;// optionally boxset
+
+	//! use this function for perfofm refit in bounding boxes
+    //! use this function for perfofm refit in bounding boxes
+    virtual void calcLocalAABB()
+    {
+		lockChildShapes();
+    	if(m_box_set.getNodeCount() == 0)
+    	{
+    		m_box_set.buildSet();
+    	}
+    	else
+    	{
+    		m_box_set.update();
+    	}
+    	unlockChildShapes();
+
+    	m_localAABB = m_box_set.getGlobalBox();
+    }
+
+
+public:
+	btGImpactShapeInterface()
+	{
+		m_shapeType=GIMPACT_SHAPE_PROXYTYPE;
+		m_localAABB.invalidate();
+		m_needs_update = true;
+		localScaling.setValue(1.f,1.f,1.f);
+	}
+
+
+	//! performs refit operation
+	/*!
+	Updates the entire Box set of this shape.
+	\pre postUpdate() must be called for attemps to calculating the box set, else this function
+		will does nothing.
+	\post if m_needs_update == true, then it calls calcLocalAABB();
+	*/
+    SIMD_FORCE_INLINE void updateBound()
+    {
+    	if(!m_needs_update) return;
+    	calcLocalAABB();
+    	m_needs_update  = false;
+    }
+
+    //! If the Bounding box is not updated, then this class attemps to calculate it.
+    /*!
+    \post Calls updateBound() for update the box set.
+    */
+    void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+    {
+        btAABB transformedbox = m_localAABB;
+        transformedbox.appy_transform(t);
+        aabbMin = transformedbox.m_min;
+        aabbMax = transformedbox.m_max;
+    }
+
+    //! Tells to this object that is needed to refit the box set
+    virtual void postUpdate()
+    {
+    	m_needs_update = true;
+    }
+
+	//! Obtains the local box, which is the global calculated box of the total of subshapes
+	SIMD_FORCE_INLINE const btAABB & getLocalBox()
+	{
+		return m_localAABB;
+	}
+
+
+    virtual int	getShapeType() const
+    {
+        return GIMPACT_SHAPE_PROXYTYPE;
+    }
+
+    /*!
+	\post You must call updateBound() for update the box set.
+	*/
+	virtual void	setLocalScaling(const btVector3& scaling)
+	{
+		localScaling = scaling;
+		postUpdate();
+	}
+
+	virtual const btVector3& getLocalScaling() const
+	{
+		return localScaling;
+	}
+
+
+	virtual void setMargin(btScalar margin)
+    {
+    	m_collisionMargin = margin;
+    	int i = getNumChildShapes();
+    	while(i--)
+    	{
+			btCollisionShape* child = getChildShape(i);
+			child->setMargin(margin);
+    	}
+
+		m_needs_update = true;
+    }
+
+
+	//! Subshape member functions
+	//!@{
+
+	//! Base method for determinig which kind of GIMPACT shape we get
+	virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() = 0;
+
+	//! gets boxset
+	SIMD_FORCE_INLINE btGImpactBoxSet * getBoxSet()
+	{
+		return &m_box_set;
+	}
+
+	//! Determines if this class has a hierarchy structure for sorting its primitives
+	SIMD_FORCE_INLINE bool hasBoxSet()  const
+	{
+		if(m_box_set.getNodeCount() == 0) return false;
+		return true;
+	}
+
+	//! Obtains the primitive manager
+	virtual const btPrimitiveManagerBase * getPrimitiveManager()  const = 0;
+
+
+	//! Gets the number of children
+	virtual int	getNumChildShapes() const  = 0;
+
+	//! if true, then its children must get transforms.
+	virtual bool childrenHasTransform() const = 0;
+
+	//! Determines if this shape has triangles
+	virtual bool needsRetrieveTriangles() const = 0;
+
+	//! Determines if this shape has tetrahedrons
+	virtual bool needsRetrieveTetrahedrons() const = 0;
+
+	virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const = 0;
+
+	virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const = 0;
+
+
+
+	//! call when reading child shapes
+	virtual void lockChildShapes() const
+	{
+	}
+
+	virtual void unlockChildShapes() const
+	{
+	}
+
+	//! if this trimesh
+	SIMD_FORCE_INLINE void getPrimitiveTriangle(int index,btPrimitiveTriangle & triangle) const
+	{
+		getPrimitiveManager()->get_primitive_triangle(index,triangle);
+	}
+
+
+	//! Retrieves the bound from a child
+    /*!
+    */
+    virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+    {
+        btAABB child_aabb;
+        getPrimitiveManager()->get_primitive_box(child_index,child_aabb);
+        child_aabb.appy_transform(t);
+        aabbMin = child_aabb.m_min;
+        aabbMax = child_aabb.m_max;
+    }
+
+	//! Gets the children
+	virtual btCollisionShape* getChildShape(int index) = 0;
+
+
+	//! Gets the child
+	virtual const btCollisionShape* getChildShape(int index) const = 0;
+
+	//! Gets the children transform
+	virtual btTransform	getChildTransform(int index) const = 0;
+
+	//! Sets the children transform
+	/*!
+	\post You must call updateBound() for update the box set.
+	*/
+	virtual void setChildTransform(int index, const btTransform & transform) = 0;
+
+	//!@}
+
+
+	//! virtual method for ray collision
+	virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback)  const
+	{
+	}
+
+	//! Function for retrieve triangles.
+	/*!
+	It gives the triangles in local space
+	*/
+	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
+	{
+	}
+
+	//!@}
+
+};
+
+
+//! btGImpactCompoundShape allows to handle multiple btCollisionShape objects at once
+/*!
+This class only can manage Convex subshapes
+*/
+class btGImpactCompoundShape	: public btGImpactShapeInterface
+{
+public:
+	//! compound primitive manager
+	class CompoundPrimitiveManager:public btPrimitiveManagerBase
+	{
+	public:
+		btGImpactCompoundShape * m_compoundShape;
+
+
+		CompoundPrimitiveManager(const CompoundPrimitiveManager& compound)
+		{
+			m_compoundShape = compound.m_compoundShape;
+		}
+
+		CompoundPrimitiveManager(btGImpactCompoundShape * compoundShape)
+		{
+			m_compoundShape = compoundShape;
+		}
+
+		CompoundPrimitiveManager()
+		{
+			m_compoundShape = NULL;
+		}
+
+		virtual bool is_trimesh() const
+		{
+			return false;
+		}
+
+		virtual int get_primitive_count() const
+		{
+			return (int )m_compoundShape->getNumChildShapes();
+		}
+
+		virtual void get_primitive_box(int prim_index ,btAABB & primbox) const
+		{
+			btTransform prim_trans;
+			if(m_compoundShape->childrenHasTransform())
+			{
+				prim_trans = m_compoundShape->getChildTransform(prim_index);
+			}
+			else
+			{
+				prim_trans.setIdentity();
+			}
+			const btCollisionShape* shape = m_compoundShape->getChildShape(prim_index);
+			shape->getAabb(prim_trans,primbox.m_min,primbox.m_max);
+		}
+
+		virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const
+		{
+			btAssert(0);
+		}
+
+	};
+
+
+
+protected:
+	CompoundPrimitiveManager m_primitive_manager;
+	btAlignedObjectArray<btTransform>		m_childTransforms;
+	btAlignedObjectArray<btCollisionShape*>	m_childShapes;
+
+
+public:
+
+	btGImpactCompoundShape(bool children_has_transform = true)
+	{
+		m_primitive_manager.m_compoundShape = this;
+		m_box_set.setPrimitiveManager(&m_primitive_manager);
+	}
+
+	virtual ~btGImpactCompoundShape()
+	{
+	}
+
+
+	//! if true, then its children must get transforms.
+	virtual bool childrenHasTransform() const
+	{
+		if(m_childTransforms.size()==0) return false;
+		return true;
+	}
+
+
+	//! Obtains the primitive manager
+	virtual const btPrimitiveManagerBase * getPrimitiveManager()  const
+	{
+		return &m_primitive_manager;
+	}
+
+	//! Obtains the compopund primitive manager
+	SIMD_FORCE_INLINE CompoundPrimitiveManager * getCompoundPrimitiveManager()
+	{
+		return &m_primitive_manager;
+	}
+
+	//! Gets the number of children
+	virtual int	getNumChildShapes() const
+	{
+		return m_childShapes.size();
+	}
+
+
+	//! Use this method for adding children. Only Convex shapes are allowed.
+	void addChildShape(const btTransform& localTransform,btCollisionShape* shape)
+	{
+		btAssert(shape->isConvex());
+		m_childTransforms.push_back(localTransform);
+		m_childShapes.push_back(shape);
+	}
+
+	//! Use this method for adding children. Only Convex shapes are allowed.
+	void addChildShape(btCollisionShape* shape)
+	{
+		btAssert(shape->isConvex());
+		m_childShapes.push_back(shape);
+	}
+
+	//! Gets the children
+	virtual btCollisionShape* getChildShape(int index)
+	{
+		return m_childShapes[index];
+	}
+
+	//! Gets the children
+	virtual const btCollisionShape* getChildShape(int index) const
+	{
+		return m_childShapes[index];
+	}
+
+	//! Retrieves the bound from a child
+    /*!
+    */
+    virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+    {
+
+    	if(childrenHasTransform())
+    	{
+    		m_childShapes[child_index]->getAabb(t*m_childTransforms[child_index],aabbMin,aabbMax);
+    	}
+    	else
+    	{
+    		m_childShapes[child_index]->getAabb(t,aabbMin,aabbMax);
+    	}
+    }
+
+
+	//! Gets the children transform
+	virtual btTransform	getChildTransform(int index) const
+	{
+		btAssert(m_childTransforms.size() == m_childShapes.size());
+		return m_childTransforms[index];
+	}
+
+	//! Sets the children transform
+	/*!
+	\post You must call updateBound() for update the box set.
+	*/
+	virtual void setChildTransform(int index, const btTransform & transform)
+	{
+		btAssert(m_childTransforms.size() == m_childShapes.size());
+		m_childTransforms[index] = transform;
+		postUpdate();
+	}
+
+	//! Determines if this shape has triangles
+	virtual bool needsRetrieveTriangles() const
+	{
+		return false;
+	}
+
+	//! Determines if this shape has tetrahedrons
+	virtual bool needsRetrieveTetrahedrons() const
+	{
+		return false;
+	}
+
+
+	virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
+	{
+		btAssert(0);
+	}
+
+	virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
+	{
+		btAssert(0);
+	}
+
+
+	//! Calculates the exact inertia tensor for this shape
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
+	virtual const char*	getName()const
+	{
+		return "GImpactCompound";
+	}
+
+	virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType()
+	{
+		return CONST_GIMPACT_COMPOUND_SHAPE;
+	}
+
+};
+
+
+
+//! This class manages a sub part of a mesh supplied by the btStridingMeshInterface interface.
+/*!
+- Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShapePart, then you must call updateBound() after creating the mesh
+- When making operations with this shape, you must call <b>lock</b> before accessing to the trimesh primitives, and then call <b>unlock</b>
+- You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices.
+
+*/
+class btGImpactMeshShapePart : public btGImpactShapeInterface
+{
+public:
+	//! Trimesh primitive manager
+	/*!
+	Manages the info from btStridingMeshInterface object and controls the Lock/Unlock mechanism
+	*/
+	class TrimeshPrimitiveManager:public btPrimitiveManagerBase
+	{
+	public:
+		btScalar m_margin;
+		btStridingMeshInterface * m_meshInterface;
+		btVector3 m_scale;
+		int m_part;
+		int m_lock_count;
+		const unsigned char *vertexbase;
+		int numverts;
+		PHY_ScalarType type;
+		int stride;
+		const unsigned char *indexbase;
+		int indexstride;
+		int  numfaces;
+		PHY_ScalarType indicestype;
+
+		TrimeshPrimitiveManager()
+		{
+			m_meshInterface = NULL;
+			m_part = 0;
+			m_margin = 0.01f;
+			m_scale = btVector3(1.f,1.f,1.f);
+			m_lock_count = 0;
+			vertexbase = 0;
+			numverts = 0;
+			stride = 0;
+			indexbase = 0;
+			indexstride = 0;
+			numfaces = 0;
+		}
+
+ 		TrimeshPrimitiveManager(const TrimeshPrimitiveManager & manager)
+		{
+			m_meshInterface = manager.m_meshInterface;
+			m_part = manager.m_part;
+			m_margin = manager.m_margin;
+			m_scale = manager.m_scale;
+			m_lock_count = 0;
+			vertexbase = 0;
+			numverts = 0;
+			stride = 0;
+			indexbase = 0;
+			indexstride = 0;
+			numfaces = 0;
+
+		}
+
+		TrimeshPrimitiveManager(
+			btStridingMeshInterface * meshInterface,	int part)
+		{
+			m_meshInterface = meshInterface;
+			m_part = part;
+			m_scale = m_meshInterface->getScaling();
+			m_margin = 0.1f;
+			m_lock_count = 0;
+			vertexbase = 0;
+			numverts = 0;
+			stride = 0;
+			indexbase = 0;
+			indexstride = 0;
+			numfaces = 0;
+
+		}
+
+
+		void lock()
+		{
+			if(m_lock_count>0)
+			{
+				m_lock_count++;
+				return;
+			}
+			m_meshInterface->getLockedReadOnlyVertexIndexBase(
+				&vertexbase,numverts,
+				type, stride,&indexbase, indexstride, numfaces,indicestype,m_part);
+
+			m_lock_count = 1;
+		}
+
+		void unlock()
+		{
+			if(m_lock_count == 0) return;
+			if(m_lock_count>1)
+			{
+				--m_lock_count;
+				return;
+			}
+			m_meshInterface->unLockReadOnlyVertexBase(m_part);
+			vertexbase = NULL;
+			m_lock_count = 0;
+		}
+
+		virtual bool is_trimesh() const
+		{
+			return true;
+		}
+
+		virtual int get_primitive_count() const
+		{
+			return (int )numfaces;
+		}
+
+		SIMD_FORCE_INLINE int get_vertex_count() const
+		{
+			return (int )numverts;
+		}
+
+		SIMD_FORCE_INLINE void get_indices(int face_index,int &i0,int &i1,int &i2) const
+		{
+			if(indicestype == PHY_SHORT)
+			{
+				short * s_indices = (short *)(indexbase + face_index*indexstride);
+				i0 = s_indices[0];
+				i1 = s_indices[1];
+				i2 = s_indices[2];
+			}
+			else
+			{
+				int * i_indices = (int *)(indexbase + face_index*indexstride);
+				i0 = i_indices[0];
+				i1 = i_indices[1];
+				i2 = i_indices[2];
+			}
+		}
+
+		SIMD_FORCE_INLINE void get_vertex(int vertex_index, btVector3 & vertex) const
+		{
+			if(type == PHY_DOUBLE)
+			{
+				double * dvertices = (double *)(vertexbase + vertex_index*stride);
+				vertex[0] = btScalar(dvertices[0]*m_scale[0]);
+				vertex[1] = btScalar(dvertices[1]*m_scale[1]);
+				vertex[2] = btScalar(dvertices[2]*m_scale[2]);
+			}
+			else
+			{
+				float * svertices = (float *)(vertexbase + vertex_index*stride);
+				vertex[0] = svertices[0]*m_scale[0];
+				vertex[1] = svertices[1]*m_scale[1];
+				vertex[2] = svertices[2]*m_scale[2];
+			}
+		}
+
+		virtual void get_primitive_box(int prim_index ,btAABB & primbox) const
+		{
+			btPrimitiveTriangle  triangle;
+			get_primitive_triangle(prim_index,triangle);
+			primbox.calc_from_triangle_margin(
+				triangle.m_vertices[0],
+				triangle.m_vertices[1],triangle.m_vertices[2],triangle.m_margin);
+		}
+
+		virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const
+		{
+			int indices[3];
+			get_indices(prim_index,indices[0],indices[1],indices[2]);
+			get_vertex(indices[0],triangle.m_vertices[0]);
+			get_vertex(indices[1],triangle.m_vertices[1]);
+			get_vertex(indices[2],triangle.m_vertices[2]);
+			triangle.m_margin = m_margin;
+		}
+
+		SIMD_FORCE_INLINE void get_bullet_triangle(int prim_index,btTriangleShapeEx & triangle) const
+		{
+			int indices[3];
+			get_indices(prim_index,indices[0],indices[1],indices[2]);
+			get_vertex(indices[0],triangle.m_vertices1[0]);
+			get_vertex(indices[1],triangle.m_vertices1[1]);
+			get_vertex(indices[2],triangle.m_vertices1[2]);
+			triangle.setMargin(m_margin);
+		}
+
+	};
+
+
+protected:
+	TrimeshPrimitiveManager m_primitive_manager;
+public:
+
+	btGImpactMeshShapePart()
+	{
+		m_box_set.setPrimitiveManager(&m_primitive_manager);
+	}
+
+
+	btGImpactMeshShapePart(btStridingMeshInterface * meshInterface,	int part)
+	{
+		m_primitive_manager.m_meshInterface = meshInterface;
+		m_primitive_manager.m_part = part;
+		m_box_set.setPrimitiveManager(&m_primitive_manager);
+	}
+
+	virtual ~btGImpactMeshShapePart()
+	{
+	}
+
+	//! if true, then its children must get transforms.
+	virtual bool childrenHasTransform() const
+	{
+		return false;
+	}
+
+
+	//! call when reading child shapes
+	virtual void lockChildShapes() const
+	{
+		void * dummy = (void*)(m_box_set.getPrimitiveManager());
+		TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>(dummy);
+		dummymanager->lock();
+	}
+
+	virtual void unlockChildShapes()  const
+	{
+		void * dummy = (void*)(m_box_set.getPrimitiveManager());
+		TrimeshPrimitiveManager * dummymanager = static_cast<TrimeshPrimitiveManager *>(dummy);
+		dummymanager->unlock();
+	}
+
+	//! Gets the number of children
+	virtual int	getNumChildShapes() const
+	{
+		return m_primitive_manager.get_primitive_count();
+	}
+
+
+	//! Gets the children
+	virtual btCollisionShape* getChildShape(int index)
+	{
+		btAssert(0);
+		return NULL;
+	}
+
+
+
+	//! Gets the child
+	virtual const btCollisionShape* getChildShape(int index) const
+	{
+		btAssert(0);
+		return NULL;
+	}
+
+	//! Gets the children transform
+	virtual btTransform	getChildTransform(int index) const
+	{
+		btAssert(0);
+		return btTransform();
+	}
+
+	//! Sets the children transform
+	/*!
+	\post You must call updateBound() for update the box set.
+	*/
+	virtual void setChildTransform(int index, const btTransform & transform)
+	{
+		btAssert(0);
+	}
+
+
+	//! Obtains the primitive manager
+	virtual const btPrimitiveManagerBase * getPrimitiveManager()  const
+	{
+		return &m_primitive_manager;
+	}
+
+	SIMD_FORCE_INLINE TrimeshPrimitiveManager * getTrimeshPrimitiveManager()
+	{
+		return &m_primitive_manager;
+	}
+
+
+
+
+
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
+
+
+
+	virtual const char*	getName()const
+	{
+		return "GImpactMeshShapePart";
+	}
+
+	virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType()
+	{
+		return CONST_GIMPACT_TRIMESH_SHAPE_PART;
+	}
+
+	//! Determines if this shape has triangles
+	virtual bool needsRetrieveTriangles() const
+	{
+		return true;
+	}
+
+	//! Determines if this shape has tetrahedrons
+	virtual bool needsRetrieveTetrahedrons() const
+	{
+		return false;
+	}
+
+	virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
+	{
+		m_primitive_manager.get_bullet_triangle(prim_index,triangle);
+	}
+
+	virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
+	{
+		btAssert(0);
+	}
+
+
+
+	SIMD_FORCE_INLINE int getVertexCount() const
+	{
+		return m_primitive_manager.get_vertex_count();
+	}
+
+	SIMD_FORCE_INLINE void getVertex(int vertex_index, btVector3 & vertex) const
+	{
+		m_primitive_manager.get_vertex(vertex_index,vertex);
+	}
+
+	SIMD_FORCE_INLINE void setMargin(btScalar margin)
+    {
+    	m_primitive_manager.m_margin = margin;
+    	postUpdate();
+    }
+
+    SIMD_FORCE_INLINE btScalar getMargin() const
+    {
+    	return m_primitive_manager.m_margin;
+    }
+
+    virtual void	setLocalScaling(const btVector3& scaling)
+    {
+    	m_primitive_manager.m_scale = scaling;
+    	postUpdate();
+    }
+
+    virtual const btVector3& getLocalScaling() const
+    {
+    	return m_primitive_manager.m_scale;
+    }
+
+    SIMD_FORCE_INLINE int getPart() const
+    {
+    	return (int)m_primitive_manager.m_part;
+    }
+
+	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+};
+
+
+//! This class manages a mesh supplied by the btStridingMeshInterface interface.
+/*!
+Set of btGImpactMeshShapePart parts
+- Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShape, then you must call updateBound() after creating the mesh
+
+- You can handle deformable meshes with this shape, by calling postUpdate() every time when changing the mesh vertices.
+
+*/
+class btGImpactMeshShape : public btGImpactShapeInterface
+{
+	btStridingMeshInterface* m_meshInterface;
+
+protected:
+	btAlignedObjectArray<btGImpactMeshShapePart*> m_mesh_parts;
+	void buildMeshParts(btStridingMeshInterface * meshInterface)
+	{
+		for (int i=0;i<meshInterface->getNumSubParts() ;++i )
+		{
+			btGImpactMeshShapePart * newpart = new btGImpactMeshShapePart(meshInterface,i);
+			m_mesh_parts.push_back(newpart);
+		}
+	}
+
+	//! use this function for perfofm refit in bounding boxes
+    virtual void calcLocalAABB()
+    {
+    	m_localAABB.invalidate();
+    	int i = m_mesh_parts.size();
+    	while(i--)
+    	{
+    		m_mesh_parts[i]->updateBound();
+    		m_localAABB.merge(m_mesh_parts[i]->getLocalBox());
+    	}
+    }
+
+public:
+	btGImpactMeshShape(btStridingMeshInterface * meshInterface)
+	{
+		m_meshInterface = meshInterface;
+		buildMeshParts(meshInterface);
+	}
+
+	virtual ~btGImpactMeshShape()
+	{
+		int i = m_mesh_parts.size();
+    	while(i--)
+    	{
+			btGImpactMeshShapePart * part = m_mesh_parts[i];
+			delete part;
+    	}
+		m_mesh_parts.clear();
+	}
+
+
+	btStridingMeshInterface* getMeshInterface()
+	{
+		return m_meshInterface;
+	}
+
+	const btStridingMeshInterface* getMeshInterface() const
+	{
+		return m_meshInterface;
+	}
+
+	int getMeshPartCount() const
+	{
+		return m_mesh_parts.size();
+	}
+
+	btGImpactMeshShapePart * getMeshPart(int index)
+	{
+		return m_mesh_parts[index];
+	}
+
+
+
+	const btGImpactMeshShapePart * getMeshPart(int index) const
+	{
+		return m_mesh_parts[index];
+	}
+
+
+	virtual void	setLocalScaling(const btVector3& scaling)
+	{
+		localScaling = scaling;
+
+		int i = m_mesh_parts.size();
+    	while(i--)
+    	{
+			btGImpactMeshShapePart * part = m_mesh_parts[i];
+			part->setLocalScaling(scaling);
+    	}
+
+		m_needs_update = true;
+	}
+
+	virtual void setMargin(btScalar margin)
+    {
+    	m_collisionMargin = margin;
+
+		int i = m_mesh_parts.size();
+    	while(i--)
+    	{
+			btGImpactMeshShapePart * part = m_mesh_parts[i];
+			part->setMargin(margin);
+    	}
+
+		m_needs_update = true;
+    }
+
+	//! Tells to this object that is needed to refit all the meshes
+    virtual void postUpdate()
+    {
+		int i = m_mesh_parts.size();
+    	while(i--)
+    	{
+			btGImpactMeshShapePart * part = m_mesh_parts[i];
+			part->postUpdate();
+    	}
+
+    	m_needs_update = true;
+    }
+
+	virtual void	calculateLocalInertia(btScalar mass,btVector3& inertia) const;
+
+
+	//! Obtains the primitive manager
+	virtual const btPrimitiveManagerBase * getPrimitiveManager()  const
+	{
+		btAssert(0);
+		return NULL;
+	}
+
+
+	//! Gets the number of children
+	virtual int	getNumChildShapes() const
+	{
+		btAssert(0);
+		return 0;
+	}
+
+
+	//! if true, then its children must get transforms.
+	virtual bool childrenHasTransform() const
+	{
+		btAssert(0);
+		return false;
+	}
+
+	//! Determines if this shape has triangles
+	virtual bool needsRetrieveTriangles() const
+	{
+		btAssert(0);
+		return false;
+	}
+
+	//! Determines if this shape has tetrahedrons
+	virtual bool needsRetrieveTetrahedrons() const
+	{
+		btAssert(0);
+		return false;
+	}
+
+	virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const
+	{
+		btAssert(0);
+	}
+
+	virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const
+	{
+		btAssert(0);
+	}
+
+	//! call when reading child shapes
+	virtual void lockChildShapes() const
+	{
+		btAssert(0);
+	}
+
+	virtual void unlockChildShapes() const
+	{
+		btAssert(0);
+	}
+
+
+
+
+	//! Retrieves the bound from a child
+    /*!
+    */
+    virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
+    {
+        btAssert(0);
+    }
+
+	//! Gets the children
+	virtual btCollisionShape* getChildShape(int index)
+	{
+		btAssert(0);
+		return NULL;
+	}
+
+
+	//! Gets the child
+	virtual const btCollisionShape* getChildShape(int index) const
+	{
+		btAssert(0);
+		return NULL;
+	}
+
+	//! Gets the children transform
+	virtual btTransform	getChildTransform(int index) const
+	{
+		btAssert(0);
+		return btTransform();
+	}
+
+	//! Sets the children transform
+	/*!
+	\post You must call updateBound() for update the box set.
+	*/
+	virtual void setChildTransform(int index, const btTransform & transform)
+	{
+		btAssert(0);
+	}
+
+
+	virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType()
+	{
+		return CONST_GIMPACT_TRIMESH_SHAPE;
+	}
+
+
+	virtual const char*	getName()const
+	{
+		return "GImpactMesh";
+	}
+
+	virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback)  const;
+
+	//! Function for retrieve triangles.
+	/*!
+	It gives the triangles in local space
+	*/
+	virtual void	processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const;
+};
+
+
+#endif //GIMPACT_MESH_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGenericPoolAllocator.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGenericPoolAllocator.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGenericPoolAllocator.cpp	(revision 6952)
@@ -0,0 +1,283 @@
+/*! \file btGenericPoolAllocator.cpp
+\author Francisco Len Nßjera. email projectileman@yahoo.com
+
+General purpose allocator class
+*/
+/*
+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 "btGenericPoolAllocator.h"
+
+
+
+/// *************** btGenericMemoryPool ******************///////////
+
+size_t btGenericMemoryPool::allocate_from_free_nodes(size_t num_elements)
+{
+	size_t ptr = BT_UINT_MAX;
+
+	if(m_free_nodes_count == 0) return BT_UINT_MAX;
+	// find an avaliable free node with the correct size
+	size_t revindex = m_free_nodes_count;
+
+	while(revindex-- && ptr == BT_UINT_MAX)
+	{
+		if(m_allocated_sizes[m_free_nodes[revindex]]>=num_elements)
+		{
+			ptr = revindex;
+		}
+	}
+	if(ptr == BT_UINT_MAX) return BT_UINT_MAX; // not found
+
+
+	revindex = ptr;
+	ptr = m_free_nodes[revindex];
+	// post: ptr contains the node index, and revindex the index in m_free_nodes
+
+	size_t  finalsize = m_allocated_sizes[ptr];
+	finalsize -= num_elements;
+
+	m_allocated_sizes[ptr] = num_elements;
+
+	// post: finalsize>=0, m_allocated_sizes[ptr] has the requested size
+
+	if(finalsize>0) // preserve free node, there are some free memory
+	{
+		m_free_nodes[revindex] = ptr + num_elements;
+		m_allocated_sizes[ptr + num_elements] = finalsize;
+	}
+	else // delete free node
+	{
+		// swap with end
+		m_free_nodes[revindex] = m_free_nodes[m_free_nodes_count-1];
+		m_free_nodes_count--;
+	}
+
+	return ptr;
+}
+
+size_t btGenericMemoryPool::allocate_from_pool(size_t num_elements)
+{
+	if(m_allocated_count+num_elements>m_max_element_count) return BT_UINT_MAX;
+
+	size_t ptr = m_allocated_count;
+
+	m_allocated_sizes[m_allocated_count] = num_elements;
+	m_allocated_count+=num_elements;
+
+	return ptr;
+}
+
+
+void btGenericMemoryPool::init_pool(size_t element_size, size_t element_count)
+{
+	m_allocated_count = 0;
+	m_free_nodes_count = 0;
+
+	m_element_size = element_size;
+	m_max_element_count = element_count;
+
+
+
+
+	m_pool = (unsigned char *) btAlignedAlloc(m_element_size*m_max_element_count,16);
+	m_free_nodes = (size_t *) btAlignedAlloc(sizeof(size_t)*m_max_element_count,16);
+	m_allocated_sizes = (size_t *) btAlignedAlloc(sizeof(size_t)*m_max_element_count,16);
+
+	for (size_t i = 0;i< m_max_element_count;i++ )
+	{
+		m_allocated_sizes[i] = 0;
+	}
+}
+
+void btGenericMemoryPool::end_pool()
+{
+	btAlignedFree(m_pool);
+	btAlignedFree(m_free_nodes);
+	btAlignedFree(m_allocated_sizes);
+	m_allocated_count = 0;
+	m_free_nodes_count = 0;
+}
+
+
+//! Allocates memory in pool
+/*!
+\param size_bytes size in bytes of the buffer
+*/
+void * btGenericMemoryPool::allocate(size_t size_bytes)
+{
+
+	size_t module = size_bytes%m_element_size;
+	size_t element_count = size_bytes/m_element_size;
+	if(module>0) element_count++;
+
+	size_t alloc_pos = allocate_from_free_nodes(element_count);
+	// a free node is found
+	if(alloc_pos != BT_UINT_MAX)
+	{
+		return get_element_data(alloc_pos);
+	}
+	// allocate directly on pool
+	alloc_pos = allocate_from_pool(element_count);
+
+	if(alloc_pos == BT_UINT_MAX) return NULL; // not space
+	return get_element_data(alloc_pos);
+}
+
+bool btGenericMemoryPool::freeMemory(void * pointer)
+{
+	unsigned char * pointer_pos = (unsigned char *)pointer;
+	unsigned char * pool_pos = (unsigned char *)m_pool;
+	// calc offset
+	if(pointer_pos<pool_pos) return false;//other pool
+	size_t offset = size_t(pointer_pos - pool_pos);
+	if(offset>=get_pool_capacity()) return false;// far away
+
+	// find free position
+	m_free_nodes[m_free_nodes_count] = offset/m_element_size;
+	m_free_nodes_count++;
+	return true;
+}
+
+
+/// *******************! btGenericPoolAllocator *******************!///
+
+
+btGenericPoolAllocator::~btGenericPoolAllocator()
+{
+	// destroy pools
+	size_t i;
+	for (i=0;i<m_pool_count;i++)
+	{
+		m_pools[i]->end_pool();
+		btAlignedFree(m_pools[i]);
+	}
+}
+
+
+// creates a pool
+btGenericMemoryPool * btGenericPoolAllocator::push_new_pool()
+{
+	if(m_pool_count >= BT_DEFAULT_MAX_POOLS) return NULL;
+
+	btGenericMemoryPool * newptr = (btGenericMemoryPool *)btAlignedAlloc(sizeof(btGenericMemoryPool),16);
+
+	m_pools[m_pool_count] = newptr;
+
+	m_pools[m_pool_count]->init_pool(m_pool_element_size,m_pool_element_count);
+
+	m_pool_count++;
+	return newptr;
+}
+
+void * btGenericPoolAllocator::failback_alloc(size_t size_bytes)
+{
+
+	btGenericMemoryPool * pool = NULL;
+
+
+	if(size_bytes<=get_pool_capacity())
+	{
+		pool = 	push_new_pool();
+	}
+
+	if(pool==NULL) // failback
+	{
+		return btAlignedAlloc(size_bytes,16);
+	}
+
+	return pool->allocate(size_bytes);
+}
+
+bool btGenericPoolAllocator::failback_free(void * pointer)
+{
+	btAlignedFree(pointer);
+	return true;
+}
+
+
+//! Allocates memory in pool
+/*!
+\param size_bytes size in bytes of the buffer
+*/
+void * btGenericPoolAllocator::allocate(size_t size_bytes)
+{
+	void * ptr = NULL;
+
+	size_t i = 0;
+	while(i<m_pool_count && ptr == NULL)
+	{
+		ptr = m_pools[i]->allocate(size_bytes);
+		++i;
+	}
+
+	if(ptr) return ptr;
+
+	return failback_alloc(size_bytes);
+}
+
+bool btGenericPoolAllocator::freeMemory(void * pointer)
+{
+	bool result = false;
+
+	size_t i = 0;
+	while(i<m_pool_count && result == false)
+	{
+		result = m_pools[i]->freeMemory(pointer);
+		++i;
+	}
+
+	if(result) return true;
+
+	return failback_free(pointer);
+}
+
+/// ************** STANDARD ALLOCATOR ***************************///
+
+
+#define BT_DEFAULT_POOL_SIZE 32768
+#define BT_DEFAULT_POOL_ELEMENT_SIZE 8
+
+// main allocator
+class GIM_STANDARD_ALLOCATOR: public btGenericPoolAllocator
+{
+public:
+	GIM_STANDARD_ALLOCATOR():btGenericPoolAllocator(BT_DEFAULT_POOL_ELEMENT_SIZE,BT_DEFAULT_POOL_SIZE)
+	{
+	}
+};
+
+// global allocator
+GIM_STANDARD_ALLOCATOR g_main_allocator;
+
+
+void * btPoolAlloc(size_t size)
+{
+	return g_main_allocator.allocate(size);
+}
+
+void * btPoolRealloc(void *ptr, size_t oldsize, size_t newsize)
+{
+	void * newptr = btPoolAlloc(newsize);
+    size_t copysize = oldsize<newsize?oldsize:newsize;
+    memcpy(newptr,ptr,copysize);
+    btPoolFree(ptr);
+    return newptr;
+}
+
+void btPoolFree(void *ptr)
+{
+	g_main_allocator.freeMemory(ptr);
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGenericPoolAllocator.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGenericPoolAllocator.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGenericPoolAllocator.h	(revision 6952)
@@ -0,0 +1,163 @@
+/*! \file btGenericPoolAllocator.h
+\author Francisco Len Nßjera. email projectileman@yahoo.com
+
+General purpose allocator class
+*/
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_GENERIC_POOL_ALLOCATOR_H
+#define BT_GENERIC_POOL_ALLOCATOR_H
+
+#include <limits.h>
+#include <stdio.h>
+#include <memory.h>
+#include "LinearMath/btAlignedAllocator.h"
+
+#define BT_UINT_MAX UINT_MAX
+#define BT_DEFAULT_MAX_POOLS 16
+
+
+//! Generic Pool class
+class btGenericMemoryPool
+{
+public:
+	unsigned char * m_pool; //[m_element_size*m_max_element_count];
+	size_t * m_free_nodes; //[m_max_element_count];//! free nodes
+	size_t * m_allocated_sizes;//[m_max_element_count];//! Number of elements allocated per node
+	size_t m_allocated_count;
+	size_t m_free_nodes_count;
+protected:
+	size_t m_element_size;
+	size_t m_max_element_count;
+
+	size_t allocate_from_free_nodes(size_t num_elements);
+	size_t allocate_from_pool(size_t num_elements);
+
+public:
+
+	void init_pool(size_t element_size, size_t element_count);
+
+	void end_pool();
+
+
+	btGenericMemoryPool(size_t element_size, size_t element_count)
+	{
+		init_pool(element_size, element_count);
+	}
+
+	~btGenericMemoryPool()
+	{
+		end_pool();
+	}
+
+
+	inline size_t get_pool_capacity()
+	{
+		return m_element_size*m_max_element_count;
+	}
+
+	inline size_t gem_element_size()
+	{
+		return m_element_size;
+	}
+
+	inline size_t get_max_element_count()
+	{
+		return m_max_element_count;
+	}
+
+	inline size_t get_allocated_count()
+	{
+		return m_allocated_count;
+	}
+
+	inline size_t get_free_positions_count()
+	{
+		return m_free_nodes_count;
+	}
+
+	inline void * get_element_data(size_t element_index)
+	{
+		return &m_pool[element_index*m_element_size];
+	}
+
+	//! Allocates memory in pool
+	/*!
+	\param size_bytes size in bytes of the buffer
+	*/
+	void * allocate(size_t size_bytes);
+
+	bool freeMemory(void * pointer);
+};
+
+
+
+
+//! Generic Allocator with pools
+/*!
+General purpose Allocator which can create Memory Pools dynamiacally as needed.
+*/
+class btGenericPoolAllocator
+{
+protected:
+	size_t m_pool_element_size;
+	size_t m_pool_element_count;
+public:
+	btGenericMemoryPool * m_pools[BT_DEFAULT_MAX_POOLS];
+	size_t m_pool_count;
+
+
+	inline size_t get_pool_capacity()
+	{
+		return m_pool_element_size*m_pool_element_count;
+	}
+
+
+protected:
+	// creates a pool
+	btGenericMemoryPool * push_new_pool();
+
+	void * failback_alloc(size_t size_bytes);
+
+	bool failback_free(void * pointer);
+public:
+
+	btGenericPoolAllocator(size_t pool_element_size, size_t pool_element_count)
+	{
+		m_pool_count = 0;
+		m_pool_element_size = pool_element_size;
+		m_pool_element_count = pool_element_count;
+	}
+
+	virtual ~btGenericPoolAllocator();
+
+	//! Allocates memory in pool
+	/*!
+	\param size_bytes size in bytes of the buffer
+	*/
+	void * allocate(size_t size_bytes);
+
+	bool freeMemory(void * pointer);
+};
+
+
+
+void * btPoolAlloc(size_t size);
+void * btPoolRealloc(void *ptr, size_t oldsize, size_t newsize);
+void btPoolFree(void *ptr);
+
+
+#endif
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGeometryOperations.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGeometryOperations.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btGeometryOperations.h	(revision 6952)
@@ -0,0 +1,212 @@
+#ifndef BT_BASIC_GEOMETRY_OPERATIONS_H_INCLUDED
+#define BT_BASIC_GEOMETRY_OPERATIONS_H_INCLUDED
+
+/*! \file btGeometryOperations.h
+*\author Francisco Len Nßjera
+
+*/
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 "btBoxCollision.h"
+
+
+
+
+
+#define PLANEDIREPSILON 0.0000001f
+#define PARALELENORMALS 0.000001f
+
+
+#define BT_CLAMP(number,minval,maxval) (number<minval?minval:(number>maxval?maxval:number))
+
+/// Calc a plane from a triangle edge an a normal. plane is a vec4f
+SIMD_FORCE_INLINE void bt_edge_plane(const btVector3 & e1,const btVector3 &  e2, const btVector3 & normal,btVector4 & plane)
+{
+	btVector3 planenormal = (e2-e1).cross(normal);
+	planenormal.normalize();
+	plane.setValue(planenormal[0],planenormal[1],planenormal[2],e2.dot(planenormal));
+}
+
+
+
+//***************** SEGMENT and LINE FUNCTIONS **********************************///
+
+/*! Finds the closest point(cp) to (v) on a segment (e1,e2)
+ */
+SIMD_FORCE_INLINE void bt_closest_point_on_segment(
+	btVector3 & cp, const btVector3 & v,
+	const btVector3  &e1,const btVector3 &e2)
+{
+    btVector3 n = e2-e1;
+    cp = v - e1;
+	btScalar _scalar = cp.dot(n)/n.dot(n);
+	if(_scalar <0.0f)
+	{
+	    cp = e1;
+	}
+	else if(_scalar >1.0f)
+	{
+	    cp = e2;
+	}
+	else
+	{
+		cp = _scalar*n + e1;
+	}
+}
+
+
+//! line plane collision
+/*!
+*\return
+	-0  if the ray never intersects
+	-1 if the ray collides in front
+	-2 if the ray collides in back
+*/
+
+SIMD_FORCE_INLINE int bt_line_plane_collision(
+	const btVector4 & plane,
+	const btVector3 & vDir,
+	const btVector3 & vPoint,
+	btVector3 & pout,
+	btScalar &tparam,
+	btScalar tmin, btScalar tmax)
+{
+
+	btScalar _dotdir = vDir.dot(plane);
+
+	if(btFabs(_dotdir)<PLANEDIREPSILON)
+	{
+		tparam = tmax;
+	    return 0;
+	}
+
+	btScalar _dis = bt_distance_point_plane(plane,vPoint);
+	char returnvalue = _dis<0.0f? 2:1;
+	tparam = -_dis/_dotdir;
+
+	if(tparam<tmin)
+	{
+		returnvalue = 0;
+		tparam = tmin;
+	}
+	else if(tparam>tmax)
+	{
+		returnvalue = 0;
+		tparam = tmax;
+	}
+	pout = tparam*vDir + vPoint;
+	return returnvalue;
+}
+
+
+//! Find closest points on segments
+SIMD_FORCE_INLINE void bt_segment_collision(
+	const btVector3 & vA1,
+	const btVector3 & vA2,
+	const btVector3 & vB1,
+	const btVector3 & vB2,
+	btVector3 & vPointA,
+	btVector3 & vPointB)
+{
+    btVector3 AD = vA2 - vA1;
+    btVector3 BD = vB2 - vB1;
+    btVector3 N = AD.cross(BD);
+    btScalar tp = N.length2();
+
+    btVector4 _M;//plane
+
+    if(tp<SIMD_EPSILON)//ARE PARALELE
+    {
+    	//project B over A
+    	bool invert_b_order = false;
+    	_M[0] = vB1.dot(AD);
+    	_M[1] = vB2.dot(AD);
+
+    	if(_M[0]>_M[1])
+    	{
+    		invert_b_order  = true;
+    		BT_SWAP_NUMBERS(_M[0],_M[1]);
+    	}
+    	_M[2] = vA1.dot(AD);
+    	_M[3] = vA2.dot(AD);
+    	//mid points
+    	N[0] = (_M[0]+_M[1])*0.5f;
+    	N[1] = (_M[2]+_M[3])*0.5f;
+
+    	if(N[0]<N[1])
+    	{
+    		if(_M[1]<_M[2])
+    		{
+    			vPointB = invert_b_order?vB1:vB2;
+    			vPointA = vA1;
+    		}
+    		else if(_M[1]<_M[3])
+    		{
+    			vPointB = invert_b_order?vB1:vB2;
+    			bt_closest_point_on_segment(vPointA,vPointB,vA1,vA2);
+    		}
+    		else
+    		{
+    			vPointA = vA2;
+    			bt_closest_point_on_segment(vPointB,vPointA,vB1,vB2);
+    		}
+    	}
+    	else
+    	{
+    		if(_M[3]<_M[0])
+    		{
+    			vPointB = invert_b_order?vB2:vB1;
+    			vPointA = vA2;
+    		}
+    		else if(_M[3]<_M[1])
+    		{
+    			vPointA = vA2;
+    			bt_closest_point_on_segment(vPointB,vPointA,vB1,vB2);
+    		}
+    		else
+    		{
+    			vPointB = invert_b_order?vB1:vB2;
+    			bt_closest_point_on_segment(vPointA,vPointB,vA1,vA2);
+    		}
+    	}
+    	return;
+    }
+
+    N = N.cross(BD);
+    _M.setValue(N[0],N[1],N[2],vB1.dot(N));
+
+	// get point A as the plane collision point
+    bt_line_plane_collision(_M,AD,vA1,vPointA,tp,btScalar(0), btScalar(1));
+
+    /*Closest point on segment*/
+    vPointB = vPointA - vB1;
+	tp = vPointB.dot(BD);
+	tp/= BD.dot(BD);
+	tp = BT_CLAMP(tp,0.0f,1.0f);
+
+	vPointB = tp*BD + vB1;
+}
+
+
+
+
+
+#endif // GIM_VECTOR_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btQuantization.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btQuantization.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btQuantization.h	(revision 6952)
@@ -0,0 +1,88 @@
+#ifndef BT_QUANTIZATION_H_INCLUDED
+#define BT_QUANTIZATION_H_INCLUDED
+
+/*! \file btQuantization.h
+*\author Francisco Len Nßjera
+
+*/
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 "LinearMath/btTransform.h"
+
+
+
+
+
+
+SIMD_FORCE_INLINE void bt_calc_quantization_parameters(
+	btVector3 & outMinBound,
+	btVector3 & outMaxBound,
+	btVector3 & bvhQuantization,
+	const btVector3& srcMinBound,const btVector3& srcMaxBound,
+	btScalar quantizationMargin)
+{
+	//enlarge the AABB to avoid division by zero when initializing the quantization values
+	btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin);
+	outMinBound = srcMinBound - clampValue;
+	outMaxBound = srcMaxBound + clampValue;
+	btVector3 aabbSize = outMaxBound - outMinBound;
+	bvhQuantization = btVector3(btScalar(65535.0),
+								btScalar(65535.0),
+								btScalar(65535.0)) / aabbSize;
+}
+
+
+SIMD_FORCE_INLINE void bt_quantize_clamp(
+	unsigned short* out,
+	const btVector3& point,
+	const btVector3 & min_bound,
+	const btVector3 & max_bound,
+	const btVector3 & bvhQuantization)
+{
+
+	btVector3 clampedPoint(point);
+	clampedPoint.setMax(min_bound);
+	clampedPoint.setMin(max_bound);
+
+	btVector3 v = (clampedPoint - min_bound) * bvhQuantization;
+	out[0] = (unsigned short)(v.getX()+0.5f);
+	out[1] = (unsigned short)(v.getY()+0.5f);
+	out[2] = (unsigned short)(v.getZ()+0.5f);
+}
+
+
+SIMD_FORCE_INLINE btVector3 bt_unquantize(
+	const unsigned short* vecIn,
+	const btVector3 & offset,
+	const btVector3 & bvhQuantization)
+{
+	btVector3	vecOut;
+	vecOut.setValue(
+		(btScalar)(vecIn[0]) / (bvhQuantization.getX()),
+		(btScalar)(vecIn[1]) / (bvhQuantization.getY()),
+		(btScalar)(vecIn[2]) / (bvhQuantization.getZ()));
+	vecOut += offset;
+	return vecOut;
+}
+
+
+
+#endif // GIM_VECTOR_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btTriangleShapeEx.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btTriangleShapeEx.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btTriangleShapeEx.cpp	(revision 6952)
@@ -0,0 +1,218 @@
+/*! \file btGImpactTriangleShape.h
+\author Francisco Len Nßjera
+*/
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 "btTriangleShapeEx.h"
+
+
+
+void GIM_TRIANGLE_CONTACT::merge_points(const btVector4 & plane,
+                                       btScalar margin, const btVector3 * points, int point_count)
+{
+    m_point_count = 0;
+    m_penetration_depth= -1000.0f;
+
+    int point_indices[MAX_TRI_CLIPPING];
+
+	int _k;
+
+    for ( _k=0;_k<point_count;_k++)
+    {
+        btScalar _dist = - bt_distance_point_plane(plane,points[_k]) + margin;
+
+        if (_dist>=0.0f)
+        {
+            if (_dist>m_penetration_depth)
+            {
+                m_penetration_depth = _dist;
+                point_indices[0] = _k;
+                m_point_count=1;
+            }
+            else if ((_dist+SIMD_EPSILON)>=m_penetration_depth)
+            {
+                point_indices[m_point_count] = _k;
+                m_point_count++;
+            }
+        }
+    }
+
+    for ( _k=0;_k<m_point_count;_k++)
+    {
+        m_points[_k] = points[point_indices[_k]];
+    }
+}
+
+///class btPrimitiveTriangle
+bool btPrimitiveTriangle::overlap_test_conservative(const btPrimitiveTriangle& other)
+{
+    btScalar total_margin = m_margin + other.m_margin;
+    // classify points on other triangle
+    btScalar dis0 = bt_distance_point_plane(m_plane,other.m_vertices[0]) - total_margin;
+
+    btScalar dis1 = bt_distance_point_plane(m_plane,other.m_vertices[1]) - total_margin;
+
+    btScalar dis2 = bt_distance_point_plane(m_plane,other.m_vertices[2]) - total_margin;
+
+    if (dis0>0.0f&&dis1>0.0f&&dis2>0.0f) return false;
+
+    // classify points on this triangle
+    dis0 = bt_distance_point_plane(other.m_plane,m_vertices[0]) - total_margin;
+
+    dis1 = bt_distance_point_plane(other.m_plane,m_vertices[1]) - total_margin;
+
+    dis2 = bt_distance_point_plane(other.m_plane,m_vertices[2]) - total_margin;
+
+    if (dis0>0.0f&&dis1>0.0f&&dis2>0.0f) return false;
+
+    return true;
+}
+
+int btPrimitiveTriangle::clip_triangle(btPrimitiveTriangle & other, btVector3 * clipped_points )
+{
+    // edge 0
+
+    btVector3 temp_points[MAX_TRI_CLIPPING];
+
+
+    btVector4 edgeplane;
+
+    get_edge_plane(0,edgeplane);
+
+
+    int clipped_count = bt_plane_clip_triangle(
+                            edgeplane,other.m_vertices[0],other.m_vertices[1],other.m_vertices[2],temp_points);
+
+    if (clipped_count == 0) return 0;
+
+    btVector3 temp_points1[MAX_TRI_CLIPPING];
+
+
+    // edge 1
+    get_edge_plane(1,edgeplane);
+
+
+    clipped_count = bt_plane_clip_polygon(edgeplane,temp_points,clipped_count,temp_points1);
+
+    if (clipped_count == 0) return 0;
+
+    // edge 2
+    get_edge_plane(2,edgeplane);
+
+    clipped_count = bt_plane_clip_polygon(
+                        edgeplane,temp_points1,clipped_count,clipped_points);
+
+    return clipped_count;
+}
+
+bool btPrimitiveTriangle::find_triangle_collision_clip_method(btPrimitiveTriangle & other, GIM_TRIANGLE_CONTACT & contacts)
+{
+    btScalar margin = m_margin + other.m_margin;
+
+    btVector3 clipped_points[MAX_TRI_CLIPPING];
+    int clipped_count;
+    //create planes
+    // plane v vs U points
+
+    GIM_TRIANGLE_CONTACT contacts1;
+
+    contacts1.m_separating_normal = m_plane;
+
+
+    clipped_count = clip_triangle(other,clipped_points);
+
+    if (clipped_count == 0 )
+    {
+        return false;//Reject
+    }
+
+    //find most deep interval face1
+    contacts1.merge_points(contacts1.m_separating_normal,margin,clipped_points,clipped_count);
+    if (contacts1.m_point_count == 0) return false; // too far
+    //Normal pointing to this triangle
+    contacts1.m_separating_normal *= -1.f;
+
+
+    //Clip tri1 by tri2 edges
+    GIM_TRIANGLE_CONTACT contacts2;
+    contacts2.m_separating_normal = other.m_plane;
+
+    clipped_count = other.clip_triangle(*this,clipped_points);
+
+    if (clipped_count == 0 )
+    {
+        return false;//Reject
+    }
+
+    //find most deep interval face1
+    contacts2.merge_points(contacts2.m_separating_normal,margin,clipped_points,clipped_count);
+    if (contacts2.m_point_count == 0) return false; // too far
+
+
+
+
+    ////check most dir for contacts
+    if (contacts2.m_penetration_depth<contacts1.m_penetration_depth)
+    {
+        contacts.copy_from(contacts2);
+    }
+    else
+    {
+        contacts.copy_from(contacts1);
+    }
+    return true;
+}
+
+
+
+///class btTriangleShapeEx: public btTriangleShape
+
+bool btTriangleShapeEx::overlap_test_conservative(const btTriangleShapeEx& other)
+{
+    btScalar total_margin = getMargin() + other.getMargin();
+
+    btVector4 plane0;
+    buildTriPlane(plane0);
+    btVector4 plane1;
+    other.buildTriPlane(plane1);
+
+    // classify points on other triangle
+    btScalar dis0 = bt_distance_point_plane(plane0,other.m_vertices1[0]) - total_margin;
+
+    btScalar dis1 = bt_distance_point_plane(plane0,other.m_vertices1[1]) - total_margin;
+
+    btScalar dis2 = bt_distance_point_plane(plane0,other.m_vertices1[2]) - total_margin;
+
+    if (dis0>0.0f&&dis1>0.0f&&dis2>0.0f) return false;
+
+    // classify points on this triangle
+    dis0 = bt_distance_point_plane(plane1,m_vertices1[0]) - total_margin;
+
+    dis1 = bt_distance_point_plane(plane1,m_vertices1[1]) - total_margin;
+
+    dis2 = bt_distance_point_plane(plane1,m_vertices1[2]) - total_margin;
+
+    if (dis0>0.0f&&dis1>0.0f&&dis2>0.0f) return false;
+
+    return true;
+}
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btTriangleShapeEx.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btTriangleShapeEx.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/btTriangleShapeEx.h	(revision 6952)
@@ -0,0 +1,180 @@
+/*! \file btGImpactShape.h
+\author Francisco Len Nßjera
+*/
+/*
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.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 TRIANGLE_SHAPE_EX_H
+#define TRIANGLE_SHAPE_EX_H
+
+#include "BulletCollision/CollisionShapes/btCollisionShape.h"
+#include "BulletCollision/CollisionShapes/btTriangleShape.h"
+#include "btBoxCollision.h"
+#include "btClipPolygon.h"
+#include "btGeometryOperations.h"
+
+
+#define MAX_TRI_CLIPPING 16
+
+//! Structure for collision
+struct GIM_TRIANGLE_CONTACT
+{
+    btScalar m_penetration_depth;
+    int m_point_count;
+    btVector4 m_separating_normal;
+    btVector3 m_points[MAX_TRI_CLIPPING];
+
+	SIMD_FORCE_INLINE void copy_from(const GIM_TRIANGLE_CONTACT& other)
+	{
+		m_penetration_depth = other.m_penetration_depth;
+		m_separating_normal = other.m_separating_normal;
+		m_point_count = other.m_point_count;
+		int i = m_point_count;
+		while(i--)
+		{
+			m_points[i] = other.m_points[i];
+		}
+	}
+
+	GIM_TRIANGLE_CONTACT()
+	{
+	}
+
+	GIM_TRIANGLE_CONTACT(const GIM_TRIANGLE_CONTACT& other)
+	{
+		copy_from(other);
+	}
+
+    //! classify points that are closer
+    void merge_points(const btVector4 & plane,
+    				btScalar margin, const btVector3 * points, int point_count);
+
+};
+
+
+
+class btPrimitiveTriangle
+{
+public:
+	btVector3 m_vertices[3];
+	btVector4 m_plane;
+	btScalar m_margin;
+	btScalar m_dummy;
+	btPrimitiveTriangle():m_margin(0.01f)
+	{
+
+	}
+
+
+	SIMD_FORCE_INLINE void buildTriPlane()
+	{
+		btVector3 normal = (m_vertices[1]-m_vertices[0]).cross(m_vertices[2]-m_vertices[0]);
+		normal.normalize();
+		m_plane.setValue(normal[0],normal[1],normal[2],m_vertices[0].dot(normal));
+	}
+
+	//! Test if triangles could collide
+	bool overlap_test_conservative(const btPrimitiveTriangle& other);
+
+	//! Calcs the plane which is paralele to the edge and perpendicular to the triangle plane
+	/*!
+	\pre this triangle must have its plane calculated.
+	*/
+	SIMD_FORCE_INLINE void get_edge_plane(int edge_index, btVector4 &plane)  const
+    {
+		const btVector3 & e0 = m_vertices[edge_index];
+		const btVector3 & e1 = m_vertices[(edge_index+1)%3];
+		bt_edge_plane(e0,e1,m_plane,plane);
+    }
+
+    void applyTransform(const btTransform& t)
+	{
+		m_vertices[0] = t(m_vertices[0]);
+		m_vertices[1] = t(m_vertices[1]);
+		m_vertices[2] = t(m_vertices[2]);
+	}
+
+	//! Clips the triangle against this
+	/*!
+	\pre clipped_points must have MAX_TRI_CLIPPING size, and this triangle must have its plane calculated.
+	\return the number of clipped points
+	*/
+    int clip_triangle(btPrimitiveTriangle & other, btVector3 * clipped_points );
+
+	//! Find collision using the clipping method
+	/*!
+	\pre this triangle and other must have their triangles calculated
+	*/
+    bool find_triangle_collision_clip_method(btPrimitiveTriangle & other, GIM_TRIANGLE_CONTACT & contacts);
+};
+
+
+
+//! Helper class for colliding Bullet Triangle Shapes
+/*!
+This class implements a better getAabb method than the previous btTriangleShape class
+*/
+class btTriangleShapeEx: public btTriangleShape
+{
+public:
+
+	btTriangleShapeEx():btTriangleShape(btVector3(0,0,0),btVector3(0,0,0),btVector3(0,0,0))
+	{
+	}
+
+	btTriangleShapeEx(const btVector3& p0,const btVector3& p1,const btVector3& p2):	btTriangleShape(p0,p1,p2)
+	{
+	}
+
+	btTriangleShapeEx(const btTriangleShapeEx & other):	btTriangleShape(other.m_vertices1[0],other.m_vertices1[1],other.m_vertices1[2])
+	{
+	}
+
+	virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax)const
+	{
+		btVector3 tv0 = t(m_vertices1[0]);
+		btVector3 tv1 = t(m_vertices1[1]);
+		btVector3 tv2 = t(m_vertices1[2]);
+
+		btAABB trianglebox(tv0,tv1,tv2,m_collisionMargin);
+		aabbMin = trianglebox.m_min;
+		aabbMax = trianglebox.m_max;
+	}
+
+	void applyTransform(const btTransform& t)
+	{
+		m_vertices1[0] = t(m_vertices1[0]);
+		m_vertices1[1] = t(m_vertices1[1]);
+		m_vertices1[2] = t(m_vertices1[2]);
+	}
+
+	SIMD_FORCE_INLINE void buildTriPlane(btVector4 & plane) const
+	{
+		btVector3 normal = (m_vertices1[1]-m_vertices1[0]).cross(m_vertices1[2]-m_vertices1[0]);
+		normal.normalize();
+		plane.setValue(normal[0],normal[1],normal[2],m_vertices1[0].dot(normal));
+	}
+
+	bool overlap_test_conservative(const btTriangleShapeEx& other);
+};
+
+
+#endif //TRIANGLE_MESH_SHAPE_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_array.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_array.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_array.h	(revision 6952)
@@ -0,0 +1,326 @@
+#ifndef GIM_ARRAY_H_INCLUDED
+#define GIM_ARRAY_H_INCLUDED
+/*! \file gim_array.h
+\author Francisco Len Nßjera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "gim_memory.h"
+
+
+#define GIM_ARRAY_GROW_INCREMENT 2
+#define GIM_ARRAY_GROW_FACTOR 2
+
+//!	Very simple array container with fast access and simd memory
+template<typename T>
+class gim_array
+{
+public:
+//! properties
+//!@{
+    T *m_data;
+    GUINT m_size;
+    GUINT m_allocated_size;
+//!@}
+//! protected operations
+//!@{
+
+    inline void destroyData()
+	{
+	    m_allocated_size = 0;
+		if(m_data==NULL) return;
+		gim_free(m_data);
+		m_data = NULL;
+	}
+
+	inline bool resizeData(GUINT newsize)
+	{
+		if(newsize==0)
+		{
+			destroyData();
+			return true;
+		}
+
+		if(m_size>0)
+		{
+            m_data = (T*)gim_realloc(m_data,m_size*sizeof(T),newsize*sizeof(T));
+		}
+		else
+		{
+		    m_data = (T*)gim_alloc(newsize*sizeof(T));
+		}
+		m_allocated_size = newsize;
+		return true;
+	}
+
+	inline bool growingCheck()
+	{
+		if(m_allocated_size<=m_size)
+		{
+		    GUINT requestsize = m_size;
+		    m_size = m_allocated_size;
+			if(resizeData((requestsize+GIM_ARRAY_GROW_INCREMENT)*GIM_ARRAY_GROW_FACTOR)==false) return false;
+		}
+		return true;
+	}
+
+//!@}
+//! public operations
+//!@{
+    inline  bool reserve(GUINT size)
+    {
+        if(m_allocated_size>=size) return false;
+        return resizeData(size);
+    }
+
+    inline void clear_range(GUINT start_range)
+    {
+        while(m_size>start_range)
+        {
+            m_data[--m_size].~T();
+        }
+    }
+
+    inline void clear()
+    {
+        if(m_size==0)return;
+        clear_range(0);
+    }
+
+    inline void clear_memory()
+    {
+        clear();
+        destroyData();
+    }
+
+    gim_array()
+    {
+        m_data = 0;
+        m_size = 0;
+        m_allocated_size = 0;
+    }
+
+    gim_array(GUINT reservesize)
+    {
+        m_data = 0;
+        m_size = 0;
+
+        m_allocated_size = 0;
+        reserve(reservesize);
+    }
+
+    ~gim_array()
+    {
+        clear_memory();
+    }
+
+    inline GUINT size() const
+    {
+        return m_size;
+    }
+
+    inline GUINT max_size() const
+    {
+        return m_allocated_size;
+    }
+
+    inline T & operator[](size_t i)
+	{
+		return m_data[i];
+	}
+	inline  const T & operator[](size_t i) const
+	{
+		return m_data[i];
+	}
+
+    inline T * pointer(){ return m_data;}
+    inline const T * pointer() const
+    { return m_data;}
+
+
+    inline T * get_pointer_at(GUINT i)
+	{
+		return m_data + i;
+	}
+
+	inline const T * get_pointer_at(GUINT i) const
+	{
+		return m_data + i;
+	}
+
+	inline T & at(GUINT i)
+	{
+		return m_data[i];
+	}
+
+	inline const T & at(GUINT i) const
+	{
+		return m_data[i];
+	}
+
+	inline T & front()
+	{
+		return *m_data;
+	}
+
+	inline const T & front() const
+	{
+		return *m_data;
+	}
+
+	inline T & back()
+	{
+		return m_data[m_size-1];
+	}
+
+	inline const T & back() const
+	{
+		return m_data[m_size-1];
+	}
+
+
+	inline void swap(GUINT i, GUINT j)
+	{
+	    gim_swap_elements(m_data,i,j);
+	}
+
+	inline void push_back(const T & obj)
+	{
+	    this->growingCheck();
+	    m_data[m_size] = obj;
+	    m_size++;
+	}
+
+	//!Simply increase the m_size, doesn't call the new element constructor
+	inline void push_back_mem()
+	{
+	    this->growingCheck();
+	    m_size++;
+	}
+
+	inline void push_back_memcpy(const T & obj)
+	{
+	    this->growingCheck();
+	    irr_simd_memcpy(&m_data[m_size],&obj,sizeof(T));
+	    m_size++;
+	}
+
+	inline void pop_back()
+	{
+	    m_size--;
+        m_data[m_size].~T();
+	}
+
+	//!Simply decrease the m_size, doesn't call the deleted element destructor
+	inline void pop_back_mem()
+	{
+	    m_size--;
+	}
+
+    //! fast erase
+	inline void erase(GUINT index)
+	{
+	    if(index<m_size-1)
+	    {
+	        swap(index,m_size-1);
+	    }
+	    pop_back();
+	}
+
+	inline void erase_sorted_mem(GUINT index)
+	{
+	    m_size--;
+	    for(GUINT i = index;i<m_size;i++)
+	    {
+	        gim_simd_memcpy(m_data+i,m_data+i+1,sizeof(T));
+	    }
+	}
+
+	inline void erase_sorted(GUINT index)
+	{
+	    m_data[index].~T();
+	    erase_sorted_mem(index);
+	}
+
+	inline void insert_mem(GUINT index)
+	{
+	    this->growingCheck();
+	    for(GUINT i = m_size;i>index;i--)
+	    {
+	        gim_simd_memcpy(m_data+i,m_data+i-1,sizeof(T));
+	    }
+	    m_size++;
+	}
+
+	inline void insert(const T & obj,GUINT index)
+	{
+	    insert_mem(index);
+	    m_data[index] = obj;
+	}
+
+	inline void resize(GUINT size, bool call_constructor = true)
+	{
+
+	    if(size>m_size)
+	    {
+            reserve(size);
+            if(call_constructor)
+            {
+            	T obj;
+                while(m_size<size)
+                {
+                    m_data[m_size] = obj;
+                    m_size++;
+                }
+            }
+            else
+            {
+            	m_size = size;
+            }
+	    }
+	    else if(size<m_size)
+	    {
+	        if(call_constructor) clear_range(size);
+	        m_size = size;
+	    }
+	}
+
+	inline void refit()
+	{
+	    resizeData(m_size);
+	}
+
+};
+
+
+
+
+
+#endif // GIM_CONTAINERS_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_basic_geometry_operations.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_basic_geometry_operations.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_basic_geometry_operations.h	(revision 6952)
@@ -0,0 +1,543 @@
+#ifndef GIM_BASIC_GEOMETRY_OPERATIONS_H_INCLUDED
+#define GIM_BASIC_GEOMETRY_OPERATIONS_H_INCLUDED
+
+/*! \file gim_basic_geometry_operations.h
+*\author Francisco Len Nßjera
+type independant geometry routines
+
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "gim_linear_math.h"
+
+
+
+
+
+#define PLANEDIREPSILON 0.0000001f
+#define PARALELENORMALS 0.000001f
+
+
+#define TRIANGLE_NORMAL(v1,v2,v3,n)\
+{\
+	vec3f _dif1,_dif2;\
+    VEC_DIFF(_dif1,v2,v1);\
+    VEC_DIFF(_dif2,v3,v1);\
+    VEC_CROSS(n,_dif1,_dif2);\
+    VEC_NORMALIZE(n);\
+}\
+
+#define TRIANGLE_NORMAL_FAST(v1,v2,v3,n){\
+    vec3f _dif1,_dif2; \
+    VEC_DIFF(_dif1,v2,v1); \
+    VEC_DIFF(_dif2,v3,v1); \
+    VEC_CROSS(n,_dif1,_dif2); \
+}\
+
+/// plane is a vec4f
+#define TRIANGLE_PLANE(v1,v2,v3,plane) {\
+    TRIANGLE_NORMAL(v1,v2,v3,plane);\
+    plane[3] = VEC_DOT(v1,plane);\
+}\
+
+/// plane is a vec4f
+#define TRIANGLE_PLANE_FAST(v1,v2,v3,plane) {\
+    TRIANGLE_NORMAL_FAST(v1,v2,v3,plane);\
+    plane[3] = VEC_DOT(v1,plane);\
+}\
+
+/// Calc a plane from an edge an a normal. plane is a vec4f
+#define EDGE_PLANE(e1,e2,n,plane) {\
+    vec3f _dif; \
+    VEC_DIFF(_dif,e2,e1); \
+    VEC_CROSS(plane,_dif,n); \
+    VEC_NORMALIZE(plane); \
+    plane[3] = VEC_DOT(e1,plane);\
+}\
+
+#define DISTANCE_PLANE_POINT(plane,point) (VEC_DOT(plane,point) - plane[3])
+
+#define PROJECT_POINT_PLANE(point,plane,projected) {\
+	GREAL _dis;\
+	_dis = DISTANCE_PLANE_POINT(plane,point);\
+	VEC_SCALE(projected,-_dis,plane);\
+	VEC_SUM(projected,projected,point);	\
+}\
+
+//! Verifies if a point is in the plane hull
+template<typename CLASS_POINT,typename CLASS_PLANE>
+SIMD_FORCE_INLINE bool POINT_IN_HULL(
+	const CLASS_POINT& point,const CLASS_PLANE * planes,GUINT plane_count)
+{
+	GREAL _dis;
+	for (GUINT _i = 0;_i< plane_count;++_i)
+	{
+		_dis = DISTANCE_PLANE_POINT(planes[_i],point);
+	    if(_dis>0.0f) return false;
+	}
+	return true;
+}
+
+template<typename CLASS_POINT,typename CLASS_PLANE>
+SIMD_FORCE_INLINE void PLANE_CLIP_SEGMENT(
+	const CLASS_POINT& s1,
+	const CLASS_POINT &s2,const CLASS_PLANE &plane,CLASS_POINT &clipped)
+{
+	GREAL _dis1,_dis2;
+	_dis1 = DISTANCE_PLANE_POINT(plane,s1);
+	VEC_DIFF(clipped,s2,s1);
+	_dis2 = VEC_DOT(clipped,plane);
+	VEC_SCALE(clipped,-_dis1/_dis2,clipped);
+	VEC_SUM(clipped,clipped,s1);
+}
+
+enum ePLANE_INTERSECTION_TYPE
+{
+	G_BACK_PLANE = 0,
+	G_COLLIDE_PLANE,
+	G_FRONT_PLANE
+};
+
+enum eLINE_PLANE_INTERSECTION_TYPE
+{
+	G_FRONT_PLANE_S1 = 0,
+	G_FRONT_PLANE_S2,
+	G_BACK_PLANE_S1,
+	G_BACK_PLANE_S2,
+	G_COLLIDE_PLANE_S1,
+	G_COLLIDE_PLANE_S2
+};
+
+//! Confirms if the plane intersect the edge or nor
+/*!
+intersection type must have the following values
+<ul>
+<li> 0 : Segment in front of plane, s1 closest
+<li> 1 : Segment in front of plane, s2 closest
+<li> 2 : Segment in back of plane, s1 closest
+<li> 3 : Segment in back of plane, s2 closest
+<li> 4 : Segment collides plane, s1 in back
+<li> 5 : Segment collides plane, s2 in back
+</ul>
+*/
+
+template<typename CLASS_POINT,typename CLASS_PLANE>
+SIMD_FORCE_INLINE eLINE_PLANE_INTERSECTION_TYPE PLANE_CLIP_SEGMENT2(
+	const CLASS_POINT& s1,
+	const CLASS_POINT &s2,
+	const CLASS_PLANE &plane,CLASS_POINT &clipped)
+{
+	GREAL _dis1 = DISTANCE_PLANE_POINT(plane,s1);
+	GREAL _dis2 = DISTANCE_PLANE_POINT(plane,s2);
+	if(_dis1 >-G_EPSILON && _dis2 >-G_EPSILON)
+	{
+	    if(_dis1<_dis2) return G_FRONT_PLANE_S1;
+	    return G_FRONT_PLANE_S2;
+	}
+	else if(_dis1 <G_EPSILON && _dis2 <G_EPSILON)
+	{
+	    if(_dis1>_dis2) return G_BACK_PLANE_S1;
+	    return G_BACK_PLANE_S2;
+	}
+
+	VEC_DIFF(clipped,s2,s1);
+	_dis2 = VEC_DOT(clipped,plane);
+	VEC_SCALE(clipped,-_dis1/_dis2,clipped);
+	VEC_SUM(clipped,clipped,s1);
+	if(_dis1<_dis2) return G_COLLIDE_PLANE_S1;
+	return G_COLLIDE_PLANE_S2;
+}
+
+//! Confirms if the plane intersect the edge or not
+/*!
+clipped1 and clipped2 are the vertices behind the plane.
+clipped1 is the closest
+
+intersection_type must have the following values
+<ul>
+<li> 0 : Segment in front of plane, s1 closest
+<li> 1 : Segment in front of plane, s2 closest
+<li> 2 : Segment in back of plane, s1 closest
+<li> 3 : Segment in back of plane, s2 closest
+<li> 4 : Segment collides plane, s1 in back
+<li> 5 : Segment collides plane, s2 in back
+</ul>
+*/
+template<typename CLASS_POINT,typename CLASS_PLANE>
+SIMD_FORCE_INLINE eLINE_PLANE_INTERSECTION_TYPE PLANE_CLIP_SEGMENT_CLOSEST(
+	const CLASS_POINT& s1,
+	const CLASS_POINT &s2,
+	const CLASS_PLANE &plane,
+	CLASS_POINT &clipped1,CLASS_POINT &clipped2)
+{
+	eLINE_PLANE_INTERSECTION_TYPE intersection_type = PLANE_CLIP_SEGMENT2(s1,s2,plane,clipped1);
+	switch(intersection_type)
+	{
+	case G_FRONT_PLANE_S1:
+		VEC_COPY(clipped1,s1);
+	    VEC_COPY(clipped2,s2);
+		break;
+	case G_FRONT_PLANE_S2:
+		VEC_COPY(clipped1,s2);
+	    VEC_COPY(clipped2,s1);
+		break;
+	case G_BACK_PLANE_S1:
+		VEC_COPY(clipped1,s1);
+	    VEC_COPY(clipped2,s2);
+		break;
+	case G_BACK_PLANE_S2:
+		VEC_COPY(clipped1,s2);
+	    VEC_COPY(clipped2,s1);
+		break;
+	case G_COLLIDE_PLANE_S1:
+		VEC_COPY(clipped2,s1);
+		break;
+	case G_COLLIDE_PLANE_S2:
+		VEC_COPY(clipped2,s2);
+		break;
+	}
+	return intersection_type;
+}
+
+
+//! Finds the 2 smallest cartesian coordinates of a plane normal
+#define PLANE_MINOR_AXES(plane, i0, i1) VEC_MINOR_AXES(plane, i0, i1)
+
+//! Ray plane collision in one way
+/*!
+Intersects plane in one way only. The ray must face the plane (normals must be in opossite directions).<br/>
+It uses the PLANEDIREPSILON constant.
+*/
+template<typename T,typename CLASS_POINT,typename CLASS_PLANE>
+SIMD_FORCE_INLINE bool RAY_PLANE_COLLISION(
+	const CLASS_PLANE & plane,
+	const CLASS_POINT & vDir,
+	const CLASS_POINT & vPoint,
+	CLASS_POINT & pout,T &tparam)
+{
+	GREAL _dis,_dotdir;
+	_dotdir = VEC_DOT(plane,vDir);
+	if(_dotdir<PLANEDIREPSILON)
+	{
+	    return false;
+	}
+	_dis = DISTANCE_PLANE_POINT(plane,vPoint);
+	tparam = -_dis/_dotdir;
+	VEC_SCALE(pout,tparam,vDir);
+	VEC_SUM(pout,vPoint,pout);
+	return true;
+}
+
+//! line collision
+/*!
+*\return
+	-0  if the ray never intersects
+	-1 if the ray collides in front
+	-2 if the ray collides in back
+*/
+template<typename T,typename CLASS_POINT,typename CLASS_PLANE>
+SIMD_FORCE_INLINE GUINT LINE_PLANE_COLLISION(
+	const CLASS_PLANE & plane,
+	const CLASS_POINT & vDir,
+	const CLASS_POINT & vPoint,
+	CLASS_POINT & pout,
+	T &tparam,
+	T tmin, T tmax)
+{
+	GREAL _dis,_dotdir;
+	_dotdir = VEC_DOT(plane,vDir);
+	if(btFabs(_dotdir)<PLANEDIREPSILON)
+	{
+		tparam = tmax;
+	    return 0;
+	}
+	_dis = DISTANCE_PLANE_POINT(plane,vPoint);
+	char returnvalue = _dis<0.0f?2:1;
+	tparam = -_dis/_dotdir;
+
+	if(tparam<tmin)
+	{
+		returnvalue = 0;
+		tparam = tmin;
+	}
+	else if(tparam>tmax)
+	{
+		returnvalue = 0;
+		tparam = tmax;
+	}
+
+	VEC_SCALE(pout,tparam,vDir);
+	VEC_SUM(pout,vPoint,pout);
+	return returnvalue;
+}
+
+/*! \brief Returns the Ray on which 2 planes intersect if they do.
+    Written by Rodrigo Hernandez on ODE convex collision
+
+  \param p1 Plane 1
+  \param p2 Plane 2
+  \param p Contains the origin of the ray upon returning if planes intersect
+  \param d Contains the direction of the ray upon returning if planes intersect
+  \return true if the planes intersect, 0 if paralell.
+
+*/
+template<typename CLASS_POINT,typename CLASS_PLANE>
+SIMD_FORCE_INLINE bool INTERSECT_PLANES(
+		const CLASS_PLANE &p1,
+		const CLASS_PLANE &p2,
+		CLASS_POINT &p,
+		CLASS_POINT &d)
+{
+	VEC_CROSS(d,p1,p2);
+  	GREAL denom = VEC_DOT(d, d);
+  	if(GIM_IS_ZERO(denom)) return false;
+	vec3f _n;
+	_n[0]=p1[3]*p2[0] - p2[3]*p1[0];
+	_n[1]=p1[3]*p2[1] - p2[3]*p1[1];
+	_n[2]=p1[3]*p2[2] - p2[3]*p1[2];
+	VEC_CROSS(p,_n,d);
+	p[0]/=denom;
+	p[1]/=denom;
+	p[2]/=denom;
+	return true;
+}
+
+//***************** SEGMENT and LINE FUNCTIONS **********************************///
+
+/*! Finds the closest point(cp) to (v) on a segment (e1,e2)
+ */
+template<typename CLASS_POINT>
+SIMD_FORCE_INLINE void CLOSEST_POINT_ON_SEGMENT(
+	CLASS_POINT & cp, const CLASS_POINT & v,
+	const CLASS_POINT &e1,const CLASS_POINT &e2)
+{
+    vec3f _n;
+    VEC_DIFF(_n,e2,e1);
+    VEC_DIFF(cp,v,e1);
+	GREAL _scalar = VEC_DOT(cp, _n);
+	_scalar/= VEC_DOT(_n, _n);
+	if(_scalar <0.0f)
+	{
+	    VEC_COPY(cp,e1);
+	}
+	else if(_scalar >1.0f)
+	{
+	    VEC_COPY(cp,e2);
+	}
+	else
+	{
+        VEC_SCALE(cp,_scalar,_n);
+        VEC_SUM(cp,cp,e1);
+	}
+}
+
+
+/*! \brief Finds the line params where these lines intersect.
+
+\param dir1 Direction of line 1
+\param point1 Point of line 1
+\param dir2 Direction of line 2
+\param point2 Point of line 2
+\param t1 Result Parameter for line 1
+\param t2 Result Parameter for line 2
+\param dointersect  0  if the lines won't intersect, else 1
+
+*/
+template<typename T,typename CLASS_POINT>
+SIMD_FORCE_INLINE bool LINE_INTERSECTION_PARAMS(
+	const CLASS_POINT & dir1,
+	CLASS_POINT & point1,
+	const CLASS_POINT & dir2,
+	CLASS_POINT &  point2,
+	T& t1,T& t2)
+{
+    GREAL det;
+	GREAL e1e1 = VEC_DOT(dir1,dir1);
+	GREAL e1e2 = VEC_DOT(dir1,dir2);
+	GREAL e2e2 = VEC_DOT(dir2,dir2);
+	vec3f p1p2;
+    VEC_DIFF(p1p2,point1,point2);
+    GREAL p1p2e1 = VEC_DOT(p1p2,dir1);
+	GREAL p1p2e2 = VEC_DOT(p1p2,dir2);
+	det = e1e2*e1e2 - e1e1*e2e2;
+	if(GIM_IS_ZERO(det)) return false;
+	t1 = (e1e2*p1p2e2 - e2e2*p1p2e1)/det;
+	t2 = (e1e1*p1p2e2 - e1e2*p1p2e1)/det;
+	return true;
+}
+
+//! Find closest points on segments
+template<typename CLASS_POINT>
+SIMD_FORCE_INLINE void SEGMENT_COLLISION(
+	const CLASS_POINT & vA1,
+	const CLASS_POINT & vA2,
+	const CLASS_POINT & vB1,
+	const CLASS_POINT & vB2,
+	CLASS_POINT & vPointA,
+	CLASS_POINT & vPointB)
+{
+    CLASS_POINT _AD,_BD,_N;
+    vec4f _M;//plane
+    VEC_DIFF(_AD,vA2,vA1);
+    VEC_DIFF(_BD,vB2,vB1);
+    VEC_CROSS(_N,_AD,_BD);
+    GREAL _tp = VEC_DOT(_N,_N);
+    if(_tp<G_EPSILON)//ARE PARALELE
+    {
+    	//project B over A
+    	bool invert_b_order = false;
+    	_M[0] = VEC_DOT(vB1,_AD);
+    	_M[1] = VEC_DOT(vB2,_AD);
+    	if(_M[0]>_M[1])
+    	{
+    		invert_b_order  = true;
+    		GIM_SWAP_NUMBERS(_M[0],_M[1]);
+    	}
+    	_M[2] = VEC_DOT(vA1,_AD);
+    	_M[3] = VEC_DOT(vA2,_AD);
+    	//mid points
+    	_N[0] = (_M[0]+_M[1])*0.5f;
+    	_N[1] = (_M[2]+_M[3])*0.5f;
+
+    	if(_N[0]<_N[1])
+    	{
+    		if(_M[1]<_M[2])
+    		{
+    			vPointB = invert_b_order?vB1:vB2;
+    			vPointA = vA1;
+    		}
+    		else if(_M[1]<_M[3])
+    		{
+    			vPointB = invert_b_order?vB1:vB2;
+    			CLOSEST_POINT_ON_SEGMENT(vPointA,vPointB,vA1,vA2);
+    		}
+    		else
+    		{
+    			vPointA = vA2;
+    			CLOSEST_POINT_ON_SEGMENT(vPointB,vPointA,vB1,vB2);
+    		}
+    	}
+    	else
+    	{
+    		if(_M[3]<_M[0])
+    		{
+    			vPointB = invert_b_order?vB2:vB1;
+    			vPointA = vA2;
+    		}
+    		else if(_M[3]<_M[1])
+    		{
+    			vPointA = vA2;
+    			CLOSEST_POINT_ON_SEGMENT(vPointB,vPointA,vB1,vB2);
+    		}
+    		else
+    		{
+    			vPointB = invert_b_order?vB1:vB2;
+    			CLOSEST_POINT_ON_SEGMENT(vPointA,vPointB,vA1,vA2);
+    		}
+    	}
+    	return;
+    }
+
+
+    VEC_CROSS(_M,_N,_BD);
+    _M[3] = VEC_DOT(_M,vB1);
+
+    LINE_PLANE_COLLISION(_M,_AD,vA1,vPointA,_tp,btScalar(0), btScalar(1));
+    /*Closest point on segment*/
+    VEC_DIFF(vPointB,vPointA,vB1);
+	_tp = VEC_DOT(vPointB, _BD);
+	_tp/= VEC_DOT(_BD, _BD);
+	_tp = GIM_CLAMP(_tp,0.0f,1.0f);
+    VEC_SCALE(vPointB,_tp,_BD);
+    VEC_SUM(vPointB,vPointB,vB1);
+}
+
+
+
+
+//! Line box intersection in one dimension
+/*!
+
+*\param pos Position of the ray
+*\param dir Projection of the Direction of the ray
+*\param bmin Minimum bound of the box
+*\param bmax Maximum bound of the box
+*\param tfirst the minimum projection. Assign to 0 at first.
+*\param tlast the maximum projection. Assign to INFINITY at first.
+*\return true if there is an intersection.
+*/
+template<typename T>
+SIMD_FORCE_INLINE bool BOX_AXIS_INTERSECT(T pos, T dir,T bmin, T bmax, T & tfirst, T & tlast)
+{
+	if(GIM_IS_ZERO(dir))
+	{
+        return !(pos < bmin || pos > bmax);
+	}
+	GREAL a0 = (bmin - pos) / dir;
+	GREAL a1 = (bmax - pos) / dir;
+	if(a0 > a1)   GIM_SWAP_NUMBERS(a0, a1);
+	tfirst = GIM_MAX(a0, tfirst);
+	tlast = GIM_MIN(a1, tlast);
+	if (tlast < tfirst) return false;
+	return true;
+}
+
+
+//! Sorts 3 componets
+template<typename T>
+SIMD_FORCE_INLINE void SORT_3_INDICES(
+		const T * values,
+		GUINT * order_indices)
+{
+	//get minimum
+	order_indices[0] = values[0] < values[1] ? (values[0] < values[2] ? 0 : 2) : (values[1] < values[2] ? 1 : 2);
+
+	//get second and third
+	GUINT i0 = (order_indices[0] + 1)%3;
+	GUINT i1 = (i0 + 1)%3;
+
+	if(values[i0] < values[i1])
+	{
+		order_indices[1] = i0;
+		order_indices[2] = i1;
+	}
+	else
+	{
+		order_indices[1] = i1;
+		order_indices[2] = i0;
+	}
+}
+
+
+
+
+
+#endif // GIM_VECTOR_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_bitset.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_bitset.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_bitset.h	(revision 6952)
@@ -0,0 +1,123 @@
+#ifndef GIM_BITSET_H_INCLUDED
+#define GIM_BITSET_H_INCLUDED
+/*! \file gim_bitset.h
+\author Francisco Len Nßjera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "gim_array.h"
+
+
+#define GUINT_BIT_COUNT 32
+#define GUINT_EXPONENT 5
+
+class gim_bitset
+{
+public:
+    gim_array<GUINT> m_container;
+
+    gim_bitset()
+    {
+
+    }
+
+    gim_bitset(GUINT bits_count)
+    {
+        resize(bits_count);
+    }
+
+    ~gim_bitset()
+    {
+    }
+
+	inline bool resize(GUINT newsize)
+	{
+		GUINT oldsize = m_container.size();
+		m_container.resize(newsize/GUINT_BIT_COUNT + 1,false);
+		while(oldsize<m_container.size())
+		{
+			m_container[oldsize] = 0;
+		}
+		return true;
+	}
+
+	inline GUINT size()
+	{
+		return m_container.size()*GUINT_BIT_COUNT;
+	}
+
+	inline void set_all()
+	{
+		for(GUINT i = 0;i<m_container.size();++i)
+		{
+			m_container[i] = 0xffffffff;
+		}
+	}
+
+	inline void clear_all()
+	{
+	    for(GUINT i = 0;i<m_container.size();++i)
+		{
+			m_container[i] = 0;
+		}
+	}
+
+	inline void set(GUINT bit_index)
+	{
+		if(bit_index>=size())
+		{
+			resize(bit_index);
+		}
+		m_container[bit_index >> GUINT_EXPONENT] |= (1 << (bit_index & (GUINT_BIT_COUNT-1)));
+	}
+
+	///Return 0 or 1
+	inline char get(GUINT bit_index)
+	{
+		if(bit_index>=size())
+		{
+			return 0;
+		}
+		char value = m_container[bit_index >> GUINT_EXPONENT] &
+					 (1 << (bit_index & (GUINT_BIT_COUNT-1)));
+		return value;
+	}
+
+	inline void clear(GUINT bit_index)
+	{
+	    m_container[bit_index >> GUINT_EXPONENT] &= ~(1 << (bit_index & (GUINT_BIT_COUNT-1)));
+	}
+};
+
+
+
+
+
+#endif // GIM_CONTAINERS_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_box_collision.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_box_collision.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_box_collision.h	(revision 6952)
@@ -0,0 +1,590 @@
+#ifndef GIM_BOX_COLLISION_H_INCLUDED
+#define GIM_BOX_COLLISION_H_INCLUDED
+
+/*! \file gim_box_collision.h
+\author Francisco Len Nßjera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+#include "gim_basic_geometry_operations.h"
+#include "LinearMath/btTransform.h"
+
+
+
+//SIMD_FORCE_INLINE bool test_cross_edge_box(
+//	const btVector3 & edge,
+//	const btVector3 & absolute_edge,
+//	const btVector3 & pointa,
+//	const btVector3 & pointb, const btVector3 & extend,
+//	int dir_index0,
+//	int dir_index1
+//	int component_index0,
+//	int component_index1)
+//{
+//	// dir coords are -z and y
+//
+//	const btScalar dir0 = -edge[dir_index0];
+//	const btScalar dir1 = edge[dir_index1];
+//	btScalar pmin = pointa[component_index0]*dir0 + pointa[component_index1]*dir1;
+//	btScalar pmax = pointb[component_index0]*dir0 + pointb[component_index1]*dir1;
+//	//find minmax
+//	if(pmin>pmax)
+//	{
+//		GIM_SWAP_NUMBERS(pmin,pmax);
+//	}
+//	//find extends
+//	const btScalar rad = extend[component_index0] * absolute_edge[dir_index0] +
+//					extend[component_index1] * absolute_edge[dir_index1];
+//
+//	if(pmin>rad || -rad>pmax) return false;
+//	return true;
+//}
+//
+//SIMD_FORCE_INLINE bool test_cross_edge_box_X_axis(
+//	const btVector3 & edge,
+//	const btVector3 & absolute_edge,
+//	const btVector3 & pointa,
+//	const btVector3 & pointb, btVector3 & extend)
+//{
+//
+//	return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,2,1,1,2);
+//}
+//
+//
+//SIMD_FORCE_INLINE bool test_cross_edge_box_Y_axis(
+//	const btVector3 & edge,
+//	const btVector3 & absolute_edge,
+//	const btVector3 & pointa,
+//	const btVector3 & pointb, btVector3 & extend)
+//{
+//
+//	return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,0,2,2,0);
+//}
+//
+//SIMD_FORCE_INLINE bool test_cross_edge_box_Z_axis(
+//	const btVector3 & edge,
+//	const btVector3 & absolute_edge,
+//	const btVector3 & pointa,
+//	const btVector3 & pointb, btVector3 & extend)
+//{
+//
+//	return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,1,0,0,1);
+//}
+
+#define TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,i_dir_0,i_dir_1,i_comp_0,i_comp_1)\
+{\
+	const btScalar dir0 = -edge[i_dir_0];\
+	const btScalar dir1 = edge[i_dir_1];\
+	btScalar pmin = pointa[i_comp_0]*dir0 + pointa[i_comp_1]*dir1;\
+	btScalar pmax = pointb[i_comp_0]*dir0 + pointb[i_comp_1]*dir1;\
+	if(pmin>pmax)\
+	{\
+		GIM_SWAP_NUMBERS(pmin,pmax); \
+	}\
+	const btScalar abs_dir0 = absolute_edge[i_dir_0];\
+	const btScalar abs_dir1 = absolute_edge[i_dir_1];\
+	const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1;\
+	if(pmin>rad || -rad>pmax) return false;\
+}\
+
+
+#define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
+{\
+	TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,2,1,1,2);\
+}\
+
+#define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
+{\
+	TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,0,2,2,0);\
+}\
+
+#define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\
+{\
+	TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,1,0,0,1);\
+}\
+
+
+
+//!  Class for transforming a model1 to the space of model0
+class GIM_BOX_BOX_TRANSFORM_CACHE
+{
+public:
+    btVector3  m_T1to0;//!< Transforms translation of model1 to model 0
+	btMatrix3x3 m_R1to0;//!< Transforms Rotation of model1 to model 0, equal  to R0' * R1
+	btMatrix3x3 m_AR;//!< Absolute value of m_R1to0
+
+	SIMD_FORCE_INLINE void calc_absolute_matrix()
+	{
+		static const btVector3 vepsi(1e-6f,1e-6f,1e-6f);
+		m_AR[0] = vepsi + m_R1to0[0].absolute();
+		m_AR[1] = vepsi + m_R1to0[1].absolute();
+		m_AR[2] = vepsi + m_R1to0[2].absolute();
+	}
+
+	GIM_BOX_BOX_TRANSFORM_CACHE()
+	{
+	}
+
+
+	GIM_BOX_BOX_TRANSFORM_CACHE(mat4f  trans1_to_0)
+	{
+		COPY_MATRIX_3X3(m_R1to0,trans1_to_0)
+        MAT_GET_TRANSLATION(trans1_to_0,m_T1to0)
+		calc_absolute_matrix();
+	}
+
+	//! Calc the transformation relative  1 to 0. Inverts matrics by transposing
+	SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform & trans0,const btTransform & trans1)
+	{
+
+		m_R1to0 = trans0.getBasis().transpose();
+		m_T1to0 = m_R1to0 * (-trans0.getOrigin());
+
+		m_T1to0 += m_R1to0*trans1.getOrigin();
+		m_R1to0 *= trans1.getBasis();
+
+		calc_absolute_matrix();
+	}
+
+	//! Calcs the full invertion of the matrices. Useful for scaling matrices
+	SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform & trans0,const btTransform & trans1)
+	{
+		m_R1to0 = trans0.getBasis().inverse();
+		m_T1to0 = m_R1to0 * (-trans0.getOrigin());
+
+		m_T1to0 += m_R1to0*trans1.getOrigin();
+		m_R1to0 *= trans1.getBasis();
+
+		calc_absolute_matrix();
+	}
+
+	SIMD_FORCE_INLINE btVector3 transform(const btVector3 & point)
+	{
+		return btVector3(m_R1to0[0].dot(point) + m_T1to0.x(),
+			m_R1to0[1].dot(point) + m_T1to0.y(),
+			m_R1to0[2].dot(point) + m_T1to0.z());
+	}
+};
+
+
+#define BOX_PLANE_EPSILON 0.000001f
+
+//! Axis aligned box
+class GIM_AABB
+{
+public:
+	btVector3 m_min;
+	btVector3 m_max;
+
+	GIM_AABB()
+	{}
+
+
+	GIM_AABB(const btVector3 & V1,
+			 const btVector3 & V2,
+			 const btVector3 & V3)
+	{
+		m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]);
+		m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]);
+		m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]);
+
+		m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]);
+		m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]);
+		m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]);
+	}
+
+	GIM_AABB(const btVector3 & V1,
+			 const btVector3 & V2,
+			 const btVector3 & V3,
+			 GREAL margin)
+	{
+		m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]);
+		m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]);
+		m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]);
+
+		m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]);
+		m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]);
+		m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]);
+
+		m_min[0] -= margin;
+		m_min[1] -= margin;
+		m_min[2] -= margin;
+		m_max[0] += margin;
+		m_max[1] += margin;
+		m_max[2] += margin;
+	}
+
+	GIM_AABB(const GIM_AABB &other):
+		m_min(other.m_min),m_max(other.m_max)
+	{
+	}
+
+	GIM_AABB(const GIM_AABB &other,btScalar margin ):
+		m_min(other.m_min),m_max(other.m_max)
+	{
+		m_min[0] -= margin;
+		m_min[1] -= margin;
+		m_min[2] -= margin;
+		m_max[0] += margin;
+		m_max[1] += margin;
+		m_max[2] += margin;
+	}
+
+	SIMD_FORCE_INLINE void invalidate()
+	{
+		m_min[0] = G_REAL_INFINITY;
+		m_min[1] = G_REAL_INFINITY;
+		m_min[2] = G_REAL_INFINITY;
+		m_max[0] = -G_REAL_INFINITY;
+		m_max[1] = -G_REAL_INFINITY;
+		m_max[2] = -G_REAL_INFINITY;
+	}
+
+	SIMD_FORCE_INLINE void increment_margin(btScalar margin)
+	{
+		m_min[0] -= margin;
+		m_min[1] -= margin;
+		m_min[2] -= margin;
+		m_max[0] += margin;
+		m_max[1] += margin;
+		m_max[2] += margin;
+	}
+
+	SIMD_FORCE_INLINE void copy_with_margin(const GIM_AABB &other, btScalar margin)
+	{
+		m_min[0] = other.m_min[0] - margin;
+		m_min[1] = other.m_min[1] - margin;
+		m_min[2] = other.m_min[2] - margin;
+
+		m_max[0] = other.m_max[0] + margin;
+		m_max[1] = other.m_max[1] + margin;
+		m_max[2] = other.m_max[2] + margin;
+	}
+
+	template<typename CLASS_POINT>
+	SIMD_FORCE_INLINE void calc_from_triangle(
+							const CLASS_POINT & V1,
+							const CLASS_POINT & V2,
+							const CLASS_POINT & V3)
+	{
+		m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]);
+		m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]);
+		m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]);
+
+		m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]);
+		m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]);
+		m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]);
+	}
+
+	template<typename CLASS_POINT>
+	SIMD_FORCE_INLINE void calc_from_triangle_margin(
+							const CLASS_POINT & V1,
+							const CLASS_POINT & V2,
+							const CLASS_POINT & V3, btScalar margin)
+	{
+		m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]);
+		m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]);
+		m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]);
+
+		m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]);
+		m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]);
+		m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]);
+
+		m_min[0] -= margin;
+		m_min[1] -= margin;
+		m_min[2] -= margin;
+		m_max[0] += margin;
+		m_max[1] += margin;
+		m_max[2] += margin;
+	}
+
+	//! Apply a transform to an AABB
+	SIMD_FORCE_INLINE void appy_transform(const btTransform & trans)
+	{
+		btVector3 center = (m_max+m_min)*0.5f;
+		btVector3 extends = m_max - center;
+		// Compute new center
+		center = trans(center);
+
+		btVector3 textends(extends.dot(trans.getBasis().getRow(0).absolute()),
+ 				 extends.dot(trans.getBasis().getRow(1).absolute()),
+				 extends.dot(trans.getBasis().getRow(2).absolute()));
+
+		m_min = center - textends;
+		m_max = center + textends;
+	}
+
+	//! Merges a Box
+	SIMD_FORCE_INLINE void merge(const GIM_AABB & box)
+	{
+		m_min[0] = GIM_MIN(m_min[0],box.m_min[0]);
+		m_min[1] = GIM_MIN(m_min[1],box.m_min[1]);
+		m_min[2] = GIM_MIN(m_min[2],box.m_min[2]);
+
+		m_max[0] = GIM_MAX(m_max[0],box.m_max[0]);
+		m_max[1] = GIM_MAX(m_max[1],box.m_max[1]);
+		m_max[2] = GIM_MAX(m_max[2],box.m_max[2]);
+	}
+
+	//! Merges a point
+	template<typename CLASS_POINT>
+	SIMD_FORCE_INLINE void merge_point(const CLASS_POINT & point)
+	{
+		m_min[0] = GIM_MIN(m_min[0],point[0]);
+		m_min[1] = GIM_MIN(m_min[1],point[1]);
+		m_min[2] = GIM_MIN(m_min[2],point[2]);
+
+		m_max[0] = GIM_MAX(m_max[0],point[0]);
+		m_max[1] = GIM_MAX(m_max[1],point[1]);
+		m_max[2] = GIM_MAX(m_max[2],point[2]);
+	}
+
+	//! Gets the extend and center
+	SIMD_FORCE_INLINE void get_center_extend(btVector3 & center,btVector3 & extend)  const
+	{
+		center = (m_max+m_min)*0.5f;
+		extend = m_max - center;
+	}
+
+	//! Finds the intersecting box between this box and the other.
+	SIMD_FORCE_INLINE void find_intersection(const GIM_AABB & other, GIM_AABB & intersection)  const
+	{
+		intersection.m_min[0] = GIM_MAX(other.m_min[0],m_min[0]);
+		intersection.m_min[1] = GIM_MAX(other.m_min[1],m_min[1]);
+		intersection.m_min[2] = GIM_MAX(other.m_min[2],m_min[2]);
+
+		intersection.m_max[0] = GIM_MIN(other.m_max[0],m_max[0]);
+		intersection.m_max[1] = GIM_MIN(other.m_max[1],m_max[1]);
+		intersection.m_max[2] = GIM_MIN(other.m_max[2],m_max[2]);
+	}
+
+
+	SIMD_FORCE_INLINE bool has_collision(const GIM_AABB & other) const
+	{
+		if(m_min[0] > other.m_max[0] ||
+		   m_max[0] < other.m_min[0] ||
+		   m_min[1] > other.m_max[1] ||
+		   m_max[1] < other.m_min[1] ||
+		   m_min[2] > other.m_max[2] ||
+		   m_max[2] < other.m_min[2])
+		{
+			return false;
+		}
+		return true;
+	}
+
+	/*! \brief Finds the Ray intersection parameter.
+	\param aabb Aligned box
+	\param vorigin A vec3f with the origin of the ray
+	\param vdir A vec3f with the direction of the ray
+	*/
+	SIMD_FORCE_INLINE bool collide_ray(const btVector3 & vorigin,const btVector3 & vdir)
+	{
+		btVector3 extents,center;
+		this->get_center_extend(center,extents);;
+
+		btScalar Dx = vorigin[0] - center[0];
+		if(GIM_GREATER(Dx, extents[0]) && Dx*vdir[0]>=0.0f)	return false;
+		btScalar Dy = vorigin[1] - center[1];
+		if(GIM_GREATER(Dy, extents[1]) && Dy*vdir[1]>=0.0f)	return false;
+		btScalar Dz = vorigin[2] - center[2];
+		if(GIM_GREATER(Dz, extents[2]) && Dz*vdir[2]>=0.0f)	return false;
+
+
+		btScalar f = vdir[1] * Dz - vdir[2] * Dy;
+		if(btFabs(f) > extents[1]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[1])) return false;
+		f = vdir[2] * Dx - vdir[0] * Dz;
+		if(btFabs(f) > extents[0]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[0]))return false;
+		f = vdir[0] * Dy - vdir[1] * Dx;
+		if(btFabs(f) > extents[0]*btFabs(vdir[1]) + extents[1]*btFabs(vdir[0]))return false;
+		return true;
+	}
+
+
+	SIMD_FORCE_INLINE void projection_interval(const btVector3 & direction, btScalar &vmin, btScalar &vmax) const
+	{
+		btVector3 center = (m_max+m_min)*0.5f;
+		btVector3 extend = m_max-center;
+
+		btScalar _fOrigin =  direction.dot(center);
+		btScalar _fMaximumExtent = extend.dot(direction.absolute());
+		vmin = _fOrigin - _fMaximumExtent;
+		vmax = _fOrigin + _fMaximumExtent;
+	}
+
+	SIMD_FORCE_INLINE ePLANE_INTERSECTION_TYPE plane_classify(const btVector4 &plane) const
+	{
+		btScalar _fmin,_fmax;
+		this->projection_interval(plane,_fmin,_fmax);
+
+		if(plane[3] > _fmax + BOX_PLANE_EPSILON)
+		{
+			return G_BACK_PLANE; // 0
+		}
+
+		if(plane[3]+BOX_PLANE_EPSILON >=_fmin)
+		{
+			return G_COLLIDE_PLANE; //1
+		}
+		return G_FRONT_PLANE;//2
+	}
+
+	SIMD_FORCE_INLINE bool overlapping_trans_conservative(const GIM_AABB & box, btTransform & trans1_to_0)
+	{
+		GIM_AABB tbox = box;
+		tbox.appy_transform(trans1_to_0);
+		return has_collision(tbox);
+	}
+
+	//! transcache is the transformation cache from box to this AABB
+	SIMD_FORCE_INLINE bool overlapping_trans_cache(
+		const GIM_AABB & box,const GIM_BOX_BOX_TRANSFORM_CACHE & transcache, bool fulltest)
+	{
+
+		//Taken from OPCODE
+		btVector3 ea,eb;//extends
+		btVector3 ca,cb;//extends
+		get_center_extend(ca,ea);
+		box.get_center_extend(cb,eb);
+
+
+		btVector3 T;
+		btScalar t,t2;
+		int i;
+
+		// Class I : A's basis vectors
+		for(i=0;i<3;i++)
+		{
+			T[i] =  transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i];
+			t = transcache.m_AR[i].dot(eb) + ea[i];
+			if(GIM_GREATER(T[i], t))	return false;
+		}
+		// Class II : B's basis vectors
+		for(i=0;i<3;i++)
+		{
+			t = MAT_DOT_COL(transcache.m_R1to0,T,i);
+			t2 = MAT_DOT_COL(transcache.m_AR,ea,i) + eb[i];
+			if(GIM_GREATER(t,t2))	return false;
+		}
+		// Class III : 9 cross products
+		if(fulltest)
+		{
+			int j,m,n,o,p,q,r;
+			for(i=0;i<3;i++)
+			{
+				m = (i+1)%3;
+				n = (i+2)%3;
+				o = i==0?1:0;
+				p = i==2?1:2;
+				for(j=0;j<3;j++)
+				{
+					q = j==2?1:2;
+					r = j==0?1:0;
+					t = T[n]*transcache.m_R1to0[m][j] - T[m]*transcache.m_R1to0[n][j];
+					t2 = ea[o]*transcache.m_AR[p][j] + ea[p]*transcache.m_AR[o][j] +
+						eb[r]*transcache.m_AR[i][q] + eb[q]*transcache.m_AR[i][r];
+					if(GIM_GREATER(t,t2))	return false;
+				}
+			}
+		}
+		return true;
+	}
+
+	//! Simple test for planes.
+	SIMD_FORCE_INLINE bool collide_plane(
+		const btVector4 & plane)
+	{
+		ePLANE_INTERSECTION_TYPE classify = plane_classify(plane);
+		return (classify == G_COLLIDE_PLANE);
+	}
+
+	//! test for a triangle, with edges
+	SIMD_FORCE_INLINE bool collide_triangle_exact(
+		const btVector3 & p1,
+		const btVector3 & p2,
+		const btVector3 & p3,
+		const btVector4 & triangle_plane)
+	{
+		if(!collide_plane(triangle_plane)) return false;
+
+		btVector3 center,extends;
+		this->get_center_extend(center,extends);
+
+		const btVector3 v1(p1 - center);
+		const btVector3 v2(p2 - center);
+		const btVector3 v3(p3 - center);
+
+		//First axis
+		btVector3 diff(v2 - v1);
+		btVector3 abs_diff = diff.absolute();
+		//Test With X axis
+		TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v1,v3,extends);
+		//Test With Y axis
+		TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v1,v3,extends);
+		//Test With Z axis
+		TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v1,v3,extends);
+
+
+		diff = v3 - v2;
+		abs_diff = diff.absolute();
+		//Test With X axis
+		TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v2,v1,extends);
+		//Test With Y axis
+		TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v2,v1,extends);
+		//Test With Z axis
+		TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v2,v1,extends);
+
+		diff = v1 - v3;
+		abs_diff = diff.absolute();
+		//Test With X axis
+		TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v3,v2,extends);
+		//Test With Y axis
+		TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v3,v2,extends);
+		//Test With Z axis
+		TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v3,v2,extends);
+
+		return true;
+	}
+};
+
+
+//! Compairison of transformation objects
+SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform & t1,const btTransform & t2)
+{
+	if(!(t1.getOrigin() == t2.getOrigin()) ) return false;
+
+	if(!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0)) ) return false;
+	if(!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1)) ) return false;
+	if(!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2)) ) return false;
+	return true;
+}
+
+
+
+#endif // GIM_BOX_COLLISION_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_box_set.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_box_set.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_box_set.cpp	(revision 6952)
@@ -0,0 +1,182 @@
+
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "gim_box_set.h"
+
+
+GUINT GIM_BOX_TREE::_calc_splitting_axis(
+	gim_array<GIM_AABB_DATA> & primitive_boxes, GUINT startIndex,  GUINT endIndex)
+{
+	GUINT i;
+
+	btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.));
+	btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.));
+	GUINT numIndices = endIndex-startIndex;
+
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
+					 primitive_boxes[i].m_bound.m_min);
+		means+=center;
+	}
+	means *= (btScalar(1.)/(btScalar)numIndices);
+
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btVector3 center = btScalar(0.5)*(primitive_boxes[i].m_bound.m_max +
+					 primitive_boxes[i].m_bound.m_min);
+		btVector3 diff2 = center-means;
+		diff2 = diff2 * diff2;
+		variance += diff2;
+	}
+	variance *= (btScalar(1.)/	((btScalar)numIndices-1)	);
+
+	return variance.maxAxis();
+}
+
+
+GUINT GIM_BOX_TREE::_sort_and_calc_splitting_index(
+	gim_array<GIM_AABB_DATA> & primitive_boxes, GUINT startIndex,
+	GUINT endIndex, GUINT splitAxis)
+{
+	GUINT i;
+	GUINT splitIndex =startIndex;
+	GUINT numIndices = endIndex - startIndex;
+
+	// average of centers
+	btScalar splitValue = 0.0f;
+	for (i=startIndex;i<endIndex;i++)
+	{
+		splitValue+= 0.5f*(primitive_boxes[i].m_bound.m_max[splitAxis] +
+					 primitive_boxes[i].m_bound.m_min[splitAxis]);
+	}
+	splitValue /= (btScalar)numIndices;
+
+	//sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
+	for (i=startIndex;i<endIndex;i++)
+	{
+		btScalar center = 0.5f*(primitive_boxes[i].m_bound.m_max[splitAxis] +
+					 primitive_boxes[i].m_bound.m_min[splitAxis]);
+		if (center > splitValue)
+		{
+			//swap
+			primitive_boxes.swap(i,splitIndex);
+			splitIndex++;
+		}
+	}
+
+	//if the splitIndex causes unbalanced trees, fix this by using the center in between startIndex and endIndex
+	//otherwise the tree-building might fail due to stack-overflows in certain cases.
+	//unbalanced1 is unsafe: it can cause stack overflows
+	//bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1)));
+
+	//unbalanced2 should work too: always use center (perfect balanced trees)
+	//bool unbalanced2 = true;
+
+	//this should be safe too:
+	GUINT rangeBalancedIndices = numIndices/3;
+	bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices)));
+
+	if (unbalanced)
+	{
+		splitIndex = startIndex+ (numIndices>>1);
+	}
+
+	btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex))));
+
+	return splitIndex;
+}
+
+
+void GIM_BOX_TREE::_build_sub_tree(gim_array<GIM_AABB_DATA> & primitive_boxes, GUINT startIndex,  GUINT endIndex)
+{
+	GUINT current_index = m_num_nodes++;
+
+	btAssert((endIndex-startIndex)>0);
+
+	if((endIndex-startIndex) == 1) //we got a leaf
+	{		
+		m_node_array[current_index].m_left = 0;
+		m_node_array[current_index].m_right = 0;
+		m_node_array[current_index].m_escapeIndex = 0;
+
+		m_node_array[current_index].m_bound = primitive_boxes[startIndex].m_bound;
+		m_node_array[current_index].m_data = primitive_boxes[startIndex].m_data;
+		return;
+	}
+
+	//configure inner node
+
+	GUINT splitIndex;
+
+	//calc this node bounding box
+	m_node_array[current_index].m_bound.invalidate();	
+	for (splitIndex=startIndex;splitIndex<endIndex;splitIndex++)
+	{
+		m_node_array[current_index].m_bound.merge(primitive_boxes[splitIndex].m_bound);
+	}
+
+	//calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
+
+	//split axis
+	splitIndex = _calc_splitting_axis(primitive_boxes,startIndex,endIndex);
+
+	splitIndex = _sort_and_calc_splitting_index(
+			primitive_boxes,startIndex,endIndex,splitIndex);
+
+	//configure this inner node : the left node index
+	m_node_array[current_index].m_left = m_num_nodes;
+	//build left child tree
+	_build_sub_tree(primitive_boxes, startIndex, splitIndex );
+
+	//configure this inner node : the right node index
+	m_node_array[current_index].m_right = m_num_nodes;
+
+	//build right child tree
+	_build_sub_tree(primitive_boxes, splitIndex ,endIndex);
+
+	//configure this inner node : the escape index
+	m_node_array[current_index].m_escapeIndex  = m_num_nodes - current_index;
+}
+
+//! stackless build tree
+void GIM_BOX_TREE::build_tree(
+	gim_array<GIM_AABB_DATA> & primitive_boxes)
+{
+	// initialize node count to 0
+	m_num_nodes = 0;
+	// allocate nodes
+	m_node_array.resize(primitive_boxes.size()*2);
+	
+	_build_sub_tree(primitive_boxes, 0, primitive_boxes.size());
+}
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_box_set.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_box_set.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_box_set.h	(revision 6952)
@@ -0,0 +1,671 @@
+#ifndef GIM_BOX_SET_H_INCLUDED
+#define GIM_BOX_SET_H_INCLUDED
+
+/*! \file gim_box_set.h
+\author Francisco Len Nßjera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "gim_array.h"
+#include "gim_radixsort.h"
+#include "gim_box_collision.h"
+#include "gim_tri_collision.h"
+
+
+
+//! Overlapping pair
+struct GIM_PAIR
+{
+    GUINT m_index1;
+    GUINT m_index2;
+    GIM_PAIR()
+    {}
+
+    GIM_PAIR(const GIM_PAIR & p)
+    {
+    	m_index1 = p.m_index1;
+    	m_index2 = p.m_index2;
+	}
+
+	GIM_PAIR(GUINT index1, GUINT index2)
+    {
+    	m_index1 = index1;
+    	m_index2 = index2;
+	}
+};
+
+//! A pairset array
+class gim_pair_set: public gim_array<GIM_PAIR>
+{
+public:
+	gim_pair_set():gim_array<GIM_PAIR>(32)
+	{
+	}
+	inline void push_pair(GUINT index1,GUINT index2)
+	{
+		push_back(GIM_PAIR(index1,index2));
+	}
+
+	inline void push_pair_inv(GUINT index1,GUINT index2)
+	{
+		push_back(GIM_PAIR(index2,index1));
+	}
+};
+
+
+//! Prototype Base class for primitive classification
+/*!
+This class is a wrapper for primitive collections.
+This tells relevant info for the Bounding Box set classes, which take care of space classification.
+This class can manage Compound shapes and trimeshes, and if it is managing trimesh then the  Hierarchy Bounding Box classes will take advantage of primitive Vs Box overlapping tests for getting optimal results and less Per Box compairisons.
+*/
+class GIM_PRIMITIVE_MANAGER_PROTOTYPE
+{
+public:
+
+	//! determines if this manager consist on only triangles, which special case will be optimized
+	virtual bool is_trimesh() = 0;
+	virtual GUINT get_primitive_count() = 0;
+	virtual void get_primitive_box(GUINT prim_index ,GIM_AABB & primbox) = 0;
+	virtual void get_primitive_triangle(GUINT prim_index,GIM_TRIANGLE & triangle) = 0;
+};
+
+
+struct GIM_AABB_DATA
+{
+	GIM_AABB m_bound;
+	GUINT m_data;
+};
+
+//! Node Structure for trees
+struct GIM_BOX_TREE_NODE
+{
+	GIM_AABB m_bound;
+	GUINT m_left;//!< Left subtree
+	GUINT m_right;//!< Right subtree
+	GUINT m_escapeIndex;//!< Scape index for traversing
+	GUINT m_data;//!< primitive index if apply
+
+	GIM_BOX_TREE_NODE()
+	{
+	    m_left = 0;
+	    m_right = 0;
+	    m_escapeIndex = 0;
+	    m_data = 0;
+	}
+
+	SIMD_FORCE_INLINE bool is_leaf_node() const
+	{
+	    return  (!m_left && !m_right);
+	}
+};
+
+//! Basic Box tree structure
+class GIM_BOX_TREE
+{
+protected:
+	GUINT m_num_nodes;
+	gim_array<GIM_BOX_TREE_NODE> m_node_array;
+protected:
+	GUINT _sort_and_calc_splitting_index(
+		gim_array<GIM_AABB_DATA> & primitive_boxes,
+		 GUINT startIndex,  GUINT endIndex, GUINT splitAxis);
+
+	GUINT _calc_splitting_axis(gim_array<GIM_AABB_DATA> & primitive_boxes, GUINT startIndex,  GUINT endIndex);
+
+	void _build_sub_tree(gim_array<GIM_AABB_DATA> & primitive_boxes, GUINT startIndex,  GUINT endIndex);
+public:
+	GIM_BOX_TREE()
+	{
+		m_num_nodes = 0;
+	}
+
+	//! prototype functions for box tree management
+	//!@{
+	void build_tree(gim_array<GIM_AABB_DATA> & primitive_boxes);
+
+	SIMD_FORCE_INLINE void clearNodes()
+	{
+		m_node_array.clear();
+		m_num_nodes = 0;
+	}
+
+	//! node count
+	SIMD_FORCE_INLINE GUINT getNodeCount() const
+	{
+		return m_num_nodes;
+	}
+
+	//! tells if the node is a leaf
+	SIMD_FORCE_INLINE bool isLeafNode(GUINT nodeindex) const
+	{
+		return m_node_array[nodeindex].is_leaf_node();
+	}
+
+	SIMD_FORCE_INLINE GUINT getNodeData(GUINT nodeindex) const
+	{
+		return m_node_array[nodeindex].m_data;
+	}
+
+	SIMD_FORCE_INLINE void getNodeBound(GUINT nodeindex, GIM_AABB & bound) const
+	{
+		bound = m_node_array[nodeindex].m_bound;
+	}
+
+	SIMD_FORCE_INLINE void setNodeBound(GUINT nodeindex, const GIM_AABB & bound)
+	{
+		m_node_array[nodeindex].m_bound = bound;
+	}
+
+	SIMD_FORCE_INLINE GUINT getLeftNodeIndex(GUINT nodeindex)  const
+	{
+		return m_node_array[nodeindex].m_left;
+	}
+
+	SIMD_FORCE_INLINE GUINT getRightNodeIndex(GUINT nodeindex)  const
+	{
+		return m_node_array[nodeindex].m_right;
+	}
+
+	SIMD_FORCE_INLINE GUINT getScapeNodeIndex(GUINT nodeindex) const
+	{
+		return m_node_array[nodeindex].m_escapeIndex;
+	}
+
+	//!@}
+};
+
+
+//! Generic Box Tree Template
+/*!
+This class offers an structure for managing a box tree of primitives.
+Requires a Primitive prototype (like GIM_PRIMITIVE_MANAGER_PROTOTYPE ) and
+a Box tree structure ( like GIM_BOX_TREE).
+*/
+template<typename _GIM_PRIMITIVE_MANAGER_PROTOTYPE, typename _GIM_BOX_TREE_PROTOTYPE>
+class GIM_BOX_TREE_TEMPLATE_SET
+{
+protected:
+	_GIM_PRIMITIVE_MANAGER_PROTOTYPE m_primitive_manager;
+	_GIM_BOX_TREE_PROTOTYPE m_box_tree;
+protected:
+	//stackless refit
+	SIMD_FORCE_INLINE void refit()
+	{
+		GUINT nodecount = getNodeCount();
+		while(nodecount--)
+		{
+			if(isLeafNode(nodecount))
+			{
+				GIM_AABB leafbox;
+				m_primitive_manager.get_primitive_box(getNodeData(nodecount),leafbox);
+				setNodeBound(nodecount,leafbox);
+			}
+			else
+			{
+				//get left bound
+				GUINT childindex = getLeftNodeIndex(nodecount);
+				GIM_AABB bound;
+				getNodeBound(childindex,bound);
+				//get right bound
+				childindex = getRightNodeIndex(nodecount);
+				GIM_AABB bound2;
+				getNodeBound(childindex,bound2);
+				bound.merge(bound2);
+
+				setNodeBound(nodecount,bound);
+			}
+		}
+	}
+public:
+
+	GIM_BOX_TREE_TEMPLATE_SET()
+	{
+	}
+
+	SIMD_FORCE_INLINE GIM_AABB getGlobalBox()  const
+	{
+		GIM_AABB totalbox;
+		getNodeBound(0, totalbox);
+		return totalbox;
+	}
+
+	SIMD_FORCE_INLINE void setPrimitiveManager(const _GIM_PRIMITIVE_MANAGER_PROTOTYPE & primitive_manager)
+	{
+		m_primitive_manager = primitive_manager;
+	}
+
+	const _GIM_PRIMITIVE_MANAGER_PROTOTYPE & getPrimitiveManager() const
+	{
+		return m_primitive_manager;
+	}
+
+	_GIM_PRIMITIVE_MANAGER_PROTOTYPE & getPrimitiveManager()
+	{
+		return m_primitive_manager;
+	}
+
+//! node manager prototype functions
+///@{
+
+	//! this attemps to refit the box set.
+	SIMD_FORCE_INLINE void update()
+	{
+		refit();
+	}
+
+	//! this rebuild the entire set
+	SIMD_FORCE_INLINE void buildSet()
+	{
+		//obtain primitive boxes
+		gim_array<GIM_AABB_DATA> primitive_boxes;
+		primitive_boxes.resize(m_primitive_manager.get_primitive_count(),false);
+
+		for (GUINT i = 0;i<primitive_boxes.size() ;i++ )
+		{
+			 m_primitive_manager.get_primitive_box(i,primitive_boxes[i].m_bound);
+			 primitive_boxes[i].m_data = i;
+		}
+
+		m_box_tree.build_tree(primitive_boxes);
+	}
+
+	//! returns the indices of the primitives in the m_primitive_manager
+	SIMD_FORCE_INLINE bool boxQuery(const GIM_AABB & box, gim_array<GUINT> & collided_results) const
+	{
+		GUINT curIndex = 0;
+		GUINT numNodes = getNodeCount();
+
+		while (curIndex < numNodes)
+		{
+			GIM_AABB bound;
+			getNodeBound(curIndex,bound);
+
+			//catch bugs in tree data
+
+			bool aabbOverlap = bound.has_collision(box);
+			bool isleafnode = isLeafNode(curIndex);
+
+			if (isleafnode && aabbOverlap)
+			{
+				collided_results.push_back(getNodeData(curIndex));
+			}
+
+			if (aabbOverlap || isleafnode)
+			{
+				//next subnode
+				curIndex++;
+			}
+			else
+			{
+				//skip node
+				curIndex+= getScapeNodeIndex(curIndex);
+			}
+		}
+		if(collided_results.size()>0) return true;
+		return false;
+	}
+
+	//! returns the indices of the primitives in the m_primitive_manager
+	SIMD_FORCE_INLINE bool boxQueryTrans(const GIM_AABB & box,
+		 const btTransform & transform, gim_array<GUINT> & collided_results) const
+	{
+		GIM_AABB transbox=box;
+		transbox.appy_transform(transform);
+		return boxQuery(transbox,collided_results);
+	}
+
+	//! returns the indices of the primitives in the m_primitive_manager
+	SIMD_FORCE_INLINE bool rayQuery(
+		const btVector3 & ray_dir,const btVector3 & ray_origin ,
+		gim_array<GUINT> & collided_results) const
+	{
+		GUINT curIndex = 0;
+		GUINT numNodes = getNodeCount();
+
+		while (curIndex < numNodes)
+		{
+			GIM_AABB bound;
+			getNodeBound(curIndex,bound);
+
+			//catch bugs in tree data
+
+			bool aabbOverlap = bound.collide_ray(ray_origin,ray_dir);
+			bool isleafnode = isLeafNode(curIndex);
+
+			if (isleafnode && aabbOverlap)
+			{
+				collided_results.push_back(getNodeData( curIndex));
+			}
+
+			if (aabbOverlap || isleafnode)
+			{
+				//next subnode
+				curIndex++;
+			}
+			else
+			{
+				//skip node
+				curIndex+= getScapeNodeIndex(curIndex);
+			}
+		}
+		if(collided_results.size()>0) return true;
+		return false;
+	}
+
+	//! tells if this set has hierarcht
+	SIMD_FORCE_INLINE bool hasHierarchy() const
+	{
+		return true;
+	}
+
+	//! tells if this set is a trimesh
+	SIMD_FORCE_INLINE bool isTrimesh()  const
+	{
+		return m_primitive_manager.is_trimesh();
+	}
+
+	//! node count
+	SIMD_FORCE_INLINE GUINT getNodeCount() const
+	{
+		return m_box_tree.getNodeCount();
+	}
+
+	//! tells if the node is a leaf
+	SIMD_FORCE_INLINE bool isLeafNode(GUINT nodeindex) const
+	{
+		return m_box_tree.isLeafNode(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE GUINT getNodeData(GUINT nodeindex) const
+	{
+		return m_box_tree.getNodeData(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE void getNodeBound(GUINT nodeindex, GIM_AABB & bound)  const
+	{
+		m_box_tree.getNodeBound(nodeindex, bound);
+	}
+
+	SIMD_FORCE_INLINE void setNodeBound(GUINT nodeindex, const GIM_AABB & bound)
+	{
+		m_box_tree.setNodeBound(nodeindex, bound);
+	}
+
+	SIMD_FORCE_INLINE GUINT getLeftNodeIndex(GUINT nodeindex) const
+	{
+		return m_box_tree.getLeftNodeIndex(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE GUINT getRightNodeIndex(GUINT nodeindex) const
+	{
+		return m_box_tree.getRightNodeIndex(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE GUINT getScapeNodeIndex(GUINT nodeindex) const
+	{
+		return m_box_tree.getScapeNodeIndex(nodeindex);
+	}
+
+	SIMD_FORCE_INLINE void getNodeTriangle(GUINT nodeindex,GIM_TRIANGLE & triangle) const
+	{
+		m_primitive_manager.get_primitive_triangle(getNodeData(nodeindex),triangle);
+	}
+
+};
+
+//! Class for Box Tree Sets
+/*!
+this has the GIM_BOX_TREE implementation for bounding boxes.
+*/
+template<typename _GIM_PRIMITIVE_MANAGER_PROTOTYPE>
+class GIM_BOX_TREE_SET: public GIM_BOX_TREE_TEMPLATE_SET< _GIM_PRIMITIVE_MANAGER_PROTOTYPE, GIM_BOX_TREE>
+{
+public:
+
+};
+
+
+
+
+
+/// GIM_BOX_SET collision methods
+template<typename BOX_SET_CLASS0,typename BOX_SET_CLASS1>
+class GIM_TREE_TREE_COLLIDER
+{
+public:
+	gim_pair_set * m_collision_pairs;
+	BOX_SET_CLASS0 * m_boxset0;
+	BOX_SET_CLASS1 * m_boxset1;
+	GUINT current_node0;
+	GUINT current_node1;
+	bool node0_is_leaf;
+	bool node1_is_leaf;
+	bool t0_is_trimesh;
+	bool t1_is_trimesh;
+	bool node0_has_triangle;
+	bool node1_has_triangle;
+	GIM_AABB m_box0;
+	GIM_AABB m_box1;
+	GIM_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0;
+	btTransform trans_cache_0to1;
+	GIM_TRIANGLE m_tri0;
+	btVector4 m_tri0_plane;
+	GIM_TRIANGLE m_tri1;
+	btVector4 m_tri1_plane;
+
+
+public:
+	GIM_TREE_TREE_COLLIDER()
+	{
+		current_node0 = G_UINT_INFINITY;
+		current_node1 = G_UINT_INFINITY;
+	}
+protected:
+	SIMD_FORCE_INLINE void retrieve_node0_triangle(GUINT node0)
+	{
+		if(node0_has_triangle) return;
+		m_boxset0->getNodeTriangle(node0,m_tri0);
+		//transform triangle
+		m_tri0.m_vertices[0] = trans_cache_0to1(m_tri0.m_vertices[0]);
+		m_tri0.m_vertices[1] = trans_cache_0to1(m_tri0.m_vertices[1]);
+		m_tri0.m_vertices[2] = trans_cache_0to1(m_tri0.m_vertices[2]);
+		m_tri0.get_plane(m_tri0_plane);
+
+		node0_has_triangle = true;
+	}
+
+	SIMD_FORCE_INLINE void retrieve_node1_triangle(GUINT node1)
+	{
+		if(node1_has_triangle) return;
+		m_boxset1->getNodeTriangle(node1,m_tri1);
+		//transform triangle
+		m_tri1.m_vertices[0] = trans_cache_1to0.transform(m_tri1.m_vertices[0]);
+		m_tri1.m_vertices[1] = trans_cache_1to0.transform(m_tri1.m_vertices[1]);
+		m_tri1.m_vertices[2] = trans_cache_1to0.transform(m_tri1.m_vertices[2]);
+		m_tri1.get_plane(m_tri1_plane);
+
+		node1_has_triangle = true;
+	}
+
+	SIMD_FORCE_INLINE void retrieve_node0_info(GUINT node0)
+	{
+		if(node0 == current_node0) return;
+		m_boxset0->getNodeBound(node0,m_box0);
+		node0_is_leaf = m_boxset0->isLeafNode(node0);
+		node0_has_triangle = false;
+		current_node0 = node0;
+	}
+
+	SIMD_FORCE_INLINE void retrieve_node1_info(GUINT node1)
+	{
+		if(node1 == current_node1) return;
+		m_boxset1->getNodeBound(node1,m_box1);
+		node1_is_leaf = m_boxset1->isLeafNode(node1);
+		node1_has_triangle = false;
+		current_node1 = node1;
+	}
+
+	SIMD_FORCE_INLINE bool node_collision(GUINT node0 ,GUINT node1)
+	{
+		retrieve_node0_info(node0);
+		retrieve_node1_info(node1);
+		bool result = m_box0.overlapping_trans_cache(m_box1,trans_cache_1to0,true);
+		if(!result) return false;
+
+		if(t0_is_trimesh && node0_is_leaf)
+		{
+			//perform primitive vs box collision
+			retrieve_node0_triangle(node0);
+			//do triangle vs box collision
+			m_box1.increment_margin(m_tri0.m_margin);
+
+			result = m_box1.collide_triangle_exact(
+				m_tri0.m_vertices[0],m_tri0.m_vertices[1],m_tri0.m_vertices[2],m_tri0_plane);
+
+			m_box1.increment_margin(-m_tri0.m_margin);
+
+			if(!result) return false;
+			return true;
+		}
+		else if(t1_is_trimesh && node1_is_leaf)
+		{
+			//perform primitive vs box collision
+			retrieve_node1_triangle(node1);
+			//do triangle vs box collision
+			m_box0.increment_margin(m_tri1.m_margin);
+
+			result = m_box0.collide_triangle_exact(
+				m_tri1.m_vertices[0],m_tri1.m_vertices[1],m_tri1.m_vertices[2],m_tri1_plane);
+
+			m_box0.increment_margin(-m_tri1.m_margin);
+
+			if(!result) return false;
+			return true;
+		}
+		return true;
+	}
+
+	//stackless collision routine
+	void find_collision_pairs()
+	{
+		gim_pair_set stack_collisions;
+		stack_collisions.reserve(32);
+
+		//add the first pair
+		stack_collisions.push_pair(0,0);
+
+
+		while(stack_collisions.size())
+		{
+			//retrieve the last pair and pop
+			GUINT node0 = stack_collisions.back().m_index1;
+			GUINT node1 = stack_collisions.back().m_index2;
+			stack_collisions.pop_back();
+			if(node_collision(node0,node1)) // a collision is found
+			{
+				if(node0_is_leaf)
+				{
+					if(node1_is_leaf)
+					{
+						m_collision_pairs->push_pair(m_boxset0->getNodeData(node0),m_boxset1->getNodeData(node1));
+					}
+					else
+					{
+						//collide left
+						stack_collisions.push_pair(node0,m_boxset1->getLeftNodeIndex(node1));
+
+						//collide right
+						stack_collisions.push_pair(node0,m_boxset1->getRightNodeIndex(node1));
+					}
+				}
+				else
+				{
+					if(node1_is_leaf)
+					{
+						//collide left
+						stack_collisions.push_pair(m_boxset0->getLeftNodeIndex(node0),node1);
+						//collide right
+						stack_collisions.push_pair(m_boxset0->getRightNodeIndex(node0),node1);
+					}
+					else
+					{
+						GUINT left0 = m_boxset0->getLeftNodeIndex(node0);
+						GUINT right0 = m_boxset0->getRightNodeIndex(node0);
+						GUINT left1 = m_boxset1->getLeftNodeIndex(node1);
+						GUINT right1 = m_boxset1->getRightNodeIndex(node1);
+						//collide left
+						stack_collisions.push_pair(left0,left1);
+						//collide right
+						stack_collisions.push_pair(left0,right1);
+						//collide left
+						stack_collisions.push_pair(right0,left1);
+						//collide right
+						stack_collisions.push_pair(right0,right1);
+
+					}// else if node1 is not a leaf
+				}// else if node0 is not a leaf
+
+			}// if(node_collision(node0,node1))
+		}//while(stack_collisions.size())
+	}
+public:
+	void find_collision(BOX_SET_CLASS0 * boxset1, const btTransform & trans1,
+		BOX_SET_CLASS1 * boxset2, const btTransform & trans2,
+		gim_pair_set & collision_pairs, bool complete_primitive_tests = true)
+	{
+		m_collision_pairs = &collision_pairs;
+		m_boxset0 = boxset1;
+		m_boxset1 = boxset2;
+
+		trans_cache_1to0.calc_from_homogenic(trans1,trans2);
+
+		trans_cache_0to1 =  trans2.inverse();
+		trans_cache_0to1 *= trans1;
+
+
+		if(complete_primitive_tests)
+		{
+			t0_is_trimesh = boxset1->getPrimitiveManager().is_trimesh();
+			t1_is_trimesh = boxset2->getPrimitiveManager().is_trimesh();
+		}
+		else
+		{
+			t0_is_trimesh = false;
+			t1_is_trimesh = false;
+		}
+
+		find_collision_pairs();
+	}
+};
+
+
+#endif // GIM_BOXPRUNING_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_clip_polygon.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_clip_polygon.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_clip_polygon.h	(revision 6952)
@@ -0,0 +1,210 @@
+#ifndef GIM_CLIP_POLYGON_H_INCLUDED
+#define GIM_CLIP_POLYGON_H_INCLUDED
+
+/*! \file gim_tri_collision.h
+\author Francisco Len Nßjera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+//! This function calcs the distance from a 3D plane
+class DISTANCE_PLANE_3D_FUNC
+{
+public:
+	template<typename CLASS_POINT,typename CLASS_PLANE>
+	inline GREAL operator()(const CLASS_PLANE & plane, const CLASS_POINT & point)
+	{
+		return DISTANCE_PLANE_POINT(plane, point);
+	}
+};
+
+
+
+template<typename CLASS_POINT>
+SIMD_FORCE_INLINE void PLANE_CLIP_POLYGON_COLLECT(
+						const CLASS_POINT & point0,
+						const CLASS_POINT & point1,
+						GREAL dist0,
+						GREAL dist1,
+						CLASS_POINT * clipped,
+						GUINT & clipped_count)
+{
+	GUINT _prevclassif = (dist0>G_EPSILON);
+	GUINT _classif = (dist1>G_EPSILON);
+	if(_classif!=_prevclassif)
+	{
+		GREAL blendfactor = -dist0/(dist1-dist0);
+		VEC_BLEND(clipped[clipped_count],point0,point1,blendfactor);
+		clipped_count++;
+	}
+	if(!_classif)
+	{
+		VEC_COPY(clipped[clipped_count],point1);
+		clipped_count++;
+	}
+}
+
+
+//! Clips a polygon by a plane
+/*!
+*\return The count of the clipped counts
+*/
+template<typename CLASS_POINT,typename CLASS_PLANE, typename DISTANCE_PLANE_FUNC>
+SIMD_FORCE_INLINE GUINT PLANE_CLIP_POLYGON_GENERIC(
+						const CLASS_PLANE & plane,
+						const CLASS_POINT * polygon_points,
+						GUINT polygon_point_count,
+						CLASS_POINT * clipped,DISTANCE_PLANE_FUNC distance_func)
+{
+    GUINT clipped_count = 0;
+
+
+    //clip first point
+	GREAL firstdist = distance_func(plane,polygon_points[0]);;
+	if(!(firstdist>G_EPSILON))
+	{
+		VEC_COPY(clipped[clipped_count],polygon_points[0]);
+		clipped_count++;
+	}
+
+	GREAL olddist = firstdist;
+	for(GUINT _i=1;_i<polygon_point_count;_i++)
+	{		
+		GREAL dist = distance_func(plane,polygon_points[_i]);
+
+		PLANE_CLIP_POLYGON_COLLECT(
+						polygon_points[_i-1],polygon_points[_i],
+						olddist,
+						dist,
+						clipped,
+						clipped_count);
+
+
+		olddist = dist;		
+	}
+
+	//RETURN TO FIRST  point	
+
+	PLANE_CLIP_POLYGON_COLLECT(
+					polygon_points[polygon_point_count-1],polygon_points[0],
+					olddist,
+					firstdist,
+					clipped,
+					clipped_count);
+
+	return clipped_count;
+}
+
+//! Clips a polygon by a plane
+/*!
+*\return The count of the clipped counts
+*/
+template<typename CLASS_POINT,typename CLASS_PLANE, typename DISTANCE_PLANE_FUNC>
+SIMD_FORCE_INLINE GUINT PLANE_CLIP_TRIANGLE_GENERIC(
+						const CLASS_PLANE & plane,
+						const CLASS_POINT & point0,
+						const CLASS_POINT & point1,
+						const CLASS_POINT & point2,
+						CLASS_POINT * clipped,DISTANCE_PLANE_FUNC distance_func)
+{
+    GUINT clipped_count = 0;
+
+    //clip first point
+	GREAL firstdist = distance_func(plane,point0);;
+	if(!(firstdist>G_EPSILON))
+	{
+		VEC_COPY(clipped[clipped_count],point0);
+		clipped_count++;
+	}
+
+	// point 1
+	GREAL olddist = firstdist;
+	GREAL dist = distance_func(plane,point1);
+
+	PLANE_CLIP_POLYGON_COLLECT(
+					point0,point1,
+					olddist,
+					dist,
+					clipped,
+					clipped_count);
+
+	olddist = dist;
+
+
+	// point 2
+	dist = distance_func(plane,point2);
+
+	PLANE_CLIP_POLYGON_COLLECT(
+					point1,point2,
+					olddist,
+					dist,
+					clipped,
+					clipped_count);
+	olddist = dist;
+
+
+
+	//RETURN TO FIRST  point
+	PLANE_CLIP_POLYGON_COLLECT(
+					point2,point0,
+					olddist,
+					firstdist,
+					clipped,
+					clipped_count);
+
+	return clipped_count;
+}
+
+
+template<typename CLASS_POINT,typename CLASS_PLANE>
+SIMD_FORCE_INLINE GUINT PLANE_CLIP_POLYGON3D(
+						const CLASS_PLANE & plane,
+						const CLASS_POINT * polygon_points,
+						GUINT polygon_point_count,
+						CLASS_POINT * clipped)
+{
+	return PLANE_CLIP_POLYGON_GENERIC<CLASS_POINT,CLASS_PLANE>(plane,polygon_points,polygon_point_count,clipped,DISTANCE_PLANE_3D_FUNC());
+}
+
+
+template<typename CLASS_POINT,typename CLASS_PLANE>
+SIMD_FORCE_INLINE GUINT PLANE_CLIP_TRIANGLE3D(
+						const CLASS_PLANE & plane,
+						const CLASS_POINT & point0,
+						const CLASS_POINT & point1,
+						const CLASS_POINT & point2,
+						CLASS_POINT * clipped)
+{
+	return PLANE_CLIP_TRIANGLE_GENERIC<CLASS_POINT,CLASS_PLANE>(plane,point0,point1,point2,clipped,DISTANCE_PLANE_3D_FUNC());
+}
+
+
+
+#endif // GIM_TRI_COLLISION_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_contact.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_contact.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_contact.cpp	(revision 6952)
@@ -0,0 +1,146 @@
+
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "gim_contact.h"
+
+#define MAX_COINCIDENT 8
+
+void gim_contact_array::merge_contacts(
+	const gim_contact_array & contacts, bool normal_contact_average)
+{
+	clear();
+
+	if(contacts.size()==1)
+	{
+		push_back(contacts.back());
+		return;
+	}
+
+	gim_array<GIM_RSORT_TOKEN> keycontacts(contacts.size());
+	keycontacts.resize(contacts.size(),false);
+
+	//fill key contacts
+
+	GUINT i;
+
+	for (i = 0;i<contacts.size() ;i++ )
+	{
+		keycontacts[i].m_key = contacts[i].calc_key_contact();
+		keycontacts[i].m_value = i;
+	}
+
+	//sort keys
+	gim_heap_sort(keycontacts.pointer(),keycontacts.size(),GIM_RSORT_TOKEN_COMPARATOR());
+
+	// Merge contacts
+
+	GUINT coincident_count=0;
+	btVector3 coincident_normals[MAX_COINCIDENT];
+
+	GUINT last_key = keycontacts[0].m_key;
+	GUINT key = 0;
+
+	push_back(contacts[keycontacts[0].m_value]);
+	GIM_CONTACT * pcontact = &back();
+
+
+
+	for( i=1;i<keycontacts.size();i++)
+	{
+	    key = keycontacts[i].m_key;
+		const GIM_CONTACT * scontact = &contacts[keycontacts[i].m_value];
+
+		if(last_key ==  key)//same points
+		{
+			//merge contact
+			if(pcontact->m_depth - CONTACT_DIFF_EPSILON > scontact->m_depth)//)
+			{
+				*pcontact = *scontact;
+                coincident_count = 0;
+			}
+			else if(normal_contact_average)
+			{
+				if(btFabs(pcontact->m_depth - scontact->m_depth)<CONTACT_DIFF_EPSILON)
+                {
+                    if(coincident_count<MAX_COINCIDENT)
+                    {
+                    	coincident_normals[coincident_count] = scontact->m_normal;
+                        coincident_count++;
+                    }
+                }
+			}
+		}
+		else
+		{//add new contact
+
+		    if(normal_contact_average && coincident_count>0)
+		    {
+		    	pcontact->interpolate_normals(coincident_normals,coincident_count);
+		        coincident_count = 0;
+		    }
+
+		    push_back(*scontact);
+		    pcontact = &back();
+        }
+		last_key = key;
+	}
+}
+
+void gim_contact_array::merge_contacts_unique(const gim_contact_array & contacts)
+{
+	clear();
+
+	if(contacts.size()==1)
+	{
+		push_back(contacts.back());
+		return;
+	}
+
+	GIM_CONTACT average_contact = contacts.back();
+
+	for (GUINT i=1;i<contacts.size() ;i++ )
+	{
+		average_contact.m_point += contacts[i].m_point;
+		average_contact.m_normal += contacts[i].m_normal * contacts[i].m_depth;
+	}
+
+	//divide
+	GREAL divide_average = 1.0f/((GREAL)contacts.size());
+
+	average_contact.m_point *= divide_average;
+
+	average_contact.m_normal *= divide_average;
+
+	average_contact.m_depth = average_contact.m_normal.length();
+
+	average_contact.m_normal /= average_contact.m_depth;
+
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_contact.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_contact.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_contact.h	(revision 6952)
@@ -0,0 +1,164 @@
+#ifndef GIM_CONTACT_H_INCLUDED
+#define GIM_CONTACT_H_INCLUDED
+
+/*! \file gim_contact.h
+\author Francisco Len Nßjera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+#include "gim_geometry.h"
+#include "gim_radixsort.h"
+#include "gim_array.h"
+
+
+/**
+Configuration var for applying interpolation of  contact normals
+*/
+#define NORMAL_CONTACT_AVERAGE 1
+#define CONTACT_DIFF_EPSILON 0.00001f
+
+/// Structure for collision results
+///Functions for managing and sorting contacts resulting from a collision query.
+///Contact lists must be create by calling \ref GIM_CREATE_CONTACT_LIST
+///After querys, contact lists must be destroy by calling \ref GIM_DYNARRAY_DESTROY
+///Contacts can be merge for avoid duplicate results by calling \ref gim_merge_contacts
+class GIM_CONTACT
+{
+public:
+    btVector3 m_point;
+    btVector3 m_normal;
+    GREAL m_depth;//Positive value indicates interpenetration
+    GREAL m_distance;//Padding not for use
+    GUINT m_feature1;//Face number
+    GUINT m_feature2;//Face number
+public:
+    GIM_CONTACT()
+    {
+    }
+
+    GIM_CONTACT(const GIM_CONTACT & contact):
+				m_point(contact.m_point),
+				m_normal(contact.m_normal),
+				m_depth(contact.m_depth),
+				m_feature1(contact.m_feature1),
+				m_feature2(contact.m_feature2)
+    {
+    	m_point = contact.m_point;
+    	m_normal = contact.m_normal;
+    	m_depth = contact.m_depth;
+    	m_feature1 = contact.m_feature1;
+    	m_feature2 = contact.m_feature2;
+    }
+
+    GIM_CONTACT(const btVector3 &point,const btVector3 & normal,
+    	 			GREAL depth, GUINT feature1, GUINT feature2):
+				m_point(point),
+				m_normal(normal),
+				m_depth(depth),
+				m_feature1(feature1),
+				m_feature2(feature2)
+    {
+    }
+
+	//! Calcs key for coord classification
+    SIMD_FORCE_INLINE GUINT calc_key_contact() const
+    {
+    	GINT _coords[] = {
+    		(GINT)(m_point[0]*1000.0f+1.0f),
+    		(GINT)(m_point[1]*1333.0f),
+    		(GINT)(m_point[2]*2133.0f+3.0f)};
+		GUINT _hash=0;
+		GUINT *_uitmp = (GUINT *)(&_coords[0]);
+		_hash = *_uitmp;
+		_uitmp++;
+		_hash += (*_uitmp)<<4;
+		_uitmp++;
+		_hash += (*_uitmp)<<8;
+		return _hash;
+    }
+
+    SIMD_FORCE_INLINE void interpolate_normals( btVector3 * normals,GUINT normal_count)
+    {
+    	btVector3 vec_sum(m_normal);
+		for(GUINT i=0;i<normal_count;i++)
+		{
+			vec_sum += normals[i];
+		}
+
+		GREAL vec_sum_len = vec_sum.length2();
+		if(vec_sum_len <CONTACT_DIFF_EPSILON) return;
+
+		GIM_INV_SQRT(vec_sum_len,vec_sum_len); // 1/sqrt(vec_sum_len)
+
+		m_normal = vec_sum*vec_sum_len;
+    }
+
+};
+
+
+class gim_contact_array:public gim_array<GIM_CONTACT>
+{
+public:
+	gim_contact_array():gim_array<GIM_CONTACT>(64)
+	{
+	}
+
+	SIMD_FORCE_INLINE void push_contact(const btVector3 &point,const btVector3 & normal,
+    	 			GREAL depth, GUINT feature1, GUINT feature2)
+	{
+		push_back_mem();
+		GIM_CONTACT & newele = back();
+		newele.m_point = point;
+		newele.m_normal = normal;
+		newele.m_depth = depth;
+		newele.m_feature1 = feature1;
+		newele.m_feature2 = feature2;
+	}
+
+	SIMD_FORCE_INLINE void push_triangle_contacts(
+		const GIM_TRIANGLE_CONTACT_DATA & tricontact,
+		GUINT feature1,GUINT feature2)
+	{
+		for(GUINT i = 0;i<tricontact.m_point_count ;i++ )
+		{
+			push_back_mem();
+			GIM_CONTACT & newele = back();
+			newele.m_point = tricontact.m_points[i];
+			newele.m_normal = tricontact.m_separating_normal;
+			newele.m_depth = tricontact.m_penetration_depth;
+			newele.m_feature1 = feature1;
+			newele.m_feature2 = feature2;
+		}
+	}
+
+	void merge_contacts(const gim_contact_array & contacts, bool normal_contact_average = true);
+	void merge_contacts_unique(const gim_contact_array & contacts);
+};
+
+#endif // GIM_CONTACT_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_geom_types.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_geom_types.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_geom_types.h	(revision 6952)
@@ -0,0 +1,97 @@
+#ifndef GIM_GEOM_TYPES_H_INCLUDED
+#define GIM_GEOM_TYPES_H_INCLUDED
+
+/*! \file gim_geom_types.h
+\author Francisco Len Nßjera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "gim_math.h"
+
+
+
+//! Short Integer vector 2D
+typedef GSHORT vec2s[2];
+//! Integer vector 3D
+typedef GSHORT vec3s[3];
+//! Integer vector 4D
+typedef GSHORT vec4s[4];
+
+//! Short Integer vector 2D
+typedef GUSHORT vec2us[2];
+//! Integer vector 3D
+typedef GUSHORT vec3us[3];
+//! Integer vector 4D
+typedef GUSHORT vec4us[4];
+
+//! Integer vector 2D
+typedef GINT vec2i[2];
+//! Integer vector 3D
+typedef GINT vec3i[3];
+//! Integer vector 4D
+typedef GINT vec4i[4];
+
+//! Unsigned Integer vector 2D
+typedef GUINT vec2ui[2];
+//! Unsigned Integer vector 3D
+typedef GUINT vec3ui[3];
+//! Unsigned Integer vector 4D
+typedef GUINT vec4ui[4];
+
+//! Float vector 2D
+typedef GREAL vec2f[2];
+//! Float vector 3D
+typedef GREAL vec3f[3];
+//! Float vector 4D
+typedef GREAL vec4f[4];
+
+//! Double vector 2D
+typedef GREAL2 vec2d[2];
+//! Float vector 3D
+typedef GREAL2 vec3d[3];
+//! Float vector 4D
+typedef GREAL2 vec4d[4];
+
+//! Matrix 2D, row ordered
+typedef GREAL mat2f[2][2];
+//! Matrix 3D, row ordered
+typedef GREAL mat3f[3][3];
+//! Matrix 4D, row ordered
+typedef GREAL mat4f[4][4];
+
+//! Quaternion
+typedef GREAL quatf[4];
+
+//typedef struct _aabb3f aabb3f;
+
+
+
+#endif // GIM_GEOM_TYPES_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_geometry.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_geometry.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_geometry.h	(revision 6952)
@@ -0,0 +1,42 @@
+#ifndef GIM_GEOMETRY_H_INCLUDED
+#define GIM_GEOMETRY_H_INCLUDED
+
+/*! \file gim_geometry.h
+\author Francisco Len Nßjera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+///Additional Headers for Collision
+#include "gim_basic_geometry_operations.h"
+#include "gim_clip_polygon.h"
+#include "gim_box_collision.h"
+#include "gim_tri_collision.h"
+
+#endif // GIM_VECTOR_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_hash_table.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_hash_table.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_hash_table.h	(revision 6952)
@@ -0,0 +1,902 @@
+#ifndef GIM_HASH_TABLE_H_INCLUDED
+#define GIM_HASH_TABLE_H_INCLUDED
+/*! \file gim_trimesh_data.h
+\author Francisco Len Nßjera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "gim_radixsort.h"
+
+
+#define GIM_INVALID_HASH 0xffffffff //!< A very very high value
+#define GIM_DEFAULT_HASH_TABLE_SIZE 380
+#define GIM_DEFAULT_HASH_TABLE_NODE_SIZE 4
+#define GIM_HASH_TABLE_GROW_FACTOR 2
+
+#define GIM_MIN_RADIX_SORT_SIZE 860 //!< calibrated on a PIII
+
+template<typename T>
+struct GIM_HASH_TABLE_NODE
+{
+    GUINT m_key;
+    T m_data;
+    GIM_HASH_TABLE_NODE()
+    {
+    }
+
+    GIM_HASH_TABLE_NODE(const GIM_HASH_TABLE_NODE & value)
+    {
+        m_key = value.m_key;
+        m_data = value.m_data;
+    }
+
+    GIM_HASH_TABLE_NODE(GUINT key, const T & data)
+    {
+        m_key = key;
+        m_data = data;
+    }
+
+    bool operator <(const GIM_HASH_TABLE_NODE<T> & other) const
+	{
+		///inverse order, further objects are first
+		if(m_key <  other.m_key) return true;
+		return false;
+	}
+
+	bool operator >(const GIM_HASH_TABLE_NODE<T> & other) const
+	{
+		///inverse order, further objects are first
+		if(m_key >  other.m_key) return true;
+		return false;
+	}
+
+	bool operator ==(const GIM_HASH_TABLE_NODE<T> & other) const
+	{
+		///inverse order, further objects are first
+		if(m_key ==  other.m_key) return true;
+		return false;
+	}
+};
+
+///Macro for getting the key
+class GIM_HASH_NODE_GET_KEY
+{
+public:
+	template<class T>
+	inline GUINT operator()( const T& a)
+	{
+		return a.m_key;
+	}
+};
+
+
+
+///Macro for comparing the key and the element
+class GIM_HASH_NODE_CMP_KEY_MACRO
+{
+public:
+	template<class T>
+	inline int operator() ( const T& a, GUINT key)
+	{
+		return ((int)(a.m_key - key));
+	}
+};
+
+///Macro for comparing Hash nodes
+class GIM_HASH_NODE_CMP_MACRO
+{
+public:
+	template<class T>
+	inline int operator() ( const T& a, const T& b )
+	{
+		return ((int)(a.m_key - b.m_key));
+	}
+};
+
+
+
+
+
+//! Sorting for hash table
+/*!
+switch automatically between quicksort and radixsort
+*/
+template<typename T>
+void gim_sort_hash_node_array(T * array, GUINT array_count)
+{
+    if(array_count<GIM_MIN_RADIX_SORT_SIZE)
+    {
+    	gim_heap_sort(array,array_count,GIM_HASH_NODE_CMP_MACRO());
+    }
+    else
+    {
+    	memcopy_elements_func cmpfunc;
+    	gim_radix_sort(array,array_count,GIM_HASH_NODE_GET_KEY(),cmpfunc);
+    }
+}
+
+
+
+
+
+
+// Note: assumes long is at least 32 bits.
+#define GIM_NUM_PRIME 28
+
+static const GUINT gim_prime_list[GIM_NUM_PRIME] =
+{
+  53ul,         97ul,         193ul,       389ul,       769ul,
+  1543ul,       3079ul,       6151ul,      12289ul,     24593ul,
+  49157ul,      98317ul,      196613ul,    393241ul,    786433ul,
+  1572869ul,    3145739ul,    6291469ul,   12582917ul,  25165843ul,
+  50331653ul,   100663319ul,  201326611ul, 402653189ul, 805306457ul,
+  1610612741ul, 3221225473ul, 4294967291ul
+};
+
+inline GUINT gim_next_prime(GUINT number)
+{
+    //Find nearest upper prime
+    GUINT result_ind = 0;
+    gim_binary_search(gim_prime_list,0,(GIM_NUM_PRIME-2),number,result_ind);
+
+    // inv: result_ind < 28
+    return gim_prime_list[result_ind];
+}
+
+
+
+//! A compact hash table implementation
+/*!
+A memory aligned compact hash table that coud be treated as an array.
+It could be a simple sorted array without the overhead of the hash key bucked, or could
+be a formely hash table with an array of keys.
+You can use switch_to_hashtable() and switch_to_sorted_array for saving space or increase speed.
+</br>
+
+<ul>
+<li> if node_size = 0, then this container becomes a simple sorted array allocator. reserve_size is used for reserve memory in m_nodes.
+When the array size reaches the size equivalent to 'min_hash_table_size', then it becomes a hash table by calling check_for_switching_to_hashtable.
+<li> If node_size != 0, then this container becomes a hash table for ever
+</ul>
+
+*/
+template<class T>
+class gim_hash_table
+{
+protected:
+    typedef GIM_HASH_TABLE_NODE<T> _node_type;
+
+    //!The nodes
+    //array< _node_type, SuperAllocator<_node_type> > m_nodes;
+    gim_array< _node_type > m_nodes;
+    //SuperBufferedArray< _node_type > m_nodes;
+    bool m_sorted;
+
+    ///Hash table data management. The hash table has the indices to the corresponding m_nodes array
+    GUINT * m_hash_table;//!<
+    GUINT m_table_size;//!<
+    GUINT m_node_size;//!<
+    GUINT m_min_hash_table_size;
+
+
+
+    //! Returns the cell index
+    inline GUINT _find_cell(GUINT hashkey)
+    {
+        _node_type * nodesptr = m_nodes.pointer();
+        GUINT start_index = (hashkey%m_table_size)*m_node_size;
+        GUINT end_index = start_index + m_node_size;
+
+        while(start_index<end_index)
+        {
+            GUINT value = m_hash_table[start_index];
+            if(value != GIM_INVALID_HASH)
+            {
+                if(nodesptr[value].m_key == hashkey) return start_index;
+            }
+            start_index++;
+        }
+        return GIM_INVALID_HASH;
+    }
+
+    //! Find the avaliable cell for the hashkey, and return an existing cell if it has the same hash key
+    inline GUINT _find_avaliable_cell(GUINT hashkey)
+    {
+        _node_type * nodesptr = m_nodes.pointer();
+        GUINT avaliable_index = GIM_INVALID_HASH;
+        GUINT start_index = (hashkey%m_table_size)*m_node_size;
+        GUINT end_index = start_index + m_node_size;
+
+        while(start_index<end_index)
+        {
+            GUINT value = m_hash_table[start_index];
+            if(value == GIM_INVALID_HASH)
+            {
+                if(avaliable_index==GIM_INVALID_HASH)
+                {
+                    avaliable_index = start_index;
+                }
+            }
+            else if(nodesptr[value].m_key == hashkey)
+            {
+                return start_index;
+            }
+            start_index++;
+        }
+        return avaliable_index;
+    }
+
+
+
+    //! reserves the memory for the hash table.
+    /*!
+    \pre hash table must be empty
+    \post reserves the memory for the hash table, an initializes all elements to GIM_INVALID_HASH.
+    */
+    inline void _reserve_table_memory(GUINT newtablesize)
+    {
+        if(newtablesize==0) return;
+        if(m_node_size==0) return;
+
+        //Get a Prime size
+
+        m_table_size = gim_next_prime(newtablesize);
+
+        GUINT datasize = m_table_size*m_node_size;
+        //Alloc the data buffer
+        m_hash_table =  (GUINT *)gim_alloc(datasize*sizeof(GUINT));
+    }
+
+    inline void _invalidate_keys()
+    {
+        GUINT datasize = m_table_size*m_node_size;
+        for(GUINT i=0;i<datasize;i++)
+        {
+            m_hash_table[i] = GIM_INVALID_HASH;// invalidate keys
+        }
+    }
+
+    //! Clear all memory for the hash table
+    inline void _clear_table_memory()
+    {
+        if(m_hash_table==NULL) return;
+        gim_free(m_hash_table);
+        m_hash_table = NULL;
+        m_table_size = 0;
+    }
+
+    //! Invalidates the keys (Assigning GIM_INVALID_HASH to all) Reorders the hash keys
+    inline void _rehash()
+    {
+        _invalidate_keys();
+
+        _node_type * nodesptr = m_nodes.pointer();
+        for(GUINT i=0;i<(GUINT)m_nodes.size();i++)
+        {
+            GUINT nodekey = nodesptr[i].m_key;
+            if(nodekey != GIM_INVALID_HASH)
+            {
+                //Search for the avaliable cell in buffer
+                GUINT index = _find_avaliable_cell(nodekey);
+
+
+				if(m_hash_table[index]!=GIM_INVALID_HASH)
+				{//The new index is alreade used... discard this new incomming object, repeated key
+				    btAssert(m_hash_table[index]==nodekey);
+					nodesptr[i].m_key = GIM_INVALID_HASH;
+				}
+				else
+				{
+					//;
+					//Assign the value for alloc
+					m_hash_table[index] = i;
+				}
+            }
+        }
+    }
+
+    //! Resize hash table indices
+    inline void _resize_table(GUINT newsize)
+    {
+        //Clear memory
+        _clear_table_memory();
+        //Alloc the data
+        _reserve_table_memory(newsize);
+        //Invalidate keys and rehash
+        _rehash();
+    }
+
+    //! Destroy hash table memory
+    inline void _destroy()
+    {
+        if(m_hash_table==NULL) return;
+        _clear_table_memory();
+    }
+
+    //! Finds an avaliable hash table cell, and resizes the table if there isn't space
+    inline GUINT _assign_hash_table_cell(GUINT hashkey)
+    {
+        GUINT cell_index = _find_avaliable_cell(hashkey);
+
+        if(cell_index==GIM_INVALID_HASH)
+        {
+            //rehashing
+            _resize_table(m_table_size+1);
+            GUINT cell_index = _find_avaliable_cell(hashkey);
+            btAssert(cell_index!=GIM_INVALID_HASH);
+        }
+        return cell_index;
+    }
+
+    //! erase by index in hash table
+    inline bool _erase_by_index_hash_table(GUINT index)
+    {
+        if(index >= m_nodes.size()) return false;
+        if(m_nodes[index].m_key != GIM_INVALID_HASH)
+        {
+            //Search for the avaliable cell in buffer
+            GUINT cell_index = _find_cell(m_nodes[index].m_key);
+
+            btAssert(cell_index!=GIM_INVALID_HASH);
+            btAssert(m_hash_table[cell_index]==index);
+
+            m_hash_table[cell_index] = GIM_INVALID_HASH;
+        }
+
+        return this->_erase_unsorted(index);
+    }
+
+    //! erase by key in hash table
+    inline bool _erase_hash_table(GUINT hashkey)
+    {
+        if(hashkey == GIM_INVALID_HASH) return false;
+
+        //Search for the avaliable cell in buffer
+        GUINT cell_index = _find_cell(hashkey);
+        if(cell_index ==GIM_INVALID_HASH) return false;
+
+        GUINT index = m_hash_table[cell_index];
+        m_hash_table[cell_index] = GIM_INVALID_HASH;
+
+        return this->_erase_unsorted(index);
+    }
+
+
+
+    //! insert an element in hash table
+    /*!
+    If the element exists, this won't insert the element
+    \return the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted
+    If so, the element has been inserted at the last position of the array.
+    */
+    inline GUINT _insert_hash_table(GUINT hashkey, const T & value)
+    {
+        if(hashkey==GIM_INVALID_HASH)
+        {
+            //Insert anyway
+            _insert_unsorted(hashkey,value);
+            return GIM_INVALID_HASH;
+        }
+
+        GUINT cell_index = _assign_hash_table_cell(hashkey);
+
+        GUINT value_key = m_hash_table[cell_index];
+
+        if(value_key!= GIM_INVALID_HASH) return value_key;// Not overrited
+
+        m_hash_table[cell_index] = m_nodes.size();
+
+        _insert_unsorted(hashkey,value);
+        return GIM_INVALID_HASH;
+    }
+
+    //! insert an element in hash table.
+    /*!
+    If the element exists, this replaces the element.
+    \return the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted
+    If so, the element has been inserted at the last position of the array.
+    */
+    inline GUINT _insert_hash_table_replace(GUINT hashkey, const T & value)
+    {
+        if(hashkey==GIM_INVALID_HASH)
+        {
+            //Insert anyway
+            _insert_unsorted(hashkey,value);
+            return GIM_INVALID_HASH;
+        }
+
+        GUINT cell_index = _assign_hash_table_cell(hashkey);
+
+        GUINT value_key = m_hash_table[cell_index];
+
+        if(value_key!= GIM_INVALID_HASH)
+        {//replaces the existing
+            m_nodes[value_key] = _node_type(hashkey,value);
+            return value_key;// index of the replaced element
+        }
+
+        m_hash_table[cell_index] = m_nodes.size();
+
+        _insert_unsorted(hashkey,value);
+        return GIM_INVALID_HASH;
+
+    }
+
+    
+    ///Sorted array data management. The hash table has the indices to the corresponding m_nodes array
+    inline bool _erase_sorted(GUINT index)
+    {
+        if(index>=(GUINT)m_nodes.size()) return false;
+        m_nodes.erase_sorted(index);
+		if(m_nodes.size()<2) m_sorted = false;
+        return true;
+    }
+
+    //! faster, but unsorted
+    inline bool _erase_unsorted(GUINT index)
+    {
+        if(index>=m_nodes.size()) return false;
+
+        GUINT lastindex = m_nodes.size()-1;
+        if(index<lastindex && m_hash_table!=0)
+        {
+			GUINT hashkey =  m_nodes[lastindex].m_key;
+			if(hashkey!=GIM_INVALID_HASH)
+			{
+				//update the new position of the last element
+				GUINT cell_index = _find_cell(hashkey);
+				btAssert(cell_index!=GIM_INVALID_HASH);
+				//new position of the last element which will be swaped
+				m_hash_table[cell_index] = index;
+			}
+        }
+        m_nodes.erase(index);
+        m_sorted = false;
+        return true;
+    }
+
+    //! Insert in position ordered
+    /*!
+    Also checks if it is needed to transform this container to a hash table, by calling check_for_switching_to_hashtable
+    */
+    inline void _insert_in_pos(GUINT hashkey, const T & value, GUINT pos)
+    {
+        m_nodes.insert(_node_type(hashkey,value),pos);
+        this->check_for_switching_to_hashtable();
+    }
+
+    //! Insert an element in an ordered array
+    inline GUINT _insert_sorted(GUINT hashkey, const T & value)
+    {
+        if(hashkey==GIM_INVALID_HASH || size()==0)
+        {
+            m_nodes.push_back(_node_type(hashkey,value));
+            return GIM_INVALID_HASH;
+        }
+        //Insert at last position
+        //Sort element
+
+
+        GUINT result_ind=0;
+        GUINT last_index = m_nodes.size()-1;
+        _node_type * ptr = m_nodes.pointer();
+
+        bool found = gim_binary_search_ex(
+        	ptr,0,last_index,result_ind,hashkey,GIM_HASH_NODE_CMP_KEY_MACRO());
+
+
+        //Insert before found index
+        if(found)
+        {
+            return result_ind;
+        }
+        else
+        {
+            _insert_in_pos(hashkey, value, result_ind);
+        }
+        return GIM_INVALID_HASH;
+    }
+
+    inline GUINT _insert_sorted_replace(GUINT hashkey, const T & value)
+    {
+        if(hashkey==GIM_INVALID_HASH || size()==0)
+        {
+            m_nodes.push_back(_node_type(hashkey,value));
+            return GIM_INVALID_HASH;
+        }
+        //Insert at last position
+        //Sort element
+        GUINT result_ind;
+        GUINT last_index = m_nodes.size()-1;
+        _node_type * ptr = m_nodes.pointer();
+
+        bool found = gim_binary_search_ex(
+        	ptr,0,last_index,result_ind,hashkey,GIM_HASH_NODE_CMP_KEY_MACRO());
+
+        //Insert before found index
+        if(found)
+        {
+            m_nodes[result_ind] = _node_type(hashkey,value);
+        }
+        else
+        {
+            _insert_in_pos(hashkey, value, result_ind);
+        }
+        return result_ind;
+    }
+
+    //! Fast insertion in m_nodes array
+    inline GUINT  _insert_unsorted(GUINT hashkey, const T & value)
+    {
+        m_nodes.push_back(_node_type(hashkey,value));
+        m_sorted = false;
+        return GIM_INVALID_HASH;
+    }
+
+    
+
+public:
+
+    /*!
+        <li> if node_size = 0, then this container becomes a simple sorted array allocator. reserve_size is used for reserve memory in m_nodes.
+        When the array size reaches the size equivalent to 'min_hash_table_size', then it becomes a hash table by calling check_for_switching_to_hashtable.
+        <li> If node_size != 0, then this container becomes a hash table for ever
+        </ul>
+    */
+    gim_hash_table(GUINT reserve_size = GIM_DEFAULT_HASH_TABLE_SIZE,
+                     GUINT node_size = GIM_DEFAULT_HASH_TABLE_NODE_SIZE,
+                     GUINT min_hash_table_size = GIM_INVALID_HASH)
+    {
+        m_hash_table = NULL;
+        m_table_size = 0;
+        m_sorted = false;
+        m_node_size = node_size;
+        m_min_hash_table_size = min_hash_table_size;
+
+        if(m_node_size!=0)
+        {
+            if(reserve_size!=0)
+            {
+                m_nodes.reserve(reserve_size);
+                _reserve_table_memory(reserve_size);
+                _invalidate_keys();
+            }
+            else
+            {
+                m_nodes.reserve(GIM_DEFAULT_HASH_TABLE_SIZE);
+                _reserve_table_memory(GIM_DEFAULT_HASH_TABLE_SIZE);
+                _invalidate_keys();
+            }
+        }
+        else if(reserve_size!=0)
+        {
+            m_nodes.reserve(reserve_size);
+        }
+
+    }
+
+    ~gim_hash_table()
+    {
+        _destroy();
+    }
+
+    inline bool is_hash_table()
+    {
+        if(m_hash_table) return true;
+        return false;
+    }
+
+    inline bool is_sorted()
+    {
+        if(size()<2) return true;
+        return m_sorted;
+    }
+
+    bool sort()
+    {
+        if(is_sorted()) return true;
+        if(m_nodes.size()<2) return false;
+
+
+        _node_type * ptr = m_nodes.pointer();
+        GUINT siz = m_nodes.size();
+        gim_sort_hash_node_array(ptr,siz);
+        m_sorted=true;
+
+
+
+        if(m_hash_table)
+        {
+            _rehash();
+        }
+        return true;
+    }
+
+    bool switch_to_hashtable()
+    {
+        if(m_hash_table) return false;
+        if(m_node_size==0) m_node_size = GIM_DEFAULT_HASH_TABLE_NODE_SIZE;
+        if(m_nodes.size()<GIM_DEFAULT_HASH_TABLE_SIZE)
+        {
+            _resize_table(GIM_DEFAULT_HASH_TABLE_SIZE);
+        }
+        else
+        {
+            _resize_table(m_nodes.size()+1);
+        }
+
+        return true;
+    }
+
+    bool switch_to_sorted_array()
+    {
+        if(m_hash_table==NULL) return true;
+        _clear_table_memory();
+        return sort();
+    }
+
+    //!If the container reaches the
+    bool check_for_switching_to_hashtable()
+    {
+        if(this->m_hash_table) return true;
+
+        if(!(m_nodes.size()< m_min_hash_table_size))
+        {
+            if(m_node_size == 0)
+            {
+                m_node_size = GIM_DEFAULT_HASH_TABLE_NODE_SIZE;
+            }
+
+            _resize_table(m_nodes.size()+1);
+            return true;
+        }
+        return false;
+    }
+
+    inline void set_sorted(bool value)
+    {
+    	m_sorted = value;
+    }
+
+    //! Retrieves the amount of keys.
+    inline GUINT size() const
+    {
+        return m_nodes.size();
+    }
+
+    //! Retrieves the hash key.
+    inline GUINT get_key(GUINT index) const
+    {
+        return m_nodes[index].m_key;
+    }
+
+    //! Retrieves the value by index
+    /*!
+    */
+    inline T * get_value_by_index(GUINT index)
+    {
+        return &m_nodes[index].m_data;
+    }
+
+    inline const T& operator[](GUINT index) const
+    {
+        return m_nodes[index].m_data;
+    }
+
+    inline T& operator[](GUINT index)
+    {
+        return m_nodes[index].m_data;
+    }
+
+    //! Finds the index of the element with the key
+    /*!
+    \return the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted
+    If so, the element has been inserted at the last position of the array.
+    */
+    inline GUINT find(GUINT hashkey)
+    {
+        if(m_hash_table)
+        {
+            GUINT cell_index = _find_cell(hashkey);
+            if(cell_index==GIM_INVALID_HASH) return GIM_INVALID_HASH;
+            return m_hash_table[cell_index];
+        }
+		GUINT last_index = m_nodes.size();
+        if(last_index<2)
+        {
+			if(last_index==0) return GIM_INVALID_HASH;
+            if(m_nodes[0].m_key == hashkey) return 0;
+            return GIM_INVALID_HASH;
+        }
+        else if(m_sorted)
+        {
+            //Binary search
+            GUINT result_ind = 0;
+			last_index--;
+            _node_type *  ptr =  m_nodes.pointer();
+
+            bool found = gim_binary_search_ex(ptr,0,last_index,result_ind,hashkey,GIM_HASH_NODE_CMP_KEY_MACRO());
+
+
+            if(found) return result_ind;
+        }
+        return GIM_INVALID_HASH;
+    }
+
+    //! Retrieves the value associated with the index
+    /*!
+    \return the found element, or null
+    */
+    inline T * get_value(GUINT hashkey)
+    {
+        GUINT index = find(hashkey);
+        if(index == GIM_INVALID_HASH) return NULL;
+        return &m_nodes[index].m_data;
+    }
+
+
+    /*!
+    */
+    inline bool erase_by_index(GUINT index)
+    {
+        if(index > m_nodes.size()) return false;
+
+        if(m_hash_table == NULL)
+        {
+            if(is_sorted())
+            {
+                return this->_erase_sorted(index);
+            }
+            else
+            {
+                return this->_erase_unsorted(index);
+            }
+        }
+        else
+        {
+            return this->_erase_by_index_hash_table(index);
+        }
+        return false;
+    }
+
+
+
+    inline bool erase_by_index_unsorted(GUINT index)
+    {
+        if(index > m_nodes.size()) return false;
+
+        if(m_hash_table == NULL)
+        {
+            return this->_erase_unsorted(index);
+        }
+        else
+        {
+            return this->_erase_by_index_hash_table(index);
+        }
+        return false;
+    }
+
+
+
+    /*!
+
+    */
+    inline bool erase_by_key(GUINT hashkey)
+    {
+        if(size()==0) return false;
+
+        if(m_hash_table)
+        {
+            return this->_erase_hash_table(hashkey);
+        }
+        //Binary search
+
+        if(is_sorted()==false) return false;
+
+        GUINT result_ind = find(hashkey);
+        if(result_ind!= GIM_INVALID_HASH)
+        {
+            return this->_erase_sorted(result_ind);
+        }
+        return false;
+    }
+
+    void clear()
+    {
+        m_nodes.clear();
+
+        if(m_hash_table==NULL) return;
+        GUINT datasize = m_table_size*m_node_size;
+        //Initialize the hashkeys.
+        GUINT i;
+        for(i=0;i<datasize;i++)
+        {
+            m_hash_table[i] = GIM_INVALID_HASH;// invalidate keys
+        }
+		m_sorted = false;
+    }
+
+    //! Insert an element into the hash
+    /*!
+    \return If GIM_INVALID_HASH, the object has been inserted succesfully. Else it returns the position
+    of the existing element.
+    */
+    inline GUINT insert(GUINT hashkey, const T & element)
+    {
+        if(m_hash_table)
+        {
+            return this->_insert_hash_table(hashkey,element);
+        }
+        if(this->is_sorted())
+        {
+            return this->_insert_sorted(hashkey,element);
+        }
+        return this->_insert_unsorted(hashkey,element);
+    }
+
+    //! Insert an element into the hash, and could overrite an existing object with the same hash.
+    /*!
+    \return If GIM_INVALID_HASH, the object has been inserted succesfully. Else it returns the position
+    of the replaced element.
+    */
+    inline GUINT insert_override(GUINT hashkey, const T & element)
+    {
+        if(m_hash_table)
+        {
+            return this->_insert_hash_table_replace(hashkey,element);
+        }
+        if(this->is_sorted())
+        {
+            return this->_insert_sorted_replace(hashkey,element);
+        }
+        this->_insert_unsorted(hashkey,element);
+        return m_nodes.size();
+    }
+
+
+
+    //! Insert an element into the hash,But if this container is a sorted array, this inserts it unsorted
+    /*!
+    */
+    inline GUINT insert_unsorted(GUINT hashkey,const T & element)
+    {
+        if(m_hash_table)
+        {
+            return this->_insert_hash_table(hashkey,element);
+        }
+        return this->_insert_unsorted(hashkey,element);
+    }
+
+
+};
+
+
+
+#endif // GIM_CONTAINERS_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_linear_math.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_linear_math.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_linear_math.h	(revision 6952)
@@ -0,0 +1,1573 @@
+#ifndef GIM_LINEAR_H_INCLUDED
+#define GIM_LINEAR_H_INCLUDED
+
+/*! \file gim_linear_math.h
+*\author Francisco Len Nßjera
+Type Independant Vector and matrix operations.
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "gim_math.h"
+#include "gim_geom_types.h"
+
+
+
+
+//! Zero out a 2D vector
+#define VEC_ZERO_2(a)				\
+{						\
+   (a)[0] = (a)[1] = 0.0f;			\
+}\
+
+
+//! Zero out a 3D vector
+#define VEC_ZERO(a)				\
+{						\
+   (a)[0] = (a)[1] = (a)[2] = 0.0f;		\
+}\
+
+
+/// Zero out a 4D vector
+#define VEC_ZERO_4(a)				\
+{						\
+   (a)[0] = (a)[1] = (a)[2] = (a)[3] = 0.0f;	\
+}\
+
+
+/// Vector copy
+#define VEC_COPY_2(b,a)				\
+{						\
+   (b)[0] = (a)[0];				\
+   (b)[1] = (a)[1];				\
+}\
+
+
+/// Copy 3D vector
+#define VEC_COPY(b,a)				\
+{						\
+   (b)[0] = (a)[0];				\
+   (b)[1] = (a)[1];				\
+   (b)[2] = (a)[2];				\
+}\
+
+
+/// Copy 4D vector
+#define VEC_COPY_4(b,a)				\
+{						\
+   (b)[0] = (a)[0];				\
+   (b)[1] = (a)[1];				\
+   (b)[2] = (a)[2];				\
+   (b)[3] = (a)[3];				\
+}\
+
+/// VECTOR SWAP
+#define VEC_SWAP(b,a)				\
+{  \
+    GIM_SWAP_NUMBERS((b)[0],(a)[0]);\
+    GIM_SWAP_NUMBERS((b)[1],(a)[1]);\
+    GIM_SWAP_NUMBERS((b)[2],(a)[2]);\
+}\
+
+/// Vector difference
+#define VEC_DIFF_2(v21,v2,v1)			\
+{						\
+   (v21)[0] = (v2)[0] - (v1)[0];		\
+   (v21)[1] = (v2)[1] - (v1)[1];		\
+}\
+
+
+/// Vector difference
+#define VEC_DIFF(v21,v2,v1)			\
+{						\
+   (v21)[0] = (v2)[0] - (v1)[0];		\
+   (v21)[1] = (v2)[1] - (v1)[1];		\
+   (v21)[2] = (v2)[2] - (v1)[2];		\
+}\
+
+
+/// Vector difference
+#define VEC_DIFF_4(v21,v2,v1)			\
+{						\
+   (v21)[0] = (v2)[0] - (v1)[0];		\
+   (v21)[1] = (v2)[1] - (v1)[1];		\
+   (v21)[2] = (v2)[2] - (v1)[2];		\
+   (v21)[3] = (v2)[3] - (v1)[3];		\
+}\
+
+
+/// Vector sum
+#define VEC_SUM_2(v21,v2,v1)			\
+{						\
+   (v21)[0] = (v2)[0] + (v1)[0];		\
+   (v21)[1] = (v2)[1] + (v1)[1];		\
+}\
+
+
+/// Vector sum
+#define VEC_SUM(v21,v2,v1)			\
+{						\
+   (v21)[0] = (v2)[0] + (v1)[0];		\
+   (v21)[1] = (v2)[1] + (v1)[1];		\
+   (v21)[2] = (v2)[2] + (v1)[2];		\
+}\
+
+
+/// Vector sum
+#define VEC_SUM_4(v21,v2,v1)			\
+{						\
+   (v21)[0] = (v2)[0] + (v1)[0];		\
+   (v21)[1] = (v2)[1] + (v1)[1];		\
+   (v21)[2] = (v2)[2] + (v1)[2];		\
+   (v21)[3] = (v2)[3] + (v1)[3];		\
+}\
+
+
+/// scalar times vector
+#define VEC_SCALE_2(c,a,b)			\
+{						\
+   (c)[0] = (a)*(b)[0];				\
+   (c)[1] = (a)*(b)[1];				\
+}\
+
+
+/// scalar times vector
+#define VEC_SCALE(c,a,b)			\
+{						\
+   (c)[0] = (a)*(b)[0];				\
+   (c)[1] = (a)*(b)[1];				\
+   (c)[2] = (a)*(b)[2];				\
+}\
+
+
+/// scalar times vector
+#define VEC_SCALE_4(c,a,b)			\
+{						\
+   (c)[0] = (a)*(b)[0];				\
+   (c)[1] = (a)*(b)[1];				\
+   (c)[2] = (a)*(b)[2];				\
+   (c)[3] = (a)*(b)[3];				\
+}\
+
+
+/// accumulate scaled vector
+#define VEC_ACCUM_2(c,a,b)			\
+{						\
+   (c)[0] += (a)*(b)[0];			\
+   (c)[1] += (a)*(b)[1];			\
+}\
+
+
+/// accumulate scaled vector
+#define VEC_ACCUM(c,a,b)			\
+{						\
+   (c)[0] += (a)*(b)[0];			\
+   (c)[1] += (a)*(b)[1];			\
+   (c)[2] += (a)*(b)[2];			\
+}\
+
+
+/// accumulate scaled vector
+#define VEC_ACCUM_4(c,a,b)			\
+{						\
+   (c)[0] += (a)*(b)[0];			\
+   (c)[1] += (a)*(b)[1];			\
+   (c)[2] += (a)*(b)[2];			\
+   (c)[3] += (a)*(b)[3];			\
+}\
+
+
+/// Vector dot product
+#define VEC_DOT_2(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1])
+
+
+/// Vector dot product
+#define VEC_DOT(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2])
+
+/// Vector dot product
+#define VEC_DOT_4(a,b)	((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] + (a)[3]*(b)[3])
+
+/// vector impact parameter (squared)
+#define VEC_IMPACT_SQ(bsq,direction,position) {\
+   GREAL _llel_ = VEC_DOT(direction, position);\
+   bsq = VEC_DOT(position, position) - _llel_*_llel_;\
+}\
+
+
+/// vector impact parameter
+#define VEC_IMPACT(bsq,direction,position)	{\
+   VEC_IMPACT_SQ(bsq,direction,position);		\
+   GIM_SQRT(bsq,bsq);					\
+}\
+
+/// Vector length
+#define VEC_LENGTH_2(a,l)\
+{\
+    GREAL _pp = VEC_DOT_2(a,a);\
+    GIM_SQRT(_pp,l);\
+}\
+
+
+/// Vector length
+#define VEC_LENGTH(a,l)\
+{\
+    GREAL _pp = VEC_DOT(a,a);\
+    GIM_SQRT(_pp,l);\
+}\
+
+
+/// Vector length
+#define VEC_LENGTH_4(a,l)\
+{\
+    GREAL _pp = VEC_DOT_4(a,a);\
+    GIM_SQRT(_pp,l);\
+}\
+
+/// Vector inv length
+#define VEC_INV_LENGTH_2(a,l)\
+{\
+    GREAL _pp = VEC_DOT_2(a,a);\
+    GIM_INV_SQRT(_pp,l);\
+}\
+
+
+/// Vector inv length
+#define VEC_INV_LENGTH(a,l)\
+{\
+    GREAL _pp = VEC_DOT(a,a);\
+    GIM_INV_SQRT(_pp,l);\
+}\
+
+
+/// Vector inv length
+#define VEC_INV_LENGTH_4(a,l)\
+{\
+    GREAL _pp = VEC_DOT_4(a,a);\
+    GIM_INV_SQRT(_pp,l);\
+}\
+
+
+
+/// distance between two points
+#define VEC_DISTANCE(_len,_va,_vb) {\
+    vec3f _tmp_;				\
+    VEC_DIFF(_tmp_, _vb, _va);			\
+    VEC_LENGTH(_tmp_,_len);			\
+}\
+
+
+/// Vector length
+#define VEC_CONJUGATE_LENGTH(a,l)\
+{\
+    GREAL _pp = 1.0 - a[0]*a[0] - a[1]*a[1] - a[2]*a[2];\
+    GIM_SQRT(_pp,l);\
+}\
+
+
+/// Vector length
+#define VEC_NORMALIZE(a) {	\
+    GREAL len;\
+    VEC_INV_LENGTH(a,len); \
+    if(len<G_REAL_INFINITY)\
+    {\
+        a[0] *= len;				\
+        a[1] *= len;				\
+        a[2] *= len;				\
+    }						\
+}\
+
+/// Set Vector size
+#define VEC_RENORMALIZE(a,newlen) {	\
+    GREAL len;\
+    VEC_INV_LENGTH(a,len); \
+    if(len<G_REAL_INFINITY)\
+    {\
+        len *= newlen;\
+        a[0] *= len;				\
+        a[1] *= len;				\
+        a[2] *= len;				\
+    }						\
+}\
+
+/// Vector cross
+#define VEC_CROSS(c,a,b)		\
+{						\
+   c[0] = (a)[1] * (b)[2] - (a)[2] * (b)[1];	\
+   c[1] = (a)[2] * (b)[0] - (a)[0] * (b)[2];	\
+   c[2] = (a)[0] * (b)[1] - (a)[1] * (b)[0];	\
+}\
+
+
+/*! Vector perp -- assumes that n is of unit length
+ * accepts vector v, subtracts out any component parallel to n */
+#define VEC_PERPENDICULAR(vp,v,n)			\
+{						\
+   GREAL dot = VEC_DOT(v, n);			\
+   vp[0] = (v)[0] - dot*(n)[0];		\
+   vp[1] = (v)[1] - dot*(n)[1];		\
+   vp[2] = (v)[2] - dot*(n)[2];		\
+}\
+
+
+/*! Vector parallel -- assumes that n is of unit length */
+#define VEC_PARALLEL(vp,v,n)			\
+{						\
+   GREAL dot = VEC_DOT(v, n);			\
+   vp[0] = (dot) * (n)[0];			\
+   vp[1] = (dot) * (n)[1];			\
+   vp[2] = (dot) * (n)[2];			\
+}\
+
+/*! Same as Vector parallel --  n can have any length
+ * accepts vector v, subtracts out any component perpendicular to n */
+#define VEC_PROJECT(vp,v,n)			\
+{ \
+	GREAL scalar = VEC_DOT(v, n);			\
+	scalar/= VEC_DOT(n, n); \
+	vp[0] = (scalar) * (n)[0];			\
+    vp[1] = (scalar) * (n)[1];			\
+    vp[2] = (scalar) * (n)[2];			\
+}\
+
+
+/*! accepts vector v*/
+#define VEC_UNPROJECT(vp,v,n)			\
+{ \
+	GREAL scalar = VEC_DOT(v, n);			\
+	scalar = VEC_DOT(n, n)/scalar; \
+	vp[0] = (scalar) * (n)[0];			\
+    vp[1] = (scalar) * (n)[1];			\
+    vp[2] = (scalar) * (n)[2];			\
+}\
+
+
+/*! Vector reflection -- assumes n is of unit length
+ Takes vector v, reflects it against reflector n, and returns vr */
+#define VEC_REFLECT(vr,v,n)			\
+{						\
+   GREAL dot = VEC_DOT(v, n);			\
+   vr[0] = (v)[0] - 2.0 * (dot) * (n)[0];	\
+   vr[1] = (v)[1] - 2.0 * (dot) * (n)[1];	\
+   vr[2] = (v)[2] - 2.0 * (dot) * (n)[2];	\
+}\
+
+
+/*! Vector blending
+Takes two vectors a, b, blends them together with two scalars */
+#define VEC_BLEND_AB(vr,sa,a,sb,b)			\
+{						\
+   vr[0] = (sa) * (a)[0] + (sb) * (b)[0];	\
+   vr[1] = (sa) * (a)[1] + (sb) * (b)[1];	\
+   vr[2] = (sa) * (a)[2] + (sb) * (b)[2];	\
+}\
+
+/*! Vector blending
+Takes two vectors a, b, blends them together with s <=1 */
+#define VEC_BLEND(vr,a,b,s) VEC_BLEND_AB(vr,(1-s),a,s,b)
+
+#define VEC_SET3(a,b,op,c) a[0]=b[0] op c[0]; a[1]=b[1] op c[1]; a[2]=b[2] op c[2];
+
+//! Finds the bigger cartesian coordinate from a vector
+#define VEC_MAYOR_COORD(vec, maxc)\
+{\
+	GREAL A[] = {fabs(vec[0]),fabs(vec[1]),fabs(vec[2])};\
+    maxc =  A[0]>A[1]?(A[0]>A[2]?0:2):(A[1]>A[2]?1:2);\
+}\
+
+//! Finds the 2 smallest cartesian coordinates from a vector
+#define VEC_MINOR_AXES(vec, i0, i1)\
+{\
+	VEC_MAYOR_COORD(vec,i0);\
+	i0 = (i0+1)%3;\
+	i1 = (i0+1)%3;\
+}\
+
+
+
+
+#define VEC_EQUAL(v1,v2) (v1[0]==v2[0]&&v1[1]==v2[1]&&v1[2]==v2[2])
+
+#define VEC_NEAR_EQUAL(v1,v2) (GIM_NEAR_EQUAL(v1[0],v2[0])&&GIM_NEAR_EQUAL(v1[1],v2[1])&&GIM_NEAR_EQUAL(v1[2],v2[2]))
+
+
+/// Vector cross
+#define X_AXIS_CROSS_VEC(dst,src)\
+{					   \
+	dst[0] = 0.0f;     \
+	dst[1] = -src[2];  \
+	dst[2] = src[1];  \
+}\
+
+#define Y_AXIS_CROSS_VEC(dst,src)\
+{					   \
+	dst[0] = src[2];     \
+	dst[1] = 0.0f;  \
+	dst[2] = -src[0];  \
+}\
+
+#define Z_AXIS_CROSS_VEC(dst,src)\
+{					   \
+	dst[0] = -src[1];     \
+	dst[1] = src[0];  \
+	dst[2] = 0.0f;  \
+}\
+
+
+
+
+
+
+/// initialize matrix
+#define IDENTIFY_MATRIX_3X3(m)			\
+{						\
+   m[0][0] = 1.0;				\
+   m[0][1] = 0.0;				\
+   m[0][2] = 0.0;				\
+						\
+   m[1][0] = 0.0;				\
+   m[1][1] = 1.0;				\
+   m[1][2] = 0.0;				\
+						\
+   m[2][0] = 0.0;				\
+   m[2][1] = 0.0;				\
+   m[2][2] = 1.0;				\
+}\
+
+/*! initialize matrix */
+#define IDENTIFY_MATRIX_4X4(m)			\
+{						\
+   m[0][0] = 1.0;				\
+   m[0][1] = 0.0;				\
+   m[0][2] = 0.0;				\
+   m[0][3] = 0.0;				\
+						\
+   m[1][0] = 0.0;				\
+   m[1][1] = 1.0;				\
+   m[1][2] = 0.0;				\
+   m[1][3] = 0.0;				\
+						\
+   m[2][0] = 0.0;				\
+   m[2][1] = 0.0;				\
+   m[2][2] = 1.0;				\
+   m[2][3] = 0.0;				\
+						\
+   m[3][0] = 0.0;				\
+   m[3][1] = 0.0;				\
+   m[3][2] = 0.0;				\
+   m[3][3] = 1.0;				\
+}\
+
+/*! initialize matrix */
+#define ZERO_MATRIX_4X4(m)			\
+{						\
+   m[0][0] = 0.0;				\
+   m[0][1] = 0.0;				\
+   m[0][2] = 0.0;				\
+   m[0][3] = 0.0;				\
+						\
+   m[1][0] = 0.0;				\
+   m[1][1] = 0.0;				\
+   m[1][2] = 0.0;				\
+   m[1][3] = 0.0;				\
+						\
+   m[2][0] = 0.0;				\
+   m[2][1] = 0.0;				\
+   m[2][2] = 0.0;				\
+   m[2][3] = 0.0;				\
+						\
+   m[3][0] = 0.0;				\
+   m[3][1] = 0.0;				\
+   m[3][2] = 0.0;				\
+   m[3][3] = 0.0;				\
+}\
+
+/*! matrix rotation  X */
+#define ROTX_CS(m,cosine,sine)		\
+{					\
+   /* rotation about the x-axis */	\
+					\
+   m[0][0] = 1.0;			\
+   m[0][1] = 0.0;			\
+   m[0][2] = 0.0;			\
+   m[0][3] = 0.0;			\
+					\
+   m[1][0] = 0.0;			\
+   m[1][1] = (cosine);			\
+   m[1][2] = (sine);			\
+   m[1][3] = 0.0;			\
+					\
+   m[2][0] = 0.0;			\
+   m[2][1] = -(sine);			\
+   m[2][2] = (cosine);			\
+   m[2][3] = 0.0;			\
+					\
+   m[3][0] = 0.0;			\
+   m[3][1] = 0.0;			\
+   m[3][2] = 0.0;			\
+   m[3][3] = 1.0;			\
+}\
+
+/*! matrix rotation  Y */
+#define ROTY_CS(m,cosine,sine)		\
+{					\
+   /* rotation about the y-axis */	\
+					\
+   m[0][0] = (cosine);			\
+   m[0][1] = 0.0;			\
+   m[0][2] = -(sine);			\
+   m[0][3] = 0.0;			\
+					\
+   m[1][0] = 0.0;			\
+   m[1][1] = 1.0;			\
+   m[1][2] = 0.0;			\
+   m[1][3] = 0.0;			\
+					\
+   m[2][0] = (sine);			\
+   m[2][1] = 0.0;			\
+   m[2][2] = (cosine);			\
+   m[2][3] = 0.0;			\
+					\
+   m[3][0] = 0.0;			\
+   m[3][1] = 0.0;			\
+   m[3][2] = 0.0;			\
+   m[3][3] = 1.0;			\
+}\
+
+/*! matrix rotation  Z */
+#define ROTZ_CS(m,cosine,sine)		\
+{					\
+   /* rotation about the z-axis */	\
+					\
+   m[0][0] = (cosine);			\
+   m[0][1] = (sine);			\
+   m[0][2] = 0.0;			\
+   m[0][3] = 0.0;			\
+					\
+   m[1][0] = -(sine);			\
+   m[1][1] = (cosine);			\
+   m[1][2] = 0.0;			\
+   m[1][3] = 0.0;			\
+					\
+   m[2][0] = 0.0;			\
+   m[2][1] = 0.0;			\
+   m[2][2] = 1.0;			\
+   m[2][3] = 0.0;			\
+					\
+   m[3][0] = 0.0;			\
+   m[3][1] = 0.0;			\
+   m[3][2] = 0.0;			\
+   m[3][3] = 1.0;			\
+}\
+
+/*! matrix copy */
+#define COPY_MATRIX_2X2(b,a)	\
+{				\
+   b[0][0] = a[0][0];		\
+   b[0][1] = a[0][1];		\
+				\
+   b[1][0] = a[1][0];		\
+   b[1][1] = a[1][1];		\
+				\
+}\
+
+
+/*! matrix copy */
+#define COPY_MATRIX_2X3(b,a)	\
+{				\
+   b[0][0] = a[0][0];		\
+   b[0][1] = a[0][1];		\
+   b[0][2] = a[0][2];		\
+				\
+   b[1][0] = a[1][0];		\
+   b[1][1] = a[1][1];		\
+   b[1][2] = a[1][2];		\
+}\
+
+
+/*! matrix copy */
+#define COPY_MATRIX_3X3(b,a)	\
+{				\
+   b[0][0] = a[0][0];		\
+   b[0][1] = a[0][1];		\
+   b[0][2] = a[0][2];		\
+				\
+   b[1][0] = a[1][0];		\
+   b[1][1] = a[1][1];		\
+   b[1][2] = a[1][2];		\
+				\
+   b[2][0] = a[2][0];		\
+   b[2][1] = a[2][1];		\
+   b[2][2] = a[2][2];		\
+}\
+
+
+/*! matrix copy */
+#define COPY_MATRIX_4X4(b,a)	\
+{				\
+   b[0][0] = a[0][0];		\
+   b[0][1] = a[0][1];		\
+   b[0][2] = a[0][2];		\
+   b[0][3] = a[0][3];		\
+				\
+   b[1][0] = a[1][0];		\
+   b[1][1] = a[1][1];		\
+   b[1][2] = a[1][2];		\
+   b[1][3] = a[1][3];		\
+				\
+   b[2][0] = a[2][0];		\
+   b[2][1] = a[2][1];		\
+   b[2][2] = a[2][2];		\
+   b[2][3] = a[2][3];		\
+				\
+   b[3][0] = a[3][0];		\
+   b[3][1] = a[3][1];		\
+   b[3][2] = a[3][2];		\
+   b[3][3] = a[3][3];		\
+}\
+
+
+/*! matrix transpose */
+#define TRANSPOSE_MATRIX_2X2(b,a)	\
+{				\
+   b[0][0] = a[0][0];		\
+   b[0][1] = a[1][0];		\
+				\
+   b[1][0] = a[0][1];		\
+   b[1][1] = a[1][1];		\
+}\
+
+
+/*! matrix transpose */
+#define TRANSPOSE_MATRIX_3X3(b,a)	\
+{				\
+   b[0][0] = a[0][0];		\
+   b[0][1] = a[1][0];		\
+   b[0][2] = a[2][0];		\
+				\
+   b[1][0] = a[0][1];		\
+   b[1][1] = a[1][1];		\
+   b[1][2] = a[2][1];		\
+				\
+   b[2][0] = a[0][2];		\
+   b[2][1] = a[1][2];		\
+   b[2][2] = a[2][2];		\
+}\
+
+
+/*! matrix transpose */
+#define TRANSPOSE_MATRIX_4X4(b,a)	\
+{				\
+   b[0][0] = a[0][0];		\
+   b[0][1] = a[1][0];		\
+   b[0][2] = a[2][0];		\
+   b[0][3] = a[3][0];		\
+				\
+   b[1][0] = a[0][1];		\
+   b[1][1] = a[1][1];		\
+   b[1][2] = a[2][1];		\
+   b[1][3] = a[3][1];		\
+				\
+   b[2][0] = a[0][2];		\
+   b[2][1] = a[1][2];		\
+   b[2][2] = a[2][2];		\
+   b[2][3] = a[3][2];		\
+				\
+   b[3][0] = a[0][3];		\
+   b[3][1] = a[1][3];		\
+   b[3][2] = a[2][3];		\
+   b[3][3] = a[3][3];		\
+}\
+
+
+/*! multiply matrix by scalar */
+#define SCALE_MATRIX_2X2(b,s,a)		\
+{					\
+   b[0][0] = (s) * a[0][0];		\
+   b[0][1] = (s) * a[0][1];		\
+					\
+   b[1][0] = (s) * a[1][0];		\
+   b[1][1] = (s) * a[1][1];		\
+}\
+
+
+/*! multiply matrix by scalar */
+#define SCALE_MATRIX_3X3(b,s,a)		\
+{					\
+   b[0][0] = (s) * a[0][0];		\
+   b[0][1] = (s) * a[0][1];		\
+   b[0][2] = (s) * a[0][2];		\
+					\
+   b[1][0] = (s) * a[1][0];		\
+   b[1][1] = (s) * a[1][1];		\
+   b[1][2] = (s) * a[1][2];		\
+					\
+   b[2][0] = (s) * a[2][0];		\
+   b[2][1] = (s) * a[2][1];		\
+   b[2][2] = (s) * a[2][2];		\
+}\
+
+
+/*! multiply matrix by scalar */
+#define SCALE_MATRIX_4X4(b,s,a)		\
+{					\
+   b[0][0] = (s) * a[0][0];		\
+   b[0][1] = (s) * a[0][1];		\
+   b[0][2] = (s) * a[0][2];		\
+   b[0][3] = (s) * a[0][3];		\
+					\
+   b[1][0] = (s) * a[1][0];		\
+   b[1][1] = (s) * a[1][1];		\
+   b[1][2] = (s) * a[1][2];		\
+   b[1][3] = (s) * a[1][3];		\
+					\
+   b[2][0] = (s) * a[2][0];		\
+   b[2][1] = (s) * a[2][1];		\
+   b[2][2] = (s) * a[2][2];		\
+   b[2][3] = (s) * a[2][3];		\
+					\
+   b[3][0] = s * a[3][0];		\
+   b[3][1] = s * a[3][1];		\
+   b[3][2] = s * a[3][2];		\
+   b[3][3] = s * a[3][3];		\
+}\
+
+
+/*! multiply matrix by scalar */
+#define SCALE_VEC_MATRIX_2X2(b,svec,a)		\
+{					\
+   b[0][0] = svec[0] * a[0][0];		\
+   b[1][0] = svec[0] * a[1][0];		\
+					\
+   b[0][1] = svec[1] * a[0][1];		\
+   b[1][1] = svec[1] * a[1][1];		\
+}\
+
+
+/*! multiply matrix by scalar. Each columns is scaled by each scalar vector component */
+#define SCALE_VEC_MATRIX_3X3(b,svec,a)		\
+{					\
+   b[0][0] = svec[0] * a[0][0];		\
+   b[1][0] = svec[0] * a[1][0];		\
+   b[2][0] = svec[0] * a[2][0];		\
+					\
+   b[0][1] = svec[1] * a[0][1];		\
+   b[1][1] = svec[1] * a[1][1];		\
+   b[2][1] = svec[1] * a[2][1];		\
+					\
+   b[0][2] = svec[2] * a[0][2];		\
+   b[1][2] = svec[2] * a[1][2];		\
+   b[2][2] = svec[2] * a[2][2];		\
+}\
+
+
+/*! multiply matrix by scalar */
+#define SCALE_VEC_MATRIX_4X4(b,svec,a)		\
+{					\
+   b[0][0] = svec[0] * a[0][0];		\
+   b[1][0] = svec[0] * a[1][0];		\
+   b[2][0] = svec[0] * a[2][0];		\
+   b[3][0] = svec[0] * a[3][0];		\
+					\
+   b[0][1] = svec[1] * a[0][1];		\
+   b[1][1] = svec[1] * a[1][1];		\
+   b[2][1] = svec[1] * a[2][1];		\
+   b[3][1] = svec[1] * a[3][1];		\
+					\
+   b[0][2] = svec[2] * a[0][2];		\
+   b[1][2] = svec[2] * a[1][2];		\
+   b[2][2] = svec[2] * a[2][2];		\
+   b[3][2] = svec[2] * a[3][2];		\
+   \
+   b[0][3] = svec[3] * a[0][3];		\
+   b[1][3] = svec[3] * a[1][3];		\
+   b[2][3] = svec[3] * a[2][3];		\
+   b[3][3] = svec[3] * a[3][3];		\
+}\
+
+
+/*! multiply matrix by scalar */
+#define ACCUM_SCALE_MATRIX_2X2(b,s,a)		\
+{					\
+   b[0][0] += (s) * a[0][0];		\
+   b[0][1] += (s) * a[0][1];		\
+					\
+   b[1][0] += (s) * a[1][0];		\
+   b[1][1] += (s) * a[1][1];		\
+}\
+
+
+/*! multiply matrix by scalar */
+#define ACCUM_SCALE_MATRIX_3X3(b,s,a)		\
+{					\
+   b[0][0] += (s) * a[0][0];		\
+   b[0][1] += (s) * a[0][1];		\
+   b[0][2] += (s) * a[0][2];		\
+					\
+   b[1][0] += (s) * a[1][0];		\
+   b[1][1] += (s) * a[1][1];		\
+   b[1][2] += (s) * a[1][2];		\
+					\
+   b[2][0] += (s) * a[2][0];		\
+   b[2][1] += (s) * a[2][1];		\
+   b[2][2] += (s) * a[2][2];		\
+}\
+
+
+/*! multiply matrix by scalar */
+#define ACCUM_SCALE_MATRIX_4X4(b,s,a)		\
+{					\
+   b[0][0] += (s) * a[0][0];		\
+   b[0][1] += (s) * a[0][1];		\
+   b[0][2] += (s) * a[0][2];		\
+   b[0][3] += (s) * a[0][3];		\
+					\
+   b[1][0] += (s) * a[1][0];		\
+   b[1][1] += (s) * a[1][1];		\
+   b[1][2] += (s) * a[1][2];		\
+   b[1][3] += (s) * a[1][3];		\
+					\
+   b[2][0] += (s) * a[2][0];		\
+   b[2][1] += (s) * a[2][1];		\
+   b[2][2] += (s) * a[2][2];		\
+   b[2][3] += (s) * a[2][3];		\
+					\
+   b[3][0] += (s) * a[3][0];		\
+   b[3][1] += (s) * a[3][1];		\
+   b[3][2] += (s) * a[3][2];		\
+   b[3][3] += (s) * a[3][3];		\
+}\
+
+/*! matrix product */
+/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
+#define MATRIX_PRODUCT_2X2(c,a,b)		\
+{						\
+   c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0];	\
+   c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1];	\
+						\
+   c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0];	\
+   c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1];	\
+						\
+}\
+
+/*! matrix product */
+/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
+#define MATRIX_PRODUCT_3X3(c,a,b)				\
+{								\
+   c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0];	\
+   c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1];	\
+   c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2];	\
+								\
+   c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0];	\
+   c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1];	\
+   c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2];	\
+								\
+   c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0];	\
+   c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1];	\
+   c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2];	\
+}\
+
+
+/*! matrix product */
+/*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/
+#define MATRIX_PRODUCT_4X4(c,a,b)		\
+{						\
+   c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]+a[0][3]*b[3][0];\
+   c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]+a[0][3]*b[3][1];\
+   c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]+a[0][3]*b[3][2];\
+   c[0][3] = a[0][0]*b[0][3]+a[0][1]*b[1][3]+a[0][2]*b[2][3]+a[0][3]*b[3][3];\
+						\
+   c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]+a[1][3]*b[3][0];\
+   c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]+a[1][3]*b[3][1];\
+   c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]+a[1][3]*b[3][2];\
+   c[1][3] = a[1][0]*b[0][3]+a[1][1]*b[1][3]+a[1][2]*b[2][3]+a[1][3]*b[3][3];\
+						\
+   c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]+a[2][3]*b[3][0];\
+   c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]+a[2][3]*b[3][1];\
+   c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]+a[2][3]*b[3][2];\
+   c[2][3] = a[2][0]*b[0][3]+a[2][1]*b[1][3]+a[2][2]*b[2][3]+a[2][3]*b[3][3];\
+						\
+   c[3][0] = a[3][0]*b[0][0]+a[3][1]*b[1][0]+a[3][2]*b[2][0]+a[3][3]*b[3][0];\
+   c[3][1] = a[3][0]*b[0][1]+a[3][1]*b[1][1]+a[3][2]*b[2][1]+a[3][3]*b[3][1];\
+   c[3][2] = a[3][0]*b[0][2]+a[3][1]*b[1][2]+a[3][2]*b[2][2]+a[3][3]*b[3][2];\
+   c[3][3] = a[3][0]*b[0][3]+a[3][1]*b[1][3]+a[3][2]*b[2][3]+a[3][3]*b[3][3];\
+}\
+
+
+/*! matrix times vector */
+#define MAT_DOT_VEC_2X2(p,m,v)					\
+{								\
+   p[0] = m[0][0]*v[0] + m[0][1]*v[1];				\
+   p[1] = m[1][0]*v[0] + m[1][1]*v[1];				\
+}\
+
+
+/*! matrix times vector */
+#define MAT_DOT_VEC_3X3(p,m,v)					\
+{								\
+   p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2];		\
+   p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2];		\
+   p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2];		\
+}\
+
+
+/*! matrix times vector
+v is a vec4f
+*/
+#define MAT_DOT_VEC_4X4(p,m,v)					\
+{								\
+   p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]*v[3];	\
+   p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]*v[3];	\
+   p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]*v[3];	\
+   p[3] = m[3][0]*v[0] + m[3][1]*v[1] + m[3][2]*v[2] + m[3][3]*v[3];	\
+}\
+
+/*! matrix times vector
+v is a vec3f
+and m is a mat4f<br>
+Last column is added as the position
+*/
+#define MAT_DOT_VEC_3X4(p,m,v)					\
+{								\
+   p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3];	\
+   p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3];	\
+   p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3];	\
+}\
+
+
+/*! vector transpose times matrix */
+/*! p[j] = v[0]*m[0][j] + v[1]*m[1][j] + v[2]*m[2][j]; */
+#define VEC_DOT_MAT_3X3(p,v,m)					\
+{								\
+   p[0] = v[0]*m[0][0] + v[1]*m[1][0] + v[2]*m[2][0];		\
+   p[1] = v[0]*m[0][1] + v[1]*m[1][1] + v[2]*m[2][1];		\
+   p[2] = v[0]*m[0][2] + v[1]*m[1][2] + v[2]*m[2][2];		\
+}\
+
+
+/*! affine matrix times vector */
+/** The matrix is assumed to be an affine matrix, with last two
+ * entries representing a translation */
+#define MAT_DOT_VEC_2X3(p,m,v)					\
+{								\
+   p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2];		\
+   p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2];		\
+}\
+
+//! Transform a plane
+#define MAT_TRANSFORM_PLANE_4X4(pout,m,plane)\
+{								\
+   pout[0] = m[0][0]*plane[0] + m[0][1]*plane[1]  + m[0][2]*plane[2];\
+   pout[1] = m[1][0]*plane[0] + m[1][1]*plane[1]  + m[1][2]*plane[2];\
+   pout[2] = m[2][0]*plane[0] + m[2][1]*plane[1]  + m[2][2]*plane[2];\
+   pout[3] = m[0][3]*pout[0] + m[1][3]*pout[1]  + m[2][3]*pout[2] + plane[3];\
+}\
+
+
+
+/** inverse transpose of matrix times vector
+ *
+ * This macro computes inverse transpose of matrix m,
+ * and multiplies vector v into it, to yeild vector p
+ *
+ * DANGER !!! Do Not use this on normal vectors!!!
+ * It will leave normals the wrong length !!!
+ * See macro below for use on normals.
+ */
+#define INV_TRANSP_MAT_DOT_VEC_2X2(p,m,v)			\
+{								\
+   GREAL det;						\
+								\
+   det = m[0][0]*m[1][1] - m[0][1]*m[1][0];			\
+   p[0] = m[1][1]*v[0] - m[1][0]*v[1];				\
+   p[1] = - m[0][1]*v[0] + m[0][0]*v[1];			\
+								\
+   /* if matrix not singular, and not orthonormal, then renormalize */ \
+   if ((det!=1.0f) && (det != 0.0f)) {				\
+      det = 1.0f / det;						\
+      p[0] *= det;						\
+      p[1] *= det;						\
+   }								\
+}\
+
+
+/** transform normal vector by inverse transpose of matrix
+ * and then renormalize the vector
+ *
+ * This macro computes inverse transpose of matrix m,
+ * and multiplies vector v into it, to yeild vector p
+ * Vector p is then normalized.
+ */
+#define NORM_XFORM_2X2(p,m,v)					\
+{								\
+   GREAL len;							\
+								\
+   /* do nothing if off-diagonals are zero and diagonals are 	\
+    * equal */							\
+   if ((m[0][1] != 0.0) || (m[1][0] != 0.0) || (m[0][0] != m[1][1])) { \
+      p[0] = m[1][1]*v[0] - m[1][0]*v[1];			\
+      p[1] = - m[0][1]*v[0] + m[0][0]*v[1];			\
+								\
+      len = p[0]*p[0] + p[1]*p[1];				\
+      GIM_INV_SQRT(len,len);					\
+      p[0] *= len;						\
+      p[1] *= len;						\
+   } else {							\
+      VEC_COPY_2 (p, v);					\
+   }								\
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define OUTER_PRODUCT_2X2(m,v,t)				\
+{								\
+   m[0][0] = v[0] * t[0];					\
+   m[0][1] = v[0] * t[1];					\
+								\
+   m[1][0] = v[1] * t[0];					\
+   m[1][1] = v[1] * t[1];					\
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define OUTER_PRODUCT_3X3(m,v,t)				\
+{								\
+   m[0][0] = v[0] * t[0];					\
+   m[0][1] = v[0] * t[1];					\
+   m[0][2] = v[0] * t[2];					\
+								\
+   m[1][0] = v[1] * t[0];					\
+   m[1][1] = v[1] * t[1];					\
+   m[1][2] = v[1] * t[2];					\
+								\
+   m[2][0] = v[2] * t[0];					\
+   m[2][1] = v[2] * t[1];					\
+   m[2][2] = v[2] * t[2];					\
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define OUTER_PRODUCT_4X4(m,v,t)				\
+{								\
+   m[0][0] = v[0] * t[0];					\
+   m[0][1] = v[0] * t[1];					\
+   m[0][2] = v[0] * t[2];					\
+   m[0][3] = v[0] * t[3];					\
+								\
+   m[1][0] = v[1] * t[0];					\
+   m[1][1] = v[1] * t[1];					\
+   m[1][2] = v[1] * t[2];					\
+   m[1][3] = v[1] * t[3];					\
+								\
+   m[2][0] = v[2] * t[0];					\
+   m[2][1] = v[2] * t[1];					\
+   m[2][2] = v[2] * t[2];					\
+   m[2][3] = v[2] * t[3];					\
+								\
+   m[3][0] = v[3] * t[0];					\
+   m[3][1] = v[3] * t[1];					\
+   m[3][2] = v[3] * t[2];					\
+   m[3][3] = v[3] * t[3];					\
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define ACCUM_OUTER_PRODUCT_2X2(m,v,t)				\
+{								\
+   m[0][0] += v[0] * t[0];					\
+   m[0][1] += v[0] * t[1];					\
+								\
+   m[1][0] += v[1] * t[0];					\
+   m[1][1] += v[1] * t[1];					\
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define ACCUM_OUTER_PRODUCT_3X3(m,v,t)				\
+{								\
+   m[0][0] += v[0] * t[0];					\
+   m[0][1] += v[0] * t[1];					\
+   m[0][2] += v[0] * t[2];					\
+								\
+   m[1][0] += v[1] * t[0];					\
+   m[1][1] += v[1] * t[1];					\
+   m[1][2] += v[1] * t[2];					\
+								\
+   m[2][0] += v[2] * t[0];					\
+   m[2][1] += v[2] * t[1];					\
+   m[2][2] += v[2] * t[2];					\
+}\
+
+
+/** outer product of vector times vector transpose
+ *
+ * The outer product of vector v and vector transpose t yeilds
+ * dyadic matrix m.
+ */
+#define ACCUM_OUTER_PRODUCT_4X4(m,v,t)				\
+{								\
+   m[0][0] += v[0] * t[0];					\
+   m[0][1] += v[0] * t[1];					\
+   m[0][2] += v[0] * t[2];					\
+   m[0][3] += v[0] * t[3];					\
+								\
+   m[1][0] += v[1] * t[0];					\
+   m[1][1] += v[1] * t[1];					\
+   m[1][2] += v[1] * t[2];					\
+   m[1][3] += v[1] * t[3];					\
+								\
+   m[2][0] += v[2] * t[0];					\
+   m[2][1] += v[2] * t[1];					\
+   m[2][2] += v[2] * t[2];					\
+   m[2][3] += v[2] * t[3];					\
+								\
+   m[3][0] += v[3] * t[0];					\
+   m[3][1] += v[3] * t[1];					\
+   m[3][2] += v[3] * t[2];					\
+   m[3][3] += v[3] * t[3];					\
+}\
+
+
+/** determinant of matrix
+ *
+ * Computes determinant of matrix m, returning d
+ */
+#define DETERMINANT_2X2(d,m)					\
+{								\
+   d = m[0][0] * m[1][1] - m[0][1] * m[1][0];			\
+}\
+
+
+/** determinant of matrix
+ *
+ * Computes determinant of matrix m, returning d
+ */
+#define DETERMINANT_3X3(d,m)					\
+{								\
+   d = m[0][0] * (m[1][1]*m[2][2] - m[1][2] * m[2][1]);		\
+   d -= m[0][1] * (m[1][0]*m[2][2] - m[1][2] * m[2][0]);	\
+   d += m[0][2] * (m[1][0]*m[2][1] - m[1][1] * m[2][0]);	\
+}\
+
+
+/** i,j,th cofactor of a 4x4 matrix
+ *
+ */
+#define COFACTOR_4X4_IJ(fac,m,i,j) 				\
+{								\
+   GUINT __ii[4], __jj[4], __k;						\
+								\
+   for (__k=0; __k<i; __k++) __ii[__k] = __k;				\
+   for (__k=i; __k<3; __k++) __ii[__k] = __k+1;				\
+   for (__k=0; __k<j; __k++) __jj[__k] = __k;				\
+   for (__k=j; __k<3; __k++) __jj[__k] = __k+1;				\
+								\
+   (fac) = m[__ii[0]][__jj[0]] * (m[__ii[1]][__jj[1]]*m[__ii[2]][__jj[2]] 	\
+                            - m[__ii[1]][__jj[2]]*m[__ii[2]][__jj[1]]); \
+   (fac) -= m[__ii[0]][__jj[1]] * (m[__ii[1]][__jj[0]]*m[__ii[2]][__jj[2]]	\
+                             - m[__ii[1]][__jj[2]]*m[__ii[2]][__jj[0]]);\
+   (fac) += m[__ii[0]][__jj[2]] * (m[__ii[1]][__jj[0]]*m[__ii[2]][__jj[1]]	\
+                             - m[__ii[1]][__jj[1]]*m[__ii[2]][__jj[0]]);\
+								\
+   __k = i+j;							\
+   if ( __k != (__k/2)*2) {						\
+      (fac) = -(fac);						\
+   }								\
+}\
+
+
+/** determinant of matrix
+ *
+ * Computes determinant of matrix m, returning d
+ */
+#define DETERMINANT_4X4(d,m)					\
+{								\
+   GREAL cofac;						\
+   COFACTOR_4X4_IJ (cofac, m, 0, 0);				\
+   d = m[0][0] * cofac;						\
+   COFACTOR_4X4_IJ (cofac, m, 0, 1);				\
+   d += m[0][1] * cofac;					\
+   COFACTOR_4X4_IJ (cofac, m, 0, 2);				\
+   d += m[0][2] * cofac;					\
+   COFACTOR_4X4_IJ (cofac, m, 0, 3);				\
+   d += m[0][3] * cofac;					\
+}\
+
+
+/** cofactor of matrix
+ *
+ * Computes cofactor of matrix m, returning a
+ */
+#define COFACTOR_2X2(a,m)					\
+{								\
+   a[0][0] = (m)[1][1];						\
+   a[0][1] = - (m)[1][0];						\
+   a[1][0] = - (m)[0][1];						\
+   a[1][1] = (m)[0][0];						\
+}\
+
+
+/** cofactor of matrix
+ *
+ * Computes cofactor of matrix m, returning a
+ */
+#define COFACTOR_3X3(a,m)					\
+{								\
+   a[0][0] = m[1][1]*m[2][2] - m[1][2]*m[2][1];			\
+   a[0][1] = - (m[1][0]*m[2][2] - m[2][0]*m[1][2]);		\
+   a[0][2] = m[1][0]*m[2][1] - m[1][1]*m[2][0];			\
+   a[1][0] = - (m[0][1]*m[2][2] - m[0][2]*m[2][1]);		\
+   a[1][1] = m[0][0]*m[2][2] - m[0][2]*m[2][0];			\
+   a[1][2] = - (m[0][0]*m[2][1] - m[0][1]*m[2][0]);		\
+   a[2][0] = m[0][1]*m[1][2] - m[0][2]*m[1][1];			\
+   a[2][1] = - (m[0][0]*m[1][2] - m[0][2]*m[1][0]);		\
+   a[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0]);		\
+}\
+
+
+/** cofactor of matrix
+ *
+ * Computes cofactor of matrix m, returning a
+ */
+#define COFACTOR_4X4(a,m)					\
+{								\
+   int i,j;							\
+								\
+   for (i=0; i<4; i++) {					\
+      for (j=0; j<4; j++) {					\
+         COFACTOR_4X4_IJ (a[i][j], m, i, j);			\
+      }								\
+   }								\
+}\
+
+
+/** adjoint of matrix
+ *
+ * Computes adjoint of matrix m, returning a
+ * (Note that adjoint is just the transpose of the cofactor matrix)
+ */
+#define ADJOINT_2X2(a,m)					\
+{								\
+   a[0][0] = (m)[1][1];						\
+   a[1][0] = - (m)[1][0];						\
+   a[0][1] = - (m)[0][1];						\
+   a[1][1] = (m)[0][0];						\
+}\
+
+
+/** adjoint of matrix
+ *
+ * Computes adjoint of matrix m, returning a
+ * (Note that adjoint is just the transpose of the cofactor matrix)
+ */
+#define ADJOINT_3X3(a,m)					\
+{								\
+   a[0][0] = m[1][1]*m[2][2] - m[1][2]*m[2][1];			\
+   a[1][0] = - (m[1][0]*m[2][2] - m[2][0]*m[1][2]);		\
+   a[2][0] = m[1][0]*m[2][1] - m[1][1]*m[2][0];			\
+   a[0][1] = - (m[0][1]*m[2][2] - m[0][2]*m[2][1]);		\
+   a[1][1] = m[0][0]*m[2][2] - m[0][2]*m[2][0];			\
+   a[2][1] = - (m[0][0]*m[2][1] - m[0][1]*m[2][0]);		\
+   a[0][2] = m[0][1]*m[1][2] - m[0][2]*m[1][1];			\
+   a[1][2] = - (m[0][0]*m[1][2] - m[0][2]*m[1][0]);		\
+   a[2][2] = m[0][0]*m[1][1] - m[0][1]*m[1][0]);		\
+}\
+
+
+/** adjoint of matrix
+ *
+ * Computes adjoint of matrix m, returning a
+ * (Note that adjoint is just the transpose of the cofactor matrix)
+ */
+#define ADJOINT_4X4(a,m)					\
+{								\
+   char _i_,_j_;							\
+								\
+   for (_i_=0; _i_<4; _i_++) {					\
+      for (_j_=0; _j_<4; _j_++) {					\
+         COFACTOR_4X4_IJ (a[_j_][_i_], m, _i_, _j_);			\
+      }								\
+   }								\
+}\
+
+
+/** compute adjoint of matrix and scale
+ *
+ * Computes adjoint of matrix m, scales it by s, returning a
+ */
+#define SCALE_ADJOINT_2X2(a,s,m)				\
+{								\
+   a[0][0] = (s) * m[1][1];					\
+   a[1][0] = - (s) * m[1][0];					\
+   a[0][1] = - (s) * m[0][1];					\
+   a[1][1] = (s) * m[0][0];					\
+}\
+
+
+/** compute adjoint of matrix and scale
+ *
+ * Computes adjoint of matrix m, scales it by s, returning a
+ */
+#define SCALE_ADJOINT_3X3(a,s,m)				\
+{								\
+   a[0][0] = (s) * (m[1][1] * m[2][2] - m[1][2] * m[2][1]);	\
+   a[1][0] = (s) * (m[1][2] * m[2][0] - m[1][0] * m[2][2]);	\
+   a[2][0] = (s) * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);	\
+								\
+   a[0][1] = (s) * (m[0][2] * m[2][1] - m[0][1] * m[2][2]);	\
+   a[1][1] = (s) * (m[0][0] * m[2][2] - m[0][2] * m[2][0]);	\
+   a[2][1] = (s) * (m[0][1] * m[2][0] - m[0][0] * m[2][1]);	\
+								\
+   a[0][2] = (s) * (m[0][1] * m[1][2] - m[0][2] * m[1][1]);	\
+   a[1][2] = (s) * (m[0][2] * m[1][0] - m[0][0] * m[1][2]);	\
+   a[2][2] = (s) * (m[0][0] * m[1][1] - m[0][1] * m[1][0]);	\
+}\
+
+
+/** compute adjoint of matrix and scale
+ *
+ * Computes adjoint of matrix m, scales it by s, returning a
+ */
+#define SCALE_ADJOINT_4X4(a,s,m)				\
+{								\
+   char _i_,_j_; \
+   for (_i_=0; _i_<4; _i_++) {					\
+      for (_j_=0; _j_<4; _j_++) {					\
+         COFACTOR_4X4_IJ (a[_j_][_i_], m, _i_, _j_);			\
+         a[_j_][_i_] *= s;						\
+      }								\
+   }								\
+}\
+
+/** inverse of matrix
+ *
+ * Compute inverse of matrix a, returning determinant m and
+ * inverse b
+ */
+#define INVERT_2X2(b,det,a)			\
+{						\
+   GREAL _tmp_;					\
+   DETERMINANT_2X2 (det, a);			\
+   _tmp_ = 1.0 / (det);				\
+   SCALE_ADJOINT_2X2 (b, _tmp_, a);		\
+}\
+
+
+/** inverse of matrix
+ *
+ * Compute inverse of matrix a, returning determinant m and
+ * inverse b
+ */
+#define INVERT_3X3(b,det,a)			\
+{						\
+   GREAL _tmp_;					\
+   DETERMINANT_3X3 (det, a);			\
+   _tmp_ = 1.0 / (det);				\
+   SCALE_ADJOINT_3X3 (b, _tmp_, a);		\
+}\
+
+
+/** inverse of matrix
+ *
+ * Compute inverse of matrix a, returning determinant m and
+ * inverse b
+ */
+#define INVERT_4X4(b,det,a)			\
+{						\
+   GREAL _tmp_;					\
+   DETERMINANT_4X4 (det, a);			\
+   _tmp_ = 1.0 / (det);				\
+   SCALE_ADJOINT_4X4 (b, _tmp_, a);		\
+}\
+
+//! Get the triple(3) row of a transform matrix
+#define MAT_GET_ROW(mat,vec3,rowindex)\
+{\
+    vec3[0] = mat[rowindex][0];\
+    vec3[1] = mat[rowindex][1];\
+    vec3[2] = mat[rowindex][2]; \
+}\
+
+//! Get the tuple(2) row of a transform matrix
+#define MAT_GET_ROW2(mat,vec2,rowindex)\
+{\
+    vec2[0] = mat[rowindex][0];\
+    vec2[1] = mat[rowindex][1];\
+}\
+
+
+//! Get the quad (4) row of a transform matrix
+#define MAT_GET_ROW4(mat,vec4,rowindex)\
+{\
+    vec4[0] = mat[rowindex][0];\
+    vec4[1] = mat[rowindex][1];\
+    vec4[2] = mat[rowindex][2];\
+    vec4[3] = mat[rowindex][3];\
+}\
+
+//! Get the triple(3) col of a transform matrix
+#define MAT_GET_COL(mat,vec3,colindex)\
+{\
+    vec3[0] = mat[0][colindex];\
+    vec3[1] = mat[1][colindex];\
+    vec3[2] = mat[2][colindex]; \
+}\
+
+//! Get the tuple(2) col of a transform matrix
+#define MAT_GET_COL2(mat,vec2,colindex)\
+{\
+    vec2[0] = mat[0][colindex];\
+    vec2[1] = mat[1][colindex];\
+}\
+
+
+//! Get the quad (4) col of a transform matrix
+#define MAT_GET_COL4(mat,vec4,colindex)\
+{\
+    vec4[0] = mat[0][colindex];\
+    vec4[1] = mat[1][colindex];\
+    vec4[2] = mat[2][colindex];\
+    vec4[3] = mat[3][colindex];\
+}\
+
+//! Get the triple(3) col of a transform matrix
+#define MAT_GET_X(mat,vec3)\
+{\
+    MAT_GET_COL(mat,vec3,0);\
+}\
+
+//! Get the triple(3) col of a transform matrix
+#define MAT_GET_Y(mat,vec3)\
+{\
+    MAT_GET_COL(mat,vec3,1);\
+}\
+
+//! Get the triple(3) col of a transform matrix
+#define MAT_GET_Z(mat,vec3)\
+{\
+    MAT_GET_COL(mat,vec3,2);\
+}\
+
+
+//! Get the triple(3) col of a transform matrix
+#define MAT_SET_X(mat,vec3)\
+{\
+    mat[0][0] = vec3[0];\
+    mat[1][0] = vec3[1];\
+    mat[2][0] = vec3[2];\
+}\
+
+//! Get the triple(3) col of a transform matrix
+#define MAT_SET_Y(mat,vec3)\
+{\
+    mat[0][1] = vec3[0];\
+    mat[1][1] = vec3[1];\
+    mat[2][1] = vec3[2];\
+}\
+
+//! Get the triple(3) col of a transform matrix
+#define MAT_SET_Z(mat,vec3)\
+{\
+    mat[0][2] = vec3[0];\
+    mat[1][2] = vec3[1];\
+    mat[2][2] = vec3[2];\
+}\
+
+
+//! Get the triple(3) col of a transform matrix
+#define MAT_GET_TRANSLATION(mat,vec3)\
+{\
+    vec3[0] = mat[0][3];\
+    vec3[1] = mat[1][3];\
+    vec3[2] = mat[2][3]; \
+}\
+
+//! Set the triple(3) col of a transform matrix
+#define MAT_SET_TRANSLATION(mat,vec3)\
+{\
+    mat[0][3] = vec3[0];\
+    mat[1][3] = vec3[1];\
+    mat[2][3] = vec3[2]; \
+}\
+
+
+
+//! Returns the dot product between a vec3f and the row of a matrix
+#define MAT_DOT_ROW(mat,vec3,rowindex) (vec3[0]*mat[rowindex][0] + vec3[1]*mat[rowindex][1] + vec3[2]*mat[rowindex][2])
+
+//! Returns the dot product between a vec2f and the row of a matrix
+#define MAT_DOT_ROW2(mat,vec2,rowindex) (vec2[0]*mat[rowindex][0] + vec2[1]*mat[rowindex][1])
+
+//! Returns the dot product between a vec4f and the row of a matrix
+#define MAT_DOT_ROW4(mat,vec4,rowindex) (vec4[0]*mat[rowindex][0] + vec4[1]*mat[rowindex][1] + vec4[2]*mat[rowindex][2] + vec4[3]*mat[rowindex][3])
+
+
+//! Returns the dot product between a vec3f and the col of a matrix
+#define MAT_DOT_COL(mat,vec3,colindex) (vec3[0]*mat[0][colindex] + vec3[1]*mat[1][colindex] + vec3[2]*mat[2][colindex])
+
+//! Returns the dot product between a vec2f and the col of a matrix
+#define MAT_DOT_COL2(mat,vec2,colindex) (vec2[0]*mat[0][colindex] + vec2[1]*mat[1][colindex])
+
+//! Returns the dot product between a vec4f and the col of a matrix
+#define MAT_DOT_COL4(mat,vec4,colindex) (vec4[0]*mat[0][colindex] + vec4[1]*mat[1][colindex] + vec4[2]*mat[2][colindex] + vec4[3]*mat[3][colindex])
+
+/*!Transpose matrix times vector
+v is a vec3f
+and m is a mat4f<br>
+*/
+#define INV_MAT_DOT_VEC_3X3(p,m,v)					\
+{								\
+   p[0] = MAT_DOT_COL(m,v,0); \
+   p[1] = MAT_DOT_COL(m,v,1);	\
+   p[2] = MAT_DOT_COL(m,v,2);	\
+}\
+
+
+
+#endif // GIM_VECTOR_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_math.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_math.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_math.h	(revision 6952)
@@ -0,0 +1,157 @@
+#ifndef GIM_MATH_H_INCLUDED
+#define GIM_MATH_H_INCLUDED
+/*! \file gim_math.h
+\author Francisco Len Nßjera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "LinearMath/btScalar.h"
+
+
+
+#define GREAL btScalar
+#define GREAL2 double
+#define GINT int
+#define GUINT unsigned int
+#define GSHORT short
+#define GUSHORT unsigned short
+#define GINT64 long long
+#define GUINT64 unsigned long long
+
+
+
+#define G_PI 3.14159265358979f
+#define G_HALF_PI 1.5707963f
+//267948966
+#define G_TWO_PI 6.28318530f
+//71795864
+#define G_ROOT3 1.73205f
+#define G_ROOT2 1.41421f
+#define G_UINT_INFINITY 0xffffffff //!< A very very high value
+#define G_REAL_INFINITY FLT_MAX
+#define	G_SIGN_BITMASK			0x80000000
+#define G_EPSILON SIMD_EPSILON
+
+
+
+enum GIM_SCALAR_TYPES
+{
+	G_STYPE_REAL =0,
+	G_STYPE_REAL2,
+	G_STYPE_SHORT,
+	G_STYPE_USHORT,
+	G_STYPE_INT,
+	G_STYPE_UINT,
+	G_STYPE_INT64,
+	G_STYPE_UINT64
+};
+
+
+
+#define G_DEGTORAD(X) ((X)*3.1415926f/180.0f)
+#define G_RADTODEG(X) ((X)*180.0f/3.1415926f)
+
+//! Integer representation of a floating-point value.
+#define GIM_IR(x)					((GUINT&)(x))
+
+//! Signed integer representation of a floating-point value.
+#define GIM_SIR(x)					((GINT&)(x))
+
+//! Absolute integer representation of a floating-point value
+#define GIM_AIR(x)					(GIM_IR(x)&0x7fffffff)
+
+//! Floating-point representation of an integer value.
+#define GIM_FR(x)					((GREAL&)(x))
+
+#define GIM_MAX(a,b) (a<b?b:a)
+#define GIM_MIN(a,b) (a>b?b:a)
+
+#define GIM_MAX3(a,b,c) GIM_MAX(a,GIM_MAX(b,c))
+#define GIM_MIN3(a,b,c) GIM_MIN(a,GIM_MIN(b,c))
+
+#define GIM_IS_ZERO(value) (value < G_EPSILON &&  value > -G_EPSILON)
+
+#define GIM_IS_NEGATIVE(value) (value <= -G_EPSILON)
+
+#define GIM_IS_POSISITVE(value) (value >= G_EPSILON)
+
+#define GIM_NEAR_EQUAL(v1,v2) GIM_IS_ZERO((v1-v2))
+
+///returns a clamped number
+#define GIM_CLAMP(number,minval,maxval) (number<minval?minval:(number>maxval?maxval:number))
+
+#define GIM_GREATER(x, y)	btFabs(x) > (y)
+
+///Swap numbers
+#define GIM_SWAP_NUMBERS(a,b){ \
+    a = a+b; \
+    b = a-b; \
+    a = a-b; \
+}\
+
+#define GIM_INV_SQRT(va,isva)\
+{\
+    if(va<=0.0000001f)\
+    {\
+        isva = G_REAL_INFINITY;\
+    }\
+    else\
+    {\
+        GREAL _x = va * 0.5f;\
+        GUINT _y = 0x5f3759df - ( GIM_IR(va) >> 1);\
+        isva = GIM_FR(_y);\
+        isva  = isva * ( 1.5f - ( _x * isva * isva ) );\
+    }\
+}\
+
+#define GIM_SQRT(va,sva)\
+{\
+    GIM_INV_SQRT(va,sva);\
+    sva = 1.0f/sva;\
+}\
+
+//! Computes 1.0f / sqrtf(x). Comes from Quake3. See http://www.magic-software.com/3DGEDInvSqrt.html
+inline GREAL gim_inv_sqrt(GREAL f)
+{
+    GREAL r;
+    GIM_INV_SQRT(f,r);
+    return r;
+}
+
+inline GREAL gim_sqrt(GREAL f)
+{
+    GREAL r;
+    GIM_SQRT(f,r);
+    return r;
+}
+
+
+
+#endif // GIM_MATH_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_memory.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_memory.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_memory.cpp	(revision 6952)
@@ -0,0 +1,135 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "gim_memory.h"
+#include "stdlib.h"
+
+#ifdef GIM_SIMD_MEMORY
+#include "LinearMath/btAlignedAllocator.h"
+#endif
+
+static gim_alloc_function *g_allocfn = 0;
+static gim_alloca_function *g_allocafn = 0;
+static gim_realloc_function *g_reallocfn = 0;
+static gim_free_function *g_freefn = 0;
+
+void gim_set_alloc_handler (gim_alloc_function *fn)
+{
+  g_allocfn = fn;
+}
+
+void gim_set_alloca_handler (gim_alloca_function *fn)
+{
+  g_allocafn = fn;
+}
+
+void gim_set_realloc_handler (gim_realloc_function *fn)
+{
+  g_reallocfn = fn;
+}
+
+void gim_set_free_handler (gim_free_function *fn)
+{
+  g_freefn = fn;
+}
+
+gim_alloc_function *gim_get_alloc_handler()
+{
+  return g_allocfn;
+}
+
+gim_alloca_function *gim_get_alloca_handler()
+{
+  return g_allocafn;
+}
+
+
+gim_realloc_function *gim_get_realloc_handler ()
+{
+  return g_reallocfn;
+}
+
+
+gim_free_function  *gim_get_free_handler ()
+{
+  return g_freefn;
+}
+
+
+void * gim_alloc(size_t size)
+{
+	void * ptr;
+	if (g_allocfn)
+	{
+		ptr = g_allocfn(size);
+	}
+	else
+	{
+#ifdef GIM_SIMD_MEMORY
+		ptr = btAlignedAlloc(size,16);
+#else
+		ptr = malloc(size);
+#endif
+	}
+  	return ptr;
+}
+
+void * gim_alloca(size_t size)
+{
+  if (g_allocafn) return g_allocafn(size); else return gim_alloc(size);
+}
+
+
+void * gim_realloc(void *ptr, size_t oldsize, size_t newsize)
+{
+ 	void * newptr = gim_alloc(newsize);
+    size_t copysize = oldsize<newsize?oldsize:newsize;
+    gim_simd_memcpy(newptr,ptr,copysize);
+    gim_free(ptr);
+    return newptr;
+}
+
+void gim_free(void *ptr)
+{
+	if (!ptr) return;
+	if (g_freefn)
+	{
+	   g_freefn(ptr);
+	}
+	else
+	{
+	#ifdef GIM_SIMD_MEMORY
+		btAlignedFree(ptr);
+	#else
+		free(ptr);
+	#endif
+	}
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_memory.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_memory.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_memory.h	(revision 6952)
@@ -0,0 +1,190 @@
+#ifndef GIM_MEMORY_H_INCLUDED
+#define GIM_MEMORY_H_INCLUDED
+/*! \file gim_memory.h
+\author Francisco Len Nßjera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+
+#include "gim_math.h"
+#include <memory.h>
+
+#ifdef PREFETCH
+#include <xmmintrin.h>	// for prefetch
+#define pfval	64
+#define pfval2	128
+//! Prefetch 64
+#define pf(_x,_i)	_mm_prefetch((void *)(_x + _i + pfval), 0)
+//! Prefetch 128
+#define pf2(_x,_i)	_mm_prefetch((void *)(_x + _i + pfval2), 0)
+#else
+//! Prefetch 64
+#define pf(_x,_i)
+//! Prefetch 128
+#define pf2(_x,_i)
+#endif
+
+
+///Functions for manip packed arrays of numbers
+#define GIM_COPY_ARRAYS(dest_array,source_array,element_count)\
+{\
+    for (GUINT _i_=0;_i_<element_count ;++_i_)\
+    {\
+    	dest_array[_i_] = source_array[_i_];\
+    }\
+}\
+
+#define GIM_COPY_ARRAYS_1(dest_array,source_array,element_count,copy_macro)\
+{\
+    for (GUINT _i_=0;_i_<element_count ;++_i_)\
+    {\
+    	copy_macro(dest_array[_i_],source_array[_i_]);\
+    }\
+}\
+
+
+#define GIM_ZERO_ARRAY(array,element_count)\
+{\
+    for (GUINT _i_=0;_i_<element_count ;++_i_)\
+    {\
+    	array[_i_] = 0;\
+    }\
+}\
+
+#define GIM_CONSTANT_ARRAY(array,element_count,constant)\
+{\
+    for (GUINT _i_=0;_i_<element_count ;++_i_)\
+    {\
+    	array[_i_] = constant;\
+    }\
+}\
+
+
+///Function prototypes to allocate and free memory.
+typedef void * gim_alloc_function (size_t size);
+typedef void * gim_alloca_function (size_t size);//Allocs on the heap
+typedef void * gim_realloc_function (void *ptr, size_t oldsize, size_t newsize);
+typedef void gim_free_function (void *ptr);
+
+
+///Memory Function Handlers
+///set new memory management functions. if fn is 0, the default handlers are used.
+void gim_set_alloc_handler (gim_alloc_function *fn);
+void gim_set_alloca_handler (gim_alloca_function *fn);
+void gim_set_realloc_handler (gim_realloc_function *fn);
+void gim_set_free_handler (gim_free_function *fn);
+
+
+///get current memory management functions.
+gim_alloc_function *gim_get_alloc_handler (void);
+gim_alloca_function *gim_get_alloca_handler(void);
+gim_realloc_function *gim_get_realloc_handler (void);
+gim_free_function  *gim_get_free_handler (void);
+
+
+///Standar Memory functions
+void * gim_alloc(size_t size);
+void * gim_alloca(size_t size);
+void * gim_realloc(void *ptr, size_t oldsize, size_t newsize);
+void gim_free(void *ptr);
+
+
+
+#if defined (WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
+    #define GIM_SIMD_MEMORY 1
+#endif
+
+//! SIMD POINTER INTEGER
+#define SIMD_T GUINT64
+//! SIMD INTEGER SIZE
+#define SIMD_T_SIZE sizeof(SIMD_T)
+
+
+inline void gim_simd_memcpy(void * dst, const void * src, size_t copysize)
+{
+#ifdef GIM_SIMD_MEMORY
+/*
+//'long long int' is incompatible with visual studio 6...
+    //copy words
+    SIMD_T * ui_src_ptr = (SIMD_T *)src;
+    SIMD_T * ui_dst_ptr = (SIMD_T *)dst;
+    while(copysize>=SIMD_T_SIZE)
+    {
+        *(ui_dst_ptr++) = *(ui_src_ptr++);
+        copysize-=SIMD_T_SIZE;
+    }
+    if(copysize==0) return;
+*/
+
+    char * c_src_ptr = (char *)src;
+    char * c_dst_ptr = (char *)dst;
+    while(copysize>0)
+    {
+        *(c_dst_ptr++) = *(c_src_ptr++);
+        copysize--;
+    }
+    return;
+#else
+    memcpy(dst,src,copysize);
+#endif
+}
+
+
+
+template<class T>
+inline void gim_swap_elements(T* _array,size_t _i,size_t _j)
+{
+	T _e_tmp_ = _array[_i];
+	_array[_i] = _array[_j];
+	_array[_j] = _e_tmp_;
+}
+
+
+template<class T>
+inline void gim_swap_elements_memcpy(T* _array,size_t _i,size_t _j)
+{
+	char _e_tmp_[sizeof(T)];
+	gim_simd_memcpy(_e_tmp_,&_array[_i],sizeof(T));
+	gim_simd_memcpy(&_array[_i],&_array[_j],sizeof(T));
+	gim_simd_memcpy(&_array[_j],_e_tmp_,sizeof(T));
+}
+
+template <int SIZE>
+inline void gim_swap_elements_ptr(char * _array,size_t _i,size_t _j)
+{
+	char _e_tmp_[SIZE];
+	_i*=SIZE;
+	_j*=SIZE;
+	gim_simd_memcpy(_e_tmp_,_array+_i,SIZE);
+	gim_simd_memcpy(_array+_i,_array+_j,SIZE);
+	gim_simd_memcpy(_array+_j,_e_tmp_,SIZE);
+}
+
+#endif // GIM_MEMORY_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_radixsort.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_radixsort.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_radixsort.h	(revision 6952)
@@ -0,0 +1,406 @@
+#ifndef GIM_RADIXSORT_H_INCLUDED
+#define GIM_RADIXSORT_H_INCLUDED
+/*! \file gim_radixsort.h
+\author Francisco Len Nßjera.
+Based on the work of Michael Herf : "fast floating-point radix sort"
+Avaliable on http://www.stereopsis.com/radix.html
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "gim_memory.h"
+
+///Macros for sorting.
+//! Prototype for comparators
+class less_comparator
+{
+	public:
+
+	template<class T,class Z>
+	inline int operator() ( const T& a, const Z& b )
+	{
+		return ( a<b?-1:(a>b?1:0));
+	}
+};
+
+//! Prototype for comparators
+class integer_comparator
+{
+	public:
+
+	template<class T>
+	inline int operator() ( const T& a, const T& b )
+	{
+		return (int)(a-b);
+	}
+};
+
+//!Prototype for getting the integer representation of an object
+class uint_key_func
+{
+public:
+	template<class T>
+	inline GUINT operator()( const T& a)
+	{
+		return (GUINT)a;
+	}
+};
+
+
+//!Prototype for copying elements
+class copy_elements_func
+{
+public:
+	template<class T>
+	inline void operator()(T& a,T& b)
+	{
+		a = b;
+	}
+};
+
+//!Prototype for copying elements
+class memcopy_elements_func
+{
+public:
+	template<class T>
+	inline void operator()(T& a,T& b)
+	{
+		gim_simd_memcpy(&a,&b,sizeof(T));
+	}
+};
+
+
+//! @{
+struct GIM_RSORT_TOKEN
+{
+    GUINT m_key;
+    GUINT m_value;
+    GIM_RSORT_TOKEN()
+    {
+    }
+    GIM_RSORT_TOKEN(const GIM_RSORT_TOKEN& rtoken)
+    {
+    	m_key = rtoken.m_key;
+    	m_value = rtoken.m_value;
+    }
+
+    inline bool operator <(const GIM_RSORT_TOKEN& other) const
+	{
+		return (m_key < other.m_key);
+	}
+
+	inline bool operator >(const GIM_RSORT_TOKEN& other) const
+	{
+		return (m_key > other.m_key);
+	}
+};
+
+//! Prototype for comparators
+class GIM_RSORT_TOKEN_COMPARATOR
+{
+	public:
+
+	inline int operator()( const GIM_RSORT_TOKEN& a, const GIM_RSORT_TOKEN& b )
+	{
+		return (int)((a.m_key) - (b.m_key));
+	}
+};
+
+
+
+#define kHist 2048
+// ---- utils for accessing 11-bit quantities
+#define D11_0(x)	(x & 0x7FF)
+#define D11_1(x)	(x >> 11 & 0x7FF)
+#define D11_2(x)	(x >> 22 )
+
+
+
+///Radix sort for unsigned integer keys
+inline void gim_radix_sort_rtokens(
+				GIM_RSORT_TOKEN * array,
+				GIM_RSORT_TOKEN * sorted, GUINT element_count)
+{
+	GUINT i;
+	GUINT b0[kHist * 3];
+	GUINT *b1 = b0 + kHist;
+	GUINT *b2 = b1 + kHist;
+	for (i = 0; i < kHist * 3; ++i)
+	{
+		b0[i] = 0;
+	}
+	GUINT fi;
+	GUINT pos;
+	for (i = 0; i < element_count; ++i)
+	{
+	    fi = array[i].m_key;
+		b0[D11_0(fi)] ++;
+		b1[D11_1(fi)] ++;
+		b2[D11_2(fi)] ++;
+	}
+	{
+		GUINT sum0 = 0, sum1 = 0, sum2 = 0;
+		GUINT tsum;
+		for (i = 0; i < kHist; ++i)
+		{
+			tsum = b0[i] + sum0;
+			b0[i] = sum0 - 1;
+			sum0 = tsum;
+			tsum = b1[i] + sum1;
+			b1[i] = sum1 - 1;
+			sum1 = tsum;
+			tsum = b2[i] + sum2;
+			b2[i] = sum2 - 1;
+			sum2 = tsum;
+		}
+	}
+	for (i = 0; i < element_count; ++i)
+	{
+        fi = array[i].m_key;
+		pos = D11_0(fi);
+		pos = ++b0[pos];
+		sorted[pos].m_key = array[i].m_key;
+		sorted[pos].m_value = array[i].m_value;
+	}
+	for (i = 0; i < element_count; ++i)
+	{
+        fi = sorted[i].m_key;
+		pos = D11_1(fi);
+		pos = ++b1[pos];
+		array[pos].m_key = sorted[i].m_key;
+		array[pos].m_value = sorted[i].m_value;
+	}
+	for (i = 0; i < element_count; ++i)
+	{
+        fi = array[i].m_key;
+		pos = D11_2(fi);
+		pos = ++b2[pos];
+		sorted[pos].m_key = array[i].m_key;
+		sorted[pos].m_value = array[i].m_value;
+	}
+}
+
+
+
+
+/// Get the sorted tokens from an array. For generic use. Tokens are IRR_RSORT_TOKEN
+/*!
+*\param array Array of elements to sort
+*\param sorted_tokens Tokens of sorted elements
+*\param element_count element count
+*\param uintkey_macro Functor which retrieves the integer representation of an array element
+*/
+template<typename T, class GETKEY_CLASS>
+void gim_radix_sort_array_tokens(
+			T* array ,
+			GIM_RSORT_TOKEN * sorted_tokens,
+			GUINT element_count,GETKEY_CLASS uintkey_macro)
+{
+	GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count);
+    for (GUINT _i=0;_i<element_count;++_i)
+    {
+        _unsorted[_i].m_key = uintkey_macro(array[_i]);
+        _unsorted[_i].m_value = _i;
+    }
+    gim_radix_sort_rtokens(_unsorted,sorted_tokens,element_count);
+    gim_free(_unsorted);
+    gim_free(_unsorted);
+}
+
+/// Sorts array in place. For generic use
+/*!
+\param type Type of the array
+\param array
+\param element_count
+\param get_uintkey_macro Macro for extract the Integer value of the element. Similar to SIMPLE_GET_UINTKEY
+\param copy_elements_macro Macro for copy elements, similar to SIMPLE_COPY_ELEMENTS
+*/
+template<typename T, class GETKEY_CLASS, class COPY_CLASS>
+void gim_radix_sort(
+	T * array, GUINT element_count,
+	GETKEY_CLASS get_uintkey_macro, COPY_CLASS copy_elements_macro)
+{
+	GIM_RSORT_TOKEN * _sorted = (GIM_RSORT_TOKEN  *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count);
+    gim_radix_sort_array_tokens(array,_sorted,element_count,get_uintkey_macro);
+    T * _original_array = (T *) gim_alloc(sizeof(T)*element_count);
+    gim_simd_memcpy(_original_array,array,sizeof(T)*element_count);
+    for (GUINT _i=0;_i<element_count;++_i)
+    {
+        copy_elements_macro(array[_i],_original_array[_sorted[_i].m_value]);
+    }
+    gim_free(_original_array);
+    gim_free(_sorted);
+}
+
+//! Failsafe Iterative binary search,
+/*!
+If the element is not found, it returns the nearest upper element position, may be the further position after the last element.
+\param _array
+\param _start_i the beginning of the array
+\param _end_i the ending  index of the array
+\param _search_key Value to find
+\param _comp_macro macro for comparing elements
+\param _found If true the value has found. Boolean
+\param _result_index the index of the found element, or if not found then it will get the index of the  closest bigger value
+*/
+template<class T, typename KEYCLASS, typename COMP_CLASS>
+bool  gim_binary_search_ex(
+		const T* _array, GUINT _start_i,
+		GUINT _end_i,GUINT & _result_index,
+		const KEYCLASS & _search_key,
+		COMP_CLASS _comp_macro)
+{
+	GUINT _k;
+	int _comp_result;
+	GUINT _i = _start_i;
+	GUINT _j = _end_i+1;
+	while (_i < _j)
+	{
+		_k = (_j+_i-1)/2;
+		_comp_result = _comp_macro(_array[_k], _search_key);
+		if (_comp_result == 0)
+		{
+			_result_index = _k;
+			return true;
+		}
+		else if (_comp_result < 0)
+		{
+			_i = _k+1;
+		}
+		else
+		{
+			_j = _k;
+		}
+	}
+	_result_index = _i;
+	return false;
+}
+
+
+
+//! Failsafe Iterative binary search,Template version
+/*!
+If the element is not found, it returns the nearest upper element position, may be the further position after the last element.
+\param _array
+\param _start_i the beginning of the array
+\param _end_i the ending  index of the array
+\param _search_key Value to find
+\param _result_index the index of the found element, or if not found then it will get the index of the  closest bigger value
+\return true if found, else false
+*/
+template<class T>
+bool gim_binary_search(
+	const T*_array,GUINT _start_i,
+	GUINT _end_i,const T & _search_key,
+	GUINT & _result_index)
+{
+	GUINT _i = _start_i;
+	GUINT _j = _end_i+1;
+	GUINT _k;
+	while(_i < _j)
+	{
+		_k = (_j+_i-1)/2;
+		if(_array[_k]==_search_key)
+		{
+			_result_index = _k;
+			return true;
+		}
+		else if (_array[_k]<_search_key)
+		{
+			_i = _k+1;
+		}
+		else
+		{
+			_j = _k;
+		}
+	}
+	_result_index = _i;
+	return false;
+}
+
+
+
+///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/
+template <typename T, typename COMP_CLASS>
+void gim_down_heap(T *pArr, GUINT k, GUINT n,COMP_CLASS CompareFunc)
+{
+	/*  PRE: a[k+1..N] is a heap */
+	/* POST:  a[k..N]  is a heap */
+
+	T temp = pArr[k - 1];
+	/* k has child(s) */
+	while (k <= n/2)
+	{
+		int child = 2*k;
+
+		if ((child < (int)n) && CompareFunc(pArr[child - 1] , pArr[child])<0)
+		{
+			child++;
+		}
+		/* pick larger child */
+		if (CompareFunc(temp , pArr[child - 1])<0)
+		{
+			/* move child up */
+			pArr[k - 1] = pArr[child - 1];
+			k = child;
+		}
+		else
+		{
+			break;
+		}
+	}
+	pArr[k - 1] = temp;
+} /*downHeap*/
+
+
+template <typename T, typename COMP_CLASS>
+void gim_heap_sort(T *pArr, GUINT element_count, COMP_CLASS CompareFunc)
+{
+	/* sort a[0..N-1],  N.B. 0 to N-1 */
+	GUINT k;
+	GUINT n = element_count;
+	for (k = n/2; k > 0; k--)
+	{
+		gim_down_heap(pArr, k, n, CompareFunc);
+	}
+
+	/* a[1..N] is now a heap */
+	while ( n>=2 )
+	{
+		gim_swap_elements(pArr,0,n-1); /* largest of a[0..n-1] */
+		--n;
+		/* restore a[1..i-1] heap */
+		gim_down_heap(pArr, 1, n, CompareFunc);
+	}
+}
+
+
+
+
+#endif // GIM_RADIXSORT_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_tri_collision.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_tri_collision.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_tri_collision.cpp	(revision 6952)
@@ -0,0 +1,640 @@
+
+/*! \file gim_tri_collision.h
+\author Francisco Len Nßjera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "gim_tri_collision.h"
+
+
+#define TRI_LOCAL_EPSILON 0.000001f
+#define MIN_EDGE_EDGE_DIS 0.00001f
+
+
+class GIM_TRIANGLE_CALCULATION_CACHE
+{
+public:
+	GREAL margin;	
+	btVector3 tu_vertices[3];
+	btVector3 tv_vertices[3];
+	btVector4 tu_plane;
+	btVector4 tv_plane;
+	btVector3 closest_point_u;
+	btVector3 closest_point_v;
+	btVector3 edge_edge_dir;
+	btVector3 distances;
+	GREAL du[4];
+	GREAL du0du1;
+	GREAL du0du2;
+	GREAL dv[4];
+	GREAL dv0dv1;
+	GREAL dv0dv2;	
+	btVector3 temp_points[MAX_TRI_CLIPPING];
+	btVector3 temp_points1[MAX_TRI_CLIPPING];
+	btVector3 contact_points[MAX_TRI_CLIPPING];
+	
+
+
+	//! if returns false, the faces are paralele
+	SIMD_FORCE_INLINE bool compute_intervals(
+					const GREAL &D0,
+					const GREAL &D1,
+					const GREAL &D2,
+					const GREAL &D0D1,
+					const GREAL &D0D2,
+					GREAL & scale_edge0,
+					GREAL & scale_edge1,
+					GUINT &edge_index0,
+					GUINT &edge_index1)
+	{
+		if(D0D1>0.0f)
+		{
+			/* here we know that D0D2<=0.0 */
+			/* that is D0, D1 are on the same side, D2 on the other or on the plane */
+			scale_edge0 = -D2/(D0-D2);
+			scale_edge1 = -D1/(D2-D1);
+			edge_index0 = 2;edge_index1 = 1;
+		}
+		else if(D0D2>0.0f)
+		{
+			/* here we know that d0d1<=0.0 */
+			scale_edge0 = -D0/(D1-D0);
+			scale_edge1 = -D1/(D2-D1);
+			edge_index0 = 0;edge_index1 = 1;
+		}
+		else if(D1*D2>0.0f || D0!=0.0f)
+		{
+			/* here we know that d0d1<=0.0 or that D0!=0.0 */
+			scale_edge0 = -D0/(D1-D0);
+			scale_edge1 = -D2/(D0-D2);
+			edge_index0 = 0 ;edge_index1 = 2;
+		}
+		else
+		{
+			return false;
+		}
+		return true;
+	}
+
+
+	//! clip triangle
+	/*!
+	*/
+	SIMD_FORCE_INLINE GUINT clip_triangle(
+		const btVector4 & tri_plane,
+		const btVector3 * tripoints,
+		const btVector3 * srcpoints,
+		btVector3 * clip_points)
+	{
+		// edge 0
+
+		btVector4 edgeplane;
+
+		EDGE_PLANE(tripoints[0],tripoints[1],tri_plane,edgeplane);
+
+		GUINT clipped_count = PLANE_CLIP_TRIANGLE3D(
+			edgeplane,srcpoints[0],srcpoints[1],srcpoints[2],temp_points);
+
+		if(clipped_count == 0) return 0;
+
+		// edge 1
+
+		EDGE_PLANE(tripoints[1],tripoints[2],tri_plane,edgeplane);
+
+		clipped_count = PLANE_CLIP_POLYGON3D(
+			edgeplane,temp_points,clipped_count,temp_points1);
+
+		if(clipped_count == 0) return 0;
+
+		// edge 2
+
+		EDGE_PLANE(tripoints[2],tripoints[0],tri_plane,edgeplane);
+
+		clipped_count = PLANE_CLIP_POLYGON3D(
+			edgeplane,temp_points1,clipped_count,clip_points);
+
+		return clipped_count;
+
+
+		/*GUINT i0 = (tri_plane.closestAxis()+1)%3;
+		GUINT i1 = (i0+1)%3;
+		// edge 0
+		btVector3 temp_points[MAX_TRI_CLIPPING];
+		btVector3 temp_points1[MAX_TRI_CLIPPING];
+
+		GUINT clipped_count= PLANE_CLIP_TRIANGLE_GENERIC(
+			0,srcpoints[0],srcpoints[1],srcpoints[2],temp_points,
+			DISTANCE_EDGE(tripoints[0],tripoints[1],i0,i1));
+		
+		
+		if(clipped_count == 0) return 0;
+
+		// edge 1
+		clipped_count = PLANE_CLIP_POLYGON_GENERIC(
+			0,temp_points,clipped_count,temp_points1,
+			DISTANCE_EDGE(tripoints[1],tripoints[2],i0,i1));
+
+		if(clipped_count == 0) return 0;
+
+		// edge 2
+		clipped_count = PLANE_CLIP_POLYGON_GENERIC(
+			0,temp_points1,clipped_count,clipped_points,
+			DISTANCE_EDGE(tripoints[2],tripoints[0],i0,i1));
+
+		return clipped_count;*/
+	}
+
+	SIMD_FORCE_INLINE void sort_isect(
+		GREAL & isect0,GREAL & isect1,GUINT &e0,GUINT &e1,btVector3 & vec0,btVector3 & vec1)
+	{
+		if(isect1<isect0)
+		{
+			//swap
+			GIM_SWAP_NUMBERS(isect0,isect1);
+			GIM_SWAP_NUMBERS(e0,e1);
+			btVector3 tmp = vec0;
+			vec0 = vec1;
+			vec1 = tmp;
+		}
+	}
+
+	//! Test verifying interval intersection with the direction between planes
+	/*!
+	\pre tv_plane and tu_plane must be set
+	\post
+	distances[2] is set with the distance
+	closest_point_u, closest_point_v, edge_edge_dir are set too
+	\return
+	- 0: faces are paralele
+	- 1: face U casts face V
+	- 2: face V casts face U
+	- 3: nearest edges
+	*/
+	SIMD_FORCE_INLINE GUINT cross_line_intersection_test()
+	{
+		// Compute direction of intersection line
+		edge_edge_dir = tu_plane.cross(tv_plane);
+		GREAL Dlen;
+		VEC_LENGTH(edge_edge_dir,Dlen);
+
+		if(Dlen<0.0001)
+		{
+			return 0; //faces near paralele
+		}
+
+		edge_edge_dir*= 1/Dlen;//normalize
+
+
+		// Compute interval for triangle 1
+		GUINT tu_e0,tu_e1;//edge indices
+		GREAL tu_scale_e0,tu_scale_e1;//edge scale
+		if(!compute_intervals(du[0],du[1],du[2],
+			du0du1,du0du2,tu_scale_e0,tu_scale_e1,tu_e0,tu_e1)) return 0;
+
+		// Compute interval for triangle 2
+		GUINT tv_e0,tv_e1;//edge indices
+		GREAL tv_scale_e0,tv_scale_e1;//edge scale
+
+		if(!compute_intervals(dv[0],dv[1],dv[2],
+			dv0dv1,dv0dv2,tv_scale_e0,tv_scale_e1,tv_e0,tv_e1)) return 0;
+
+		//proyected vertices
+		btVector3 up_e0 = tu_vertices[tu_e0].lerp(tu_vertices[(tu_e0+1)%3],tu_scale_e0);
+		btVector3 up_e1 = tu_vertices[tu_e1].lerp(tu_vertices[(tu_e1+1)%3],tu_scale_e1);
+
+		btVector3 vp_e0 = tv_vertices[tv_e0].lerp(tv_vertices[(tv_e0+1)%3],tv_scale_e0);
+		btVector3 vp_e1 = tv_vertices[tv_e1].lerp(tv_vertices[(tv_e1+1)%3],tv_scale_e1);
+
+		//proyected intervals
+		GREAL isect_u[] = {up_e0.dot(edge_edge_dir),up_e1.dot(edge_edge_dir)};
+		GREAL isect_v[] = {vp_e0.dot(edge_edge_dir),vp_e1.dot(edge_edge_dir)};
+
+		sort_isect(isect_u[0],isect_u[1],tu_e0,tu_e1,up_e0,up_e1);
+		sort_isect(isect_v[0],isect_v[1],tv_e0,tv_e1,vp_e0,vp_e1);
+
+		const GREAL midpoint_u = 0.5f*(isect_u[0]+isect_u[1]); // midpoint
+		const GREAL midpoint_v = 0.5f*(isect_v[0]+isect_v[1]); // midpoint
+
+		if(midpoint_u<midpoint_v)
+		{
+			if(isect_u[1]>=isect_v[1]) // face U casts face V
+			{
+				return 1;
+			}
+			else if(isect_v[0]<=isect_u[0]) // face V casts face U
+			{
+				return 2;
+			}
+			// closest points
+			closest_point_u = up_e1;
+			closest_point_v = vp_e0;
+			// calc edges and separation
+
+			if(isect_u[1]+ MIN_EDGE_EDGE_DIS<isect_v[0]) //calc distance between two lines instead
+			{
+				SEGMENT_COLLISION(
+					tu_vertices[tu_e1],tu_vertices[(tu_e1+1)%3],
+					tv_vertices[tv_e0],tv_vertices[(tv_e0+1)%3],
+					closest_point_u,
+					closest_point_v);
+
+				edge_edge_dir = closest_point_u-closest_point_v;
+				VEC_LENGTH(edge_edge_dir,distances[2]);
+				edge_edge_dir *= 1.0f/distances[2];// normalize
+			}
+			else
+			{
+				distances[2] = isect_v[0]-isect_u[1];//distance negative
+				//edge_edge_dir *= -1.0f; //normal pointing from V to U
+			}
+
+		}
+		else
+		{
+			if(isect_v[1]>=isect_u[1]) // face V casts face U
+			{
+				return 2;
+			}
+			else if(isect_u[0]<=isect_v[0]) // face U casts face V
+			{
+				return 1;
+			}
+			// closest points
+			closest_point_u = up_e0;
+			closest_point_v = vp_e1;
+			// calc edges and separation
+
+			if(isect_v[1]+MIN_EDGE_EDGE_DIS<isect_u[0]) //calc distance between two lines instead
+			{
+				SEGMENT_COLLISION(
+					tu_vertices[tu_e0],tu_vertices[(tu_e0+1)%3],
+					tv_vertices[tv_e1],tv_vertices[(tv_e1+1)%3],
+					closest_point_u,
+					closest_point_v);
+
+				edge_edge_dir = closest_point_u-closest_point_v;
+				VEC_LENGTH(edge_edge_dir,distances[2]);
+				edge_edge_dir *= 1.0f/distances[2];// normalize
+			}
+			else
+			{
+				distances[2] = isect_u[0]-isect_v[1];//distance negative
+				//edge_edge_dir *= -1.0f; //normal pointing from V to U
+			}
+		}
+		return 3;
+	}
+
+
+	//! collides by two sides
+	SIMD_FORCE_INLINE bool triangle_collision(
+					const btVector3 & u0,
+					const btVector3 & u1,
+					const btVector3 & u2,
+					GREAL margin_u,
+					const btVector3 & v0,
+					const btVector3 & v1,
+					const btVector3 & v2,
+					GREAL margin_v,
+					GIM_TRIANGLE_CONTACT_DATA & contacts)
+	{
+
+		margin = margin_u + margin_v;
+
+		tu_vertices[0] = u0;
+		tu_vertices[1] = u1;
+		tu_vertices[2] = u2;
+
+		tv_vertices[0] = v0;
+		tv_vertices[1] = v1;
+		tv_vertices[2] = v2;
+
+		//create planes
+		// plane v vs U points
+
+		TRIANGLE_PLANE(tv_vertices[0],tv_vertices[1],tv_vertices[2],tv_plane);
+
+		du[0] = DISTANCE_PLANE_POINT(tv_plane,tu_vertices[0]);
+		du[1] = DISTANCE_PLANE_POINT(tv_plane,tu_vertices[1]);
+		du[2] = DISTANCE_PLANE_POINT(tv_plane,tu_vertices[2]);
+
+
+		du0du1 = du[0] * du[1];
+		du0du2 = du[0] * du[2];
+
+
+		if(du0du1>0.0f && du0du2>0.0f)	// same sign on all of them + not equal 0 ?
+		{
+			if(du[0]<0) //we need test behind the triangle plane
+			{
+				distances[0] = GIM_MAX3(du[0],du[1],du[2]);
+				distances[0] = -distances[0];
+				if(distances[0]>margin) return false; //never intersect
+
+				//reorder triangle v
+				VEC_SWAP(tv_vertices[0],tv_vertices[1]);
+				VEC_SCALE_4(tv_plane,-1.0f,tv_plane);
+			}
+			else
+			{
+				distances[0] = GIM_MIN3(du[0],du[1],du[2]);
+				if(distances[0]>margin) return false; //never intersect
+			}
+		}
+		else
+		{
+			//Look if we need to invert the triangle
+			distances[0] = (du[0]+du[1]+du[2])/3.0f; //centroid
+
+			if(distances[0]<0.0f)
+			{
+				//reorder triangle v
+				VEC_SWAP(tv_vertices[0],tv_vertices[1]);
+				VEC_SCALE_4(tv_plane,-1.0f,tv_plane);
+
+				distances[0] = GIM_MAX3(du[0],du[1],du[2]);
+				distances[0] = -distances[0];
+			}
+			else
+			{
+				distances[0] = GIM_MIN3(du[0],du[1],du[2]);
+			}
+		}
+
+
+		// plane U vs V points
+
+		TRIANGLE_PLANE(tu_vertices[0],tu_vertices[1],tu_vertices[2],tu_plane);
+
+		dv[0] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[0]);
+		dv[1] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[1]);
+		dv[2] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[2]);
+
+		dv0dv1 = dv[0] * dv[1];
+		dv0dv2 = dv[0] * dv[2];
+
+
+		if(dv0dv1>0.0f && dv0dv2>0.0f)	// same sign on all of them + not equal 0 ?
+		{
+			if(dv[0]<0) //we need test behind the triangle plane
+			{
+				distances[1] = GIM_MAX3(dv[0],dv[1],dv[2]);
+				distances[1] = -distances[1];
+				if(distances[1]>margin) return false; //never intersect
+
+				//reorder triangle u
+				VEC_SWAP(tu_vertices[0],tu_vertices[1]);
+				VEC_SCALE_4(tu_plane,-1.0f,tu_plane);
+			}
+			else
+			{
+				distances[1] = GIM_MIN3(dv[0],dv[1],dv[2]);
+				if(distances[1]>margin) return false; //never intersect
+			}
+		}
+		else
+		{
+			//Look if we need to invert the triangle
+			distances[1] = (dv[0]+dv[1]+dv[2])/3.0f; //centroid
+
+			if(distances[1]<0.0f)
+			{
+				//reorder triangle v
+				VEC_SWAP(tu_vertices[0],tu_vertices[1]);
+				VEC_SCALE_4(tu_plane,-1.0f,tu_plane);
+
+				distances[1] = GIM_MAX3(dv[0],dv[1],dv[2]);
+				distances[1] = -distances[1];
+			}
+			else
+			{
+				distances[1] = GIM_MIN3(dv[0],dv[1],dv[2]);
+			}
+		}
+
+		GUINT bl;
+		/* bl = cross_line_intersection_test();
+		if(bl==3)
+		{
+			//take edge direction too
+			bl = distances.maxAxis();
+		}
+		else
+		{*/
+			bl = 0;
+			if(distances[0]<distances[1]) bl = 1;
+		//}
+
+		if(bl==2) //edge edge separation
+		{
+			if(distances[2]>margin) return false;
+
+			contacts.m_penetration_depth = -distances[2] + margin;
+			contacts.m_points[0] = closest_point_v;
+			contacts.m_point_count = 1;
+			VEC_COPY(contacts.m_separating_normal,edge_edge_dir);
+
+			return true;
+		}
+
+		//clip face against other
+
+		
+		GUINT point_count;
+		//TODO
+		if(bl == 0) //clip U points against V
+		{
+			point_count = clip_triangle(tv_plane,tv_vertices,tu_vertices,contact_points);
+			if(point_count == 0) return false;						
+			contacts.merge_points(tv_plane,margin,contact_points,point_count);			
+		}
+		else //clip V points against U
+		{
+			point_count = clip_triangle(tu_plane,tu_vertices,tv_vertices,contact_points);
+			if(point_count == 0) return false;			
+			contacts.merge_points(tu_plane,margin,contact_points,point_count);
+			contacts.m_separating_normal *= -1.f;
+		}
+		if(contacts.m_point_count == 0) return false;
+		return true;
+	}
+
+};
+
+
+/*class GIM_TRIANGLE_CALCULATION_CACHE
+{
+public:
+	GREAL margin;
+	GUINT clipped_count;
+	btVector3 tu_vertices[3];
+	btVector3 tv_vertices[3];
+	btVector3 temp_points[MAX_TRI_CLIPPING];
+	btVector3 temp_points1[MAX_TRI_CLIPPING];
+	btVector3 clipped_points[MAX_TRI_CLIPPING];
+	GIM_TRIANGLE_CONTACT_DATA contacts1;
+	GIM_TRIANGLE_CONTACT_DATA contacts2;
+
+
+	//! clip triangle
+	GUINT clip_triangle(
+		const btVector4 & tri_plane,
+		const btVector3 * tripoints,
+		const btVector3 * srcpoints,
+		btVector3 * clipped_points)
+	{
+		// edge 0
+
+		btVector4 edgeplane;
+
+		EDGE_PLANE(tripoints[0],tripoints[1],tri_plane,edgeplane);
+
+		GUINT clipped_count = PLANE_CLIP_TRIANGLE3D(
+			edgeplane,srcpoints[0],srcpoints[1],srcpoints[2],temp_points);
+
+		if(clipped_count == 0) return 0;
+
+		// edge 1
+
+		EDGE_PLANE(tripoints[1],tripoints[2],tri_plane,edgeplane);
+
+		clipped_count = PLANE_CLIP_POLYGON3D(
+			edgeplane,temp_points,clipped_count,temp_points1);
+
+		if(clipped_count == 0) return 0;
+
+		// edge 2
+
+		EDGE_PLANE(tripoints[2],tripoints[0],tri_plane,edgeplane);
+
+		clipped_count = PLANE_CLIP_POLYGON3D(
+			edgeplane,temp_points1,clipped_count,clipped_points);
+
+		return clipped_count;
+	}
+
+
+
+
+	//! collides only on one side
+	bool triangle_collision(
+					const btVector3 & u0,
+					const btVector3 & u1,
+					const btVector3 & u2,
+					GREAL margin_u,
+					const btVector3 & v0,
+					const btVector3 & v1,
+					const btVector3 & v2,
+					GREAL margin_v,
+					GIM_TRIANGLE_CONTACT_DATA & contacts)
+	{
+
+		margin = margin_u + margin_v;
+
+		
+		tu_vertices[0] = u0;
+		tu_vertices[1] = u1;
+		tu_vertices[2] = u2;
+
+		tv_vertices[0] = v0;
+		tv_vertices[1] = v1;
+		tv_vertices[2] = v2;
+
+		//create planes
+		// plane v vs U points
+
+
+		TRIANGLE_PLANE(tv_vertices[0],tv_vertices[1],tv_vertices[2],contacts1.m_separating_normal);
+
+		clipped_count = clip_triangle(
+			contacts1.m_separating_normal,tv_vertices,tu_vertices,clipped_points);
+
+		if(clipped_count == 0 )
+		{
+			 return false;//Reject
+		}
+
+		//find most deep interval face1
+		contacts1.merge_points(contacts1.m_separating_normal,margin,clipped_points,clipped_count);
+		if(contacts1.m_point_count == 0) return false; // too far
+
+		//Normal pointing to triangle1
+		//contacts1.m_separating_normal *= -1.f;
+
+		//Clip tri1 by tri2 edges
+
+		TRIANGLE_PLANE(tu_vertices[0],tu_vertices[1],tu_vertices[2],contacts2.m_separating_normal);
+
+		clipped_count = clip_triangle(
+			contacts2.m_separating_normal,tu_vertices,tv_vertices,clipped_points);
+
+		if(clipped_count == 0 )
+		{
+			 return false;//Reject
+		}
+
+		//find most deep interval face1
+		contacts2.merge_points(contacts2.m_separating_normal,margin,clipped_points,clipped_count);
+		if(contacts2.m_point_count == 0) return false; // too far
+
+		contacts2.m_separating_normal *= -1.f;
+
+		////check most dir for contacts
+		if(contacts2.m_penetration_depth<contacts1.m_penetration_depth)
+		{
+			contacts.copy_from(contacts2);
+		}
+		else
+		{
+			contacts.copy_from(contacts1);
+		}
+		return true;
+	}
+
+
+};*/
+
+
+
+bool GIM_TRIANGLE::collide_triangle_hard_test(
+		const GIM_TRIANGLE & other,
+		GIM_TRIANGLE_CONTACT_DATA & contact_data) const
+{
+	GIM_TRIANGLE_CALCULATION_CACHE calc_cache;	
+	return calc_cache.triangle_collision(
+					m_vertices[0],m_vertices[1],m_vertices[2],m_margin,
+					other.m_vertices[0],other.m_vertices[1],other.m_vertices[2],other.m_margin,
+					contact_data);
+
+}
+
+
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_tri_collision.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_tri_collision.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/Gimpact/gim_tri_collision.h	(revision 6952)
@@ -0,0 +1,379 @@
+#ifndef GIM_TRI_COLLISION_H_INCLUDED
+#define GIM_TRI_COLLISION_H_INCLUDED
+
+/*! \file gim_tri_collision.h
+\author Francisco Len Nßjera
+*/
+/*
+-----------------------------------------------------------------------------
+This source file is part of GIMPACT Library.
+
+For the latest info, see http://gimpact.sourceforge.net/
+
+Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
+email: projectileman@yahoo.com
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of EITHER:
+   (1) The GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 2.1 of the License, or (at
+       your option) any later version. The text of the GNU Lesser
+       General Public License is included with this library in the
+       file GIMPACT-LICENSE-LGPL.TXT.
+   (2) The BSD-style license that is included with this library in
+       the file GIMPACT-LICENSE-BSD.TXT.
+   (3) The zlib/libpng license that is included with this library in
+       the file GIMPACT-LICENSE-ZLIB.TXT.
+
+ This library 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 files
+ GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.
+
+-----------------------------------------------------------------------------
+*/
+
+#include "gim_box_collision.h"
+#include "gim_clip_polygon.h"
+
+
+
+
+#define MAX_TRI_CLIPPING 16
+
+//! Structure for collision
+struct GIM_TRIANGLE_CONTACT_DATA
+{
+    GREAL m_penetration_depth;
+    GUINT m_point_count;
+    btVector4 m_separating_normal;
+    btVector3 m_points[MAX_TRI_CLIPPING];
+
+	SIMD_FORCE_INLINE void copy_from(const GIM_TRIANGLE_CONTACT_DATA& other)
+	{
+		m_penetration_depth = other.m_penetration_depth;
+		m_separating_normal = other.m_separating_normal;
+		m_point_count = other.m_point_count;
+		GUINT i = m_point_count;
+		while(i--)
+		{
+			m_points[i] = other.m_points[i];
+		}
+	}
+
+	GIM_TRIANGLE_CONTACT_DATA()
+	{
+	}
+
+	GIM_TRIANGLE_CONTACT_DATA(const GIM_TRIANGLE_CONTACT_DATA& other)
+	{
+		copy_from(other);
+	}
+
+	
+	
+
+    //! classify points that are closer
+    template<typename DISTANCE_FUNC,typename CLASS_PLANE>
+    SIMD_FORCE_INLINE void mergepoints_generic(const CLASS_PLANE & plane,
+    				GREAL margin, const btVector3 * points, GUINT point_count, DISTANCE_FUNC distance_func)
+    {	
+    	m_point_count = 0;
+    	m_penetration_depth= -1000.0f;
+
+		GUINT point_indices[MAX_TRI_CLIPPING];
+
+		GUINT _k;
+
+		for(_k=0;_k<point_count;_k++)
+		{
+			GREAL _dist = -distance_func(plane,points[_k]) + margin;
+
+			if(_dist>=0.0f)
+			{
+				if(_dist>m_penetration_depth)
+				{
+					m_penetration_depth = _dist;
+					point_indices[0] = _k;
+					m_point_count=1;
+				}
+				else if((_dist+G_EPSILON)>=m_penetration_depth)
+				{
+					point_indices[m_point_count] = _k;
+					m_point_count++;
+				}
+			}
+		}
+
+		for( _k=0;_k<m_point_count;_k++)
+		{
+			m_points[_k] = points[point_indices[_k]];
+		}
+	}
+
+	//! classify points that are closer
+	SIMD_FORCE_INLINE void merge_points(const btVector4 & plane, GREAL margin,
+										 const btVector3 * points, GUINT point_count)
+	{
+		m_separating_normal = plane;
+		mergepoints_generic(plane, margin, points, point_count, DISTANCE_PLANE_3D_FUNC());
+	}
+};
+
+
+//! Class for colliding triangles
+class GIM_TRIANGLE
+{
+public:
+	btScalar m_margin;
+    btVector3 m_vertices[3];
+
+    GIM_TRIANGLE():m_margin(0.1f)
+    {
+    }
+
+    SIMD_FORCE_INLINE GIM_AABB get_box()  const
+    {
+    	return GIM_AABB(m_vertices[0],m_vertices[1],m_vertices[2],m_margin);
+    }
+
+    SIMD_FORCE_INLINE void get_normal(btVector3 &normal)  const
+    {
+    	TRIANGLE_NORMAL(m_vertices[0],m_vertices[1],m_vertices[2],normal);
+    }
+
+    SIMD_FORCE_INLINE void get_plane(btVector4 &plane)  const
+    {
+    	TRIANGLE_PLANE(m_vertices[0],m_vertices[1],m_vertices[2],plane);;
+    }
+
+    SIMD_FORCE_INLINE void apply_transform(const btTransform & trans)
+    {
+    	m_vertices[0] = trans(m_vertices[0]);
+    	m_vertices[1] = trans(m_vertices[1]);
+    	m_vertices[2] = trans(m_vertices[2]);
+    }
+
+    SIMD_FORCE_INLINE void get_edge_plane(GUINT edge_index,const btVector3 &triangle_normal,btVector4 &plane)  const
+    {
+		const btVector3 & e0 = m_vertices[edge_index];
+		const btVector3 & e1 = m_vertices[(edge_index+1)%3];
+		EDGE_PLANE(e0,e1,triangle_normal,plane);
+    }
+
+    //! Gets the relative transformation of this triangle
+    /*!
+    The transformation is oriented to the triangle normal , and aligned to the 1st edge of this triangle. The position corresponds to vertice 0:
+    - triangle normal corresponds to Z axis.
+    - 1st normalized edge corresponds to X axis,
+
+    */
+    SIMD_FORCE_INLINE void get_triangle_transform(btTransform & triangle_transform)  const
+    {
+    	btMatrix3x3 & matrix = triangle_transform.getBasis();
+
+    	btVector3 zaxis;
+    	get_normal(zaxis);
+    	MAT_SET_Z(matrix,zaxis);
+
+    	btVector3 xaxis = m_vertices[1] - m_vertices[0];
+    	VEC_NORMALIZE(xaxis);
+    	MAT_SET_X(matrix,xaxis);
+
+    	//y axis
+    	xaxis = zaxis.cross(xaxis);
+    	MAT_SET_Y(matrix,xaxis);
+
+    	triangle_transform.setOrigin(m_vertices[0]);
+    }
+
+
+	//! Test triangles by finding separating axis
+	/*!
+	\param other Triangle for collide
+	\param contact_data Structure for holding contact points, normal and penetration depth; The normal is pointing toward this triangle from the other triangle
+	*/
+	bool collide_triangle_hard_test(
+		const GIM_TRIANGLE & other,
+		GIM_TRIANGLE_CONTACT_DATA & contact_data) const;
+
+	//! Test boxes before doing hard test
+	/*!
+	\param other Triangle for collide
+	\param contact_data Structure for holding contact points, normal and penetration depth; The normal is pointing toward this triangle from the other triangle
+	\
+	*/
+	SIMD_FORCE_INLINE bool collide_triangle(
+		const GIM_TRIANGLE & other,
+		GIM_TRIANGLE_CONTACT_DATA & contact_data) const
+	{
+		//test box collisioin
+		GIM_AABB boxu(m_vertices[0],m_vertices[1],m_vertices[2],m_margin);
+		GIM_AABB boxv(other.m_vertices[0],other.m_vertices[1],other.m_vertices[2],other.m_margin);
+		if(!boxu.has_collision(boxv)) return false;
+
+		//do hard test
+		return collide_triangle_hard_test(other,contact_data);
+	}
+
+	/*!
+
+	Solve the System for u,v parameters:
+
+	u*axe1[i1] + v*axe2[i1] = vecproj[i1]
+	u*axe1[i2] + v*axe2[i2] = vecproj[i2]
+
+	sustitute:
+	v = (vecproj[i2] - u*axe1[i2])/axe2[i2]
+
+	then the first equation in terms of 'u':
+
+	--> u*axe1[i1] + ((vecproj[i2] - u*axe1[i2])/axe2[i2])*axe2[i1] = vecproj[i1]
+
+	--> u*axe1[i1] + vecproj[i2]*axe2[i1]/axe2[i2] - u*axe1[i2]*axe2[i1]/axe2[i2] = vecproj[i1]
+
+	--> u*(axe1[i1]  - axe1[i2]*axe2[i1]/axe2[i2]) = vecproj[i1] - vecproj[i2]*axe2[i1]/axe2[i2]
+
+	--> u*((axe1[i1]*axe2[i2]  - axe1[i2]*axe2[i1])/axe2[i2]) = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1])/axe2[i2]
+
+	--> u*(axe1[i1]*axe2[i2]  - axe1[i2]*axe2[i1]) = vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]
+
+	--> u = (vecproj[i1]*axe2[i2] - vecproj[i2]*axe2[i1]) /(axe1[i1]*axe2[i2]  - axe1[i2]*axe2[i1])
+
+if 0.0<= u+v <=1.0 then they are inside of triangle
+
+	\return false if the point is outside of triangle.This function  doesn't take the margin
+	*/
+	SIMD_FORCE_INLINE bool get_uv_parameters(
+			const btVector3 & point,
+			const btVector3 & tri_plane,
+			GREAL & u, GREAL & v) const
+	{
+		btVector3 _axe1 = m_vertices[1]-m_vertices[0];
+		btVector3 _axe2 = m_vertices[2]-m_vertices[0];
+		btVector3 _vecproj = point - m_vertices[0];
+		GUINT _i1 = (tri_plane.closestAxis()+1)%3;
+		GUINT _i2 = (_i1+1)%3;
+		if(btFabs(_axe2[_i2])<G_EPSILON)
+		{
+			u = (_vecproj[_i2]*_axe2[_i1] - _vecproj[_i1]*_axe2[_i2]) /(_axe1[_i2]*_axe2[_i1]  - _axe1[_i1]*_axe2[_i2]);
+			v = (_vecproj[_i1] - u*_axe1[_i1])/_axe2[_i1];
+		}
+		else
+		{
+			u = (_vecproj[_i1]*_axe2[_i2] - _vecproj[_i2]*_axe2[_i1]) /(_axe1[_i1]*_axe2[_i2]  - _axe1[_i2]*_axe2[_i1]);
+			v = (_vecproj[_i2] - u*_axe1[_i2])/_axe2[_i2];
+		}
+
+		if(u<-G_EPSILON)
+		{
+			return false;
+		}
+		else if(v<-G_EPSILON)
+		{
+			return false;
+		}
+		else
+		{
+			btScalar sumuv;
+			sumuv = u+v;
+			if(sumuv<-G_EPSILON)
+			{
+				return false;
+			}
+			else if(sumuv-1.0f>G_EPSILON)
+			{
+				return false;
+			}
+		}
+		return true;
+	}
+
+	//! is point in triangle beam?
+	/*!
+	Test if point is in triangle, with m_margin tolerance
+	*/
+	SIMD_FORCE_INLINE bool is_point_inside(const btVector3 & point, const btVector3 & tri_normal) const
+	{
+		//Test with edge 0
+		btVector4 edge_plane;
+		this->get_edge_plane(0,tri_normal,edge_plane);
+		GREAL dist = DISTANCE_PLANE_POINT(edge_plane,point);
+		if(dist-m_margin>0.0f) return false; // outside plane
+
+		this->get_edge_plane(1,tri_normal,edge_plane);
+		dist = DISTANCE_PLANE_POINT(edge_plane,point);
+		if(dist-m_margin>0.0f) return false; // outside plane
+
+		this->get_edge_plane(2,tri_normal,edge_plane);
+		dist = DISTANCE_PLANE_POINT(edge_plane,point);
+		if(dist-m_margin>0.0f) return false; // outside plane
+		return true;
+	}
+
+
+	//! Bidireccional ray collision
+	SIMD_FORCE_INLINE bool ray_collision(
+		const btVector3 & vPoint,
+		const btVector3 & vDir, btVector3 & pout, btVector3 & triangle_normal,
+		GREAL & tparam, GREAL tmax = G_REAL_INFINITY)
+	{
+		btVector4 faceplane;
+		{
+			btVector3 dif1 = m_vertices[1] - m_vertices[0];
+			btVector3 dif2 = m_vertices[2] - m_vertices[0];
+    		VEC_CROSS(faceplane,dif1,dif2);
+    		faceplane[3] = m_vertices[0].dot(faceplane);
+		}
+
+		GUINT res = LINE_PLANE_COLLISION(faceplane,vDir,vPoint,pout,tparam, btScalar(0), tmax);
+		if(res == 0) return false;
+		if(! is_point_inside(pout,faceplane)) return false;
+
+		if(res==2) //invert normal
+		{
+			triangle_normal.setValue(-faceplane[0],-faceplane[1],-faceplane[2]);
+		}
+		else
+		{
+			triangle_normal.setValue(faceplane[0],faceplane[1],faceplane[2]);
+		}
+
+		VEC_NORMALIZE(triangle_normal);
+
+		return true;
+	}
+
+
+	//! one direccion ray collision
+	SIMD_FORCE_INLINE bool ray_collision_front_side(
+		const btVector3 & vPoint,
+		const btVector3 & vDir, btVector3 & pout, btVector3 & triangle_normal,
+		GREAL & tparam, GREAL tmax = G_REAL_INFINITY)
+	{
+		btVector4 faceplane;
+		{
+			btVector3 dif1 = m_vertices[1] - m_vertices[0];
+			btVector3 dif2 = m_vertices[2] - m_vertices[0];
+    		VEC_CROSS(faceplane,dif1,dif2);
+    		faceplane[3] = m_vertices[0].dot(faceplane);
+		}
+
+		GUINT res = LINE_PLANE_COLLISION(faceplane,vDir,vPoint,pout,tparam, btScalar(0), tmax);
+		if(res != 1) return false;
+
+		if(!is_point_inside(pout,faceplane)) return false;
+
+		triangle_normal.setValue(faceplane[0],faceplane[1],faceplane[2]);
+
+		VEC_NORMALIZE(triangle_normal);
+
+		return true;
+	}
+
+};
+
+
+
+
+#endif // GIM_TRI_COLLISION_H_INCLUDED
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp	(revision 6952)
@@ -0,0 +1,227 @@
+/*
+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 "btContinuousConvexCollision.h"
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
+#include "LinearMath/btTransformUtil.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
+
+#include "btGjkPairDetector.h"
+#include "btPointCollector.h"
+
+
+
+btContinuousConvexCollision::btContinuousConvexCollision ( const btConvexShape*	convexA,const btConvexShape*	convexB,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* penetrationDepthSolver)
+:m_simplexSolver(simplexSolver),
+m_penetrationDepthSolver(penetrationDepthSolver),
+m_convexA(convexA),m_convexB(convexB)
+{
+}
+
+/// This maximum should not be necessary. It allows for untested/degenerate cases in production code.
+/// You don't want your game ever to lock-up.
+#define MAX_ITERATIONS 64
+
+bool	btContinuousConvexCollision::calcTimeOfImpact(
+				const btTransform& fromA,
+				const btTransform& toA,
+				const btTransform& fromB,
+				const btTransform& toB,
+				CastResult& result)
+{
+
+	m_simplexSolver->reset();
+
+	/// compute linear and angular velocity for this interval, to interpolate
+	btVector3 linVelA,angVelA,linVelB,angVelB;
+	btTransformUtil::calculateVelocity(fromA,toA,btScalar(1.),linVelA,angVelA);
+	btTransformUtil::calculateVelocity(fromB,toB,btScalar(1.),linVelB,angVelB);
+
+
+	btScalar boundingRadiusA = m_convexA->getAngularMotionDisc();
+	btScalar boundingRadiusB = m_convexB->getAngularMotionDisc();
+
+	btScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB;
+	btVector3 relLinVel = (linVelB-linVelA);
+
+	btScalar relLinVelocLength = (linVelB-linVelA).length();
+	
+	if ((relLinVelocLength+maxAngularProjectedVelocity) == 0.f)
+		return false;
+
+
+	btScalar radius = btScalar(0.001);
+
+	btScalar lambda = btScalar(0.);
+	btVector3 v(1,0,0);
+
+	int maxIter = MAX_ITERATIONS;
+
+	btVector3 n;
+	n.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
+	bool hasResult = false;
+	btVector3 c;
+
+	btScalar lastLambda = lambda;
+	//btScalar epsilon = btScalar(0.001);
+
+	int numIter = 0;
+	//first solution, using GJK
+
+
+	btTransform identityTrans;
+	identityTrans.setIdentity();
+
+	btSphereShape	raySphere(btScalar(0.0));
+	raySphere.setMargin(btScalar(0.));
+
+
+//	result.drawCoordSystem(sphereTr);
+
+	btPointCollector	pointCollector1;
+
+	{
+		
+		btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver);		
+		btGjkPairDetector::ClosestPointInput input;
+	
+		//we don't use margins during CCD
+	//	gjk.setIgnoreMargin(true);
+
+		input.m_transformA = fromA;
+		input.m_transformB = fromB;
+		gjk.getClosestPoints(input,pointCollector1,0);
+
+		hasResult = pointCollector1.m_hasResult;
+		c = pointCollector1.m_pointInWorld;
+	}
+
+	if (hasResult)
+	{
+		btScalar dist;
+		dist = pointCollector1.m_distance;
+		n = pointCollector1.m_normalOnBInWorld;
+
+		btScalar projectedLinearVelocity = relLinVel.dot(n);
+		
+		//not close enough
+		while (dist > radius)
+		{
+			numIter++;
+			if (numIter > maxIter)
+			{
+				return false; //todo: report a failure
+			}
+			btScalar dLambda = btScalar(0.);
+
+			projectedLinearVelocity = relLinVel.dot(n);
+
+			//calculate safe moving fraction from distance / (linear+rotational velocity)
+			
+			//btScalar clippedDist  = GEN_min(angularConservativeRadius,dist);
+			//btScalar clippedDist  = dist;
+			
+			//don't report time of impact for motion away from the contact normal (or causes minor penetration)
+			if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=SIMD_EPSILON)
+				return false;
+			
+			dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity);
+
+			
+			
+			lambda = lambda + dLambda;
+
+			if (lambda > btScalar(1.))
+				return false;
+
+			if (lambda < btScalar(0.))
+				return false;
+
+
+			//todo: next check with relative epsilon
+			if (lambda <= lastLambda)
+			{
+				return false;
+				//n.setValue(0,0,0);
+				break;
+			}
+			lastLambda = lambda;
+
+			
+
+			//interpolate to next lambda
+			btTransform interpolatedTransA,interpolatedTransB,relativeTrans;
+
+			btTransformUtil::integrateTransform(fromA,linVelA,angVelA,lambda,interpolatedTransA);
+			btTransformUtil::integrateTransform(fromB,linVelB,angVelB,lambda,interpolatedTransB);
+			relativeTrans = interpolatedTransB.inverseTimes(interpolatedTransA);
+
+			result.DebugDraw( lambda );
+
+			btPointCollector	pointCollector;
+			btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver);
+			btGjkPairDetector::ClosestPointInput input;
+			input.m_transformA = interpolatedTransA;
+			input.m_transformB = interpolatedTransB;
+			gjk.getClosestPoints(input,pointCollector,0);
+			if (pointCollector.m_hasResult)
+			{
+				if (pointCollector.m_distance < btScalar(0.))
+				{
+					//degenerate ?!
+					result.m_fraction = lastLambda;
+					n = pointCollector.m_normalOnBInWorld;
+					result.m_normal=n;//.setValue(1,1,1);// = n;
+					result.m_hitPoint = pointCollector.m_pointInWorld;
+					return true;
+				}
+				c = pointCollector.m_pointInWorld;		
+				n = pointCollector.m_normalOnBInWorld;
+				dist = pointCollector.m_distance;
+			} else
+			{
+				//??
+				return false;
+			}
+
+		}
+	
+		if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=result.m_allowedPenetration)//SIMD_EPSILON)
+			return false;
+			
+		result.m_fraction = lambda;
+		result.m_normal = n;
+		result.m_hitPoint = c;
+		return true;
+	}
+
+	return false;
+
+/*
+//todo:
+	//if movement away from normal, discard result
+	btVector3 move = transBLocalTo.getOrigin() - transBLocalFrom.getOrigin();
+	if (result.m_fraction < btScalar(1.))
+	{
+		if (move.dot(result.m_normal) <= btScalar(0.))
+		{
+		}
+	}
+*/
+
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h	(revision 6952)
@@ -0,0 +1,52 @@
+/*
+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 CONTINUOUS_COLLISION_CONVEX_CAST_H
+#define CONTINUOUS_COLLISION_CONVEX_CAST_H
+
+#include "btConvexCast.h"
+#include "btSimplexSolverInterface.h"
+class btConvexPenetrationDepthSolver;
+class btConvexShape;
+
+/// btContinuousConvexCollision implements angular and linear time of impact for convex objects.
+/// Based on Brian Mirtich's Conservative Advancement idea (PhD thesis).
+/// Algorithm operates in worldspace, in order to keep inbetween motion globally consistent.
+/// It uses GJK at the moment. Future improvement would use minkowski sum / supporting vertex, merging innerloops
+class btContinuousConvexCollision : public btConvexCast
+{
+	btSimplexSolverInterface* m_simplexSolver;
+	btConvexPenetrationDepthSolver*	m_penetrationDepthSolver;
+	const btConvexShape*	m_convexA;
+	const btConvexShape*	m_convexB;
+
+
+public:
+
+	btContinuousConvexCollision (const btConvexShape*	shapeA,const btConvexShape*	shapeB ,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver);
+
+	virtual bool	calcTimeOfImpact(
+				const btTransform& fromA,
+				const btTransform& toA,
+				const btTransform& fromB,
+				const btTransform& toB,
+				CastResult& result);
+
+
+};
+
+#endif //CONTINUOUS_COLLISION_CONVEX_CAST_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp	(revision 6952)
@@ -0,0 +1,20 @@
+/*
+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 "btConvexCast.h"
+
+btConvexCast::~btConvexCast()
+{
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.h	(revision 6952)
@@ -0,0 +1,73 @@
+/*
+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_CAST_H
+#define CONVEX_CAST_H
+
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btScalar.h"
+class btMinkowskiSumShape;
+#include "LinearMath/btIDebugDraw.h"
+
+/// btConvexCast is an interface for Casting
+class btConvexCast
+{
+public:
+
+
+	virtual ~btConvexCast();
+
+	///RayResult stores the closest result
+	/// alternatively, add a callback method to decide about closest/all results
+	struct	CastResult
+	{
+		//virtual bool	addRayResult(const btVector3& normal,btScalar	fraction) = 0;
+				
+		virtual void	DebugDraw(btScalar	fraction) {(void)fraction;}
+		virtual void	drawCoordSystem(const btTransform& trans) {(void)trans;}
+
+		CastResult()
+			:m_fraction(btScalar(1e30)),
+			m_debugDrawer(0),
+			m_allowedPenetration(btScalar(0))
+		{
+		}
+
+
+		virtual ~CastResult() {};
+
+		btTransform	m_hitTransformA;
+		btTransform	m_hitTransformB;
+		btVector3	m_normal;
+		btVector3   m_hitPoint;
+		btScalar	m_fraction; //input and output
+		btIDebugDraw* m_debugDrawer;
+		btScalar	m_allowedPenetration;
+
+	};
+
+
+	/// cast a convex against another convex object
+	virtual bool	calcTimeOfImpact(
+					const btTransform& fromA,
+					const btTransform& toA,
+					const btTransform& fromB,
+					const btTransform& toB,
+					CastResult& result) = 0;
+};
+
+#endif //CONVEX_CAST_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h	(revision 6952)
@@ -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.
+*/
+
+
+#ifndef CONVEX_PENETRATION_DEPTH_H
+#define CONVEX_PENETRATION_DEPTH_H
+
+class btStackAlloc;
+class btVector3;
+#include "btSimplexSolverInterface.h"
+class btConvexShape;
+class btTransform;
+
+///ConvexPenetrationDepthSolver provides an interface for penetration depth calculation.
+class btConvexPenetrationDepthSolver
+{
+public:	
+	
+	virtual ~btConvexPenetrationDepthSolver() {};
+	virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver,
+		const btConvexShape* convexA,const btConvexShape* convexB,
+					const btTransform& transA,const btTransform& transB,
+				btVector3& v, btVector3& pa, btVector3& pb,
+				class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
+				) = 0;
+
+
+};
+#endif //CONVEX_PENETRATION_DEPTH_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h	(revision 6952)
@@ -0,0 +1,88 @@
+/*
+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 DISCRETE_COLLISION_DETECTOR1_INTERFACE_H
+#define DISCRETE_COLLISION_DETECTOR1_INTERFACE_H
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btVector3.h"
+class btStackAlloc;
+
+/// This interface is made to be used by an iterative approach to do TimeOfImpact calculations
+/// This interface allows to query for closest points and penetration depth between two (convex) objects
+/// the closest point is on the second object (B), and the normal points from the surface on B towards A.
+/// distance is between closest points on B and closest point on A. So you can calculate closest point on A
+/// by taking closestPointInA = closestPointInB + m_distance * m_normalOnSurfaceB
+struct btDiscreteCollisionDetectorInterface
+{
+	
+	struct Result
+	{
+	
+		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;
+		virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)=0;
+	};
+
+	struct ClosestPointInput
+	{
+		ClosestPointInput()
+			:m_maximumDistanceSquared(btScalar(1e30)),
+			m_stackAlloc(0)
+		{
+		}
+
+		btTransform m_transformA;
+		btTransform m_transformB;
+		btScalar	m_maximumDistanceSquared;
+		btStackAlloc* m_stackAlloc;
+	};
+
+	virtual ~btDiscreteCollisionDetectorInterface() {};
+
+	//
+	// give either closest points (distance > 0) or penetration (distance)
+	// the normal always points from B towards A
+	//
+	virtual void	getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false) = 0;
+
+};
+
+struct btStorageResult : public btDiscreteCollisionDetectorInterface::Result
+{
+		btVector3	m_normalOnSurfaceB;
+		btVector3	m_closestPointInB;
+		btScalar	m_distance; //negative means penetration !
+
+		btStorageResult() : m_distance(btScalar(1e30))
+		{
+
+		}
+		virtual ~btStorageResult() {};
+
+		virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
+		{
+			if (depth < m_distance)
+			{
+				m_normalOnSurfaceB = normalOnBInWorld;
+				m_closestPointInB = pointInWorld;
+				m_distance = depth;
+			}
+		}
+};
+
+#endif //DISCRETE_COLLISION_DETECTOR_INTERFACE1_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp	(revision 6952)
@@ -0,0 +1,176 @@
+/*
+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 "btGjkConvexCast.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
+#include "btGjkPairDetector.h"
+#include "btPointCollector.h"
+#include "LinearMath/btTransformUtil.h"
+
+#ifdef BT_USE_DOUBLE_PRECISION
+#define MAX_ITERATIONS 64
+#else
+#define MAX_ITERATIONS 32
+#endif
+
+btGjkConvexCast::btGjkConvexCast(const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver)
+:m_simplexSolver(simplexSolver),
+m_convexA(convexA),
+m_convexB(convexB)
+{
+}
+
+bool	btGjkConvexCast::calcTimeOfImpact(
+					const btTransform& fromA,
+					const btTransform& toA,
+					const btTransform& fromB,
+					const btTransform& toB,
+					CastResult& result)
+{
+
+
+	m_simplexSolver->reset();
+
+	/// compute linear velocity for this interval, to interpolate
+	//assume no rotation/angular velocity, assert here?
+	btVector3 linVelA,linVelB;
+	linVelA = toA.getOrigin()-fromA.getOrigin();
+	linVelB = toB.getOrigin()-fromB.getOrigin();
+
+	btScalar radius = btScalar(0.001);
+	btScalar lambda = btScalar(0.);
+	btVector3 v(1,0,0);
+
+	int maxIter = MAX_ITERATIONS;
+
+	btVector3 n;
+	n.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
+	bool hasResult = false;
+	btVector3 c;
+	btVector3 r = (linVelA-linVelB);
+
+	btScalar lastLambda = lambda;
+	//btScalar epsilon = btScalar(0.001);
+
+	int numIter = 0;
+	//first solution, using GJK
+
+
+	btTransform identityTrans;
+	identityTrans.setIdentity();
+
+
+//	result.drawCoordSystem(sphereTr);
+
+	btPointCollector	pointCollector;
+
+		
+	btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,0);//m_penetrationDepthSolver);		
+	btGjkPairDetector::ClosestPointInput input;
+
+	//we don't use margins during CCD
+	//	gjk.setIgnoreMargin(true);
+
+	input.m_transformA = fromA;
+	input.m_transformB = fromB;
+	gjk.getClosestPoints(input,pointCollector,0);
+
+	hasResult = pointCollector.m_hasResult;
+	c = pointCollector.m_pointInWorld;
+
+	if (hasResult)
+	{
+		btScalar dist;
+		dist = pointCollector.m_distance;
+		n = pointCollector.m_normalOnBInWorld;
+
+	
+
+		//not close enough
+		while (dist > radius)
+		{
+			numIter++;
+			if (numIter > maxIter)
+			{
+				return false; //todo: report a failure
+			}
+			btScalar dLambda = btScalar(0.);
+
+			btScalar projectedLinearVelocity = r.dot(n);
+			
+			dLambda = dist / (projectedLinearVelocity);
+
+			lambda = lambda - dLambda;
+
+			if (lambda > btScalar(1.))
+				return false;
+
+			if (lambda < btScalar(0.))
+				return false;
+
+			//todo: next check with relative epsilon
+			if (lambda <= lastLambda)
+			{
+				return false;
+				//n.setValue(0,0,0);
+				break;
+			}
+			lastLambda = lambda;
+
+			//interpolate to next lambda
+			result.DebugDraw( lambda );
+			input.m_transformA.getOrigin().setInterpolate3(fromA.getOrigin(),toA.getOrigin(),lambda);
+			input.m_transformB.getOrigin().setInterpolate3(fromB.getOrigin(),toB.getOrigin(),lambda);
+			
+			gjk.getClosestPoints(input,pointCollector,0);
+			if (pointCollector.m_hasResult)
+			{
+				if (pointCollector.m_distance < btScalar(0.))
+				{
+					result.m_fraction = lastLambda;
+					n = pointCollector.m_normalOnBInWorld;
+					result.m_normal=n;
+					result.m_hitPoint = pointCollector.m_pointInWorld;
+					return true;
+				}
+				c = pointCollector.m_pointInWorld;		
+				n = pointCollector.m_normalOnBInWorld;
+				dist = pointCollector.m_distance;
+			} else
+			{
+				//??
+				return false;
+			}
+
+		}
+
+		//is n normalized?
+		//don't report time of impact for motion away from the contact normal (or causes minor penetration)
+		if (n.dot(r)>=-result.m_allowedPenetration)
+			return false;
+
+		result.m_fraction = lambda;
+		result.m_normal = n;
+		result.m_hitPoint = c;
+		return true;
+	}
+
+	return false;
+
+
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h	(revision 6952)
@@ -0,0 +1,50 @@
+/*
+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 GJK_CONVEX_CAST_H
+#define GJK_CONVEX_CAST_H
+
+#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+
+#include "LinearMath/btVector3.h"
+#include "btConvexCast.h"
+class btConvexShape;
+class btMinkowskiSumShape;
+#include "btSimplexSolverInterface.h"
+
+///GjkConvexCast performs a raycast on a convex object using support mapping.
+class btGjkConvexCast : public btConvexCast
+{
+	btSimplexSolverInterface*	m_simplexSolver;
+	const btConvexShape*	m_convexA;
+	const btConvexShape*	m_convexB;
+
+public:
+
+	btGjkConvexCast(const btConvexShape*	convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver);
+
+	/// cast a convex against another convex object
+	virtual bool	calcTimeOfImpact(
+					const btTransform& fromA,
+					const btTransform& toA,
+					const btTransform& fromB,
+					const btTransform& toB,
+					CastResult& result);
+
+};
+
+#endif //GJK_CONVEX_CAST_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp	(revision 6952)
@@ -0,0 +1,943 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 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.
+*/
+
+/*
+GJK-EPA collision solver by Nathanael Presson, 2008
+*/
+#include "BulletCollision/CollisionShapes/btConvexInternalShape.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
+#include "btGjkEpa2.h"
+
+#if defined(DEBUG) || defined (_DEBUG)
+#include <stdio.h> //for debug printf
+#ifdef __SPU__
+#include <spu_printf.h>
+#define printf spu_printf
+#endif //__SPU__
+#endif
+
+namespace gjkepa2_impl
+{
+
+	// Config
+
+	/* GJK	*/ 
+#define GJK_MAX_ITERATIONS	128
+#define GJK_ACCURARY		((btScalar)0.0001)
+#define GJK_MIN_DISTANCE	((btScalar)0.0001)
+#define GJK_DUPLICATED_EPS	((btScalar)0.0001)
+#define GJK_SIMPLEX2_EPS	((btScalar)0.0)
+#define GJK_SIMPLEX3_EPS	((btScalar)0.0)
+#define GJK_SIMPLEX4_EPS	((btScalar)0.0)
+
+	/* EPA	*/ 
+#define EPA_MAX_VERTICES	64
+#define EPA_MAX_FACES		(EPA_MAX_VERTICES*2)
+#define EPA_MAX_ITERATIONS	255
+#define EPA_ACCURACY		((btScalar)0.0001)
+#define EPA_FALLBACK		(10*EPA_ACCURACY)
+#define EPA_PLANE_EPS		((btScalar)0.00001)
+#define EPA_INSIDE_EPS		((btScalar)0.01)
+
+
+	// Shorthands
+	typedef unsigned int	U;
+	typedef unsigned char	U1;
+
+	// MinkowskiDiff
+	struct	MinkowskiDiff
+	{
+		const btConvexShape*	m_shapes[2];
+		btMatrix3x3				m_toshape1;
+		btTransform				m_toshape0;
+		btVector3				(btConvexShape::*Ls)(const btVector3&) const;
+		void					EnableMargin(bool enable)
+		{
+			if(enable)
+				Ls=&btConvexShape::localGetSupportVertexNonVirtual;
+			else
+				Ls=&btConvexShape::localGetSupportVertexWithoutMarginNonVirtual;
+		}	
+		inline btVector3		Support0(const btVector3& d) const
+		{
+			return(((m_shapes[0])->*(Ls))(d));
+		}
+		inline btVector3		Support1(const btVector3& d) const
+		{
+			return(m_toshape0*((m_shapes[1])->*(Ls))(m_toshape1*d));
+		}
+		inline btVector3		Support(const btVector3& d) const
+		{
+			return(Support0(d)-Support1(-d));
+		}
+		btVector3				Support(const btVector3& d,U index) const
+		{
+			if(index)
+				return(Support1(d));
+			else
+				return(Support0(d));
+		}
+	};
+
+	typedef	MinkowskiDiff	tShape;
+
+
+	// GJK
+	struct	GJK
+	{
+		/* Types		*/ 
+		struct	sSV
+		{
+			btVector3	d,w;
+		};
+		struct	sSimplex
+		{
+			sSV*		c[4];
+			btScalar	p[4];
+			U			rank;
+		};
+		struct	eStatus	{ enum _ {
+			Valid,
+			Inside,
+			Failed		};};
+			/* Fields		*/ 
+			tShape			m_shape;
+			btVector3		m_ray;
+			btScalar		m_distance;
+			sSimplex		m_simplices[2];
+			sSV				m_store[4];
+			sSV*			m_free[4];
+			U				m_nfree;
+			U				m_current;
+			sSimplex*		m_simplex;
+			eStatus::_		m_status;
+			/* Methods		*/ 
+			GJK()
+			{
+				Initialize();
+			}
+			void				Initialize()
+			{
+				m_ray		=	btVector3(0,0,0);
+				m_nfree		=	0;
+				m_status	=	eStatus::Failed;
+				m_current	=	0;
+				m_distance	=	0;
+			}
+			eStatus::_			Evaluate(const tShape& shapearg,const btVector3& guess)
+			{
+				U			iterations=0;
+				btScalar	sqdist=0;
+				btScalar	alpha=0;
+				btVector3	lastw[4];
+				U			clastw=0;
+				/* Initialize solver		*/ 
+				m_free[0]			=	&m_store[0];
+				m_free[1]			=	&m_store[1];
+				m_free[2]			=	&m_store[2];
+				m_free[3]			=	&m_store[3];
+				m_nfree				=	4;
+				m_current			=	0;
+				m_status			=	eStatus::Valid;
+				m_shape				=	shapearg;
+				m_distance			=	0;
+				/* Initialize simplex		*/ 
+				m_simplices[0].rank	=	0;
+				m_ray				=	guess;
+				const btScalar	sqrl=	m_ray.length2();
+				appendvertice(m_simplices[0],sqrl>0?-m_ray:btVector3(1,0,0));
+				m_simplices[0].p[0]	=	1;
+				m_ray				=	m_simplices[0].c[0]->w;	
+				sqdist				=	sqrl;
+				lastw[0]			=
+					lastw[1]			=
+					lastw[2]			=
+					lastw[3]			=	m_ray;
+				/* Loop						*/ 
+				do	{
+					const U		next=1-m_current;
+					sSimplex&	cs=m_simplices[m_current];
+					sSimplex&	ns=m_simplices[next];
+					/* Check zero							*/ 
+					const btScalar	rl=m_ray.length();
+					if(rl<GJK_MIN_DISTANCE)
+					{/* Touching or inside				*/ 
+						m_status=eStatus::Inside;
+						break;
+					}
+					/* Append new vertice in -'v' direction	*/ 
+					appendvertice(cs,-m_ray);
+					const btVector3&	w=cs.c[cs.rank-1]->w;
+					bool				found=false;
+					for(U i=0;i<4;++i)
+					{
+						if((w-lastw[i]).length2()<GJK_DUPLICATED_EPS)
+						{ found=true;break; }
+					}
+					if(found)
+					{/* Return old simplex				*/ 
+						removevertice(m_simplices[m_current]);
+						break;
+					}
+					else
+					{/* Update lastw					*/ 
+						lastw[clastw=(clastw+1)&3]=w;
+					}
+					/* Check for termination				*/ 
+					const btScalar	omega=dot(m_ray,w)/rl;
+					alpha=btMax(omega,alpha);
+					if(((rl-alpha)-(GJK_ACCURARY*rl))<=0)
+					{/* Return old simplex				*/ 
+						removevertice(m_simplices[m_current]);
+						break;
+					}		
+					/* Reduce simplex						*/ 
+					btScalar	weights[4];
+					U			mask=0;
+					switch(cs.rank)
+					{
+					case	2:	sqdist=projectorigin(	cs.c[0]->w,
+									cs.c[1]->w,
+									weights,mask);break;
+					case	3:	sqdist=projectorigin(	cs.c[0]->w,
+									cs.c[1]->w,
+									cs.c[2]->w,
+									weights,mask);break;
+					case	4:	sqdist=projectorigin(	cs.c[0]->w,
+									cs.c[1]->w,
+									cs.c[2]->w,
+									cs.c[3]->w,
+									weights,mask);break;
+					}
+					if(sqdist>=0)
+					{/* Valid	*/ 
+						ns.rank		=	0;
+						m_ray		=	btVector3(0,0,0);
+						m_current	=	next;
+						for(U i=0,ni=cs.rank;i<ni;++i)
+						{
+							if(mask&(1<<i))
+							{
+								ns.c[ns.rank]		=	cs.c[i];
+								ns.p[ns.rank++]		=	weights[i];
+								m_ray				+=	cs.c[i]->w*weights[i];
+							}
+							else
+							{
+								m_free[m_nfree++]	=	cs.c[i];
+							}
+						}
+						if(mask==15) m_status=eStatus::Inside;
+					}
+					else
+					{/* Return old simplex				*/ 
+						removevertice(m_simplices[m_current]);
+						break;
+					}
+					m_status=((++iterations)<GJK_MAX_ITERATIONS)?m_status:eStatus::Failed;
+				} while(m_status==eStatus::Valid);
+				m_simplex=&m_simplices[m_current];
+				switch(m_status)
+				{
+				case	eStatus::Valid:		m_distance=m_ray.length();break;
+				case	eStatus::Inside:	m_distance=0;break;
+				}	
+				return(m_status);
+			}
+			bool					EncloseOrigin()
+			{
+				switch(m_simplex->rank)
+				{
+				case	1:
+					{
+						for(U i=0;i<3;++i)
+						{
+							btVector3		axis=btVector3(0,0,0);
+							axis[i]=1;
+							appendvertice(*m_simplex, axis);
+							if(EncloseOrigin())	return(true);
+							removevertice(*m_simplex);
+							appendvertice(*m_simplex,-axis);
+							if(EncloseOrigin())	return(true);
+							removevertice(*m_simplex);
+						}
+					}
+					break;
+				case	2:
+					{
+						const btVector3	d=m_simplex->c[1]->w-m_simplex->c[0]->w;
+						for(U i=0;i<3;++i)
+						{
+							btVector3		axis=btVector3(0,0,0);
+							axis[i]=1;
+							const btVector3	p=cross(d,axis);
+							if(p.length2()>0)
+							{
+								appendvertice(*m_simplex, p);
+								if(EncloseOrigin())	return(true);
+								removevertice(*m_simplex);
+								appendvertice(*m_simplex,-p);
+								if(EncloseOrigin())	return(true);
+								removevertice(*m_simplex);
+							}
+						}
+					}
+					break;
+				case	3:
+					{
+						const btVector3	n=cross(m_simplex->c[1]->w-m_simplex->c[0]->w,
+							m_simplex->c[2]->w-m_simplex->c[0]->w);
+						if(n.length2()>0)
+						{
+							appendvertice(*m_simplex,n);
+							if(EncloseOrigin())	return(true);
+							removevertice(*m_simplex);
+							appendvertice(*m_simplex,-n);
+							if(EncloseOrigin())	return(true);
+							removevertice(*m_simplex);
+						}
+					}
+					break;
+				case	4:
+					{
+						if(btFabs(det(	m_simplex->c[0]->w-m_simplex->c[3]->w,
+							m_simplex->c[1]->w-m_simplex->c[3]->w,
+							m_simplex->c[2]->w-m_simplex->c[3]->w))>0)
+							return(true);
+					}
+					break;
+				}
+				return(false);
+			}
+			/* Internals	*/ 
+			void				getsupport(const btVector3& d,sSV& sv) const
+			{
+				sv.d	=	d/d.length();
+				sv.w	=	m_shape.Support(sv.d);
+			}
+			void				removevertice(sSimplex& simplex)
+			{
+				m_free[m_nfree++]=simplex.c[--simplex.rank];
+			}
+			void				appendvertice(sSimplex& simplex,const btVector3& v)
+			{
+				simplex.p[simplex.rank]=0;
+				simplex.c[simplex.rank]=m_free[--m_nfree];
+				getsupport(v,*simplex.c[simplex.rank++]);
+			}
+			static btScalar		det(const btVector3& a,const btVector3& b,const btVector3& c)
+			{
+				return(	a.y()*b.z()*c.x()+a.z()*b.x()*c.y()-
+					a.x()*b.z()*c.y()-a.y()*b.x()*c.z()+
+					a.x()*b.y()*c.z()-a.z()*b.y()*c.x());
+			}
+			static btScalar		projectorigin(	const btVector3& a,
+				const btVector3& b,
+				btScalar* w,U& m)
+			{
+				const btVector3	d=b-a;
+				const btScalar	l=d.length2();
+				if(l>GJK_SIMPLEX2_EPS)
+				{
+					const btScalar	t(l>0?-dot(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()); }
+					else			{ w[0]=1-(w[1]=t);m=3;return((a+d*t).length2()); }
+				}
+				return(-1);
+			}
+			static btScalar		projectorigin(	const btVector3& a,
+				const btVector3& b,
+				const btVector3& c,
+				btScalar* w,U& m)
+			{
+				static const U		imd3[]={1,2,0};
+				const btVector3*	vt[]={&a,&b,&c};
+				const btVector3		dl[]={a-b,b-c,c-a};
+				const btVector3		n=cross(dl[0],dl[1]);
+				const btScalar		l=n.length2();
+				if(l>GJK_SIMPLEX3_EPS)
+				{
+					btScalar	mindist=-1;
+					btScalar	subw[2];
+					U			subm;
+					for(U i=0;i<3;++i)
+					{
+						if(dot(*vt[i],cross(dl[i],n))>0)
+						{
+							const U			j=imd3[i];
+							const btScalar	subd(projectorigin(*vt[i],*vt[j],subw,subm));
+							if((mindist<0)||(subd<mindist))
+							{
+								mindist		=	subd;
+								m			=	static_cast<U>(((subm&1)?1<<i:0)+((subm&2)?1<<j:0));
+								w[i]		=	subw[0];
+								w[j]		=	subw[1];
+								w[imd3[j]]	=	0;				
+							}
+						}
+					}
+					if(mindist<0)
+					{
+						const btScalar	d=dot(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[2]	=	1-(w[0]+w[1]);
+					}
+					return(mindist);
+				}
+				return(-1);
+			}
+			static btScalar		projectorigin(	const btVector3& a,
+				const btVector3& b,
+				const btVector3& c,
+				const btVector3& d,
+				btScalar* w,U& m)
+			{
+				static const U		imd3[]={1,2,0};
+				const btVector3*	vt[]={&a,&b,&c,&d};
+				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;
+				if(ng&&(btFabs(vl)>GJK_SIMPLEX4_EPS))
+				{
+					btScalar	mindist=-1;
+					btScalar	subw[3];
+					U			subm;
+					for(U i=0;i<3;++i)
+					{
+						const U			j=imd3[i];
+						const btScalar	s=vl*dot(d,cross(dl[i],dl[j]));
+						if(s>0)
+						{
+							const btScalar	subd=projectorigin(*vt[i],*vt[j],d,subw,subm);
+							if((mindist<0)||(subd<mindist))
+							{
+								mindist		=	subd;
+								m			=	static_cast<U>((subm&1?1<<i:0)+
+									(subm&2?1<<j:0)+
+									(subm&4?8:0));
+								w[i]		=	subw[0];
+								w[j]		=	subw[1];
+								w[imd3[j]]	=	0;
+								w[3]		=	subw[2];
+							}
+						}
+					}
+					if(mindist<0)
+					{
+						mindist	=	0;
+						m		=	15;
+						w[0]	=	det(c,b,d)/vl;
+						w[1]	=	det(a,c,d)/vl;
+						w[2]	=	det(b,a,d)/vl;
+						w[3]	=	1-(w[0]+w[1]+w[2]);
+					}
+					return(mindist);
+				}
+				return(-1);
+			}
+	};
+
+	// EPA
+	struct	EPA
+	{
+		/* Types		*/ 
+		typedef	GJK::sSV	sSV;
+		struct	sFace
+		{
+			btVector3	n;
+			btScalar	d;
+			btScalar	p;
+			sSV*		c[3];
+			sFace*		f[3];
+			sFace*		l[2];
+			U1			e[3];
+			U1			pass;
+		};
+		struct	sList
+		{
+			sFace*		root;
+			U			count;
+			sList() : root(0),count(0)	{}
+		};
+		struct	sHorizon
+		{
+			sFace*		cf;
+			sFace*		ff;
+			U			nf;
+			sHorizon() : cf(0),ff(0),nf(0)	{}
+		};
+		struct	eStatus { enum _ {
+			Valid,
+			Touching,
+			Degenerated,
+			NonConvex,
+			InvalidHull,		
+			OutOfFaces,
+			OutOfVertices,
+			AccuraryReached,
+			FallBack,
+			Failed		};};
+			/* Fields		*/ 
+			eStatus::_		m_status;
+			GJK::sSimplex	m_result;
+			btVector3		m_normal;
+			btScalar		m_depth;
+			sSV				m_sv_store[EPA_MAX_VERTICES];
+			sFace			m_fc_store[EPA_MAX_FACES];
+			U				m_nextsv;
+			sList			m_hull;
+			sList			m_stock;
+			/* Methods		*/ 
+			EPA()
+			{
+				Initialize();	
+			}
+
+
+			static inline void		bind(sFace* fa,U ea,sFace* fb,U eb)
+			{
+				fa->e[ea]=(U1)eb;fa->f[ea]=fb;
+				fb->e[eb]=(U1)ea;fb->f[eb]=fa;
+			}
+			static inline void		append(sList& list,sFace* face)
+			{
+				face->l[0]	=	0;
+				face->l[1]	=	list.root;
+				if(list.root) list.root->l[0]=face;
+				list.root	=	face;
+				++list.count;
+			}
+			static inline void		remove(sList& list,sFace* face)
+			{
+				if(face->l[1]) face->l[1]->l[0]=face->l[0];
+				if(face->l[0]) face->l[0]->l[1]=face->l[1];
+				if(face==list.root) list.root=face->l[1];
+				--list.count;
+			}
+
+
+			void				Initialize()
+			{
+				m_status	=	eStatus::Failed;
+				m_normal	=	btVector3(0,0,0);
+				m_depth		=	0;
+				m_nextsv	=	0;
+				for(U i=0;i<EPA_MAX_FACES;++i)
+				{
+					append(m_stock,&m_fc_store[EPA_MAX_FACES-i-1]);
+				}
+			}
+			eStatus::_			Evaluate(GJK& gjk,const btVector3& guess)
+			{
+				GJK::sSimplex&	simplex=*gjk.m_simplex;
+				if((simplex.rank>1)&&gjk.EncloseOrigin())
+				{
+
+					/* Clean up				*/ 
+					while(m_hull.root)
+					{
+						sFace*	f = m_hull.root;
+						remove(m_hull,f);
+						append(m_stock,f);
+					}
+					m_status	=	eStatus::Valid;
+					m_nextsv	=	0;
+					/* Orient simplex		*/ 
+					if(gjk.det(	simplex.c[0]->w-simplex.c[3]->w,
+						simplex.c[1]->w-simplex.c[3]->w,
+						simplex.c[2]->w-simplex.c[3]->w)<0)
+					{
+						btSwap(simplex.c[0],simplex.c[1]);
+						btSwap(simplex.p[0],simplex.p[1]);
+					}
+					/* Build initial hull	*/ 
+					sFace*	tetra[]={newface(simplex.c[0],simplex.c[1],simplex.c[2],true),
+						newface(simplex.c[1],simplex.c[0],simplex.c[3],true),
+						newface(simplex.c[2],simplex.c[1],simplex.c[3],true),
+						newface(simplex.c[0],simplex.c[2],simplex.c[3],true)};
+					if(m_hull.count==4)
+					{
+						sFace*		best=findbest();
+						sFace		outer=*best;
+						U			pass=0;
+						U			iterations=0;
+						bind(tetra[0],0,tetra[1],0);
+						bind(tetra[0],1,tetra[2],0);
+						bind(tetra[0],2,tetra[3],0);
+						bind(tetra[1],1,tetra[3],2);
+						bind(tetra[1],2,tetra[2],1);
+						bind(tetra[2],2,tetra[3],1);
+						m_status=eStatus::Valid;
+						for(;iterations<EPA_MAX_ITERATIONS;++iterations)
+						{
+							if(m_nextsv<EPA_MAX_VERTICES)
+							{	
+								sHorizon		horizon;
+								sSV*			w=&m_sv_store[m_nextsv++];
+								bool			valid=true;					
+								best->pass	=	(U1)(++pass);
+								gjk.getsupport(best->n,*w);
+								const btScalar	wdist=dot(best->n,w->w)-best->d;
+								if(wdist>EPA_ACCURACY)
+								{
+									for(U j=0;(j<3)&&valid;++j)
+									{
+										valid&=expand(	pass,w,
+											best->f[j],best->e[j],
+											horizon);
+									}
+									if(valid&&(horizon.nf>=3))
+									{
+										bind(horizon.cf,1,horizon.ff,2);
+										remove(m_hull,best);
+										append(m_stock,best);
+										best=findbest();
+										if(best->p>=outer.p) outer=*best;
+									} else { m_status=eStatus::InvalidHull;break; }
+								} else { m_status=eStatus::AccuraryReached;break; }
+							} else { m_status=eStatus::OutOfVertices;break; }
+						}
+						const btVector3	projection=outer.n*outer.d;
+						m_normal	=	outer.n;
+						m_depth		=	outer.d;
+						m_result.rank	=	3;
+						m_result.c[0]	=	outer.c[0];
+						m_result.c[1]	=	outer.c[1];
+						m_result.c[2]	=	outer.c[2];
+						m_result.p[0]	=	cross(	outer.c[1]->w-projection,
+							outer.c[2]->w-projection).length();
+						m_result.p[1]	=	cross(	outer.c[2]->w-projection,
+							outer.c[0]->w-projection).length();
+						m_result.p[2]	=	cross(	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];
+						m_result.p[0]	/=	sum;
+						m_result.p[1]	/=	sum;
+						m_result.p[2]	/=	sum;
+						return(m_status);
+					}
+				}
+				/* Fallback		*/ 
+				m_status	=	eStatus::FallBack;
+				m_normal	=	-guess;
+				const btScalar	nl=m_normal.length();
+				if(nl>0)
+					m_normal	=	m_normal/nl;
+				else
+					m_normal	=	btVector3(1,0,0);
+				m_depth	=	0;
+				m_result.rank=1;
+				m_result.c[0]=simplex.c[0];
+				m_result.p[0]=1;	
+				return(m_status);
+			}
+			sFace*				newface(sSV* a,sSV* b,sSV* c,bool forced)
+			{
+				if(m_stock.root)
+				{
+					sFace*	face=m_stock.root;
+					remove(m_stock,face);
+					append(m_hull,face);
+					face->pass	=	0;
+					face->c[0]	=	a;
+					face->c[1]	=	b;
+					face->c[2]	=	c;
+					face->n		=	cross(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)))	/
+						(v?l:1);
+					face->p		=	face->p>=-EPA_INSIDE_EPS?0:face->p;
+					if(v)
+					{
+						face->d		=	dot(a->w,face->n)/l;
+						face->n		/=	l;
+						if(forced||(face->d>=-EPA_PLANE_EPS))
+						{
+							return(face);
+						} else m_status=eStatus::NonConvex;
+					} else m_status=eStatus::Degenerated;
+					remove(m_hull,face);
+					append(m_stock,face);
+					return(0);
+				}
+				m_status=m_stock.root?eStatus::OutOfVertices:eStatus::OutOfFaces;
+				return(0);
+			}
+			sFace*				findbest()
+			{
+				sFace*		minf=m_hull.root;
+				btScalar	mind=minf->d*minf->d;
+				btScalar	maxp=minf->p;
+				for(sFace* f=minf->l[1];f;f=f->l[1])
+				{
+					const btScalar	sqd=f->d*f->d;
+					if((f->p>=maxp)&&(sqd<mind))
+					{
+						minf=f;
+						mind=sqd;
+						maxp=f->p;
+					}
+				}
+				return(minf);
+			}
+			bool				expand(U pass,sSV* w,sFace* f,U e,sHorizon& horizon)
+			{
+				static const U	i1m3[]={1,2,0};
+				static const U	i2m3[]={2,0,1};
+				if(f->pass!=pass)
+				{
+					const U	e1=i1m3[e];
+					if((dot(f->n,w->w)-f->d)<-EPA_PLANE_EPS)
+					{
+						sFace*	nf=newface(f->c[e1],f->c[e],w,false);
+						if(nf)
+						{
+							bind(nf,0,f,e);
+							if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf;
+							horizon.cf=nf;
+							++horizon.nf;
+							return(true);
+						}
+					}
+					else
+					{
+						const U	e2=i2m3[e];
+						f->pass		=	(U1)pass;
+						if(	expand(pass,w,f->f[e1],f->e[e1],horizon)&&
+							expand(pass,w,f->f[e2],f->e[e2],horizon))
+						{
+							remove(m_hull,f);
+							append(m_stock,f);
+							return(true);
+						}
+					}
+				}
+				return(false);
+			}
+
+	};
+
+	//
+	static void	Initialize(	const btConvexShape* shape0,const btTransform& wtrs0,
+		const btConvexShape* shape1,const btTransform& wtrs1,
+		btGjkEpaSolver2::sResults& results,
+		tShape& shape,
+		bool withmargins)
+	{
+		/* Results		*/ 
+		results.witnesses[0]	=
+			results.witnesses[1]	=	btVector3(0,0,0);
+		results.status			=	btGjkEpaSolver2::sResults::Separated;
+		/* Shape		*/ 
+		shape.m_shapes[0]		=	shape0;
+		shape.m_shapes[1]		=	shape1;
+		shape.m_toshape1		=	wtrs1.getBasis().transposeTimes(wtrs0.getBasis());
+		shape.m_toshape0		=	wtrs0.inverseTimes(wtrs1);
+		shape.EnableMargin(withmargins);
+	}
+
+}
+
+//
+// Api
+//
+
+using namespace	gjkepa2_impl;
+
+//
+int			btGjkEpaSolver2::StackSizeRequirement()
+{
+	return(sizeof(GJK)+sizeof(EPA));
+}
+
+//
+bool		btGjkEpaSolver2::Distance(	const btConvexShape*	shape0,
+									  const btTransform&		wtrs0,
+									  const btConvexShape*	shape1,
+									  const btTransform&		wtrs1,
+									  const btVector3&		guess,
+									  sResults&				results)
+{
+	tShape			shape;
+	Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,false);
+	GJK				gjk;
+	GJK::eStatus::_	gjk_status=gjk.Evaluate(shape,guess);
+	if(gjk_status==GJK::eStatus::Valid)
+	{
+		btVector3	w0=btVector3(0,0,0);
+		btVector3	w1=btVector3(0,0,0);
+		for(U i=0;i<gjk.m_simplex->rank;++i)
+		{
+			const btScalar	p=gjk.m_simplex->p[i];
+			w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p;
+			w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p;
+		}
+		results.witnesses[0]	=	wtrs0*w0;
+		results.witnesses[1]	=	wtrs0*w1;
+		results.normal			=	w0-w1;
+		results.distance		=	results.normal.length();
+		results.normal			/=	results.distance>GJK_MIN_DISTANCE?results.distance:1;
+		return(true);
+	}
+	else
+	{
+		results.status	=	gjk_status==GJK::eStatus::Inside?
+			sResults::Penetrating	:
+		sResults::GJK_Failed	;
+		return(false);
+	}
+}
+
+//
+bool	btGjkEpaSolver2::Penetration(	const btConvexShape*	shape0,
+									 const btTransform&		wtrs0,
+									 const btConvexShape*	shape1,
+									 const btTransform&		wtrs1,
+									 const btVector3&		guess,
+									 sResults&				results,
+									 bool					usemargins)
+{
+	tShape			shape;
+	Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,usemargins);
+	GJK				gjk;	
+	GJK::eStatus::_	gjk_status=gjk.Evaluate(shape,-guess);
+	switch(gjk_status)
+	{
+	case	GJK::eStatus::Inside:
+		{
+			EPA				epa;
+			EPA::eStatus::_	epa_status=epa.Evaluate(gjk,-guess);
+			if(epa_status!=EPA::eStatus::Failed)
+			{
+				btVector3	w0=btVector3(0,0,0);
+				for(U i=0;i<epa.m_result.rank;++i)
+				{
+					w0+=shape.Support(epa.m_result.c[i]->d,0)*epa.m_result.p[i];
+				}
+				results.status			=	sResults::Penetrating;
+				results.witnesses[0]	=	wtrs0*w0;
+				results.witnesses[1]	=	wtrs0*(w0-epa.m_normal*epa.m_depth);
+				results.normal			=	-epa.m_normal;
+				results.distance		=	-epa.m_depth;
+				return(true);
+			} else results.status=sResults::EPA_Failed;
+		}
+		break;
+	case	GJK::eStatus::Failed:
+		results.status=sResults::GJK_Failed;
+		break;
+	}
+	return(false);
+}
+
+//
+btScalar	btGjkEpaSolver2::SignedDistance(const btVector3& position,
+											btScalar margin,
+											const btConvexShape* shape0,
+											const btTransform& wtrs0,
+											sResults& results)
+{
+	tShape			shape;
+	btSphereShape	shape1(margin);
+	btTransform		wtrs1(btQuaternion(0,0,0,1),position);
+	Initialize(shape0,wtrs0,&shape1,wtrs1,results,shape,false);
+	GJK				gjk;	
+	GJK::eStatus::_	gjk_status=gjk.Evaluate(shape,btVector3(1,1,1));
+	if(gjk_status==GJK::eStatus::Valid)
+	{
+		btVector3	w0=btVector3(0,0,0);
+		btVector3	w1=btVector3(0,0,0);
+		for(U i=0;i<gjk.m_simplex->rank;++i)
+		{
+			const btScalar	p=gjk.m_simplex->p[i];
+			w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p;
+			w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p;
+		}
+		results.witnesses[0]	=	wtrs0*w0;
+		results.witnesses[1]	=	wtrs0*w1;
+		const btVector3	delta=	results.witnesses[1]-
+			results.witnesses[0];
+		const btScalar	margin=	shape0->getMarginNonVirtual()+
+			shape1.getMarginNonVirtual();
+		const btScalar	length=	delta.length();	
+		results.normal			=	delta/length;
+		results.witnesses[0]	+=	results.normal*margin;
+		return(length-margin);
+	}
+	else
+	{
+		if(gjk_status==GJK::eStatus::Inside)
+		{
+			if(Penetration(shape0,wtrs0,&shape1,wtrs1,gjk.m_ray,results))
+			{
+				const btVector3	delta=	results.witnesses[0]-
+					results.witnesses[1];
+				const btScalar	length=	delta.length();
+				if (length >= SIMD_EPSILON)
+					results.normal	=	delta/length;			
+				return(-length);
+			}
+		}	
+	}
+	return(SIMD_INFINITY);
+}
+
+//
+bool	btGjkEpaSolver2::SignedDistance(const btConvexShape*	shape0,
+										const btTransform&		wtrs0,
+										const btConvexShape*	shape1,
+										const btTransform&		wtrs1,
+										const btVector3&		guess,
+										sResults&				results)
+{
+	if(!Distance(shape0,wtrs0,shape1,wtrs1,guess,results))
+		return(Penetration(shape0,wtrs0,shape1,wtrs1,guess,results,false));
+	else
+		return(true);
+}
+
+/* Symbols cleanup		*/ 
+
+#undef GJK_MAX_ITERATIONS
+#undef GJK_ACCURARY
+#undef GJK_MIN_DISTANCE
+#undef GJK_DUPLICATED_EPS
+#undef GJK_SIMPLEX2_EPS
+#undef GJK_SIMPLEX3_EPS
+#undef GJK_SIMPLEX4_EPS
+
+#undef EPA_MAX_VERTICES
+#undef EPA_MAX_FACES
+#undef EPA_MAX_ITERATIONS
+#undef EPA_ACCURACY
+#undef EPA_FALLBACK
+#undef EPA_PLANE_EPS
+#undef EPA_INSIDE_EPS
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h	(revision 6952)
@@ -0,0 +1,71 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 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.
+*/
+
+/*
+GJK-EPA collision solver by Nathanael Presson, 2008
+*/
+#ifndef _68DA1F85_90B7_4bb0_A705_83B4040A75C6_
+#define _68DA1F85_90B7_4bb0_A705_83B4040A75C6_
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+
+///btGjkEpaSolver contributed under zlib by Nathanael Presson
+struct	btGjkEpaSolver2
+{
+struct	sResults
+	{
+	enum eStatus
+		{
+		Separated,		/* Shapes doesnt penetrate												*/ 
+		Penetrating,	/* Shapes are penetrating												*/ 
+		GJK_Failed,		/* GJK phase fail, no big issue, shapes are probably just 'touching'	*/ 
+		EPA_Failed		/* EPA phase fail, bigger problem, need to save parameters, and debug	*/ 
+		}		status;
+	btVector3	witnesses[2];
+	btVector3	normal;
+	btScalar	distance;
+	};
+
+static int		StackSizeRequirement();
+
+static bool		Distance(	const btConvexShape* shape0,const btTransform& wtrs0,
+							const btConvexShape* shape1,const btTransform& wtrs1,
+							const btVector3& guess,
+							sResults& results);
+
+static bool		Penetration(const btConvexShape* shape0,const btTransform& wtrs0,
+							const btConvexShape* shape1,const btTransform& wtrs1,
+							const btVector3& guess,
+							sResults& results,
+							bool usemargins=true);
+
+static btScalar	SignedDistance(	const btVector3& position,
+								btScalar margin,
+								const btConvexShape* shape,
+								const btTransform& wtrs,
+								sResults& results);
+							
+static bool		SignedDistance(	const btConvexShape* shape0,const btTransform& wtrs0,
+								const btConvexShape* shape1,const btTransform& wtrs1,
+								const btVector3& guess,
+								sResults& results);
+};
+
+#endif
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp	(revision 6952)
@@ -0,0 +1,54 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+EPA Copyright (c) Ricardo Padrela 2006
+
+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 "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "btGjkEpaPenetrationDepthSolver.h"
+
+
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
+
+bool btGjkEpaPenetrationDepthSolver::calcPenDepth( btSimplexSolverInterface& simplexSolver,
+											  const btConvexShape* pConvexA, const btConvexShape* pConvexB,
+											  const btTransform& transformA, const btTransform& transformB,
+											  btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB,
+											  class btIDebugDraw* debugDraw, btStackAlloc* stackAlloc )
+{
+
+	(void)debugDraw;
+	(void)v;
+	(void)simplexSolver;
+
+	const btScalar				radialmargin(btScalar(0.));
+	
+	btVector3	guessVector(transformA.getOrigin()-transformB.getOrigin());
+	btGjkEpaSolver2::sResults	results;
+	if(btGjkEpaSolver2::Penetration(pConvexA,transformA,
+								pConvexB,transformB,
+								guessVector,results))
+	
+		{
+	//	debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0));
+		//resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth);
+		wWitnessOnA = results.witnesses[0];
+		wWitnessOnB = results.witnesses[1];
+		return true;		
+		}
+
+	return false;
+}
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h	(revision 6952)
@@ -0,0 +1,39 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+EPA Copyright (c) Ricardo Padrela 2006 
+
+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_GJP_EPA_PENETRATION_DEPTH_H
+#define BT_GJP_EPA_PENETRATION_DEPTH_H
+
+#include "btConvexPenetrationDepthSolver.h"
+
+///EpaPenetrationDepthSolver uses the Expanding Polytope Algorithm to
+///calculate the penetration depth between two convex shapes.
+class btGjkEpaPenetrationDepthSolver : public btConvexPenetrationDepthSolver
+{
+	public :
+
+		bool			calcPenDepth( btSimplexSolverInterface& simplexSolver,
+									  const btConvexShape* pConvexA, const btConvexShape* pConvexB,
+									  const btTransform& transformA, const btTransform& transformB,
+									  btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB,
+									  class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc );
+
+	private :
+
+};
+
+#endif	// BT_GJP_EPA_PENETRATION_DEPTH_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp	(revision 6952)
@@ -0,0 +1,364 @@
+/*
+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 "btGjkPairDetector.h"
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
+#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h"
+
+
+
+#if defined(DEBUG) || defined (_DEBUG)
+//#define TEST_NON_VIRTUAL 1
+#include <stdio.h> //for debug printf
+#ifdef __SPU__
+#include <spu_printf.h>
+#define printf spu_printf
+//#define DEBUG_SPU_COLLISION_DETECTION 1
+#endif //__SPU__
+#endif
+
+//must be above the machine epsilon
+#define REL_ERROR2 btScalar(1.0e-6)
+
+//temp globals, to improve GJK/EPA/penetration calculations
+int gNumDeepPenetrationChecks = 0;
+int gNumGjkChecks = 0;
+
+
+
+btGjkPairDetector::btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver*	penetrationDepthSolver)
+:m_cachedSeparatingAxis(btScalar(0.),btScalar(0.),btScalar(1.)),
+m_penetrationDepthSolver(penetrationDepthSolver),
+m_simplexSolver(simplexSolver),
+m_minkowskiA(objectA),
+m_minkowskiB(objectB),
+m_ignoreMargin(false),
+m_lastUsedMethod(-1),
+m_catchDegeneracies(1)
+{
+}
+
+void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults)
+{
+	m_cachedSeparatingDistance = 0.f;
+
+	btScalar distance=btScalar(0.);
+	btVector3	normalInB(btScalar(0.),btScalar(0.),btScalar(0.));
+	btVector3 pointOnA,pointOnB;
+	btTransform	localTransA = input.m_transformA;
+	btTransform localTransB = input.m_transformB;
+	btVector3 positionOffset = (localTransA.getOrigin() + localTransB.getOrigin()) * btScalar(0.5);
+	localTransA.getOrigin() -= positionOffset;
+	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
+	
+
+
+	gNumGjkChecks++;
+
+#ifdef DEBUG_SPU_COLLISION_DETECTION
+	spu_printf("inside gjk\n");
+#endif
+	//for CCD we don't use margins
+	if (m_ignoreMargin)
+	{
+		marginA = btScalar(0.);
+		marginB = btScalar(0.);
+#ifdef DEBUG_SPU_COLLISION_DETECTION
+		spu_printf("ignoring margin\n");
+#endif
+	}
+
+	m_curIter = 0;
+	int gGjkMaxIter = 1000;//this is to catch invalid input, perhaps check for #NaN?
+	m_cachedSeparatingAxis.setValue(0,1,0);
+
+	bool isValid = false;
+	bool checkSimplex = false;
+	bool checkPenetration = true;
+	m_degenerateSimplex = 0;
+
+	m_lastUsedMethod = -1;
+
+	{
+		btScalar squaredDistance = SIMD_INFINITY;
+		btScalar delta = btScalar(0.);
+		
+		btScalar margin = marginA + marginB;
+		
+		
+
+		m_simplexSolver->reset();
+		
+		for ( ; ; )
+		//while (true)
+		{
+
+			btVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* input.m_transformA.getBasis();
+			btVector3 seperatingAxisInB = m_cachedSeparatingAxis* input.m_transformB.getBasis();
+
+#ifdef __SPU__
+			btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
+			btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
+#else
+			btVector3 pInA = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA);
+			btVector3 qInB = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB);
+#ifdef TEST_NON_VIRTUAL
+			btVector3 pInAv = m_minkowskiA->localGetSupportingVertexWithoutMargin(seperatingAxisInA);
+			btVector3 qInBv = m_minkowskiB->localGetSupportingVertexWithoutMargin(seperatingAxisInB);
+			btAssert((pInAv-pInA).length() < 0.0001);
+			btAssert((qInBv-qInB).length() < 0.0001);
+#endif //
+#endif //__SPU__
+
+			btVector3  pWorld = localTransA(pInA);	
+			btVector3  qWorld = localTransB(qInB);
+
+#ifdef DEBUG_SPU_COLLISION_DETECTION
+		spu_printf("got local supporting vertices\n");
+#endif
+
+			btVector3 w	= pWorld - qWorld;
+			delta = m_cachedSeparatingAxis.dot(w);
+
+			// potential exit, they don't overlap
+			if ((delta > btScalar(0.0)) && (delta * delta > squaredDistance * input.m_maximumDistanceSquared)) 
+			{
+				checkSimplex=true;
+				//checkPenetration = false;
+				break;
+			}
+
+			//exit 0: the new point is already in the simplex, or we didn't come any closer
+			if (m_simplexSolver->inSimplex(w))
+			{
+				m_degenerateSimplex = 1;
+				checkSimplex = true;
+				break;
+			}
+			// are we getting any closer ?
+			btScalar f0 = squaredDistance - delta;
+			btScalar f1 = squaredDistance * REL_ERROR2;
+
+			if (f0 <= f1)
+			{
+				if (f0 <= btScalar(0.))
+				{
+					m_degenerateSimplex = 2;
+				}
+				checkSimplex = true;
+				break;
+			}
+
+#ifdef DEBUG_SPU_COLLISION_DETECTION
+		spu_printf("addVertex 1\n");
+#endif
+			//add current vertex to simplex
+			m_simplexSolver->addVertex(w, pWorld, qWorld);
+#ifdef DEBUG_SPU_COLLISION_DETECTION
+		spu_printf("addVertex 2\n");
+#endif
+			//calculate the closest point to the origin (update vector v)
+			if (!m_simplexSolver->closest(m_cachedSeparatingAxis))
+			{
+				m_degenerateSimplex = 3;
+				checkSimplex = true;
+				break;
+			}
+
+			if(m_cachedSeparatingAxis.length2()<REL_ERROR2)
+            {
+                m_degenerateSimplex = 6;
+                checkSimplex = true;
+                break;
+            }
+
+			btScalar previousSquaredDistance = squaredDistance;
+			squaredDistance = m_cachedSeparatingAxis.length2();
+			
+			//redundant m_simplexSolver->compute_points(pointOnA, pointOnB);
+
+			//are we getting any closer ?
+			if (previousSquaredDistance - squaredDistance <= SIMD_EPSILON * previousSquaredDistance) 
+			{ 
+				m_simplexSolver->backup_closest(m_cachedSeparatingAxis);
+				checkSimplex = true;
+				break;
+			}
+
+			  //degeneracy, this is typically due to invalid/uninitialized worldtransforms for a btCollisionObject   
+              if (m_curIter++ > gGjkMaxIter)   
+              {   
+                      #if defined(DEBUG) || defined (_DEBUG) || defined (DEBUG_SPU_COLLISION_DETECTION)
+
+                              printf("btGjkPairDetector maxIter exceeded:%i\n",m_curIter);   
+                              printf("sepAxis=(%f,%f,%f), squaredDistance = %f, shapeTypeA=%i,shapeTypeB=%i\n",   
+                              m_cachedSeparatingAxis.getX(),   
+                              m_cachedSeparatingAxis.getY(),   
+                              m_cachedSeparatingAxis.getZ(),   
+                              squaredDistance,   
+                              m_minkowskiA->getShapeType(),   
+                              m_minkowskiB->getShapeType());   
+
+                      #endif   
+                      break;   
+
+              } 
+
+
+			bool check = (!m_simplexSolver->fullSimplex());
+			//bool check = (!m_simplexSolver->fullSimplex() && squaredDistance > SIMD_EPSILON * m_simplexSolver->maxVertex());
+
+			if (!check)
+			{
+				//do we need this backup_closest here ?
+				m_simplexSolver->backup_closest(m_cachedSeparatingAxis);
+				break;
+			}
+		}
+
+		if (checkSimplex)
+		{
+			m_simplexSolver->compute_points(pointOnA, pointOnB);
+			normalInB = pointOnA-pointOnB;
+			btScalar lenSqr = m_cachedSeparatingAxis.length2();
+			//valid normal
+			if (lenSqr < 0.0001)
+			{
+				m_degenerateSimplex = 5;
+			} 
+			if (lenSqr > SIMD_EPSILON*SIMD_EPSILON)
+			{
+				btScalar rlen = btScalar(1.) / btSqrt(lenSqr );
+				normalInB *= rlen; //normalize
+				btScalar s = btSqrt(squaredDistance);
+			
+				btAssert(s > btScalar(0.0));
+				pointOnA -= m_cachedSeparatingAxis * (marginA / s);
+				pointOnB += m_cachedSeparatingAxis * (marginB / s);
+				distance = ((btScalar(1.)/rlen) - margin);
+				isValid = true;
+				
+				m_lastUsedMethod = 1;
+			} else
+			{
+				m_lastUsedMethod = 2;
+			}
+		}
+
+		bool catchDegeneratePenetrationCase = 
+			(m_catchDegeneracies && m_penetrationDepthSolver && m_degenerateSimplex && ((distance+margin) < 0.01));
+
+		//if (checkPenetration && !isValid)
+		if (checkPenetration && (!isValid || catchDegeneratePenetrationCase ))
+		{
+			//penetration case
+		
+			//if there is no way to handle penetrations, bail out
+			if (m_penetrationDepthSolver)
+			{
+				// Penetration depth case.
+				btVector3 tmpPointOnA,tmpPointOnB;
+				
+				gNumDeepPenetrationChecks++;
+
+				bool isValid2 = m_penetrationDepthSolver->calcPenDepth( 
+					*m_simplexSolver, 
+					m_minkowskiA,m_minkowskiB,
+					localTransA,localTransB,
+					m_cachedSeparatingAxis, tmpPointOnA, tmpPointOnB,
+					debugDraw,input.m_stackAlloc
+					);
+
+				if (isValid2)
+				{
+					btVector3 tmpNormalInB = tmpPointOnB-tmpPointOnA;
+					btScalar lenSqr = tmpNormalInB.length2();
+					if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON))
+					{
+						tmpNormalInB /= btSqrt(lenSqr);
+						btScalar distance2 = -(tmpPointOnA-tmpPointOnB).length();
+						//only replace valid penetrations when the result is deeper (check)
+						if (!isValid || (distance2 < distance))
+						{
+							distance = distance2;
+							pointOnA = tmpPointOnA;
+							pointOnB = tmpPointOnB;
+							normalInB = tmpNormalInB;
+							isValid = true;
+							m_lastUsedMethod = 3;
+						} else
+						{
+							
+						}
+					} else
+					{
+						//isValid = false;
+						m_lastUsedMethod = 4;
+					}
+				} else
+				{
+					m_lastUsedMethod = 5;
+				}
+				
+			}
+		}
+	}
+
+	if (isValid)
+	{
+#ifdef __SPU__
+		//spu_printf("distance\n");
+#endif //__CELLOS_LV2__
+
+
+#ifdef DEBUG_SPU_COLLISION_DETECTION
+		spu_printf("output 1\n");
+#endif
+		m_cachedSeparatingAxis = normalInB;
+		m_cachedSeparatingDistance = distance;
+
+		output.addContactPoint(
+			normalInB,
+			pointOnB+positionOffset,
+			distance);
+
+#ifdef DEBUG_SPU_COLLISION_DETECTION
+		spu_printf("output 2\n");
+#endif
+		//printf("gjk add:%f",distance);
+	}
+
+
+}
+
+
+
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h	(revision 6952)
@@ -0,0 +1,94 @@
+/*
+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 GJK_PAIR_DETECTOR_H
+#define GJK_PAIR_DETECTOR_H
+
+#include "btDiscreteCollisionDetectorInterface.h"
+#include "BulletCollision/CollisionShapes/btCollisionMargin.h"
+
+class btConvexShape;
+#include "btSimplexSolverInterface.h"
+class btConvexPenetrationDepthSolver;
+
+/// btGjkPairDetector uses GJK to implement the btDiscreteCollisionDetectorInterface
+class btGjkPairDetector : public btDiscreteCollisionDetectorInterface
+{
+	
+
+	btVector3	m_cachedSeparatingAxis;
+	btConvexPenetrationDepthSolver*	m_penetrationDepthSolver;
+	btSimplexSolverInterface* m_simplexSolver;
+	const btConvexShape* m_minkowskiA;
+	const btConvexShape* m_minkowskiB;
+	bool		m_ignoreMargin;
+	btScalar	m_cachedSeparatingDistance;
+	
+
+public:
+
+	//some debugging to fix degeneracy problems
+	int			m_lastUsedMethod;
+	int			m_curIter;
+	int			m_degenerateSimplex;
+	int			m_catchDegeneracies;
+
+
+	btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver*	penetrationDepthSolver);
+	virtual ~btGjkPairDetector() {};
+
+	virtual void	getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false);
+
+	void setMinkowskiA(btConvexShape* minkA)
+	{
+		m_minkowskiA = minkA;
+	}
+
+	void setMinkowskiB(btConvexShape* minkB)
+	{
+		m_minkowskiB = minkB;
+	}
+	void setCachedSeperatingAxis(const btVector3& seperatingAxis)
+	{
+		m_cachedSeparatingAxis = seperatingAxis;
+	}
+
+	const btVector3& getCachedSeparatingAxis() const
+	{
+		return m_cachedSeparatingAxis;
+	}
+	btScalar	getCachedSeparatingDistance() const
+	{
+		return m_cachedSeparatingDistance;
+	}
+
+	void	setPenetrationDepthSolver(btConvexPenetrationDepthSolver*	penetrationDepthSolver)
+	{
+		m_penetrationDepthSolver = penetrationDepthSolver;
+	}
+
+	///don't use setIgnoreMargin, it's for Bullet's internal use
+	void	setIgnoreMargin(bool ignoreMargin)
+	{
+		m_ignoreMargin = ignoreMargin;
+	}
+
+
+};
+
+#endif //GJK_PAIR_DETECTOR_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h	(revision 6952)
@@ -0,0 +1,125 @@
+/*
+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 MANIFOLD_CONTACT_POINT_H
+#define MANIFOLD_CONTACT_POINT_H
+
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btTransformUtil.h"
+
+
+
+
+
+/// ManifoldContactPoint collects and maintains persistent contactpoints.
+/// used to improve stability and performance of rigidbody dynamics response.
+class btManifoldPoint
+	{
+		public:
+			btManifoldPoint()
+				:m_userPersistentData(0),
+				m_appliedImpulse(0.f),
+				m_lateralFrictionInitialized(false),
+				m_appliedImpulseLateral1(0.f),
+				m_appliedImpulseLateral2(0.f),
+				m_lifeTime(0)
+			{
+			}
+
+			btManifoldPoint( const btVector3 &pointA, const btVector3 &pointB, 
+					const btVector3 &normal, 
+					btScalar distance ) :
+					m_localPointA( pointA ), 
+					m_localPointB( pointB ), 
+					m_normalWorldOnB( normal ), 
+					m_distance1( distance ),
+					m_combinedFriction(btScalar(0.)),
+					m_combinedRestitution(btScalar(0.)),
+					m_userPersistentData(0),
+					m_appliedImpulse(0.f),
+					m_lateralFrictionInitialized(false),
+					m_appliedImpulseLateral1(0.f),
+					m_appliedImpulseLateral2(0.f),
+					m_lifeTime(0)
+			{
+				
+					
+			}
+
+			
+
+			btVector3 m_localPointA;			
+			btVector3 m_localPointB;			
+			btVector3	m_positionWorldOnB;
+			///m_positionWorldOnA is redundant information, see getPositionWorldOnA(), but for clarity
+			btVector3	m_positionWorldOnA;
+			btVector3 m_normalWorldOnB;
+		
+			btScalar	m_distance1;
+			btScalar	m_combinedFriction;
+			btScalar	m_combinedRestitution;
+
+         //BP mod, store contact triangles.
+         int	   m_partId0;
+         int      m_partId1;
+         int      m_index0;
+         int      m_index1;
+				
+			mutable void*	m_userPersistentData;
+			btScalar		m_appliedImpulse;
+
+			bool			m_lateralFrictionInitialized;
+			btScalar		m_appliedImpulseLateral1;
+			btScalar		m_appliedImpulseLateral2;
+			int				m_lifeTime;//lifetime of the contactpoint in frames
+			
+			btVector3		m_lateralFrictionDir1;
+			btVector3		m_lateralFrictionDir2;
+
+			btScalar getDistance() const
+			{
+				return m_distance1;
+			}
+			int	getLifeTime() const
+			{
+				return m_lifeTime;
+			}
+
+			const btVector3& getPositionWorldOnA() const {
+				return m_positionWorldOnA;
+//				return m_positionWorldOnB + m_normalWorldOnB * m_distance1;
+			}
+
+			const btVector3& getPositionWorldOnB() const
+			{
+				return m_positionWorldOnB;
+			}
+
+			void	setDistance(btScalar dist)
+			{
+				m_distance1 = dist;
+			}
+			
+			///this returns the most recent applied impulse, to satisfy contact constraints by the constraint solver
+			btScalar	getAppliedImpulse() const
+			{
+				return m_appliedImpulse;
+			}
+
+			
+
+	};
+
+#endif //MANIFOLD_CONTACT_POINT_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp	(revision 6952)
@@ -0,0 +1,334 @@
+/*
+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 "btMinkowskiPenetrationDepthSolver.h"
+#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+
+#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))
+};
+
+
+bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& simplexSolver,
+												   const btConvexShape* convexA,const btConvexShape* convexB,
+												   const btTransform& transA,const btTransform& transB,
+												   btVector3& v, btVector3& pa, btVector3& pb,
+												   class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
+												   )
+{
+
+	(void)stackAlloc;
+	(void)v;
+	
+
+	struct btIntermediateResult : public btDiscreteCollisionDetectorInterface::Result
+	{
+
+		btIntermediateResult():m_hasResult(false)
+		{
+		}
+		
+		btVector3 m_normalOnBInWorld;
+		btVector3 m_pointInWorld;
+		btScalar m_depth;
+		bool	m_hasResult;
+
+		virtual void setShapeIdentifiers(int partId0,int index0,	int partId1,int index1)
+		{
+			(void)partId0;
+			(void)index0;
+			(void)partId1;
+			(void)index1;
+		}
+		void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
+		{
+			m_normalOnBInWorld = normalOnBInWorld;
+			m_pointInWorld = pointInWorld;
+			m_depth = depth;
+			m_hasResult = true;
+		}
+	};
+
+	//just take fixed number of orientation, and sample the penetration depth in that direction
+	btScalar minProj = btScalar(1e30);
+	btVector3 minNorm(btScalar(0.), btScalar(0.), btScalar(0.));
+	btVector3 minA,minB;
+	btVector3 seperatingAxisInA,seperatingAxisInB;
+	btVector3 pInA,qInB,pWorld,qWorld,w;
+
+#ifndef __SPU__
+#define USE_BATCHED_SUPPORT 1
+#endif
+#ifdef USE_BATCHED_SUPPORT
+
+	btVector3	supportVerticesABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2];
+	btVector3	supportVerticesBBatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2];
+	btVector3	seperatingAxisInABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2];
+	btVector3	seperatingAxisInBBatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2];
+	int i;
+
+	int numSampleDirections = NUM_UNITSPHERE_POINTS;
+
+	for (i=0;i<numSampleDirections;i++)
+	{
+		const btVector3& norm = sPenetrationDirections[i];
+		seperatingAxisInABatch[i] =  (-norm) * transA.getBasis() ;
+		seperatingAxisInBBatch[i] =  norm   * transB.getBasis() ;
+	}
+
+	{
+		int numPDA = convexA->getNumPreferredPenetrationDirections();
+		if (numPDA)
+		{
+			for (int i=0;i<numPDA;i++)
+			{
+				btVector3 norm;
+				convexA->getPreferredPenetrationDirection(i,norm);
+				norm  = transA.getBasis() * norm;
+				sPenetrationDirections[numSampleDirections] = norm;
+				seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis();
+				seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis();
+				numSampleDirections++;
+			}
+		}
+	}
+
+	{
+		int numPDB = convexB->getNumPreferredPenetrationDirections();
+		if (numPDB)
+		{
+			for (int i=0;i<numPDB;i++)
+			{
+				btVector3 norm;
+				convexB->getPreferredPenetrationDirection(i,norm);
+				norm  = transB.getBasis() * norm;
+				sPenetrationDirections[numSampleDirections] = norm;
+				seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis();
+				seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis();
+				numSampleDirections++;
+			}
+		}
+	}
+
+
+
+	convexA->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInABatch,supportVerticesABatch,numSampleDirections);
+	convexB->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInBBatch,supportVerticesBBatch,numSampleDirections);
+
+	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;
+		}
+	}	
+#else
+
+	int numSampleDirections = NUM_UNITSPHERE_POINTS;
+
+#ifndef __SPU__
+	{
+		int numPDA = convexA->getNumPreferredPenetrationDirections();
+		if (numPDA)
+		{
+			for (int i=0;i<numPDA;i++)
+			{
+				btVector3 norm;
+				convexA->getPreferredPenetrationDirection(i,norm);
+				norm  = transA.getBasis() * norm;
+				sPenetrationDirections[numSampleDirections] = norm;
+				numSampleDirections++;
+			}
+		}
+	}
+
+	{
+		int numPDB = convexB->getNumPreferredPenetrationDirections();
+		if (numPDB)
+		{
+			for (int i=0;i<numPDB;i++)
+			{
+				btVector3 norm;
+				convexB->getPreferredPenetrationDirection(i,norm);
+				norm  = transB.getBasis() * norm;
+				sPenetrationDirections[numSampleDirections] = norm;
+				numSampleDirections++;
+			}
+		}
+	}
+#endif // __SPU__
+
+	for (int i=0;i<numSampleDirections;i++)
+	{
+		const btVector3& norm = sPenetrationDirections[i];
+		seperatingAxisInA = (-norm)* transA.getBasis();
+		seperatingAxisInB = norm* transB.getBasis();
+		pInA = convexA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA);
+		qInB = convexB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB);
+		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;
+		}
+	}
+#endif //USE_BATCHED_SUPPORT
+
+	//add the margins
+
+	minA += minNorm*convexA->getMarginNonVirtual();
+	minB -= minNorm*convexB->getMarginNonVirtual();
+	//no penetration
+	if (minProj < btScalar(0.))
+		return false;
+
+	minProj += (convexA->getMarginNonVirtual() + convexB->getMarginNonVirtual());
+
+
+
+
+
+//#define DEBUG_DRAW 1
+#ifdef DEBUG_DRAW
+	if (debugDraw)
+	{
+		btVector3 color(0,1,0);
+		debugDraw->drawLine(minA,minB,color);
+		color = btVector3 (1,1,1);
+		btVector3 vec = minB-minA;
+		btScalar prj2 = minNorm.dot(vec);
+		debugDraw->drawLine(minA,minA+(minNorm*minProj),color);
+
+	}
+#endif //DEBUG_DRAW
+
+	
+
+	btGjkPairDetector gjkdet(convexA,convexB,&simplexSolver,0);
+
+	btScalar offsetDist = minProj;
+	btVector3 offset = minNorm * offsetDist;
+	
+
+
+	btGjkPairDetector::ClosestPointInput input;
+		
+	btVector3 newOrg = transA.getOrigin() + offset;
+
+	btTransform displacedTrans = transA;
+	displacedTrans.setOrigin(newOrg);
+
+	input.m_transformA = displacedTrans;
+	input.m_transformB = transB;
+	input.m_maximumDistanceSquared = btScalar(1e30);//minProj;
+	
+	btIntermediateResult res;
+	gjkdet.getClosestPoints(input,res,debugDraw);
+
+	btScalar correctedMinNorm = minProj - res.m_depth;
+
+
+	//the penetration depth is over-estimated, relax it
+	btScalar penetration_relaxation= btScalar(1.);
+	minNorm*=penetration_relaxation;
+
+	if (res.m_hasResult)
+	{
+
+		pa = res.m_pointInWorld - minNorm * correctedMinNorm;
+		pb = res.m_pointInWorld;
+		
+#ifdef DEBUG_DRAW
+		if (debugDraw)
+		{
+			btVector3 color(1,0,0);
+			debugDraw->drawLine(pa,pb,color);
+		}
+#endif//DEBUG_DRAW
+
+
+	}
+	return res.m_hasResult;
+}
+
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h	(revision 6952)
@@ -0,0 +1,36 @@
+/*
+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 MINKOWSKI_PENETRATION_DEPTH_SOLVER_H
+#define MINKOWSKI_PENETRATION_DEPTH_SOLVER_H
+
+#include "btConvexPenetrationDepthSolver.h"
+
+///MinkowskiPenetrationDepthSolver implements bruteforce penetration depth estimation.
+///Implementation is based on sampling the depth using support mapping, and using GJK step to get the witness points.
+class btMinkowskiPenetrationDepthSolver : public btConvexPenetrationDepthSolver
+{
+public:
+
+	virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver,
+	const btConvexShape* convexA,const btConvexShape* convexB,
+				const btTransform& transA,const btTransform& transB,
+			btVector3& v, btVector3& pa, btVector3& pb,
+			class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
+			);
+};
+
+#endif //MINKOWSKI_PENETRATION_DEPTH_SOLVER_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp	(revision 6952)
@@ -0,0 +1,259 @@
+/*
+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 "btPersistentManifold.h"
+#include "LinearMath/btTransform.h"
+
+
+btScalar					gContactBreakingThreshold = btScalar(0.02);
+ContactDestroyedCallback	gContactDestroyedCallback = 0;
+ContactProcessedCallback	gContactProcessedCallback = 0;
+
+
+
+btPersistentManifold::btPersistentManifold()
+:m_body0(0),
+m_body1(0),
+m_cachedPoints (0),
+m_index1a(0)
+{
+}
+
+
+
+
+#ifdef DEBUG_PERSISTENCY
+#include <stdio.h>
+void	btPersistentManifold::DebugPersistency()
+{
+	int i;
+	printf("DebugPersistency : numPoints %d\n",m_cachedPoints);
+	for (i=0;i<m_cachedPoints;i++)
+	{
+		printf("m_pointCache[%d].m_userPersistentData = %x\n",i,m_pointCache[i].m_userPersistentData);
+	}
+}
+#endif //DEBUG_PERSISTENCY
+
+void btPersistentManifold::clearUserCache(btManifoldPoint& pt)
+{
+
+	void* oldPtr = pt.m_userPersistentData;
+	if (oldPtr)
+	{
+#ifdef DEBUG_PERSISTENCY
+		int i;
+		int occurance = 0;
+		for (i=0;i<m_cachedPoints;i++)
+		{
+			if (m_pointCache[i].m_userPersistentData == oldPtr)
+			{
+				occurance++;
+				if (occurance>1)
+					printf("error in clearUserCache\n");
+			}
+		}
+		btAssert(occurance<=0);
+#endif //DEBUG_PERSISTENCY
+
+		if (pt.m_userPersistentData && gContactDestroyedCallback)
+		{
+			(*gContactDestroyedCallback)(pt.m_userPersistentData);
+			pt.m_userPersistentData = 0;
+		}
+		
+#ifdef DEBUG_PERSISTENCY
+		DebugPersistency();
+#endif
+	}
+
+	
+}
+
+
+int btPersistentManifold::sortCachedPoints(const btManifoldPoint& pt) 
+{
+
+		//calculate 4 possible cases areas, and take biggest area
+		//also need to keep 'deepest'
+		
+		int maxPenetrationIndex = -1;
+#define KEEP_DEEPEST_POINT 1
+#ifdef KEEP_DEEPEST_POINT
+		btScalar maxPenetration = pt.getDistance();
+		for (int i=0;i<4;i++)
+		{
+			if (m_pointCache[i].getDistance() < maxPenetration)
+			{
+				maxPenetrationIndex = i;
+				maxPenetration = m_pointCache[i].getDistance();
+			}
+		}
+#endif //KEEP_DEEPEST_POINT
+		
+		btScalar res0(btScalar(0.)),res1(btScalar(0.)),res2(btScalar(0.)),res3(btScalar(0.));
+		if (maxPenetrationIndex != 0)
+		{
+			btVector3 a0 = pt.m_localPointA-m_pointCache[1].m_localPointA;
+			btVector3 b0 = m_pointCache[3].m_localPointA-m_pointCache[2].m_localPointA;
+			btVector3 cross = a0.cross(b0);
+			res0 = cross.length2();
+		}
+		if (maxPenetrationIndex != 1)
+		{
+			btVector3 a1 = pt.m_localPointA-m_pointCache[0].m_localPointA;
+			btVector3 b1 = m_pointCache[3].m_localPointA-m_pointCache[2].m_localPointA;
+			btVector3 cross = a1.cross(b1);
+			res1 = cross.length2();
+		}
+
+		if (maxPenetrationIndex != 2)
+		{
+			btVector3 a2 = pt.m_localPointA-m_pointCache[0].m_localPointA;
+			btVector3 b2 = m_pointCache[3].m_localPointA-m_pointCache[1].m_localPointA;
+			btVector3 cross = a2.cross(b2);
+			res2 = cross.length2();
+		}
+
+		if (maxPenetrationIndex != 3)
+		{
+			btVector3 a3 = pt.m_localPointA-m_pointCache[0].m_localPointA;
+			btVector3 b3 = m_pointCache[2].m_localPointA-m_pointCache[1].m_localPointA;
+			btVector3 cross = a3.cross(b3);
+			res3 = cross.length2();
+		}
+
+		btVector4 maxvec(res0,res1,res2,res3);
+		int biggestarea = maxvec.closestAxis4();
+		return biggestarea;
+}
+
+
+int btPersistentManifold::getCacheEntry(const btManifoldPoint& newPoint) const
+{
+	btScalar shortestDist =  getContactBreakingThreshold() * getContactBreakingThreshold();
+	int size = getNumContacts();
+	int nearestPoint = -1;
+	for( int i = 0; i < size; i++ )
+	{
+		const btManifoldPoint &mp = m_pointCache[i];
+
+		btVector3 diffA =  mp.m_localPointA- newPoint.m_localPointA;
+		const btScalar distToManiPoint = diffA.dot(diffA);
+		if( distToManiPoint < shortestDist )
+		{
+			shortestDist = distToManiPoint;
+			nearestPoint = i;
+		}
+	}
+	return nearestPoint;
+}
+
+int btPersistentManifold::addManifoldPoint(const btManifoldPoint& newPoint)
+{
+	btAssert(validContactDistance(newPoint));
+
+	int insertIndex = getNumContacts();
+	if (insertIndex == MANIFOLD_CACHE_SIZE)
+	{
+#if MANIFOLD_CACHE_SIZE >= 4
+		//sort cache so best points come first, based on area
+		insertIndex = sortCachedPoints(newPoint);
+#else
+		insertIndex = 0;
+#endif
+		clearUserCache(m_pointCache[insertIndex]);
+		
+	} else
+	{
+		m_cachedPoints++;
+
+		
+	}
+	if (insertIndex<0)
+		insertIndex=0;
+
+	btAssert(m_pointCache[insertIndex].m_userPersistentData==0);
+	m_pointCache[insertIndex] = newPoint;
+	return insertIndex;
+}
+
+btScalar	btPersistentManifold::getContactBreakingThreshold() const
+{
+	return m_contactBreakingThreshold;
+}
+
+
+
+void btPersistentManifold::refreshContactPoints(const btTransform& trA,const btTransform& trB)
+{
+	int i;
+#ifdef DEBUG_PERSISTENCY
+	printf("refreshContactPoints posA = (%f,%f,%f) posB = (%f,%f,%f)\n",
+		trA.getOrigin().getX(),
+		trA.getOrigin().getY(),
+		trA.getOrigin().getZ(),
+		trB.getOrigin().getX(),
+		trB.getOrigin().getY(),
+		trB.getOrigin().getZ());
+#endif //DEBUG_PERSISTENCY
+	/// first refresh worldspace positions and distance
+	for (i=getNumContacts()-1;i>=0;i--)
+	{
+		btManifoldPoint &manifoldPoint = m_pointCache[i];
+		manifoldPoint.m_positionWorldOnA = trA( manifoldPoint.m_localPointA );
+		manifoldPoint.m_positionWorldOnB = trB( manifoldPoint.m_localPointB );
+		manifoldPoint.m_distance1 = (manifoldPoint.m_positionWorldOnA -  manifoldPoint.m_positionWorldOnB).dot(manifoldPoint.m_normalWorldOnB);
+		manifoldPoint.m_lifeTime++;
+	}
+
+	/// then 
+	btScalar distance2d;
+	btVector3 projectedDifference,projectedPoint;
+	for (i=getNumContacts()-1;i>=0;i--)
+	{
+		
+		btManifoldPoint &manifoldPoint = m_pointCache[i];
+		//contact becomes invalid when signed distance exceeds margin (projected on contactnormal direction)
+		if (!validContactDistance(manifoldPoint))
+		{
+			removeContactPoint(i);
+		} else
+		{
+			//contact also becomes invalid when relative movement orthogonal to normal exceeds margin
+			projectedPoint = manifoldPoint.m_positionWorldOnA - manifoldPoint.m_normalWorldOnB * manifoldPoint.m_distance1;
+			projectedDifference = manifoldPoint.m_positionWorldOnB - projectedPoint;
+			distance2d = projectedDifference.dot(projectedDifference);
+			if (distance2d  > getContactBreakingThreshold()*getContactBreakingThreshold() )
+			{
+				removeContactPoint(i);
+			} else
+			{
+				//contact point processed callback
+				if (gContactProcessedCallback)
+					(*gContactProcessedCallback)(manifoldPoint,m_body0,m_body1);
+			}
+		}
+	}
+#ifdef DEBUG_PERSISTENCY
+	DebugPersistency();
+#endif //
+}
+
+
+
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h	(revision 6952)
@@ -0,0 +1,203 @@
+/*
+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 PERSISTENT_MANIFOLD_H
+#define PERSISTENT_MANIFOLD_H
+
+
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btTransform.h"
+#include "btManifoldPoint.h"
+#include "LinearMath/btAlignedAllocator.h"
+
+struct btCollisionResult;
+
+///maximum contact breaking and merging threshold
+extern btScalar gContactBreakingThreshold;
+
+typedef bool (*ContactDestroyedCallback)(void* userPersistentData);
+typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp,void* body0,void* body1);
+extern ContactDestroyedCallback	gContactDestroyedCallback;
+
+
+
+
+#define MANIFOLD_CACHE_SIZE 4
+
+///btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping in the broadphase.
+///Those contact points are created by the collision narrow phase.
+///The cache can be empty, or hold 1,2,3 or 4 points. Some collision algorithms (GJK) might only add one point at a time.
+///updates/refreshes old contact points, and throw them away if necessary (distance becomes too large)
+///reduces the cache to 4 points, when more then 4 points are added, using following rules:
+///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 
+{
+
+	btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE];
+
+	/// this two body pointers can point to the physics rigidbody class.
+	/// void* will allow any rigidbody class
+	void* m_body0;
+	void* m_body1;
+	int	m_cachedPoints;
+
+	btScalar	m_contactBreakingThreshold;
+	btScalar	m_contactProcessingThreshold;
+
+	
+	/// sort cached points so most isolated points come first
+	int	sortCachedPoints(const btManifoldPoint& pt);
+
+	int		findContactPoint(const btManifoldPoint* unUsed, int numUnused,const btManifoldPoint& pt);
+
+public:
+
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	int m_index1a;
+
+	btPersistentManifold();
+
+	btPersistentManifold(void* body0,void* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold)
+		: m_body0(body0),m_body1(body1),m_cachedPoints(0),
+		m_contactBreakingThreshold(contactBreakingThreshold),
+		m_contactProcessingThreshold(contactProcessingThreshold)
+	{
+		
+	}
+
+	SIMD_FORCE_INLINE void* getBody0() { return m_body0;}
+	SIMD_FORCE_INLINE void* getBody1() { return m_body1;}
+
+	SIMD_FORCE_INLINE const void* getBody0() const { return m_body0;}
+	SIMD_FORCE_INLINE const void* getBody1() const { return m_body1;}
+
+	void	setBodies(void* body0,void* body1)
+	{
+		m_body0 = body0;
+		m_body1 = body1;
+	}
+
+	void clearUserCache(btManifoldPoint& pt);
+
+#ifdef DEBUG_PERSISTENCY
+	void	DebugPersistency();
+#endif //
+	
+	SIMD_FORCE_INLINE int	getNumContacts() const { return m_cachedPoints;}
+
+	SIMD_FORCE_INLINE const btManifoldPoint& getContactPoint(int index) const
+	{
+		btAssert(index < m_cachedPoints);
+		return m_pointCache[index];
+	}
+
+	SIMD_FORCE_INLINE btManifoldPoint& getContactPoint(int index)
+	{
+		btAssert(index < m_cachedPoints);
+		return m_pointCache[index];
+	}
+
+	///@todo: get this margin from the current physics / collision environment
+	btScalar	getContactBreakingThreshold() const;
+
+	btScalar	getContactProcessingThreshold() const
+	{
+		return m_contactProcessingThreshold;
+	}
+	
+	int getCacheEntry(const btManifoldPoint& newPoint) const;
+
+	int addManifoldPoint( const btManifoldPoint& newPoint);
+
+	void removeContactPoint (int index)
+	{
+		clearUserCache(m_pointCache[index]);
+
+		int lastUsedIndex = getNumContacts() - 1;
+//		m_pointCache[index] = m_pointCache[lastUsedIndex];
+		if(index != lastUsedIndex) 
+		{
+			m_pointCache[index] = m_pointCache[lastUsedIndex]; 
+			//get rid of duplicated userPersistentData pointer
+			m_pointCache[lastUsedIndex].m_userPersistentData = 0;
+			m_pointCache[lastUsedIndex].m_appliedImpulse = 0.f;
+			m_pointCache[lastUsedIndex].m_lateralFrictionInitialized = false;
+			m_pointCache[lastUsedIndex].m_appliedImpulseLateral1 = 0.f;
+			m_pointCache[lastUsedIndex].m_appliedImpulseLateral2 = 0.f;
+			m_pointCache[lastUsedIndex].m_lifeTime = 0;
+		}
+
+		btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0);
+		m_cachedPoints--;
+	}
+	void replaceContactPoint(const btManifoldPoint& newPoint,int insertIndex)
+	{
+		btAssert(validContactDistance(newPoint));
+
+#define MAINTAIN_PERSISTENCY 1
+#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;
+				
+		btAssert(lifeTime>=0);
+		void* cache = m_pointCache[insertIndex].m_userPersistentData;
+		
+		m_pointCache[insertIndex] = newPoint;
+
+		m_pointCache[insertIndex].m_userPersistentData = cache;
+		m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse;
+		m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1;
+		m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
+		
+		m_pointCache[insertIndex].m_lifeTime = lifeTime;
+#else
+		clearUserCache(m_pointCache[insertIndex]);
+		m_pointCache[insertIndex] = newPoint;
+	
+#endif
+	}
+
+	bool validContactDistance(const btManifoldPoint& pt) const
+	{
+		return pt.m_distance1 <= getContactBreakingThreshold();
+	}
+	/// calculated new worldspace coordinates and depth, and reject points that exceed the collision margin
+	void	refreshContactPoints(  const btTransform& trA,const btTransform& trB);
+
+	
+	SIMD_FORCE_INLINE	void	clearManifold()
+	{
+		int i;
+		for (i=0;i<m_cachedPoints;i++)
+		{
+			clearUserCache(m_pointCache[i]);
+		}
+		m_cachedPoints = 0;
+	}
+
+
+
+}
+;
+
+
+
+
+
+#endif //PERSISTENT_MANIFOLD_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPointCollector.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPointCollector.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btPointCollector.h	(revision 6952)
@@ -0,0 +1,61 @@
+/*
+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 POINT_COLLECTOR_H
+#define POINT_COLLECTOR_H
+
+#include "btDiscreteCollisionDetectorInterface.h"
+
+
+
+struct btPointCollector : public btDiscreteCollisionDetectorInterface::Result
+{
+	
+	
+	btVector3 m_normalOnBInWorld;
+	btVector3 m_pointInWorld;
+	btScalar	m_distance;//negative means penetration
+
+	bool	m_hasResult;
+
+	btPointCollector () 
+		: m_distance(btScalar(1e30)),m_hasResult(false)
+	{
+	}
+
+	virtual void setShapeIdentifiers(int partId0,int index0,	int partId1,int index1)
+	{
+		(void)partId0;
+		(void)index0;
+		(void)partId1;
+		(void)index1;
+		//??
+	}
+
+	virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)
+	{
+		if (depth< m_distance)
+		{
+			m_hasResult = true;
+			m_normalOnBInWorld = normalOnBInWorld;
+			m_pointInWorld = pointInWorld;
+			//negative means penetration
+			m_distance = depth;
+		}
+	}
+};
+
+#endif //POINT_COLLECTOR_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp	(revision 6952)
@@ -0,0 +1,175 @@
+/*
+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 <stdio.h>
+
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "BulletCollision/CollisionShapes/btTriangleShape.h"
+#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h"
+#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
+#include "btRaycastCallback.h"
+
+btTriangleRaycastCallback::btTriangleRaycastCallback(const btVector3& from,const btVector3& to, unsigned int flags)
+	:
+	m_from(from),
+	m_to(to),
+   //@BP Mod
+   m_flags(flags),
+	m_hitFraction(btScalar(1.))
+{
+
+}
+
+
+
+void btTriangleRaycastCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex)
+{
+	const btVector3 &vert0=triangle[0];
+	const btVector3 &vert1=triangle[1];
+	const btVector3 &vert2=triangle[2];
+
+	btVector3 v10; v10 = vert1 - vert0 ;
+	btVector3 v20; v20 = vert2 - vert0 ;
+
+	btVector3 triangleNormal; triangleNormal = v10.cross( v20 );
+	
+	const btScalar dist = vert0.dot(triangleNormal);
+	btScalar dist_a = triangleNormal.dot(m_from) ;
+	dist_a-= dist;
+	btScalar dist_b = triangleNormal.dot(m_to);
+	dist_b -= dist;
+
+	if ( dist_a * dist_b >= btScalar(0.0) )
+	{
+		return ; // same sign
+	}
+   //@BP Mod - Backface filtering
+   if (((m_flags & kF_FilterBackfaces) != 0) && (dist_a > btScalar(0.0)))
+   {
+      // Backface, skip check
+      return;
+   }
+	
+	const btScalar proj_length=dist_a-dist_b;
+	const btScalar distance = (dist_a)/(proj_length);
+	// Now we have the intersection point on the plane, we'll see if it's inside the triangle
+	// Add an epsilon as a tolerance for the raycast,
+	// in case the ray hits exacly on the edge of the triangle.
+	// It must be scaled for the triangle size.
+	
+	if(distance < m_hitFraction)
+	{
+		
+
+		btScalar edge_tolerance =triangleNormal.length2();		
+		edge_tolerance *= btScalar(-0.0001);
+		btVector3 point; point.setInterpolate3( m_from, m_to, distance);
+		{
+			btVector3 v0p; v0p = vert0 - point;
+			btVector3 v1p; v1p = vert1 - point;
+			btVector3 cp0; cp0 = v0p.cross( v1p );
+
+			if ( (btScalar)(cp0.dot(triangleNormal)) >=edge_tolerance) 
+			{
+						
+
+				btVector3 v2p; v2p = vert2 -  point;
+				btVector3 cp1;
+				cp1 = v1p.cross( v2p);
+				if ( (btScalar)(cp1.dot(triangleNormal)) >=edge_tolerance) 
+				{
+					btVector3 cp2;
+					cp2 = v2p.cross(v0p);
+					
+					if ( (btScalar)(cp2.dot(triangleNormal)) >=edge_tolerance) 
+					{
+                  //@BP Mod
+                  // Triangle normal isn't normalized
+				      triangleNormal.normalize();
+
+                  //@BP Mod - Allow for unflipped normal when raycasting against backfaces
+                  if (((m_flags & kF_KeepUnflippedNormal) != 0) || (dist_a <= btScalar(0.0)))
+						{
+							m_hitFraction = reportHit(-triangleNormal,distance,partId,triangleIndex);
+						}
+						else
+						{
+                     m_hitFraction = reportHit(triangleNormal,distance,partId,triangleIndex);
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+
+btTriangleConvexcastCallback::btTriangleConvexcastCallback (const btConvexShape* convexShape, const btTransform& convexShapeFrom, const btTransform& convexShapeTo, const btTransform& triangleToWorld, const btScalar triangleCollisionMargin)
+{
+	m_convexShape = convexShape;
+	m_convexShapeFrom = convexShapeFrom;
+	m_convexShapeTo = convexShapeTo;
+	m_triangleToWorld = triangleToWorld;
+	m_hitFraction = 1.0;
+    m_triangleCollisionMargin = triangleCollisionMargin;
+}
+
+void
+btTriangleConvexcastCallback::processTriangle (btVector3* triangle, int partId, int triangleIndex)
+{
+	btTriangleShape triangleShape (triangle[0], triangle[1], triangle[2]);
+    triangleShape.setMargin(m_triangleCollisionMargin);
+
+	btVoronoiSimplexSolver	simplexSolver;
+	btGjkEpaPenetrationDepthSolver	gjkEpaPenetrationSolver;
+
+//#define  USE_SUBSIMPLEX_CONVEX_CAST 1
+//if you reenable USE_SUBSIMPLEX_CONVEX_CAST see commented out code below
+#ifdef USE_SUBSIMPLEX_CONVEX_CAST
+	btSubsimplexConvexCast convexCaster(m_convexShape, &triangleShape, &simplexSolver);
+#else
+	//btGjkConvexCast	convexCaster(m_convexShape,&triangleShape,&simplexSolver);
+	btContinuousConvexCollision convexCaster(m_convexShape,&triangleShape,&simplexSolver,&gjkEpaPenetrationSolver);
+#endif //#USE_SUBSIMPLEX_CONVEX_CAST
+	
+	btConvexCast::CastResult castResult;
+	castResult.m_fraction = btScalar(1.);
+	if (convexCaster.calcTimeOfImpact(m_convexShapeFrom,m_convexShapeTo,m_triangleToWorld, m_triangleToWorld, castResult))
+	{
+		//add hit
+		if (castResult.m_normal.length2() > btScalar(0.0001))
+		{					
+			if (castResult.m_fraction < m_hitFraction)
+			{
+/* btContinuousConvexCast's normal is already in world space */
+/*
+#ifdef USE_SUBSIMPLEX_CONVEX_CAST
+				//rotate normal into worldspace
+				castResult.m_normal = m_convexShapeFrom.getBasis() * castResult.m_normal;
+#endif //USE_SUBSIMPLEX_CONVEX_CAST
+*/
+				castResult.m_normal.normalize();
+
+				reportHit (castResult.m_normal,
+							castResult.m_hitPoint,
+							castResult.m_fraction,
+							partId,
+							triangleIndex);
+			}
+		}
+	}
+}
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h	(revision 6952)
@@ -0,0 +1,71 @@
+/*
+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 RAYCAST_TRI_CALLBACK_H
+#define RAYCAST_TRI_CALLBACK_H
+
+#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
+#include "LinearMath/btTransform.h"
+struct btBroadphaseProxy;
+class btConvexShape;
+
+class  btTriangleRaycastCallback: public btTriangleCallback
+{
+public:
+
+	//input
+	btVector3 m_from;
+	btVector3 m_to;
+
+   //@BP Mod - allow backface filtering and unflipped normals
+   enum EFlags
+   {
+      kF_None                 = 0,
+      kF_FilterBackfaces      = 1 << 0,
+      kF_KeepUnflippedNormal  = 1 << 1,   // Prevents returned face normal getting flipped when a ray hits a back-facing triangle
+
+      kF_Terminator        = 0xFFFFFFFF
+   };
+   unsigned int m_flags;
+
+	btScalar	m_hitFraction;
+
+	btTriangleRaycastCallback(const btVector3& from,const btVector3& to, unsigned int flags=0);
+	
+	virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex);
+
+	virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex ) = 0;
+	
+};
+
+class btTriangleConvexcastCallback : public btTriangleCallback
+{
+public:
+	const btConvexShape* m_convexShape;
+	btTransform m_convexShapeFrom;
+	btTransform m_convexShapeTo;
+	btTransform m_triangleToWorld;
+	btScalar m_hitFraction;
+    btScalar m_triangleCollisionMargin;
+
+	btTriangleConvexcastCallback (const btConvexShape* convexShape, const btTransform& convexShapeFrom, const btTransform& convexShapeTo, const btTransform& triangleToWorld, const btScalar triangleCollisionMargin);
+
+	virtual void processTriangle (btVector3* triangle, int partId, int triangleIndex);
+
+	virtual btScalar reportHit (const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex) = 0;
+};
+
+#endif //RAYCAST_TRI_CALLBACK_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h	(revision 6952)
@@ -0,0 +1,63 @@
+/*
+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 SIMPLEX_SOLVER_INTERFACE_H
+#define SIMPLEX_SOLVER_INTERFACE_H
+
+#include "LinearMath/btVector3.h"
+
+#define NO_VIRTUAL_INTERFACE 1
+#ifdef NO_VIRTUAL_INTERFACE
+#include "btVoronoiSimplexSolver.h"
+#define btSimplexSolverInterface btVoronoiSimplexSolver
+#else
+
+/// btSimplexSolverInterface can incrementally calculate distance between origin and up to 4 vertices
+/// Used by GJK or Linear Casting. Can be implemented by the Johnson-algorithm or alternative approaches based on
+/// voronoi regions or barycentric coordinates
+class btSimplexSolverInterface
+{
+	public:
+		virtual ~btSimplexSolverInterface() {};
+
+	virtual void reset() = 0;
+
+	virtual void addVertex(const btVector3& w, const btVector3& p, const btVector3& q) = 0;
+	
+	virtual bool closest(btVector3& v) = 0;
+
+	virtual btScalar maxVertex() = 0;
+
+	virtual bool fullSimplex() const = 0;
+
+	virtual int getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const = 0;
+
+	virtual bool inSimplex(const btVector3& w) = 0;
+	
+	virtual void backup_closest(btVector3& v) = 0;
+
+	virtual bool emptySimplex() const = 0;
+
+	virtual void compute_points(btVector3& p1, btVector3& p2) = 0;
+
+	virtual int numVertices() const =0;
+
+
+};
+#endif
+#endif //SIMPLEX_SOLVER_INTERFACE_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp	(revision 6952)
@@ -0,0 +1,157 @@
+/*
+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 "btSubSimplexConvexCast.h"
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+
+#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h"
+#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
+#include "btPointCollector.h"
+#include "LinearMath/btTransformUtil.h"
+
+btSubsimplexConvexCast::btSubsimplexConvexCast (const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver)
+:m_simplexSolver(simplexSolver),
+m_convexA(convexA),m_convexB(convexB)
+{
+}
+
+///Typically the conservative advancement reaches solution in a few iterations, clip it to 32 for degenerate cases.
+///See discussion about this here http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=565
+#ifdef BT_USE_DOUBLE_PRECISION
+#define MAX_ITERATIONS 64
+#else
+#define MAX_ITERATIONS 32
+#endif
+bool	btSubsimplexConvexCast::calcTimeOfImpact(
+		const btTransform& fromA,
+		const btTransform& toA,
+		const btTransform& fromB,
+		const btTransform& toB,
+		CastResult& result)
+{
+
+	m_simplexSolver->reset();
+
+	btVector3 linVelA,linVelB;
+	linVelA = toA.getOrigin()-fromA.getOrigin();
+	linVelB = toB.getOrigin()-fromB.getOrigin();
+
+	btScalar lambda = btScalar(0.);
+
+	btTransform interpolatedTransA = fromA;
+	btTransform interpolatedTransB = fromB;
+
+	///take relative motion
+	btVector3 r = (linVelA-linVelB);
+	btVector3 v;
+	
+	btVector3 supVertexA = fromA(m_convexA->localGetSupportingVertex(-r*fromA.getBasis()));
+	btVector3 supVertexB = fromB(m_convexB->localGetSupportingVertex(r*fromB.getBasis()));
+	v = supVertexA-supVertexB;
+	int maxIter = MAX_ITERATIONS;
+
+	btVector3 n;
+	n.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
+	bool hasResult = false;
+	btVector3 c;
+
+	btScalar lastLambda = lambda;
+
+
+	btScalar dist2 = v.length2();
+#ifdef BT_USE_DOUBLE_PRECISION
+	btScalar epsilon = btScalar(0.0001);
+#else
+	btScalar epsilon = btScalar(0.0001);
+#endif //BT_USE_DOUBLE_PRECISION
+	btVector3	w,p;
+	btScalar VdotR;
+	
+	while ( (dist2 > epsilon) && maxIter--)
+	{
+		supVertexA = interpolatedTransA(m_convexA->localGetSupportingVertex(-v*interpolatedTransA.getBasis()));
+		supVertexB = interpolatedTransB(m_convexB->localGetSupportingVertex(v*interpolatedTransB.getBasis()));
+		w = supVertexA-supVertexB;
+
+		btScalar VdotW = v.dot(w);
+
+		if (lambda > btScalar(1.0))
+		{
+			return false;
+		}
+
+		if ( VdotW > btScalar(0.))
+		{
+			VdotR = v.dot(r);
+
+			if (VdotR >= -(SIMD_EPSILON*SIMD_EPSILON))
+				return false;
+			else
+			{
+				lambda = lambda - VdotW / VdotR;
+				//interpolate to next lambda
+				//	x = s + lambda * r;
+				interpolatedTransA.getOrigin().setInterpolate3(fromA.getOrigin(),toA.getOrigin(),lambda);
+				interpolatedTransB.getOrigin().setInterpolate3(fromB.getOrigin(),toB.getOrigin(),lambda);
+				//m_simplexSolver->reset();
+				//check next line
+				 w = supVertexA-supVertexB;
+				lastLambda = lambda;
+				n = v;
+				hasResult = true;
+			}
+		} 
+		m_simplexSolver->addVertex( w, supVertexA , supVertexB);
+		if (m_simplexSolver->closest(v))
+		{
+			dist2 = v.length2();
+			hasResult = true;
+			//todo: check this normal for validity
+			//n=v;
+			//printf("V=%f , %f, %f\n",v[0],v[1],v[2]);
+			//printf("DIST2=%f\n",dist2);
+			//printf("numverts = %i\n",m_simplexSolver->numVertices());
+		} else
+		{
+			dist2 = btScalar(0.);
+		} 
+	}
+
+	//int numiter = MAX_ITERATIONS - maxIter;
+//	printf("number of iterations: %d", numiter);
+	
+	//don't report a time of impact when moving 'away' from the hitnormal
+	
+
+	result.m_fraction = lambda;
+	if (n.length2() >= (SIMD_EPSILON*SIMD_EPSILON))
+		result.m_normal = n.normalized();
+	else
+		result.m_normal = btVector3(btScalar(0.0), btScalar(0.0), btScalar(0.0));
+
+	//don't report time of impact for motion away from the contact normal (or causes minor penetration)
+	if (result.m_normal.dot(r)>=-result.m_allowedPenetration)
+		return false;
+
+	btVector3 hitA,hitB;
+	m_simplexSolver->compute_points(hitA,hitB);
+	result.m_hitPoint=hitB;
+	return true;
+}
+
+
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h	(revision 6952)
@@ -0,0 +1,50 @@
+/*
+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 SUBSIMPLEX_CONVEX_CAST_H
+#define SUBSIMPLEX_CONVEX_CAST_H
+
+#include "btConvexCast.h"
+#include "btSimplexSolverInterface.h"
+class btConvexShape;
+
+/// btSubsimplexConvexCast implements Gino van den Bergens' paper
+///"Ray Casting against bteral Convex Objects with Application to Continuous Collision Detection"
+/// GJK based Ray Cast, optimized version
+/// Objects should not start in overlap, otherwise results are not defined.
+class btSubsimplexConvexCast : public btConvexCast
+{
+	btSimplexSolverInterface* m_simplexSolver;
+	const btConvexShape*	m_convexA;
+	const btConvexShape*	m_convexB;
+
+public:
+
+	btSubsimplexConvexCast (const btConvexShape*	shapeA,const btConvexShape*	shapeB,btSimplexSolverInterface* simplexSolver);
+
+	//virtual ~btSubsimplexConvexCast();
+	///SimsimplexConvexCast calculateTimeOfImpact calculates the time of impact+normal for the linear cast (sweep) between two moving objects.
+	///Precondition is that objects should not penetration/overlap at the start from the interval. Overlap can be tested using btGjkPairDetector.
+	virtual bool	calcTimeOfImpact(
+			const btTransform& fromA,
+			const btTransform& toA,
+			const btTransform& fromB,
+			const btTransform& toB,
+			CastResult& result);
+
+};
+
+#endif //SUBSIMPLEX_CONVEX_CAST_H
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp	(revision 6952)
@@ -0,0 +1,605 @@
+
+/*
+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.
+	
+	Elsevier CDROM license agreements grants nonexclusive license to use the software
+	for any purpose, commercial or non-commercial as long as the following credit is included
+	identifying the original source of the software:
+
+	Parts of the source are "from the book Real-Time Collision Detection by
+	Christer Ericson, published by Morgan Kaufmann Publishers,
+	(c) 2005 Elsevier Inc."
+		
+*/
+
+
+#include "btVoronoiSimplexSolver.h"
+
+#define VERTA  0
+#define VERTB  1
+#define VERTC  2
+#define VERTD  3
+
+#define CATCH_DEGENERATE_TETRAHEDRON 1
+void	btVoronoiSimplexSolver::removeVertex(int index)
+{
+	
+	btAssert(m_numVertices>0);
+	m_numVertices--;
+	m_simplexVectorW[index] = m_simplexVectorW[m_numVertices];
+	m_simplexPointsP[index] = m_simplexPointsP[m_numVertices];
+	m_simplexPointsQ[index] = m_simplexPointsQ[m_numVertices];
+}
+
+void	btVoronoiSimplexSolver::reduceVertices (const btUsageBitfield& usedVerts)
+{
+	if ((numVertices() >= 4) && (!usedVerts.usedVertexD))
+		removeVertex(3);
+
+	if ((numVertices() >= 3) && (!usedVerts.usedVertexC))
+		removeVertex(2);
+
+	if ((numVertices() >= 2) && (!usedVerts.usedVertexB))
+		removeVertex(1);
+	
+	if ((numVertices() >= 1) && (!usedVerts.usedVertexA))
+		removeVertex(0);
+
+}
+
+
+
+
+
+//clear the simplex, remove all the vertices
+void btVoronoiSimplexSolver::reset()
+{
+	m_cachedValidClosest = false;
+	m_numVertices = 0;
+	m_needsUpdate = true;
+	m_lastW = btVector3(btScalar(1e30),btScalar(1e30),btScalar(1e30));
+	m_cachedBC.reset();
+}
+
+
+
+	//add a vertex
+void btVoronoiSimplexSolver::addVertex(const btVector3& w, const btVector3& p, const btVector3& q)
+{
+	m_lastW = w;
+	m_needsUpdate = true;
+
+	m_simplexVectorW[m_numVertices] = w;
+	m_simplexPointsP[m_numVertices] = p;
+	m_simplexPointsQ[m_numVertices] = q;
+
+	m_numVertices++;
+}
+
+bool	btVoronoiSimplexSolver::updateClosestVectorAndPoints()
+{
+	
+	if (m_needsUpdate)
+	{
+		m_cachedBC.reset();
+
+		m_needsUpdate = false;
+
+		switch (numVertices())
+		{
+		case 0:
+				m_cachedValidClosest = false;
+				break;
+		case 1:
+			{
+				m_cachedP1 = m_simplexPointsP[0];
+				m_cachedP2 = m_simplexPointsQ[0];
+				m_cachedV = m_cachedP1-m_cachedP2; //== m_simplexVectorW[0]
+				m_cachedBC.reset();
+				m_cachedBC.setBarycentricCoordinates(btScalar(1.),btScalar(0.),btScalar(0.),btScalar(0.));
+				m_cachedValidClosest = m_cachedBC.isValid();
+				break;
+			};
+		case 2:
+			{
+			//closest point origin from line segment
+					const btVector3& from = m_simplexVectorW[0];
+					const btVector3& to = m_simplexVectorW[1];
+					btVector3 nearest;
+
+					btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.));
+					btVector3 diff = p - from;
+					btVector3 v = to - from;
+					btScalar t = v.dot(diff);
+					
+					if (t > 0) {
+						btScalar dotVV = v.dot(v);
+						if (t < dotVV) {
+							t /= dotVV;
+							diff -= t*v;
+							m_cachedBC.m_usedVertices.usedVertexA = true;
+							m_cachedBC.m_usedVertices.usedVertexB = true;
+						} else {
+							t = 1;
+							diff -= v;
+							//reduce to 1 point
+							m_cachedBC.m_usedVertices.usedVertexB = true;
+						}
+					} else
+					{
+						t = 0;
+						//reduce to 1 point
+						m_cachedBC.m_usedVertices.usedVertexA = true;
+					}
+					m_cachedBC.setBarycentricCoordinates(1-t,t);
+					nearest = from + t*v;
+
+					m_cachedP1 = m_simplexPointsP[0] + t * (m_simplexPointsP[1] - m_simplexPointsP[0]);
+					m_cachedP2 = m_simplexPointsQ[0] + t * (m_simplexPointsQ[1] - m_simplexPointsQ[0]);
+					m_cachedV = m_cachedP1 - m_cachedP2;
+					
+					reduceVertices(m_cachedBC.m_usedVertices);
+
+					m_cachedValidClosest = m_cachedBC.isValid();
+					break;
+			}
+		case 3: 
+			{ 
+				//closest point origin from triangle 
+				btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.)); 
+
+				const btVector3& a = m_simplexVectorW[0]; 
+				const btVector3& b = m_simplexVectorW[1]; 
+				const btVector3& c = m_simplexVectorW[2]; 
+
+				closestPtPointTriangle(p,a,b,c,m_cachedBC); 
+				m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + 
+				m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + 
+				m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2]; 
+
+				m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + 
+				m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + 
+				m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2]; 
+
+				m_cachedV = m_cachedP1-m_cachedP2; 
+
+				reduceVertices (m_cachedBC.m_usedVertices); 
+				m_cachedValidClosest = m_cachedBC.isValid(); 
+
+				break; 
+			}
+		case 4:
+			{
+
+				
+				btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.));
+				
+				const btVector3& a = m_simplexVectorW[0];
+				const btVector3& b = m_simplexVectorW[1];
+				const btVector3& c = m_simplexVectorW[2];
+				const btVector3& d = m_simplexVectorW[3];
+
+				bool hasSeperation = closestPtPointTetrahedron(p,a,b,c,d,m_cachedBC);
+
+				if (hasSeperation)
+				{
+
+					m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] +
+						m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] +
+						m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2] +
+						m_simplexPointsP[3] * m_cachedBC.m_barycentricCoords[3];
+
+					m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] +
+						m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] +
+						m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2] +
+						m_simplexPointsQ[3] * m_cachedBC.m_barycentricCoords[3];
+
+					m_cachedV = m_cachedP1-m_cachedP2;
+					reduceVertices (m_cachedBC.m_usedVertices);
+				} else
+				{
+//					printf("sub distance got penetration\n");
+
+					if (m_cachedBC.m_degenerate)
+					{
+						m_cachedValidClosest = false;
+					} else
+					{
+						m_cachedValidClosest = true;
+						//degenerate case == false, penetration = true + zero
+						m_cachedV.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
+					}
+					break;
+				}
+
+				m_cachedValidClosest = m_cachedBC.isValid();
+
+				//closest point origin from tetrahedron
+				break;
+			}
+		default:
+			{
+				m_cachedValidClosest = false;
+			}
+		};
+	}
+
+	return m_cachedValidClosest;
+
+}
+
+//return/calculate the closest vertex
+bool btVoronoiSimplexSolver::closest(btVector3& v)
+{
+	bool succes = updateClosestVectorAndPoints();
+	v = m_cachedV;
+	return succes;
+}
+
+
+
+btScalar btVoronoiSimplexSolver::maxVertex()
+{
+	int i, numverts = numVertices();
+	btScalar maxV = btScalar(0.);
+	for (i=0;i<numverts;i++)
+	{
+		btScalar curLen2 = m_simplexVectorW[i].length2();
+		if (maxV < curLen2)
+			maxV = curLen2;
+	}
+	return maxV;
+}
+
+
+
+	//return the current simplex
+int btVoronoiSimplexSolver::getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const
+{
+	int i;
+	for (i=0;i<numVertices();i++)
+	{
+		yBuf[i] = m_simplexVectorW[i];
+		pBuf[i] = m_simplexPointsP[i];
+		qBuf[i] = m_simplexPointsQ[i];
+	}
+	return numVertices();
+}
+
+
+
+
+bool btVoronoiSimplexSolver::inSimplex(const btVector3& w)
+{
+	bool found = false;
+	int i, numverts = numVertices();
+	//btScalar maxV = btScalar(0.);
+	
+	//w is in the current (reduced) simplex
+	for (i=0;i<numverts;i++)
+	{
+		if (m_simplexVectorW[i] == w)
+			found = true;
+	}
+
+	//check in case lastW is already removed
+	if (w == m_lastW)
+		return true;
+    	
+	return found;
+}
+
+void btVoronoiSimplexSolver::backup_closest(btVector3& v) 
+{
+	v = m_cachedV;
+}
+
+
+bool btVoronoiSimplexSolver::emptySimplex() const 
+{
+	return (numVertices() == 0);
+
+}
+
+void btVoronoiSimplexSolver::compute_points(btVector3& p1, btVector3& p2) 
+{
+	updateClosestVectorAndPoints();
+	p1 = m_cachedP1;
+	p2 = m_cachedP2;
+
+}
+
+
+
+
+bool	btVoronoiSimplexSolver::closestPtPointTriangle(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c,btSubSimplexClosestResult& result)
+{
+	result.m_usedVertices.reset();
+
+    // Check if P in vertex region outside A
+    btVector3 ab = b - a;
+    btVector3 ac = c - a;
+    btVector3 ap = p - a;
+    btScalar d1 = ab.dot(ap);
+    btScalar d2 = ac.dot(ap);
+    if (d1 <= btScalar(0.0) && d2 <= btScalar(0.0)) 
+	{
+		result.m_closestPointOnSimplex = a;
+		result.m_usedVertices.usedVertexA = true;
+		result.setBarycentricCoordinates(1,0,0);
+		return true;// a; // barycentric coordinates (1,0,0)
+	}
+
+    // Check if P in vertex region outside B
+    btVector3 bp = p - b;
+    btScalar d3 = ab.dot(bp);
+    btScalar d4 = ac.dot(bp);
+    if (d3 >= btScalar(0.0) && d4 <= d3) 
+	{
+		result.m_closestPointOnSimplex = b;
+		result.m_usedVertices.usedVertexB = true;
+		result.setBarycentricCoordinates(0,1,0);
+
+		return true; // b; // barycentric coordinates (0,1,0)
+	}
+    // Check if P in edge region of AB, if so return projection of P onto AB
+    btScalar vc = d1*d4 - d3*d2;
+    if (vc <= btScalar(0.0) && d1 >= btScalar(0.0) && d3 <= btScalar(0.0)) {
+        btScalar v = d1 / (d1 - d3);
+		result.m_closestPointOnSimplex = a + v * ab;
+		result.m_usedVertices.usedVertexA = true;
+		result.m_usedVertices.usedVertexB = true;
+		result.setBarycentricCoordinates(1-v,v,0);
+		return true;
+        //return a + v * ab; // barycentric coordinates (1-v,v,0)
+    }
+
+    // Check if P in vertex region outside C
+    btVector3 cp = p - c;
+    btScalar d5 = ab.dot(cp);
+    btScalar d6 = ac.dot(cp);
+    if (d6 >= btScalar(0.0) && d5 <= d6) 
+	{
+		result.m_closestPointOnSimplex = c;
+		result.m_usedVertices.usedVertexC = true;
+		result.setBarycentricCoordinates(0,0,1);
+		return true;//c; // barycentric coordinates (0,0,1)
+	}
+
+    // Check if P in edge region of AC, if so return projection of P onto AC
+    btScalar vb = d5*d2 - d1*d6;
+    if (vb <= btScalar(0.0) && d2 >= btScalar(0.0) && d6 <= btScalar(0.0)) {
+        btScalar w = d2 / (d2 - d6);
+		result.m_closestPointOnSimplex = a + w * ac;
+		result.m_usedVertices.usedVertexA = true;
+		result.m_usedVertices.usedVertexC = true;
+		result.setBarycentricCoordinates(1-w,0,w);
+		return true;
+        //return a + w * ac; // barycentric coordinates (1-w,0,w)
+    }
+
+    // Check if P in edge region of BC, if so return projection of P onto BC
+    btScalar va = d3*d6 - d5*d4;
+    if (va <= btScalar(0.0) && (d4 - d3) >= btScalar(0.0) && (d5 - d6) >= btScalar(0.0)) {
+        btScalar w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
+		
+		result.m_closestPointOnSimplex = b + w * (c - b);
+		result.m_usedVertices.usedVertexB = true;
+		result.m_usedVertices.usedVertexC = true;
+		result.setBarycentricCoordinates(0,1-w,w);
+		return true;		
+       // return b + w * (c - b); // barycentric coordinates (0,1-w,w)
+    }
+
+    // P inside face region. Compute Q through its barycentric coordinates (u,v,w)
+    btScalar denom = btScalar(1.0) / (va + vb + vc);
+    btScalar v = vb * denom;
+    btScalar w = vc * denom;
+    
+	result.m_closestPointOnSimplex = a + ab * v + ac * w;
+	result.m_usedVertices.usedVertexA = true;
+	result.m_usedVertices.usedVertexB = true;
+	result.m_usedVertices.usedVertexC = true;
+	result.setBarycentricCoordinates(1-v-w,v,w);
+	
+	return true;
+//	return a + ab * v + ac * w; // = u*a + v*b + w*c, u = va * denom = btScalar(1.0) - v - w
+
+}
+
+
+
+
+
+/// Test if point p and d lie on opposite sides of plane through abc
+int btVoronoiSimplexSolver::pointOutsideOfPlane(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d)
+{
+	btVector3 normal = (b-a).cross(c-a);
+
+    btScalar signp = (p - a).dot(normal); // [AP AB AC]
+    btScalar signd = (d - a).dot( normal); // [AD AB AC]
+
+#ifdef CATCH_DEGENERATE_TETRAHEDRON
+#ifdef BT_USE_DOUBLE_PRECISION
+if (signd * signd < (btScalar(1e-8) * btScalar(1e-8)))
+	{
+		return -1;
+	}
+#else
+	if (signd * signd < (btScalar(1e-4) * btScalar(1e-4)))
+	{
+//		printf("affine dependent/degenerate\n");//
+		return -1;
+	}
+#endif
+
+#endif
+	// Points on opposite sides if expression signs are opposite
+    return signp * signd < btScalar(0.);
+}
+
+
+bool	btVoronoiSimplexSolver::closestPtPointTetrahedron(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, btSubSimplexClosestResult& finalResult)
+{
+	btSubSimplexClosestResult tempResult;
+
+    // Start out assuming point inside all halfspaces, so closest to itself
+	finalResult.m_closestPointOnSimplex = p;
+	finalResult.m_usedVertices.reset();
+    finalResult.m_usedVertices.usedVertexA = true;
+	finalResult.m_usedVertices.usedVertexB = true;
+	finalResult.m_usedVertices.usedVertexC = true;
+	finalResult.m_usedVertices.usedVertexD = true;
+
+    int pointOutsideABC = pointOutsideOfPlane(p, a, b, c, d);
+	int pointOutsideACD = pointOutsideOfPlane(p, a, c, d, b);
+  	int	pointOutsideADB = pointOutsideOfPlane(p, a, d, b, c);
+	int	pointOutsideBDC = pointOutsideOfPlane(p, b, d, c, a);
+
+   if (pointOutsideABC < 0 || pointOutsideACD < 0 || pointOutsideADB < 0 || pointOutsideBDC < 0)
+   {
+	   finalResult.m_degenerate = true;
+	   return false;
+   }
+
+   if (!pointOutsideABC  && !pointOutsideACD && !pointOutsideADB && !pointOutsideBDC)
+	 {
+		 return false;
+	 }
+
+
+    btScalar bestSqDist = FLT_MAX;
+    // If point outside face abc then compute closest point on abc
+	if (pointOutsideABC) 
+	{
+        closestPtPointTriangle(p, a, b, c,tempResult);
+		btVector3 q = tempResult.m_closestPointOnSimplex;
+		
+        btScalar sqDist = (q - p).dot( q - p);
+        // Update best closest point if (squared) distance is less than current best
+        if (sqDist < bestSqDist) {
+			bestSqDist = sqDist;
+			finalResult.m_closestPointOnSimplex = q;
+			//convert result bitmask!
+			finalResult.m_usedVertices.reset();
+			finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA;
+			finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexB;
+			finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC;
+			finalResult.setBarycentricCoordinates(
+					tempResult.m_barycentricCoords[VERTA],
+					tempResult.m_barycentricCoords[VERTB],
+					tempResult.m_barycentricCoords[VERTC],
+					0
+			);
+
+		}
+    }
+  
+
+	// Repeat test for face acd
+	if (pointOutsideACD) 
+	{
+        closestPtPointTriangle(p, a, c, d,tempResult);
+		btVector3 q = tempResult.m_closestPointOnSimplex;
+		//convert result bitmask!
+
+        btScalar sqDist = (q - p).dot( q - p);
+        if (sqDist < bestSqDist) 
+		{
+			bestSqDist = sqDist;
+			finalResult.m_closestPointOnSimplex = q;
+			finalResult.m_usedVertices.reset();
+			finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA;
+
+			finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexB;
+			finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexC;
+			finalResult.setBarycentricCoordinates(
+					tempResult.m_barycentricCoords[VERTA],
+					0,
+					tempResult.m_barycentricCoords[VERTB],
+					tempResult.m_barycentricCoords[VERTC]
+			);
+
+		}
+    }
+    // Repeat test for face adb
+
+	
+	if (pointOutsideADB)
+	{
+		closestPtPointTriangle(p, a, d, b,tempResult);
+		btVector3 q = tempResult.m_closestPointOnSimplex;
+		//convert result bitmask!
+
+        btScalar sqDist = (q - p).dot( q - p);
+        if (sqDist < bestSqDist) 
+		{
+			bestSqDist = sqDist;
+			finalResult.m_closestPointOnSimplex = q;
+			finalResult.m_usedVertices.reset();
+			finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA;
+			finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexC;
+			
+			finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB;
+			finalResult.setBarycentricCoordinates(
+					tempResult.m_barycentricCoords[VERTA],
+					tempResult.m_barycentricCoords[VERTC],
+					0,
+					tempResult.m_barycentricCoords[VERTB]
+			);
+
+		}
+    }
+    // Repeat test for face bdc
+    
+
+	if (pointOutsideBDC)
+	{
+        closestPtPointTriangle(p, b, d, c,tempResult);
+		btVector3 q = tempResult.m_closestPointOnSimplex;
+		//convert result bitmask!
+        btScalar sqDist = (q - p).dot( q - p);
+        if (sqDist < bestSqDist) 
+		{
+			bestSqDist = sqDist;
+			finalResult.m_closestPointOnSimplex = q;
+			finalResult.m_usedVertices.reset();
+			//
+			finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexA;
+			finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC;
+			finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB;
+
+			finalResult.setBarycentricCoordinates(
+					0,
+					tempResult.m_barycentricCoords[VERTA],
+					tempResult.m_barycentricCoords[VERTC],
+					tempResult.m_barycentricCoords[VERTB]
+			);
+
+		}
+    }
+
+	//help! we ended up full !
+	
+	if (finalResult.m_usedVertices.usedVertexA &&
+		finalResult.m_usedVertices.usedVertexB &&
+		finalResult.m_usedVertices.usedVertexC &&
+		finalResult.m_usedVertices.usedVertexD) 
+	{
+		return true;
+	}
+
+    return true;
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h	(revision 6952)
@@ -0,0 +1,157 @@
+/*
+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 btVoronoiSimplexSolver_H
+#define btVoronoiSimplexSolver_H
+
+#include "btSimplexSolverInterface.h"
+
+
+
+#define VORONOI_SIMPLEX_MAX_VERTS 5
+
+struct btUsageBitfield{
+	btUsageBitfield()
+	{
+		reset();
+	}
+
+	void reset()
+	{
+		usedVertexA = false;
+		usedVertexB = false;
+		usedVertexC = false;
+		usedVertexD = false;
+	}
+	unsigned short usedVertexA	: 1;
+	unsigned short usedVertexB	: 1;
+	unsigned short usedVertexC	: 1;
+	unsigned short usedVertexD	: 1;
+	unsigned short unused1		: 1;
+	unsigned short unused2		: 1;
+	unsigned short unused3		: 1;
+	unsigned short unused4		: 1;
+};
+
+
+struct	btSubSimplexClosestResult
+{
+	btVector3	m_closestPointOnSimplex;
+	//MASK for m_usedVertices
+	//stores the simplex vertex-usage, using the MASK, 
+	// if m_usedVertices & MASK then the related vertex is used
+	btUsageBitfield	m_usedVertices;
+	btScalar	m_barycentricCoords[4];
+	bool m_degenerate;
+
+	void	reset()
+	{
+		m_degenerate = false;
+		setBarycentricCoordinates();
+		m_usedVertices.reset();
+	}
+	bool	isValid()
+	{
+		bool valid = (m_barycentricCoords[0] >= btScalar(0.)) &&
+			(m_barycentricCoords[1] >= btScalar(0.)) &&
+			(m_barycentricCoords[2] >= btScalar(0.)) &&
+			(m_barycentricCoords[3] >= btScalar(0.));
+
+
+		return valid;
+	}
+	void	setBarycentricCoordinates(btScalar a=btScalar(0.),btScalar b=btScalar(0.),btScalar c=btScalar(0.),btScalar d=btScalar(0.))
+	{
+		m_barycentricCoords[0] = a;
+		m_barycentricCoords[1] = b;
+		m_barycentricCoords[2] = c;
+		m_barycentricCoords[3] = d;
+	}
+
+};
+
+/// btVoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points simplex to the origin.
+/// Can be used with GJK, as an alternative to Johnson distance algorithm.
+#ifdef NO_VIRTUAL_INTERFACE
+class btVoronoiSimplexSolver
+#else
+class btVoronoiSimplexSolver : public btSimplexSolverInterface
+#endif
+{
+public:
+
+	int	m_numVertices;
+
+	btVector3	m_simplexVectorW[VORONOI_SIMPLEX_MAX_VERTS];
+	btVector3	m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS];
+	btVector3	m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS];
+
+	
+
+	btVector3	m_cachedP1;
+	btVector3	m_cachedP2;
+	btVector3	m_cachedV;
+	btVector3	m_lastW;
+	bool		m_cachedValidClosest;
+
+	btSubSimplexClosestResult m_cachedBC;
+
+	bool	m_needsUpdate;
+	
+	void	removeVertex(int index);
+	void	reduceVertices (const btUsageBitfield& usedVerts);
+	bool	updateClosestVectorAndPoints();
+
+	bool	closestPtPointTetrahedron(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, btSubSimplexClosestResult& finalResult);
+	int		pointOutsideOfPlane(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d);
+	bool	closestPtPointTriangle(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c,btSubSimplexClosestResult& result);
+
+public:
+
+	 void reset();
+
+	 void addVertex(const btVector3& w, const btVector3& p, const btVector3& q);
+
+
+	 bool closest(btVector3& v);
+
+	 btScalar maxVertex();
+
+	 bool fullSimplex() const
+	 {
+		 return (m_numVertices == 4);
+	 }
+
+	 int getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const;
+
+	 bool inSimplex(const btVector3& w);
+	
+	 void backup_closest(btVector3& v) ;
+
+	 bool emptySimplex() const ;
+
+	 void compute_points(btVector3& p1, btVector3& p2) ;
+
+	 int numVertices() const 
+	 {
+		 return m_numVertices;
+	 }
+
+
+};
+
+#endif //VoronoiSimplexSolver
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,56 @@
+ADD_SOURCE_FILES(BULLET_FILES
+
+COMPILATION_BEGIN BulletDynamicsCompilation.cpp
+
+	ConstraintSolver/btContactConstraint.cpp
+	ConstraintSolver/btConeTwistConstraint.cpp
+	ConstraintSolver/btGeneric6DofConstraint.cpp
+	ConstraintSolver/btHingeConstraint.cpp
+	ConstraintSolver/btPoint2PointConstraint.cpp
+	ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
+	ConstraintSolver/btSliderConstraint.cpp
+	ConstraintSolver/btSolve2LinearConstraint.cpp
+	ConstraintSolver/btTypedConstraint.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/btConstraintSolver.h
+	ConstraintSolver/btContactConstraint.h
+	ConstraintSolver/btContactSolverInfo.h
+	ConstraintSolver/btConeTwistConstraint.h
+	ConstraintSolver/btGeneric6DofConstraint.h
+	ConstraintSolver/btHingeConstraint.h
+	ConstraintSolver/btJacobianEntry.h
+	ConstraintSolver/btPoint2PointConstraint.h
+	ConstraintSolver/btSequentialImpulseConstraintSolver.h
+	ConstraintSolver/btSliderConstraint.h
+	ConstraintSolver/btSolve2LinearConstraint.h
+	ConstraintSolver/btSolverBody.h
+	ConstraintSolver/btSolverConstraint.h
+	ConstraintSolver/btTypedConstraint.h
+
+	Dynamics/btActionInterface.h
+	Dynamics/btContinuousDynamicsWorld.h
+	Dynamics/btDiscreteDynamicsWorld.h
+	Dynamics/btDynamicsWorld.h
+	Dynamics/btSimpleDynamicsWorld.h
+	Dynamics/btRigidBody.h
+
+	Vehicle/btRaycastVehicle.h
+	Vehicle/btVehicleRaycaster.h
+	Vehicle/btWheelInfo.h
+
+	Character/btCharacterControllerInterface.h
+	Character/btKinematicCharacterController.h
+)
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Character/btCharacterControllerInterface.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Character/btCharacterControllerInterface.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Character/btCharacterControllerInterface.h	(revision 6952)
@@ -0,0 +1,44 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.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 CHARACTER_CONTROLLER_INTERFACE_H
+#define CHARACTER_CONTROLLER_INTERFACE_H
+
+#include "LinearMath/btVector3.h"
+#include "BulletDynamics/Dynamics/btActionInterface.h"
+
+class btCollisionShape;
+class btRigidBody;
+class btCollisionWorld;
+
+class btCharacterControllerInterface : public btActionInterface
+{
+public:
+	btCharacterControllerInterface () {};
+	virtual ~btCharacterControllerInterface () {};
+	
+	virtual void	setWalkDirection(const btVector3& walkDirection) = 0;
+	virtual void	reset () = 0;
+	virtual void	warp (const btVector3& origin) = 0;
+
+	virtual void	preStep ( btCollisionWorld* collisionWorld) = 0;
+	virtual void	playerStep (btCollisionWorld* collisionWorld, btScalar dt) = 0;
+	virtual bool	canJump () const = 0;
+	virtual void	jump () = 0;
+
+	virtual bool	onGround () const = 0;
+};
+
+#endif
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Character/btKinematicCharacterController.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Character/btKinematicCharacterController.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Character/btKinematicCharacterController.cpp	(revision 6952)
@@ -0,0 +1,476 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.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 "LinearMath/btIDebugDraw.h"
+#include "BulletCollision/CollisionDispatch/btGhostObject.h"
+#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
+#include "LinearMath/btDefaultMotionState.h"
+#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) };
+
+///@todo Interact with dynamic objects,
+///Ride kinematicly animated platforms properly
+///More realistic (or maybe just a config option) falling
+/// -> Should integrate falling velocity manually and use that in stepDown()
+///Support jumping
+///Support ducking
+class btKinematicClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
+{
+public:
+	btKinematicClosestNotMeRayResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
+	{
+		m_me = me;
+	}
+
+	virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
+	{
+		if (rayResult.m_collisionObject == m_me)
+			return 1.0;
+
+		return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace);
+	}
+protected:
+	btCollisionObject* m_me;
+};
+
+class btKinematicClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
+{
+public:
+	btKinematicClosestNotMeConvexResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0))
+	{
+		m_me = me;
+	}
+
+	virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
+	{
+		if (convexResult.m_hitCollisionObject == m_me)
+			return 1.0;
+
+		return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
+	}
+protected:
+	btCollisionObject* m_me;
+};
+
+/*
+ * Returns the reflection direction of a ray going 'direction' hitting a surface with normal 'normal'
+ *
+ * from: http://www-cs-students.stanford.edu/~adityagp/final/node3.html
+ */
+btVector3 btKinematicCharacterController::computeReflectionDirection (const btVector3& direction, const btVector3& normal)
+{
+	return direction - (btScalar(2.0) * direction.dot(normal)) * normal;
+}
+
+/*
+ * Returns the portion of 'direction' that is parallel to 'normal'
+ */
+btVector3 btKinematicCharacterController::parallelComponent (const btVector3& direction, const btVector3& normal)
+{
+	btScalar magnitude = direction.dot(normal);
+	return normal * magnitude;
+}
+
+/*
+ * Returns the portion of 'direction' that is perpindicular to 'normal'
+ */
+btVector3 btKinematicCharacterController::perpindicularComponent (const btVector3& direction, const btVector3& normal)
+{
+	return direction - parallelComponent(direction, normal);
+}
+
+btKinematicCharacterController::btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, int upAxis)
+{
+	m_upAxis = upAxis;
+	m_addedMargin = 0.02f;
+	m_walkDirection.setValue(0,0,0);
+	m_useGhostObjectSweepTest = true;
+	m_ghostObject = ghostObject;
+	m_stepHeight = stepHeight;
+	m_turnAngle = btScalar(0.0);
+	m_convexShape=convexShape;	
+}
+
+btKinematicCharacterController::~btKinematicCharacterController ()
+{
+}
+
+btPairCachingGhostObject* btKinematicCharacterController::getGhostObject()
+{
+	return m_ghostObject;
+}
+
+bool btKinematicCharacterController::recoverFromPenetration ( btCollisionWorld* collisionWorld)
+{
+
+	bool penetration = false;
+
+	collisionWorld->getDispatcher()->dispatchAllCollisionPairs(m_ghostObject->getOverlappingPairCache(), collisionWorld->getDispatchInfo(), collisionWorld->getDispatcher());
+
+	m_currentPosition = m_ghostObject->getWorldTransform().getOrigin();
+	
+	btScalar maxPen = btScalar(0.0);
+	for (int i = 0; i < m_ghostObject->getOverlappingPairCache()->getNumOverlappingPairs(); i++)
+	{
+		m_manifoldArray.resize(0);
+
+		btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i];
+		
+		if (collisionPair->m_algorithm)
+			collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray);
+
+		
+		for (int j=0;j<m_manifoldArray.size();j++)
+		{
+			btPersistentManifold* manifold = m_manifoldArray[j];
+			btScalar directionSign = manifold->getBody0() == m_ghostObject ? btScalar(-1.0) : btScalar(1.0);
+			for (int p=0;p<manifold->getNumContacts();p++)
+			{
+				const btManifoldPoint&pt = manifold->getContactPoint(p);
+
+				if (pt.getDistance() < 0.0)
+				{
+					if (pt.getDistance() < maxPen)
+					{
+						maxPen = pt.getDistance();
+						m_touchingNormal = pt.m_normalWorldOnB * directionSign;//??
+
+					}
+					m_currentPosition += pt.m_normalWorldOnB * directionSign * pt.getDistance() * btScalar(0.2);
+					penetration = true;
+				} else {
+					//printf("touching %f\n", pt.getDistance());
+				}
+			}
+			
+			//manifold->clearManifold();
+		}
+	}
+	btTransform newTrans = m_ghostObject->getWorldTransform();
+	newTrans.setOrigin(m_currentPosition);
+	m_ghostObject->setWorldTransform(newTrans);
+//	printf("m_touchingNormal = %f,%f,%f\n",m_touchingNormal[0],m_touchingNormal[1],m_touchingNormal[2]);
+	return penetration;
+}
+
+void btKinematicCharacterController::stepUp ( btCollisionWorld* world)
+{
+	// phase 1: up
+	btTransform start, end;
+	m_targetPosition = m_currentPosition + upAxisDirection[m_upAxis] * m_stepHeight;
+
+	start.setIdentity ();
+	end.setIdentity ();
+
+	/* FIXME: Handle penetration properly */
+	start.setOrigin (m_currentPosition + upAxisDirection[m_upAxis] * btScalar(0.1f));
+	end.setOrigin (m_targetPosition);
+
+	btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject);
+	callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
+	callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
+	
+	if (m_useGhostObjectSweepTest)
+	{
+		m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, world->getDispatchInfo().m_allowedCcdPenetration);
+	}
+	else
+	{
+		world->convexSweepTest (m_convexShape, start, end, callback);
+	}
+	
+	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);
+	} else {
+		m_currentStepOffset = m_stepHeight;
+		m_currentPosition = m_targetPosition;
+	}
+}
+
+void btKinematicCharacterController::updateTargetPositionBasedOnCollision (const btVector3& hitNormal, btScalar tangentMag, btScalar normalMag)
+{
+	btVector3 movementDirection = m_targetPosition - m_currentPosition;
+	btScalar movementLength = movementDirection.length();
+	if (movementLength>SIMD_EPSILON)
+	{
+		movementDirection.normalize();
+
+		btVector3 reflectDir = computeReflectionDirection (movementDirection, hitNormal);
+		reflectDir.normalize();
+
+		btVector3 parallelDir, perpindicularDir;
+
+		parallelDir = parallelComponent (reflectDir, hitNormal);
+		perpindicularDir = perpindicularComponent (reflectDir, hitNormal);
+
+		m_targetPosition = m_currentPosition;
+		if (0)//tangentMag != 0.0)
+		{
+			btVector3 parComponent = parallelDir * btScalar (tangentMag*movementLength);
+//			printf("parComponent=%f,%f,%f\n",parComponent[0],parComponent[1],parComponent[2]);
+			m_targetPosition +=  parComponent;
+		}
+
+		if (normalMag != 0.0)
+		{
+			btVector3 perpComponent = perpindicularDir * btScalar (normalMag*movementLength);
+//			printf("perpComponent=%f,%f,%f\n",perpComponent[0],perpComponent[1],perpComponent[2]);
+			m_targetPosition += perpComponent;
+		}
+	} else
+	{
+//		printf("movementLength don't normalize a zero vector\n");
+	}
+}
+
+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]);
+	// phase 2: forward and strafe
+	btTransform start, end;
+	m_targetPosition = m_currentPosition + walkMove;
+	start.setIdentity ();
+	end.setIdentity ();
+	
+	btScalar fraction = 1.0;
+	btScalar distance2 = (m_currentPosition-m_targetPosition).length2();
+//	printf("distance2=%f\n",distance2);
+
+	if (m_touchingContact)
+	{
+		if (originalDir.dot(m_touchingNormal) > btScalar(0.0))
+			updateTargetPositionBasedOnCollision (m_touchingNormal);
+	}
+
+	int maxIter = 10;
+
+	while (fraction > btScalar(0.01) && maxIter-- > 0)
+	{
+		start.setOrigin (m_currentPosition);
+		end.setOrigin (m_targetPosition);
+
+		btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject);
+		callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
+		callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
+
+
+		btScalar margin = m_convexShape->getMargin();
+		m_convexShape->setMargin(margin + m_addedMargin);
+
+
+		if (m_useGhostObjectSweepTest)
+		{
+			m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
+		} else
+		{
+			collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
+		}
+		
+		m_convexShape->setMargin(margin);
+
+		
+		fraction -= callback.m_closestHitFraction;
+
+		if (callback.hasHit())
+		{	
+			// 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);
+			}
+
+			updateTargetPositionBasedOnCollision (callback.m_hitNormalWorld);
+			btVector3 currentDir = m_targetPosition - m_currentPosition;
+			distance2 = currentDir.length2();
+			if (distance2 > SIMD_EPSILON)
+			{
+				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))
+				{
+					break;
+				}
+			} else
+			{
+//				printf("currentDir: don't normalize a zero vector\n");
+				break;
+			}
+		} else {
+			// we moved whole way
+			m_currentPosition = m_targetPosition;
+		}
+
+	//	if (callback.m_closestHitFraction == 0.f)
+	//		break;
+
+	}
+}
+
+void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld, btScalar dt)
+{
+	btTransform start, end;
+
+	// 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);
+
+	start.setIdentity ();
+	end.setIdentity ();
+
+	start.setOrigin (m_currentPosition);
+	end.setOrigin (m_targetPosition);
+
+	btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject);
+	callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup;
+	callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask;
+	
+	if (m_useGhostObjectSweepTest)
+	{
+		m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
+	} else
+	{
+		collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration);
+	}
+
+	if (callback.hasHit())
+	{
+		// we dropped a fraction of the height -> hit floor
+		m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
+	} else {
+		// we dropped the full height
+		
+		m_currentPosition = m_targetPosition;
+	}
+}
+
+void btKinematicCharacterController::reset ()
+{
+}
+
+void btKinematicCharacterController::warp (const btVector3& origin)
+{
+	btTransform xform;
+	xform.setIdentity();
+	xform.setOrigin (origin);
+	m_ghostObject->setWorldTransform (xform);
+}
+
+
+void btKinematicCharacterController::preStep (  btCollisionWorld* collisionWorld)
+{
+	
+	int numPenetrationLoops = 0;
+	m_touchingContact = false;
+	while (recoverFromPenetration (collisionWorld))
+	{
+		numPenetrationLoops++;
+		m_touchingContact = true;
+		if (numPenetrationLoops > 4)
+		{
+//			printf("character could not recover from penetration = %d\n", numPenetrationLoops);
+			break;
+		}
+	}
+
+	m_currentPosition = m_ghostObject->getWorldTransform().getOrigin();
+	m_targetPosition = m_currentPosition;
+//	printf("m_targetPosition=%f,%f,%f\n",m_targetPosition[0],m_targetPosition[1],m_targetPosition[2]);
+
+	
+}
+
+void btKinematicCharacterController::playerStep (  btCollisionWorld* collisionWorld, btScalar dt)
+{
+	btTransform xform;
+	xform = m_ghostObject->getWorldTransform ();
+
+//	printf("walkDirection(%f,%f,%f)\n",walkDirection[0],walkDirection[1],walkDirection[2]);
+//	printf("walkSpeed=%f\n",walkSpeed);
+
+	stepUp (collisionWorld);
+	stepForwardAndStrafe (collisionWorld, m_walkDirection);
+	stepDown (collisionWorld, dt);
+
+	xform.setOrigin (m_currentPosition);
+	m_ghostObject->setWorldTransform (xform);
+}
+
+void btKinematicCharacterController::setFallSpeed (btScalar fallSpeed)
+{
+	m_fallSpeed = fallSpeed;
+}
+
+void btKinematicCharacterController::setJumpSpeed (btScalar jumpSpeed)
+{
+	m_jumpSpeed = jumpSpeed;
+}
+
+void btKinematicCharacterController::setMaxJumpHeight (btScalar maxJumpHeight)
+{
+	m_maxJumpHeight = maxJumpHeight;
+}
+
+bool btKinematicCharacterController::canJump () const
+{
+	return onGround();
+}
+
+void btKinematicCharacterController::jump ()
+{
+	if (!canJump())
+		return;
+
+#if 0
+	currently no jumping.
+	btTransform xform;
+	m_rigidBody->getMotionState()->getWorldTransform (xform);
+	btVector3 up = xform.getBasis()[1];
+	up.normalize ();
+	btScalar magnitude = (btScalar(1.0)/m_rigidBody->getInvMass()) * btScalar(8.0);
+	m_rigidBody->applyCentralImpulse (up * magnitude);
+#endif
+}
+
+bool btKinematicCharacterController::onGround () const
+{
+	return true;
+}
+
+
+void	btKinematicCharacterController::debugDraw(btIDebugDraw* debugDrawer)
+{
+}
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Character/btKinematicCharacterController.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Character/btKinematicCharacterController.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Character/btKinematicCharacterController.h	(revision 6952)
@@ -0,0 +1,127 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans  http://bulletphysics.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 KINEMATIC_CHARACTER_CONTROLLER_H
+#define KINEMATIC_CHARACTER_CONTROLLER_H
+
+#include "LinearMath/btVector3.h"
+
+#include "btCharacterControllerInterface.h"
+
+class btCollisionShape;
+class btRigidBody;
+class btCollisionWorld;
+class btCollisionDispatcher;
+class btPairCachingGhostObject;
+
+///btKinematicCharacterController is an object that supports a sliding motion in a world.
+///It uses a ghost object and convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations.
+///Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user.
+class btKinematicCharacterController : public btCharacterControllerInterface
+{
+protected:
+	btScalar m_halfHeight;
+	
+	btPairCachingGhostObject* m_ghostObject;
+	btConvexShape*	m_convexShape;//is also in m_ghostObject, but it needs to be convex, so we store it here to avoid upcast
+	
+	btScalar m_fallSpeed;
+	btScalar m_jumpSpeed;
+	btScalar m_maxJumpHeight;
+
+	btScalar m_turnAngle;
+	
+	btScalar m_stepHeight;
+
+	btScalar	m_addedMargin;//@todo: remove this and fix the code
+
+	///this is the desired walk direction, set by the user
+	btVector3	m_walkDirection;
+
+	//some internal variables
+	btVector3 m_currentPosition;
+	btScalar  m_currentStepOffset;
+	btVector3 m_targetPosition;
+
+	///keep track of the contact manifolds
+	btManifoldArray	m_manifoldArray;
+
+	bool m_touchingContact;
+	btVector3 m_touchingNormal;
+
+	bool	m_useGhostObjectSweepTest;
+
+	int m_upAxis;
+	
+	btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal);
+	btVector3 parallelComponent (const btVector3& direction, const btVector3& normal);
+	btVector3 perpindicularComponent (const btVector3& direction, const btVector3& normal);
+
+	bool recoverFromPenetration ( btCollisionWorld* collisionWorld);
+	void stepUp (btCollisionWorld* collisionWorld);
+	void updateTargetPositionBasedOnCollision (const btVector3& hit_normal, btScalar tangentMag = btScalar(0.0), btScalar normalMag = btScalar(1.0));
+	void stepForwardAndStrafe (btCollisionWorld* collisionWorld, const btVector3& walkMove);
+	void stepDown (btCollisionWorld* collisionWorld, btScalar dt);
+public:
+	btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, int upAxis = 1);
+	~btKinematicCharacterController ();
+	
+
+	///btActionInterface interface
+	virtual void updateAction( btCollisionWorld* collisionWorld,btScalar deltaTime)
+	{
+		preStep ( collisionWorld);
+		playerStep (collisionWorld, deltaTime);
+	}
+	
+	///btActionInterface interface
+	void	debugDraw(btIDebugDraw* debugDrawer);
+
+	void setUpAxis (int axis)
+	{
+		if (axis < 0)
+			axis = 0;
+		if (axis > 2)
+			axis = 2;
+		m_upAxis = axis;
+	}
+
+	virtual void	setWalkDirection(const btVector3& walkDirection)
+	{
+		m_walkDirection = walkDirection;
+	}
+
+	void reset ();
+	void warp (const btVector3& origin);
+
+	void preStep (  btCollisionWorld* collisionWorld);
+	void playerStep ( btCollisionWorld* collisionWorld, btScalar dt);
+
+	void setFallSpeed (btScalar fallSpeed);
+	void setJumpSpeed (btScalar jumpSpeed);
+	void setMaxJumpHeight (btScalar maxJumpHeight);
+	bool canJump () const;
+	void jump ();
+
+	btPairCachingGhostObject* getGhostObject();
+	void	setUseGhostSweepTest(bool useGhostObjectSweepTest)
+	{
+		m_useGhostObjectSweepTest = useGhostObjectSweepTest;
+	}
+
+	bool onGround () const;
+};
+
+#endif // KINEMATIC_CHARACTER_CONTROLLER_H
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp	(revision 6952)
@@ -0,0 +1,989 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+btConeTwistConstraint is Copyright (c) 2007 Starbreeze Studios
+
+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.
+
+Written by: Marcus Hennix
+*/
+
+
+#include "btConeTwistConstraint.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "LinearMath/btTransformUtil.h"
+#include "LinearMath/btMinMax.h"
+#include <new>
+
+//-----------------------------------------------------------------------------
+
+#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)
+{
+}
+
+
+btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB, 
+											 const btTransform& rbAFrame,const btTransform& rbBFrame)
+											 :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE, rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame),
+											 m_angularOnly(false),
+											 m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER)
+{
+	init();
+}
+
+btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame)
+											:btTypedConstraint(CONETWIST_CONSTRAINT_TYPE,rbA),m_rbAFrame(rbAFrame),
+											 m_angularOnly(false),
+											 m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER)
+{
+	m_rbBFrame = m_rbAFrame;
+	init();	
+}
+
+
+void btConeTwistConstraint::init()
+{
+	m_angularOnly = false;
+	m_solveTwistLimit = false;
+	m_solveSwingLimit = false;
+	m_bMotorEnabled = false;
+	m_maxMotorImpulse = btScalar(-1);
+
+	setLimit(btScalar(1e30), btScalar(1e30), btScalar(1e30));
+	m_damping = btScalar(0.01);
+	m_fixThresh = CONETWIST_DEF_FIX_THRESH;
+}
+
+
+//-----------------------------------------------------------------------------
+
+void btConeTwistConstraint::getInfo1 (btConstraintInfo1* info)
+{
+	if (m_useSolveConstraintObsolete)
+	{
+		info->m_numConstraintRows = 0;
+		info->nub = 0;
+	} 
+	else
+	{
+		info->m_numConstraintRows = 3;
+		info->nub = 3;
+		calcAngleInfo2();
+		if(m_solveSwingLimit)
+		{
+			info->m_numConstraintRows++;
+			info->nub--;
+			if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh))
+			{
+				info->m_numConstraintRows++;
+				info->nub--;
+			}
+		}
+		if(m_solveTwistLimit)
+		{
+			info->m_numConstraintRows++;
+			info->nub--;
+		}
+	}
+} // btConeTwistConstraint::getInfo1()
+	
+//-----------------------------------------------------------------------------
+
+void btConeTwistConstraint::getInfo2 (btConstraintInfo2* info)
+{
+	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* angular0 = (btVector3*)(info->m_J1angularAxis);
+		btVector3* angular1 = (btVector3*)(info->m_J1angularAxis+info->rowskip);
+		btVector3* angular2 = (btVector3*)(info->m_J1angularAxis+2*info->rowskip);
+		btVector3 a1neg = -a1;
+		a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2);
+	}
+	btVector3 a2 = body1_trans.getBasis() * m_rbBFrame.getOrigin();
+	{
+		btVector3* angular0 = (btVector3*)(info->m_J2angularAxis);
+		btVector3* angular1 = (btVector3*)(info->m_J2angularAxis+info->rowskip);
+		btVector3* angular2 = (btVector3*)(info->m_J2angularAxis+2*info->rowskip);
+		a2.getSkewSymmetricMatrix(angular0,angular1,angular2);
+	}
+    // set right hand side
+    btScalar k = info->fps * info->erp;
+    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_lowerLimit[j*info->rowskip] = -SIMD_INFINITY;
+		info->m_upperLimit[j*info->rowskip] = SIMD_INFINITY;
+    }
+	int row = 3;
+    int srow = row * info->rowskip;
+	btVector3 ax1;
+	// angular limits
+	if(m_solveSwingLimit)
+	{
+		btScalar *J1 = info->m_J1angularAxis;
+		btScalar *J2 = info->m_J2angularAxis;
+		if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh))
+		{
+			btTransform trA = m_rbA.getCenterOfMassTransform()*m_rbAFrame;
+			btVector3 p = trA.getBasis().getColumn(1);
+			btVector3 q = trA.getBasis().getColumn(2);
+			int srow1 = srow + info->rowskip;
+			J1[srow+0] = p[0];
+			J1[srow+1] = p[1];
+			J1[srow+2] = p[2];
+			J1[srow1+0] = q[0];
+			J1[srow1+1] = q[1];
+			J1[srow1+2] = q[2];
+			J2[srow+0] = -p[0];
+			J2[srow+1] = -p[1];
+			J2[srow+2] = -p[2];
+			J2[srow1+0] = -q[0];
+			J2[srow1+1] = -q[1];
+			J2[srow1+2] = -q[2];
+			btScalar fact = info->fps * m_relaxationFactor;
+			info->m_constraintError[srow] =   fact * m_swingAxis.dot(p);
+			info->m_constraintError[srow1] =  fact * m_swingAxis.dot(q);
+			info->m_lowerLimit[srow] = -SIMD_INFINITY;
+			info->m_upperLimit[srow] = SIMD_INFINITY;
+			info->m_lowerLimit[srow1] = -SIMD_INFINITY;
+			info->m_upperLimit[srow1] = SIMD_INFINITY;
+			srow = srow1 + info->rowskip;
+		}
+		else
+		{
+			ax1 = m_swingAxis * m_relaxationFactor * m_relaxationFactor;
+			J1[srow+0] = ax1[0];
+			J1[srow+1] = ax1[1];
+			J1[srow+2] = ax1[2];
+			J2[srow+0] = -ax1[0];
+			J2[srow+1] = -ax1[1];
+			J2[srow+2] = -ax1[2];
+			btScalar k = info->fps * m_biasFactor;
+
+			info->m_constraintError[srow] = k * m_swingCorrection;
+			info->cfm[srow] = 0.0f;
+			// m_swingCorrection is always positive or 0
+			info->m_lowerLimit[srow] = 0;
+			info->m_upperLimit[srow] = SIMD_INFINITY;
+			srow += info->rowskip;
+		}
+	}
+	if(m_solveTwistLimit)
+	{
+		ax1 = m_twistAxis * m_relaxationFactor * m_relaxationFactor;
+		btScalar *J1 = info->m_J1angularAxis;
+		btScalar *J2 = info->m_J2angularAxis;
+		J1[srow+0] = ax1[0];
+		J1[srow+1] = ax1[1];
+		J1[srow+2] = ax1[2];
+		J2[srow+0] = -ax1[0];
+		J2[srow+1] = -ax1[1];
+		J2[srow+2] = -ax1[2];
+		btScalar k = info->fps * m_biasFactor;
+		info->m_constraintError[srow] = k * m_twistCorrection;
+		info->cfm[srow] = 0.0f;
+		if(m_twistSpan > 0.0f)
+		{
+
+			if(m_twistCorrection > 0.0f)
+			{
+				info->m_lowerLimit[srow] = 0;
+				info->m_upperLimit[srow] = SIMD_INFINITY;
+			} 
+			else
+			{
+				info->m_lowerLimit[srow] = -SIMD_INFINITY;
+				info->m_upperLimit[srow] = 0;
+			} 
+		}
+		else
+		{
+			info->m_lowerLimit[srow] = -SIMD_INFINITY;
+			info->m_upperLimit[srow] = SIMD_INFINITY;
+		}
+		srow += info->rowskip;
+	}
+}
+	
+//-----------------------------------------------------------------------------
+
+void	btConeTwistConstraint::buildJacobian()
+{
+	if (m_useSolveConstraintObsolete)
+	{
+		m_appliedImpulse = btScalar(0.);
+		m_accTwistLimitImpulse = btScalar(0.);
+		m_accSwingLimitImpulse = btScalar(0.);
+
+		if (!m_angularOnly)
+		{
+			btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin();
+			btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin();
+			btVector3 relPos = pivotBInW - pivotAInW;
+
+			btVector3 normal[3];
+			if (relPos.length2() > SIMD_EPSILON)
+			{
+				normal[0] = relPos.normalized();
+			}
+			else
+			{
+				normal[0].setValue(btScalar(1.0),0,0);
+			}
+
+			btPlaneSpace1(normal[0], normal[1], normal[2]);
+
+			for (int i=0;i<3;i++)
+			{
+				new (&m_jac[i]) btJacobianEntry(
+				m_rbA.getCenterOfMassTransform().getBasis().transpose(),
+				m_rbB.getCenterOfMassTransform().getBasis().transpose(),
+				pivotAInW - m_rbA.getCenterOfMassPosition(),
+				pivotBInW - m_rbB.getCenterOfMassPosition(),
+				normal[i],
+				m_rbA.getInvInertiaDiagLocal(),
+				m_rbA.getInvMass(),
+				m_rbB.getInvInertiaDiagLocal(),
+				m_rbB.getInvMass());
+			}
+		}
+
+		calcAngleInfo2();
+	}
+}
+
+//-----------------------------------------------------------------------------
+
+void	btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep)
+{
+	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;
+			bodyA.getVelocityInLocalPointObsolete(rel_pos1,vel1);
+			btVector3 vel2;
+			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 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);
+		
+			}
+		}
+
+		// apply motor
+		if (m_bMotorEnabled)
+		{
+			// compute current and predicted transforms
+			btTransform trACur = m_rbA.getCenterOfMassTransform();
+			btTransform trBCur = m_rbB.getCenterOfMassTransform();
+			btVector3 omegaA; bodyA.getAngularVelocity(omegaA);
+			btVector3 omegaB; bodyB.getAngularVelocity(omegaB);
+			btTransform trAPred; trAPred.setIdentity(); 
+			btVector3 zerovec(0,0,0);
+			btTransformUtil::integrateTransform(
+				trACur, zerovec, omegaA, timeStep, trAPred);
+			btTransform trBPred; trBPred.setIdentity(); 
+			btTransformUtil::integrateTransform(
+				trBCur, zerovec, omegaB, timeStep, trBPred);
+
+			// compute desired transforms in world
+			btTransform trPose(m_qTarget);
+			btTransform trABDes = m_rbBFrame * trPose * m_rbAFrame.inverse();
+			btTransform trADes = trBPred * trABDes;
+			btTransform trBDes = trAPred * trABDes.inverse();
+
+			// compute desired omegas in world
+			btVector3 omegaADes, omegaBDes;
+			
+			btTransformUtil::calculateVelocity(trACur, trADes, timeStep, zerovec, omegaADes);
+			btTransformUtil::calculateVelocity(trBCur, trBDes, timeStep, zerovec, omegaBDes);
+
+			// compute delta omegas
+			btVector3 dOmegaA = omegaADes - omegaA;
+			btVector3 dOmegaB = omegaBDes - omegaB;
+
+			// compute weighted avg axis of dOmega (weighting based on inertias)
+			btVector3 axisA, axisB;
+			btScalar kAxisAInv = 0, kAxisBInv = 0;
+
+			if (dOmegaA.length2() > SIMD_EPSILON)
+			{
+				axisA = dOmegaA.normalized();
+				kAxisAInv = getRigidBodyA().computeAngularImpulseDenominator(axisA);
+			}
+
+			if (dOmegaB.length2() > SIMD_EPSILON)
+			{
+				axisB = dOmegaB.normalized();
+				kAxisBInv = getRigidBodyB().computeAngularImpulseDenominator(axisB);
+			}
+
+			btVector3 avgAxis = kAxisAInv * axisA + kAxisBInv * axisB;
+
+			static bool bDoTorque = true;
+			if (bDoTorque && avgAxis.length2() > SIMD_EPSILON)
+			{
+				avgAxis.normalize();
+				kAxisAInv = getRigidBodyA().computeAngularImpulseDenominator(avgAxis);
+				kAxisBInv = getRigidBodyB().computeAngularImpulseDenominator(avgAxis);
+				btScalar kInvCombined = kAxisAInv + kAxisBInv;
+
+				btVector3 impulse = (kAxisAInv * dOmegaA - kAxisBInv * dOmegaB) /
+									(kInvCombined * kInvCombined);
+
+				if (m_maxMotorImpulse >= 0)
+				{
+					btScalar fMaxImpulse = m_maxMotorImpulse;
+					if (m_bNormalizedMotorStrength)
+						fMaxImpulse = fMaxImpulse/kAxisAInv;
+
+					btVector3 newUnclampedAccImpulse = m_accMotorImpulse + impulse;
+					btScalar  newUnclampedMag = newUnclampedAccImpulse.length();
+					if (newUnclampedMag > fMaxImpulse)
+					{
+						newUnclampedAccImpulse.normalize();
+						newUnclampedAccImpulse *= fMaxImpulse;
+						impulse = newUnclampedAccImpulse - m_accMotorImpulse;
+					}
+					m_accMotorImpulse += impulse;
+				}
+
+				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);
+
+			}
+		}
+		else // no motor: do a little damping
+		{
+			const btVector3& angVelA = getRigidBodyA().getAngularVelocity();
+			const btVector3& angVelB = getRigidBodyB().getAngularVelocity();
+			btVector3 relVel = angVelB - angVelA;
+			if (relVel.length2() > SIMD_EPSILON)
+			{
+				btVector3 relVelAxis = relVel.normalized();
+				btScalar m_kDamping =  btScalar(1.) /
+					(getRigidBodyA().computeAngularImpulseDenominator(relVelAxis) +
+					 getRigidBodyB().computeAngularImpulseDenominator(relVelAxis));
+				btVector3 impulse = m_damping * m_kDamping * relVel;
+
+				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);
+			}
+		}
+
+		// joint limits
+		{
+			///solve angular part
+			btVector3 angVelA;
+			bodyA.getAngularVelocity(angVelA);
+			btVector3 angVelB;
+			bodyB.getAngularVelocity(angVelB);
+
+			// solve swing limit
+			if (m_solveSwingLimit)
+			{
+				btScalar amplitude = m_swingLimitRatio * m_swingCorrection*m_biasFactor/timeStep;
+				btScalar relSwingVel = (angVelB - angVelA).dot(m_swingAxis);
+				if (relSwingVel > 0)
+					amplitude += m_swingLimitRatio * relSwingVel * m_relaxationFactor;
+				btScalar impulseMag = amplitude * m_kSwing;
+
+				// Clamp the accumulated impulse
+				btScalar temp = m_accSwingLimitImpulse;
+				m_accSwingLimitImpulse = btMax(m_accSwingLimitImpulse + impulseMag, btScalar(0.0) );
+				impulseMag = m_accSwingLimitImpulse - temp;
+
+				btVector3 impulse = m_swingAxis * impulseMag;
+
+				// don't let cone response affect twist
+				// (this can happen since body A's twist doesn't match body B's AND we use an elliptical cone limit)
+				{
+					btVector3 impulseTwistCouple = impulse.dot(m_twistAxisA) * m_twistAxisA;
+					btVector3 impulseNoTwistCouple = impulse - impulseTwistCouple;
+					impulse = impulseNoTwistCouple;
+				}
+
+				impulseMag = impulse.length();
+				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);
+			}
+
+
+			// solve twist limit
+			if (m_solveTwistLimit)
+			{
+				btScalar amplitude = m_twistLimitRatio * m_twistCorrection*m_biasFactor/timeStep;
+				btScalar relTwistVel = (angVelB - angVelA).dot( m_twistAxis );
+				if (relTwistVel > 0) // only damp when moving towards limit (m_twistAxis flipping is important)
+					amplitude += m_twistLimitRatio * relTwistVel * m_relaxationFactor;
+				btScalar impulseMag = amplitude * m_kTwist;
+
+				// Clamp the accumulated impulse
+				btScalar temp = m_accTwistLimitImpulse;
+				m_accTwistLimitImpulse = btMax(m_accTwistLimitImpulse + impulseMag, btScalar(0.0) );
+				impulseMag = m_accTwistLimitImpulse - temp;
+
+				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);
+			}		
+		}
+	}
+
+}
+
+//-----------------------------------------------------------------------------
+
+void	btConeTwistConstraint::updateRHS(btScalar	timeStep)
+{
+	(void)timeStep;
+
+}
+
+//-----------------------------------------------------------------------------
+
+void btConeTwistConstraint::calcAngleInfo()
+{
+	m_swingCorrection = btScalar(0.);
+	m_twistLimitSign = btScalar(0.);
+	m_solveTwistLimit = false;
+	m_solveSwingLimit = false;
+
+	btVector3 b1Axis1,b1Axis2,b1Axis3;
+	btVector3 b2Axis1,b2Axis2;
+
+	b1Axis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(0);
+	b2Axis1 = getRigidBodyB().getCenterOfMassTransform().getBasis() * this->m_rbBFrame.getBasis().getColumn(0);
+
+	btScalar swing1=btScalar(0.),swing2 = btScalar(0.);
+
+	btScalar swx=btScalar(0.),swy = btScalar(0.);
+	btScalar thresh = btScalar(10.);
+	btScalar fact;
+
+	// Get Frame into world space
+	if (m_swingSpan1 >= btScalar(0.05f))
+	{
+		b1Axis2 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(1);
+		swx = b2Axis1.dot(b1Axis1);
+		swy = b2Axis1.dot(b1Axis2);
+		swing1  = btAtan2Fast(swy, swx);
+		fact = (swy*swy + swx*swx) * thresh * thresh;
+		fact = fact / (fact + btScalar(1.0));
+		swing1 *= fact; 
+	}
+
+	if (m_swingSpan2 >= btScalar(0.05f))
+	{
+		b1Axis3 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(2);			
+		swx = b2Axis1.dot(b1Axis1);
+		swy = b2Axis1.dot(b1Axis3);
+		swing2  = btAtan2Fast(swy, swx);
+		fact = (swy*swy + swx*swx) * thresh * thresh;
+		fact = fact / (fact + btScalar(1.0));
+		swing2 *= fact; 
+	}
+
+	btScalar RMaxAngle1Sq = 1.0f / (m_swingSpan1*m_swingSpan1);		
+	btScalar RMaxAngle2Sq = 1.0f / (m_swingSpan2*m_swingSpan2);	
+	btScalar EllipseAngle = btFabs(swing1*swing1)* RMaxAngle1Sq + btFabs(swing2*swing2) * RMaxAngle2Sq;
+
+	if (EllipseAngle > 1.0f)
+	{
+		m_swingCorrection = EllipseAngle-1.0f;
+		m_solveSwingLimit = true;
+		// Calculate necessary axis & factors
+		m_swingAxis = b2Axis1.cross(b1Axis2* b2Axis1.dot(b1Axis2) + b1Axis3* b2Axis1.dot(b1Axis3));
+		m_swingAxis.normalize();
+		btScalar swingAxisSign = (b2Axis1.dot(b1Axis1) >= 0.0f) ? 1.0f : -1.0f;
+		m_swingAxis *= swingAxisSign;
+	}
+
+	// Twist limits
+	if (m_twistSpan >= btScalar(0.))
+	{
+		btVector3 b2Axis2 = getRigidBodyB().getCenterOfMassTransform().getBasis() * this->m_rbBFrame.getBasis().getColumn(1);
+		btQuaternion rotationArc = shortestArcQuat(b2Axis1,b1Axis1);
+		btVector3 TwistRef = quatRotate(rotationArc,b2Axis2); 
+		btScalar twist = btAtan2Fast( TwistRef.dot(b1Axis3), TwistRef.dot(b1Axis2) );
+		m_twistAngle = twist;
+
+//		btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? m_limitSoftness : btScalar(0.);
+		btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? btScalar(1.0f) : btScalar(0.);
+		if (twist <= -m_twistSpan*lockedFreeFactor)
+		{
+			m_twistCorrection = -(twist + m_twistSpan);
+			m_solveTwistLimit = true;
+			m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f;
+			m_twistAxis.normalize();
+			m_twistAxis *= -1.0f;
+		}
+		else if (twist >  m_twistSpan*lockedFreeFactor)
+		{
+			m_twistCorrection = (twist - m_twistSpan);
+			m_solveTwistLimit = true;
+			m_twistAxis = (b2Axis1 + b1Axis1) * 0.5f;
+			m_twistAxis.normalize();
+		}
+	}
+} // btConeTwistConstraint::calcAngleInfo()
+
+
+static btVector3 vTwist(1,0,0); // twist axis in constraint's space
+
+//-----------------------------------------------------------------------------
+
+void btConeTwistConstraint::calcAngleInfo2()
+{
+	m_swingCorrection = btScalar(0.);
+	m_twistLimitSign = btScalar(0.);
+	m_solveTwistLimit = false;
+	m_solveSwingLimit = false;
+
+	{
+		// 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 qAB = qB.inverse() * qA;
+
+		// split rotation into cone and twist
+		// (all this is done from B's perspective. Maybe I should be averaging axes...)
+		btVector3 vConeNoTwist = quatRotate(qAB, vTwist); vConeNoTwist.normalize();
+		btQuaternion qABCone  = shortestArcQuat(vTwist, vConeNoTwist); qABCone.normalize();
+		btQuaternion qABTwist = qABCone.inverse() * qAB; qABTwist.normalize();
+
+		if (m_swingSpan1 >= m_fixThresh && m_swingSpan2 >= m_fixThresh)
+		{
+			btScalar swingAngle, swingLimit = 0; btVector3 swingAxis;
+			computeConeLimitInfo(qABCone, swingAngle, swingAxis, swingLimit);
+
+			if (swingAngle > swingLimit * m_limitSoftness)
+			{
+				m_solveSwingLimit = true;
+
+				// compute limit ratio: 0->1, where
+				// 0 == beginning of soft limit
+				// 1 == hard/real limit
+				m_swingLimitRatio = 1.f;
+				if (swingAngle < swingLimit && m_limitSoftness < 1.f - SIMD_EPSILON)
+				{
+					m_swingLimitRatio = (swingAngle - swingLimit * m_limitSoftness)/
+										(swingLimit - swingLimit * m_limitSoftness);
+				}				
+
+				// swing correction tries to get back to soft limit
+				m_swingCorrection = swingAngle - (swingLimit * m_limitSoftness);
+
+				// adjustment of swing axis (based on ellipse normal)
+				adjustSwingAxisToUseEllipseNormal(swingAxis);
+
+				// Calculate necessary axis & factors		
+				m_swingAxis = quatRotate(qB, -swingAxis);
+
+				m_twistAxisA.setValue(0,0,0);
+
+				m_kSwing =  btScalar(1.) /
+					(getRigidBodyA().computeAngularImpulseDenominator(m_swingAxis) +
+					 getRigidBodyB().computeAngularImpulseDenominator(m_swingAxis));
+			}
+		}
+		else
+		{
+			// you haven't set any limits;
+			// 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 target;
+			btScalar x = ivB.dot(ivA);
+			btScalar y = ivB.dot(jvA);
+			btScalar z = ivB.dot(kvA);
+			if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh))
+			{ // fixed. We'll need to add one more row to constraint
+				if((!btFuzzyZero(y)) || (!(btFuzzyZero(z))))
+				{
+					m_solveSwingLimit = true;
+					m_swingAxis = -ivB.cross(ivA);
+				}
+			}
+			else
+			{
+				if(m_swingSpan1 < m_fixThresh)
+				{ // hinge around Y axis
+					if(!(btFuzzyZero(y)))
+					{
+						m_solveSwingLimit = true;
+						if(m_swingSpan2 >= m_fixThresh)
+						{
+							y = btScalar(0.f);
+							btScalar span2 = btAtan2(z, x);
+							if(span2 > m_swingSpan2)
+							{
+								x = btCos(m_swingSpan2);
+								z = btSin(m_swingSpan2);
+							}
+							else if(span2 < -m_swingSpan2)
+							{
+								x =  btCos(m_swingSpan2);
+								z = -btSin(m_swingSpan2);
+							}
+						}
+					}
+				}
+				else
+				{ // hinge around Z axis
+					if(!btFuzzyZero(z))
+					{
+						m_solveSwingLimit = true;
+						if(m_swingSpan1 >= m_fixThresh)
+						{
+							z = btScalar(0.f);
+							btScalar span1 = btAtan2(y, x);
+							if(span1 > m_swingSpan1)
+							{
+								x = btCos(m_swingSpan1);
+								y = btSin(m_swingSpan1);
+							}
+							else if(span1 < -m_swingSpan1)
+							{
+								x =  btCos(m_swingSpan1);
+								y = -btSin(m_swingSpan1);
+							}
+						}
+					}
+				}
+				target[0] = x * ivA[0] + y * jvA[0] + z * kvA[0];
+				target[1] = x * ivA[1] + y * jvA[1] + z * kvA[1];
+				target[2] = x * ivA[2] + y * jvA[2] + z * kvA[2];
+				target.normalize();
+				m_swingAxis = -ivB.cross(target);
+				m_swingCorrection = m_swingAxis.length();
+				m_swingAxis.normalize();
+			}
+		}
+
+		if (m_twistSpan >= btScalar(0.f))
+		{
+			btVector3 twistAxis;
+			computeTwistLimitInfo(qABTwist, m_twistAngle, twistAxis);
+
+			if (m_twistAngle > m_twistSpan*m_limitSoftness)
+			{
+				m_solveTwistLimit = true;
+
+				m_twistLimitRatio = 1.f;
+				if (m_twistAngle < m_twistSpan && m_limitSoftness < 1.f - SIMD_EPSILON)
+				{
+					m_twistLimitRatio = (m_twistAngle - m_twistSpan * m_limitSoftness)/
+										(m_twistSpan  - m_twistSpan * m_limitSoftness);
+				}
+
+				// twist correction tries to get back to soft limit
+				m_twistCorrection = m_twistAngle - (m_twistSpan * m_limitSoftness);
+
+				m_twistAxis = quatRotate(qB, -twistAxis);
+
+				m_kTwist = btScalar(1.) /
+					(getRigidBodyA().computeAngularImpulseDenominator(m_twistAxis) +
+					 getRigidBodyB().computeAngularImpulseDenominator(m_twistAxis));
+			}
+
+			if (m_solveSwingLimit)
+				m_twistAxisA = quatRotate(qA, -twistAxis);
+		}
+		else
+		{
+			m_twistAngle = btScalar(0.f);
+		}
+	}
+} // btConeTwistConstraint::calcAngleInfo2()
+
+
+
+// given a cone rotation in constraint space, (pre: twist must already be removed)
+// this method computes its corresponding swing angle and axis.
+// more interestingly, it computes the cone/swing limit (angle) for this cone "pose".
+void btConeTwistConstraint::computeConeLimitInfo(const btQuaternion& qCone,
+												 btScalar& swingAngle, // out
+												 btVector3& vSwingAxis, // out
+												 btScalar& swingLimit) // out
+{
+	swingAngle = qCone.getAngle();
+	if (swingAngle > SIMD_EPSILON)
+	{
+		vSwingAxis = btVector3(qCone.x(), qCone.y(), qCone.z());
+		vSwingAxis.normalize();
+		if (fabs(vSwingAxis.x()) > SIMD_EPSILON)
+		{
+			// non-zero twist?! this should never happen.
+			int wtf = 0; wtf = wtf;
+		}
+
+		// Compute limit for given swing. tricky:
+		// Given a swing axis, we're looking for the intersection with the bounding cone ellipse.
+		// (Since we're dealing with angles, this ellipse is embedded on the surface of a sphere.)
+
+		// For starters, compute the direction from center to surface of ellipse.
+		// This is just the perpendicular (ie. rotate 2D vector by PI/2) of the swing axis.
+		// (vSwingAxis is the cone rotation (in z,y); change vars and rotate to (x,y) coords.)
+		btScalar xEllipse =  vSwingAxis.y();
+		btScalar yEllipse = -vSwingAxis.z();
+
+		// Now, we use the slope of the vector (using x/yEllipse) and find the length
+		// of the line that intersects the ellipse:
+		//  x^2   y^2
+		//  --- + --- = 1, where a and b are semi-major axes 2 and 1 respectively (ie. the limits)
+		//  a^2   b^2
+		// Do the math and it should be clear.
+
+		swingLimit = m_swingSpan1; // if xEllipse == 0, we have a pure vSwingAxis.z rotation: just use swingspan1
+		if (fabs(xEllipse) > SIMD_EPSILON)
+		{
+			btScalar surfaceSlope2 = (yEllipse*yEllipse)/(xEllipse*xEllipse);
+			btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2);
+			norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1);
+			btScalar swingLimit2 = (1 + surfaceSlope2) / norm;
+			swingLimit = sqrt(swingLimit2);
+		}
+
+		// test!
+		/*swingLimit = m_swingSpan2;
+		if (fabs(vSwingAxis.z()) > SIMD_EPSILON)
+		{
+		btScalar mag_2 = m_swingSpan1*m_swingSpan1 + m_swingSpan2*m_swingSpan2;
+		btScalar sinphi = m_swingSpan2 / sqrt(mag_2);
+		btScalar phi = asin(sinphi);
+		btScalar theta = atan2(fabs(vSwingAxis.y()),fabs(vSwingAxis.z()));
+		btScalar alpha = 3.14159f - theta - phi;
+		btScalar sinalpha = sin(alpha);
+		swingLimit = m_swingSpan1 * sinphi/sinalpha;
+		}*/
+	}
+	else if (swingAngle < 0)
+	{
+		// this should never happen!
+		int wtf = 0; wtf = wtf;
+	}
+}
+
+btVector3 btConeTwistConstraint::GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const
+{
+	// compute x/y in ellipse using cone angle (0 -> 2*PI along surface of cone)
+	btScalar xEllipse = btCos(fAngleInRadians);
+	btScalar yEllipse = btSin(fAngleInRadians);
+
+	// Use the slope of the vector (using x/yEllipse) and find the length
+	// of the line that intersects the ellipse:
+	//  x^2   y^2
+	//  --- + --- = 1, where a and b are semi-major axes 2 and 1 respectively (ie. the limits)
+	//  a^2   b^2
+	// Do the math and it should be clear.
+
+	float swingLimit = m_swingSpan1; // if xEllipse == 0, just use axis b (1)
+	if (fabs(xEllipse) > SIMD_EPSILON)
+	{
+		btScalar surfaceSlope2 = (yEllipse*yEllipse)/(xEllipse*xEllipse);
+		btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2);
+		norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1);
+		btScalar swingLimit2 = (1 + surfaceSlope2) / norm;
+		swingLimit = sqrt(swingLimit2);
+	}
+
+	// convert into point in constraint space:
+	// note: twist is x-axis, swing 1 and 2 are along the z and y axes respectively
+	btVector3 vSwingAxis(0, xEllipse, -yEllipse);
+	btQuaternion qSwing(vSwingAxis, swingLimit);
+	btVector3 vPointInConstraintSpace(fLength,0,0);
+	return quatRotate(qSwing, vPointInConstraintSpace);
+}
+
+// given a twist rotation in constraint space, (pre: cone must already be removed)
+// this method computes its corresponding angle and axis.
+void btConeTwistConstraint::computeTwistLimitInfo(const btQuaternion& qTwist,
+												  btScalar& twistAngle, // out
+												  btVector3& vTwistAxis) // out
+{
+	btQuaternion qMinTwist = qTwist;
+	twistAngle = qTwist.getAngle();
+
+	if (twistAngle > SIMD_PI) // long way around. flip quat and recalculate.
+	{
+		qMinTwist = operator-(qTwist);
+		twistAngle = qMinTwist.getAngle();
+	}
+	if (twistAngle < 0)
+	{
+		// this should never happen
+		int wtf = 0; wtf = wtf;			
+	}
+
+	vTwistAxis = btVector3(qMinTwist.x(), qMinTwist.y(), qMinTwist.z());
+	if (twistAngle > SIMD_EPSILON)
+		vTwistAxis.normalize();
+}
+
+
+void btConeTwistConstraint::adjustSwingAxisToUseEllipseNormal(btVector3& vSwingAxis) const
+{
+	// the swing axis is computed as the "twist-free" cone rotation,
+	// but the cone limit is not circular, but elliptical (if swingspan1 != swingspan2).
+	// so, if we're outside the limits, the closest way back inside the cone isn't 
+	// along the vector back to the center. better (and more stable) to use the ellipse normal.
+
+	// convert swing axis to direction from center to surface of ellipse
+	// (ie. rotate 2D vector by PI/2)
+	btScalar y = -vSwingAxis.z();
+	btScalar z =  vSwingAxis.y();
+
+	// do the math...
+	if (fabs(z) > SIMD_EPSILON) // avoid division by 0. and we don't need an update if z == 0.
+	{
+		// compute gradient/normal of ellipse surface at current "point"
+		btScalar grad = y/z;
+		grad *= m_swingSpan2 / m_swingSpan1;
+
+		// adjust y/z to represent normal at point (instead of vector to point)
+		if (y > 0)
+			y =  fabs(grad * z);
+		else
+			y = -fabs(grad * z);
+
+		// convert ellipse direction back to swing axis
+		vSwingAxis.setZ(-y);
+		vSwingAxis.setY( z);
+		vSwingAxis.normalize();
+	}
+}
+
+
+
+void btConeTwistConstraint::setMotorTarget(const btQuaternion &q)
+{
+	btTransform trACur = m_rbA.getCenterOfMassTransform();
+	btTransform trBCur = m_rbB.getCenterOfMassTransform();
+	btTransform trABCur = trBCur.inverse() * trACur;
+	btQuaternion qABCur = trABCur.getRotation();
+	btTransform trConstraintCur = (trBCur * m_rbBFrame).inverse() * (trACur * m_rbAFrame);
+	btQuaternion qConstraintCur = trConstraintCur.getRotation();
+
+	btQuaternion qConstraint = m_rbBFrame.getRotation().inverse() * q * m_rbAFrame.getRotation();
+	setMotorTargetInConstraintSpace(qConstraint);
+}
+
+
+void btConeTwistConstraint::setMotorTargetInConstraintSpace(const btQuaternion &q)
+{
+	m_qTarget = q;
+
+	// clamp motor target to within limits
+	{
+		btScalar softness = 1.f;//m_limitSoftness;
+
+		// split into twist and cone
+		btVector3 vTwisted = quatRotate(m_qTarget, vTwist);
+		btQuaternion qTargetCone  = shortestArcQuat(vTwist, vTwisted); qTargetCone.normalize();
+		btQuaternion qTargetTwist = qTargetCone.inverse() * m_qTarget; qTargetTwist.normalize();
+
+		// clamp cone
+		if (m_swingSpan1 >= btScalar(0.05f) && m_swingSpan2 >= btScalar(0.05f))
+		{
+			btScalar swingAngle, swingLimit; btVector3 swingAxis;
+			computeConeLimitInfo(qTargetCone, swingAngle, swingAxis, swingLimit);
+
+			if (fabs(swingAngle) > SIMD_EPSILON)
+			{
+				if (swingAngle > swingLimit*softness)
+					swingAngle = swingLimit*softness;
+				else if (swingAngle < -swingLimit*softness)
+					swingAngle = -swingLimit*softness;
+				qTargetCone = btQuaternion(swingAxis, swingAngle);
+			}
+		}
+
+		// clamp twist
+		if (m_twistSpan >= btScalar(0.05f))
+		{
+			btScalar twistAngle; btVector3 twistAxis;
+			computeTwistLimitInfo(qTargetTwist, twistAngle, twistAxis);
+
+			if (fabs(twistAngle) > SIMD_EPSILON)
+			{
+				// eddy todo: limitSoftness used here???
+				if (twistAngle > m_twistSpan*softness)
+					twistAngle = m_twistSpan*softness;
+				else if (twistAngle < -m_twistSpan*softness)
+					twistAngle = -m_twistSpan*softness;
+				qTargetTwist = btQuaternion(twistAxis, twistAngle);
+			}
+		}
+
+		m_qTarget = qTargetCone * qTargetTwist;
+	}
+}
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h	(revision 6952)
@@ -0,0 +1,229 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+btConeTwistConstraint is Copyright (c) 2007 Starbreeze Studios
+
+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.
+
+Written by: Marcus Hennix
+*/
+
+
+
+#ifndef CONETWISTCONSTRAINT_H
+#define CONETWISTCONSTRAINT_H
+
+#include "LinearMath/btVector3.h"
+#include "btJacobianEntry.h"
+#include "btTypedConstraint.h"
+
+class btRigidBody;
+
+
+///btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc)
+class btConeTwistConstraint : public btTypedConstraint
+{
+#ifdef IN_PARALLELL_SOLVER
+public:
+#endif
+	btJacobianEntry	m_jac[3]; //3 orthogonal linear constraints
+
+	btTransform m_rbAFrame; 
+	btTransform m_rbBFrame;
+
+	btScalar	m_limitSoftness;
+	btScalar	m_biasFactor;
+	btScalar	m_relaxationFactor;
+
+	btScalar	m_damping;
+
+	btScalar	m_swingSpan1;
+	btScalar	m_swingSpan2;
+	btScalar	m_twistSpan;
+
+	btScalar	m_fixThresh;
+
+	btVector3   m_swingAxis;
+	btVector3	m_twistAxis;
+
+	btScalar	m_kSwing;
+	btScalar	m_kTwist;
+
+	btScalar	m_twistLimitSign;
+	btScalar	m_swingCorrection;
+	btScalar	m_twistCorrection;
+
+	btScalar	m_twistAngle;
+
+	btScalar	m_accSwingLimitImpulse;
+	btScalar	m_accTwistLimitImpulse;
+
+	bool		m_angularOnly;
+	bool		m_solveTwistLimit;
+	bool		m_solveSwingLimit;
+
+	bool	m_useSolveConstraintObsolete;
+
+	// not yet used...
+	btScalar	m_swingLimitRatio;
+	btScalar	m_twistLimitRatio;
+	btVector3   m_twistAxisA;
+
+	// motor
+	bool		 m_bMotorEnabled;
+	bool		 m_bNormalizedMotorStrength;
+	btQuaternion m_qTarget;
+	btScalar	 m_maxMotorImpulse;
+	btVector3	 m_accMotorImpulse;
+	
+public:
+
+	btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame);
+	
+	btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame);
+
+	btConeTwistConstraint();
+
+	virtual void	buildJacobian();
+
+	virtual void getInfo1 (btConstraintInfo1* info);
+	
+	virtual void getInfo2 (btConstraintInfo2* info);
+	
+
+	virtual	void	solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep);
+
+	void	updateRHS(btScalar	timeStep);
+
+	const btRigidBody& getRigidBodyA() const
+	{
+		return m_rbA;
+	}
+	const btRigidBody& getRigidBodyB() const
+	{
+		return m_rbB;
+	}
+
+	void	setAngularOnly(bool angularOnly)
+	{
+		m_angularOnly = angularOnly;
+	}
+
+	void	setLimit(int limitIndex,btScalar limitValue)
+	{
+		switch (limitIndex)
+		{
+		case 3:
+			{
+				m_twistSpan = limitValue;
+				break;
+			}
+		case 4:
+			{
+				m_swingSpan2 = limitValue;
+				break;
+			}
+		case 5:
+			{
+				m_swingSpan1 = limitValue;
+				break;
+			}
+		default:
+			{
+			}
+		};
+	}
+
+	void	setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan,  btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f)
+	{
+		m_swingSpan1 = _swingSpan1;
+		m_swingSpan2 = _swingSpan2;
+		m_twistSpan  = _twistSpan;
+
+		m_limitSoftness =  _softness;
+		m_biasFactor = _biasFactor;
+		m_relaxationFactor = _relaxationFactor;
+	}
+
+	const btTransform& getAFrame() { return m_rbAFrame; };	
+	const btTransform& getBFrame() { return m_rbBFrame; };
+
+	inline int getSolveTwistLimit()
+	{
+		return m_solveTwistLimit;
+	}
+
+	inline int getSolveSwingLimit()
+	{
+		return m_solveTwistLimit;
+	}
+
+	inline btScalar getTwistLimitSign()
+	{
+		return m_twistLimitSign;
+	}
+
+	void calcAngleInfo();
+	void calcAngleInfo2();
+
+	inline btScalar getSwingSpan1()
+	{
+		return m_swingSpan1;
+	}
+	inline btScalar getSwingSpan2()
+	{
+		return m_swingSpan2;
+	}
+	inline btScalar getTwistSpan()
+	{
+		return m_twistSpan;
+	}
+	inline btScalar getTwistAngle()
+	{
+		return m_twistAngle;
+	}
+	bool isPastSwingLimit() { return m_solveSwingLimit; }
+
+
+	void setDamping(btScalar damping) { m_damping = damping; }
+
+	void enableMotor(bool b) { m_bMotorEnabled = b; }
+	void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = false; }
+	void setMaxMotorImpulseNormalized(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = true; }
+
+	btScalar getFixThresh() { return m_fixThresh; }
+	void setFixThresh(btScalar fixThresh) { m_fixThresh = fixThresh; }
+
+	// setMotorTarget:
+	// q: the desired rotation of bodyA wrt bodyB.
+	// note: if q violates the joint limits, the internal target is clamped to avoid conflicting impulses (very bad for stability)
+	// note: don't forget to enableMotor()
+	void setMotorTarget(const btQuaternion &q);
+
+	// same as above, but q is the desired rotation of frameA wrt frameB in constraint space
+	void setMotorTargetInConstraintSpace(const btQuaternion &q);
+
+	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;
+};
+
+#endif //CONETWISTCONSTRAINT_H
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btConstraintSolver.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btConstraintSolver.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btConstraintSolver.h	(revision 6952)
@@ -0,0 +1,52 @@
+/*
+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 CONSTRAINT_SOLVER_H
+#define CONSTRAINT_SOLVER_H
+
+#include "LinearMath/btScalar.h"
+
+class btPersistentManifold;
+class btRigidBody;
+class btCollisionObject;
+class btTypedConstraint;
+struct btContactSolverInfo;
+struct btBroadphaseProxy;
+class btIDebugDraw;
+class btStackAlloc;
+class	btDispatcher;
+/// btConstraintSolver provides solver interface
+class btConstraintSolver
+{
+
+public:
+
+	virtual ~btConstraintSolver() {}
+	
+	virtual void prepareSolve (int /* numBodies */, int /* numManifolds */) {;}
+
+	///solve a group of constraints
+	virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher) = 0;
+
+	virtual void allSolved (const btContactSolverInfo& /* info */,class btIDebugDraw* /* debugDrawer */, btStackAlloc* /* stackAlloc */) {;}
+
+	///clear internal cached data and reset random seed
+	virtual	void	reset() = 0;
+};
+
+
+
+
+#endif //CONSTRAINT_SOLVER_H
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.cpp	(revision 6952)
@@ -0,0 +1,429 @@
+/*
+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 "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"
+
+#define ASSERT2 btAssert
+
+#define USE_INTERNAL_APPLY_IMPULSE 1
+
+
+//bilateral constraint between two dynamic objects
+void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1,
+                      btRigidBody& body2, const btVector3& pos2,
+                      btScalar distance, const btVector3& normal,btScalar& impulse ,btScalar timeStep)
+{
+	(void)timeStep;
+	(void)distance;
+
+
+	btScalar normalLenSqr = normal.length2();
+	ASSERT2(btFabs(normalLenSqr) < btScalar(1.1));
+	if (normalLenSqr > btScalar(1.1))
+	{
+		impulse = btScalar(0.);
+		return;
+	}
+	btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); 
+	btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition();
+	//this jacobian entry could be re-used for all iterations
+	
+	btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1);
+	btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2);
+	btVector3 vel = vel1 - vel2;
+	
+
+	   btJacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(),
+		body2.getCenterOfMassTransform().getBasis().transpose(),
+		rel_pos1,rel_pos2,normal,body1.getInvInertiaDiagLocal(),body1.getInvMass(),
+		body2.getInvInertiaDiagLocal(),body2.getInvMass());
+
+	btScalar jacDiagAB = jac.getDiagonal();
+	btScalar jacDiagABInv = btScalar(1.) / jacDiagAB;
+	
+	  btScalar rel_vel = jac.getRelativeVelocity(
+		body1.getLinearVelocity(),
+		body1.getCenterOfMassTransform().getBasis().transpose() * body1.getAngularVelocity(),
+		body2.getLinearVelocity(),
+		body2.getCenterOfMassTransform().getBasis().transpose() * body2.getAngularVelocity()); 
+	btScalar a;
+	a=jacDiagABInv;
+
+
+	rel_vel = normal.dot(vel);
+	
+	//todo: move this into proper structure
+	btScalar contactDamping = btScalar(0.2);
+
+#ifdef ONLY_USE_LINEAR_MASS
+	btScalar massTerm = btScalar(1.) / (body1.getInvMass() + body2.getInvMass());
+	impulse = - contactDamping * rel_vel * massTerm;
+#else	
+	btScalar velocityImpulse = -contactDamping * rel_vel * jacDiagABInv;
+	impulse = velocityImpulse;
+#endif
+}
+
+
+
+//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/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactConstraint.h	(revision 6952)
@@ -0,0 +1,122 @@
+/*
+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 CONTACT_CONSTRAINT_H
+#define CONTACT_CONSTRAINT_H
+
+///@todo: make into a proper class working with the iterative constraint solver
+
+class btRigidBody;
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btScalar.h"
+struct btContactSolverInfo;
+class btManifoldPoint;
+
+enum {
+	DEFAULT_CONTACT_SOLVER_TYPE=0,
+	CONTACT_SOLVER_TYPE1,
+	CONTACT_SOLVER_TYPE2,
+	USER_CONTACT_SOLVER_TYPE1,
+	MAX_CONTACT_SOLVER_TYPES
+};
+
+
+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
+void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1,
+                      btRigidBody& body2, const btVector3& pos2,
+                      btScalar distance, const btVector3& normal,btScalar& impulse ,btScalar timeStep);
+
+
+///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/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h	(revision 6952)
@@ -0,0 +1,85 @@
+/*
+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 CONTACT_SOLVER_INFO
+#define CONTACT_SOLVER_INFO
+
+enum	btSolverMode
+{
+	SOLVER_RANDMIZE_ORDER = 1,
+	SOLVER_FRICTION_SEPARATE = 2,
+	SOLVER_USE_WARMSTARTING = 4,
+	SOLVER_USE_FRICTION_WARMSTARTING = 8,
+	SOLVER_USE_2_FRICTION_DIRECTIONS = 16,
+	SOLVER_ENABLE_FRICTION_DIRECTION_CACHING = 32,
+	SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION = 64,
+	SOLVER_CACHE_FRIENDLY = 128,
+	SOLVER_SIMD = 256,	//enabled for Windows, the solver innerloop is branchless SIMD, 40% faster than FPU/scalar version
+	SOLVER_CUDA = 512	//will be open sourced during Game Developers Conference 2009. Much faster.
+};
+
+struct btContactSolverInfoData
+{
+	
+
+	btScalar	m_tau;
+	btScalar	m_damping;
+	btScalar	m_friction;
+	btScalar	m_timeStep;
+	btScalar	m_restitution;
+	int		m_numIterations;
+	btScalar	m_maxErrorReduction;
+	btScalar	m_sor;
+	btScalar	m_erp;//used as Baumgarte factor
+	btScalar	m_erp2;//used in Split Impulse
+	btScalar	m_globalCfm;//constraint force mixing
+	int			m_splitImpulse;
+	btScalar	m_splitImpulsePenetrationThreshold;
+	btScalar	m_linearSlop;
+	btScalar	m_warmstartingFactor;
+
+	int			m_solverMode;
+	int	m_restingContactRestitutionThreshold;
+
+
+};
+
+struct btContactSolverInfo : public btContactSolverInfoData
+{
+
+	
+
+	inline btContactSolverInfo()
+	{
+		m_tau = btScalar(0.6);
+		m_damping = btScalar(1.0);
+		m_friction = btScalar(0.3);
+		m_restitution = btScalar(0.);
+		m_maxErrorReduction = btScalar(20.);
+		m_numIterations = 10;
+		m_erp = btScalar(0.2);
+		m_erp2 = btScalar(0.1);
+		m_globalCfm = btScalar(0.);
+		m_sor = btScalar(1.);
+		m_splitImpulse = false;
+		m_splitImpulsePenetrationThreshold = -0.02f;
+		m_linearSlop = btScalar(0.0);
+		m_warmstartingFactor=btScalar(0.85);
+		m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD ;//SOLVER_RANDMIZE_ORDER
+		m_restingContactRestitutionThreshold = 2;//resting contact lifetime threshold to disable restitution
+	}
+};
+
+#endif //CONTACT_SOLVER_INFO
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp	(revision 6952)
@@ -0,0 +1,829 @@
+/*
+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.
+*/
+/*
+2007-09-09
+Refactored by Francisco Le?n
+email: projectileman@yahoo.com
+http://gimpact.sf.net
+*/
+
+#include "btGeneric6DofConstraint.h"
+#include "BulletDynamics/Dynamics/btRigidBody.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)
+{
+}
+
+//-----------------------------------------------------------------------------
+
+btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA)
+: btTypedConstraint(D6_CONSTRAINT_TYPE, rbA, rbB)
+, m_frameInA(frameInA)
+, m_frameInB(frameInB),
+m_useLinearReferenceFrameA(useLinearReferenceFrameA),
+m_useSolveConstraintObsolete(D6_USE_OBSOLETE_METHOD)
+{
+
+}
+//-----------------------------------------------------------------------------
+
+
+#define GENERIC_D6_DISABLE_WARMSTARTING 1
+
+//-----------------------------------------------------------------------------
+
+btScalar btGetMatrixElem(const btMatrix3x3& mat, int index);
+btScalar btGetMatrixElem(const btMatrix3x3& mat, int index)
+{
+	int i = index%3;
+	int j = index/3;
+	return mat[i][j];
+}
+
+//-----------------------------------------------------------------------------
+
+///MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3.inl.html
+bool	matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz);
+bool	matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz)
+{
+	//	// rot =  cy*cz          -cy*sz           sy
+	//	//        cz*sx*sy+cx*sz  cx*cz-sx*sy*sz -cy*sx
+	//	//       -cx*cz*sy+sx*sz  cz*sx+cx*sy*sz  cx*cy
+	//
+
+	btScalar fi = btGetMatrixElem(mat,2);
+	if (fi < btScalar(1.0f))
+	{
+		if (fi > btScalar(-1.0f))
+		{
+			xyz[0] = btAtan2(-btGetMatrixElem(mat,5),btGetMatrixElem(mat,8));
+			xyz[1] = btAsin(btGetMatrixElem(mat,2));
+			xyz[2] = btAtan2(-btGetMatrixElem(mat,1),btGetMatrixElem(mat,0));
+			return true;
+		}
+		else
+		{
+			// WARNING.  Not unique.  XA - ZA = -atan2(r10,r11)
+			xyz[0] = -btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4));
+			xyz[1] = -SIMD_HALF_PI;
+			xyz[2] = btScalar(0.0);
+			return false;
+		}
+	}
+	else
+	{
+		// WARNING.  Not unique.  XAngle + ZAngle = atan2(r10,r11)
+		xyz[0] = btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4));
+		xyz[1] = SIMD_HALF_PI;
+		xyz[2] = 0.0;
+	}
+	return false;
+}
+
+//////////////////////////// btRotationalLimitMotor ////////////////////////////////////
+
+int btRotationalLimitMotor::testLimitValue(btScalar test_value)
+{
+	if(m_loLimit>m_hiLimit)
+	{
+		m_currentLimit = 0;//Free from violation
+		return 0;
+	}
+
+	if (test_value < m_loLimit)
+	{
+		m_currentLimit = 1;//low limit violation
+		m_currentLimitError =  test_value - m_loLimit;
+		return 1;
+	}
+	else if (test_value> m_hiLimit)
+	{
+		m_currentLimit = 2;//High limit violation
+		m_currentLimitError = test_value - m_hiLimit;
+		return 2;
+	};
+
+	m_currentLimit = 0;//Free from violation
+	return 0;
+
+}
+
+//-----------------------------------------------------------------------------
+
+btScalar btRotationalLimitMotor::solveAngularLimits(
+	btScalar timeStep,btVector3& axis,btScalar jacDiagABInv,
+	btRigidBody * body0, btSolverBody& bodyA, btRigidBody * body1, btSolverBody& bodyB)
+{
+	if (needApplyTorques()==false) return 0.0f;
+
+	btScalar target_velocity = m_targetVelocity;
+	btScalar maxMotorForce = m_maxMotorForce;
+
+	//current error correction
+	if (m_currentLimit!=0)
+	{
+		target_velocity = -m_ERP*m_currentLimitError/(timeStep);
+		maxMotorForce = m_maxLimitForce;
+	}
+
+	maxMotorForce *= timeStep;
+
+	// current velocity difference
+
+	btVector3 angVelA;
+	bodyA.getAngularVelocity(angVelA);
+	btVector3 angVelB;
+	bodyB.getAngularVelocity(angVelB);
+
+	btVector3 vel_diff;
+	vel_diff = angVelA-angVelB;
+
+
+
+	btScalar rel_vel = axis.dot(vel_diff);
+
+	// correction velocity
+	btScalar motor_relvel = m_limitSoftness*(target_velocity  - m_damping*rel_vel);
+
+
+	if ( motor_relvel < SIMD_EPSILON && motor_relvel > -SIMD_EPSILON  )
+	{
+		return 0.0f;//no need for applying force
+	}
+
+
+	// correction impulse
+	btScalar unclippedMotorImpulse = (1+m_bounce)*motor_relvel*jacDiagABInv;
+
+	// clip correction impulse
+	btScalar clippedMotorImpulse;
+
+	///@todo: should clip against accumulated impulse
+	if (unclippedMotorImpulse>0.0f)
+	{
+		clippedMotorImpulse =  unclippedMotorImpulse > maxMotorForce? maxMotorForce: unclippedMotorImpulse;
+	}
+	else
+	{
+		clippedMotorImpulse =  unclippedMotorImpulse < -maxMotorForce ? -maxMotorForce: unclippedMotorImpulse;
+	}
+
+
+	// sort with accumulated impulses
+	btScalar	lo = btScalar(-1e30);
+	btScalar	hi = btScalar(1e30);
+
+	btScalar oldaccumImpulse = m_accumulatedImpulse;
+	btScalar sum = oldaccumImpulse + clippedMotorImpulse;
+	m_accumulatedImpulse = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum;
+
+	clippedMotorImpulse = m_accumulatedImpulse - oldaccumImpulse;
+
+	btVector3 motorImp = clippedMotorImpulse * axis;
+
+	//body0->applyTorqueImpulse(motorImp);
+	//body1->applyTorqueImpulse(-motorImp);
+
+	bodyA.applyImpulse(btVector3(0,0,0), body0->getInvInertiaTensorWorld()*axis,clippedMotorImpulse);
+	bodyB.applyImpulse(btVector3(0,0,0), body1->getInvInertiaTensorWorld()*axis,-clippedMotorImpulse);
+
+
+	return clippedMotorImpulse;
+
+
+}
+
+//////////////////////////// End btRotationalLimitMotor ////////////////////////////////////
+
+
+
+
+//////////////////////////// btTranslationalLimitMotor ////////////////////////////////////
+
+
+int btTranslationalLimitMotor::testLimitValue(int limitIndex, btScalar test_value)
+{
+	btScalar loLimit = m_lowerLimit[limitIndex];
+	btScalar hiLimit = m_upperLimit[limitIndex];
+	if(loLimit > hiLimit)
+	{
+		m_currentLimit[limitIndex] = 0;//Free from violation
+		m_currentLimitError[limitIndex] = btScalar(0.f);
+		return 0;
+	}
+
+	if (test_value < loLimit)
+	{
+		m_currentLimit[limitIndex] = 2;//low limit violation
+		m_currentLimitError[limitIndex] =  test_value - loLimit;
+		return 2;
+	}
+	else if (test_value> hiLimit)
+	{
+		m_currentLimit[limitIndex] = 1;//High limit violation
+		m_currentLimitError[limitIndex] = test_value - hiLimit;
+		return 1;
+	};
+
+	m_currentLimit[limitIndex] = 0;//Free from violation
+	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,
+	int limit_index,
+	const btVector3 & axis_normal_on_a,
+	const btVector3 & anchorPos)
+{
+
+	///find relative velocity
+	//    btVector3 rel_pos1 = pointInA - body1.getCenterOfMassPosition();
+	//    btVector3 rel_pos2 = pointInB - body2.getCenterOfMassPosition();
+	btVector3 rel_pos1 = anchorPos - body1.getCenterOfMassPosition();
+	btVector3 rel_pos2 = anchorPos - body2.getCenterOfMassPosition();
+
+	btVector3 vel1;
+	bodyA.getVelocityInLocalPointObsolete(rel_pos1,vel1);
+	btVector3 vel2;
+	bodyB.getVelocityInLocalPointObsolete(rel_pos2,vel2);
+	btVector3 vel = vel1 - vel2;
+
+	btScalar rel_vel = axis_normal_on_a.dot(vel);
+
+
+
+	/// apply displacement correction
+
+	//positional error (zeroth order error)
+	btScalar depth = -(pointInA - pointInB).dot(axis_normal_on_a);
+	btScalar	lo = btScalar(-1e30);
+	btScalar	hi = btScalar(1e30);
+
+	btScalar minLimit = m_lowerLimit[limit_index];
+	btScalar maxLimit = m_upperLimit[limit_index];
+
+	//handle the limits
+	if (minLimit < maxLimit)
+	{
+		{
+			if (depth > maxLimit)
+			{
+				depth -= maxLimit;
+				lo = btScalar(0.);
+
+			}
+			else
+			{
+				if (depth < minLimit)
+				{
+					depth -= minLimit;
+					hi = btScalar(0.);
+				}
+				else
+				{
+					return 0.0f;
+				}
+			}
+		}
+	}
+
+	btScalar normalImpulse= m_limitSoftness*(m_restitution*depth/timeStep - m_damping*rel_vel) * jacDiagABInv;
+
+
+
+
+	btScalar oldNormalImpulse = m_accumulatedImpulse[limit_index];
+	btScalar sum = oldNormalImpulse + normalImpulse;
+	m_accumulatedImpulse[limit_index] = sum > hi ? btScalar(0.) : sum < lo ? btScalar(0.) : sum;
+	normalImpulse = m_accumulatedImpulse[limit_index] - oldNormalImpulse;
+
+	btVector3 impulse_vector = axis_normal_on_a * normalImpulse;
+	//body1.applyImpulse( impulse_vector, rel_pos1);
+	//body2.applyImpulse(-impulse_vector, rel_pos2);
+
+	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);
+
+
+
+
+	return normalImpulse;
+}
+
+//////////////////////////// btTranslationalLimitMotor ////////////////////////////////////
+
+void btGeneric6DofConstraint::calculateAngleInfo()
+{
+	btMatrix3x3 relative_frame = m_calculatedTransformA.getBasis().inverse()*m_calculatedTransformB.getBasis();
+	matrixToEulerXYZ(relative_frame,m_calculatedAxisAngleDiff);
+	// in euler angle mode we do not actually constrain the angular velocity
+	// along the axes axis[0] and axis[2] (although we do use axis[1]) :
+	//
+	//    to get			constrain w2-w1 along		...not
+	//    ------			---------------------		------
+	//    d(angle[0])/dt = 0	ax[1] x ax[2]			ax[0]
+	//    d(angle[1])/dt = 0	ax[1]
+	//    d(angle[2])/dt = 0	ax[0] x ax[1]			ax[2]
+	//
+	// constraining w2-w1 along an axis 'a' means that a'*(w2-w1)=0.
+	// to prove the result for angle[0], write the expression for angle[0] from
+	// GetInfo1 then take the derivative. to prove this for angle[2] it is
+	// easier to take the euler rate expression for d(angle[2])/dt with respect
+	// to the components of w and set that to 0.
+	btVector3 axis0 = m_calculatedTransformB.getBasis().getColumn(0);
+	btVector3 axis2 = m_calculatedTransformA.getBasis().getColumn(2);
+
+	m_calculatedAxis[1] = axis2.cross(axis0);
+	m_calculatedAxis[0] = m_calculatedAxis[1].cross(axis2);
+	m_calculatedAxis[2] = axis0.cross(m_calculatedAxis[1]);
+
+	m_calculatedAxis[0].normalize();
+	m_calculatedAxis[1].normalize();
+	m_calculatedAxis[2].normalize();
+
+}
+
+//-----------------------------------------------------------------------------
+
+void btGeneric6DofConstraint::calculateTransforms()
+{
+	m_calculatedTransformA = m_rbA.getCenterOfMassTransform() * m_frameInA;
+	m_calculatedTransformB = m_rbB.getCenterOfMassTransform() * m_frameInB;
+	calculateLinearInfo();
+	calculateAngleInfo();
+}
+
+//-----------------------------------------------------------------------------
+
+void btGeneric6DofConstraint::buildLinearJacobian(
+	btJacobianEntry & jacLinear,const btVector3 & normalWorld,
+	const btVector3 & pivotAInW,const btVector3 & pivotBInW)
+{
+	new (&jacLinear) btJacobianEntry(
+        m_rbA.getCenterOfMassTransform().getBasis().transpose(),
+        m_rbB.getCenterOfMassTransform().getBasis().transpose(),
+        pivotAInW - m_rbA.getCenterOfMassPosition(),
+        pivotBInW - m_rbB.getCenterOfMassPosition(),
+        normalWorld,
+        m_rbA.getInvInertiaDiagLocal(),
+        m_rbA.getInvMass(),
+        m_rbB.getInvInertiaDiagLocal(),
+        m_rbB.getInvMass());
+}
+
+//-----------------------------------------------------------------------------
+
+void btGeneric6DofConstraint::buildAngularJacobian(
+	btJacobianEntry & jacAngular,const btVector3 & jointAxisW)
+{
+	 new (&jacAngular)	btJacobianEntry(jointAxisW,
+                                      m_rbA.getCenterOfMassTransform().getBasis().transpose(),
+                                      m_rbB.getCenterOfMassTransform().getBasis().transpose(),
+                                      m_rbA.getInvInertiaDiagLocal(),
+                                      m_rbB.getInvInertiaDiagLocal());
+
+}
+
+//-----------------------------------------------------------------------------
+
+bool btGeneric6DofConstraint::testAngularLimitMotor(int axis_index)
+{
+	btScalar angle = m_calculatedAxisAngleDiff[axis_index];
+	//test limits
+	m_angularLimits[axis_index].testLimitValue(angle);
+	return m_angularLimits[axis_index].needApplyTorques();
+}
+
+//-----------------------------------------------------------------------------
+
+void btGeneric6DofConstraint::buildJacobian()
+{
+	if (m_useSolveConstraintObsolete)
+	{
+
+		// Clear accumulated impulses for the next simulation step
+		m_linearLimits.m_accumulatedImpulse.setValue(btScalar(0.), btScalar(0.), btScalar(0.));
+		int i;
+		for(i = 0; i < 3; i++)
+		{
+			m_angularLimits[i].m_accumulatedImpulse = btScalar(0.);
+		}
+		//calculates transform
+		calculateTransforms();
+
+		//  const btVector3& pivotAInW = m_calculatedTransformA.getOrigin();
+		//  const btVector3& pivotBInW = m_calculatedTransformB.getOrigin();
+		calcAnchorPos();
+		btVector3 pivotAInW = m_AnchorPos;
+		btVector3 pivotBInW = m_AnchorPos;
+
+		// not used here
+		//    btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition();
+		//    btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition();
+
+		btVector3 normalWorld;
+		//linear part
+		for (i=0;i<3;i++)
+		{
+			if (m_linearLimits.isLimited(i))
+			{
+				if (m_useLinearReferenceFrameA)
+					normalWorld = m_calculatedTransformA.getBasis().getColumn(i);
+				else
+					normalWorld = m_calculatedTransformB.getBasis().getColumn(i);
+
+				buildLinearJacobian(
+					m_jacLinear[i],normalWorld ,
+					pivotAInW,pivotBInW);
+
+			}
+		}
+
+		// angular part
+		for (i=0;i<3;i++)
+		{
+			//calculates error angle
+			if (testAngularLimitMotor(i))
+			{
+				normalWorld = this->getAxis(i);
+				// Create angular atom
+				buildAngularJacobian(m_jacAng[i],normalWorld);
+			}
+		}
+
+	}
+}
+
+//-----------------------------------------------------------------------------
+
+void btGeneric6DofConstraint::getInfo1 (btConstraintInfo1* info)
+{
+	if (m_useSolveConstraintObsolete)
+	{
+		info->m_numConstraintRows = 0;
+		info->nub = 0;
+	} else
+	{
+		//prepare constraint
+		calculateTransforms();
+		info->m_numConstraintRows = 0;
+		info->nub = 6;
+		int i;
+		//test linear limits
+		for(i = 0; i < 3; i++)
+		{
+			if(m_linearLimits.needApplyForce(i))
+			{
+				info->m_numConstraintRows++;
+				info->nub--;
+			}
+		}
+		//test angular limits
+		for (i=0;i<3 ;i++ )
+		{
+			if(testAngularLimitMotor(i))
+			{
+				info->m_numConstraintRows++;
+				info->nub--;
+			}
+		}
+	}
+}
+
+//-----------------------------------------------------------------------------
+
+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;
+	//solve linear limits
+	btRotationalLimitMotor limot;
+	for (int i=0;i<3 ;i++ )
+	{
+		if(m_linearLimits.needApplyForce(i))
+		{ // re-use rotational motor code
+			limot.m_bounce = btScalar(0.f);
+			limot.m_currentLimit = m_linearLimits.m_currentLimit[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;
+			limot.m_loLimit  = m_linearLimits.m_lowerLimit[i];
+			limot.m_maxLimitForce  = btScalar(0.f);
+			limot.m_maxMotorForce  = m_linearLimits.m_maxMotorForce[i];
+			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);
+		}
+	}
+	return row;
+}
+
+//-----------------------------------------------------------------------------
+
+int btGeneric6DofConstraint::setAngularLimits(btConstraintInfo2 *info, int row_offset)
+{
+	btGeneric6DofConstraint * d6constraint = this;
+	int row = row_offset;
+	//solve angular limits
+	for (int i=0;i<3 ;i++ )
+	{
+		if(d6constraint->getRotationalLimitMotor(i)->needApplyTorques())
+		{
+			btVector3 axis = d6constraint->getAxis(i);
+			row += get_limit_motor_info2(
+				d6constraint->getRotationalLimitMotor(i),
+				&m_rbA,
+				&m_rbB,
+				info,row,axis,1);
+		}
+	}
+
+	return row;
+}
+
+//-----------------------------------------------------------------------------
+
+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)
+{
+	(void)timeStep;
+
+}
+
+//-----------------------------------------------------------------------------
+
+btVector3 btGeneric6DofConstraint::getAxis(int axis_index) const
+{
+	return m_calculatedAxis[axis_index];
+}
+
+//-----------------------------------------------------------------------------
+
+btScalar btGeneric6DofConstraint::getAngle(int axis_index) const
+{
+	return m_calculatedAxisAngleDiff[axis_index];
+}
+
+//-----------------------------------------------------------------------------
+
+void btGeneric6DofConstraint::calcAnchorPos(void)
+{
+	btScalar imA = m_rbA.getInvMass();
+	btScalar imB = m_rbB.getInvMass();
+	btScalar weight;
+	if(imB == btScalar(0.0))
+	{
+		weight = btScalar(1.0);
+	}
+	else
+	{
+		weight = imA / (imA + imB);
+	}
+	const btVector3& pA = m_calculatedTransformA.getOrigin();
+	const btVector3& pB = m_calculatedTransformB.getOrigin();
+	m_AnchorPos = pA * weight + pB * (btScalar(1.0) - weight);
+	return;
+} // btGeneric6DofConstraint::calcAnchorPos()
+
+//-----------------------------------------------------------------------------
+
+void btGeneric6DofConstraint::calculateLinearInfo()
+{
+	m_calculatedLinearDiff = m_calculatedTransformB.getOrigin() - m_calculatedTransformA.getOrigin();
+	m_calculatedLinearDiff = m_calculatedTransformA.getBasis().inverse() * m_calculatedLinearDiff;
+	for(int i = 0; i < 3; 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)
+{
+    int srow = row * info->rowskip;
+    int powered = limot->m_enableMotor;
+    int limit = limot->m_currentLimit;
+    if (powered || limit)
+    {   // if the joint is powered, or has joint limits, add in the extra row
+        btScalar *J1 = rotational ? info->m_J1angularAxis : info->m_J1linearAxis;
+        btScalar *J2 = rotational ? info->m_J2angularAxis : 0;
+        J1[srow+0] = ax1[0];
+        J1[srow+1] = ax1[1];
+        J1[srow+2] = ax1[2];
+        if(rotational)
+        {
+            J2[srow+0] = -ax1[0];
+            J2[srow+1] = -ax1[1];
+            J2[srow+2] = -ax1[2];
+        }
+        if((!rotational) && limit)
+        {
+			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 we're limited low and high simultaneously, the joint motor is
+        // ineffective
+        if (limit && (limot->m_loLimit == limot->m_hiLimit)) powered = 0;
+        info->m_constraintError[srow] = btScalar(0.f);
+        if (powered)
+        {
+            info->cfm[srow] = 0.0f;
+            if(!limit)
+            {
+                info->m_constraintError[srow] += limot->m_targetVelocity;
+                info->m_lowerLimit[srow] = -limot->m_maxMotorForce;
+                info->m_upperLimit[srow] = limot->m_maxMotorForce;
+            }
+        }
+        if(limit)
+        {
+            btScalar k = info->fps * limot->m_ERP;
+			if(!rotational)
+			{
+				info->m_constraintError[srow] += k * limot->m_currentLimitError;
+			}
+			else
+			{
+				info->m_constraintError[srow] += -k * limot->m_currentLimitError;
+			}
+            info->cfm[srow] = 0.0f;
+            if (limot->m_loLimit == limot->m_hiLimit)
+            {   // limited low and high simultaneously
+                info->m_lowerLimit[srow] = -SIMD_INFINITY;
+                info->m_upperLimit[srow] = SIMD_INFINITY;
+            }
+            else
+            {
+                if (limit == 1)
+                {
+                    info->m_lowerLimit[srow] = 0;
+                    info->m_upperLimit[srow] = SIMD_INFINITY;
+                }
+                else
+                {
+                    info->m_lowerLimit[srow] = -SIMD_INFINITY;
+                    info->m_upperLimit[srow] = 0;
+                }
+                // deal with bounce
+                if (limot->m_bounce > 0)
+                {
+                    // calculate joint velocity
+                    btScalar vel;
+                    if (rotational)
+                    {
+                        vel = body0->getAngularVelocity().dot(ax1);
+                        if (body1)
+                            vel -= body1->getAngularVelocity().dot(ax1);
+                    }
+                    else
+                    {
+                        vel = body0->getLinearVelocity().dot(ax1);
+                        if (body1)
+                            vel -= body1->getLinearVelocity().dot(ax1);
+                    }
+                    // only apply bounce if the velocity is incoming, and if the
+                    // resulting c[] exceeds what we already have.
+                    if (limit == 1)
+                    {
+                        if (vel < 0)
+                        {
+                            btScalar newc = -limot->m_bounce* vel;
+                            if (newc > info->m_constraintError[srow]) 
+								info->m_constraintError[srow] = newc;
+                        }
+                    }
+                    else
+                    {
+                        if (vel > 0)
+                        {
+                            btScalar newc = -limot->m_bounce * vel;
+                            if (newc < info->m_constraintError[srow]) 
+								info->m_constraintError[srow] = newc;
+                        }
+                    }
+                }
+            }
+        }
+        return 1;
+    }
+    else return 0;
+}
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h	(revision 6952)
@@ -0,0 +1,480 @@
+/*
+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.
+*/
+/*
+2007-09-09
+btGeneric6DofConstraint Refactored by Francisco Le?n
+email: projectileman@yahoo.com
+http://gimpact.sf.net
+*/
+
+
+#ifndef GENERIC_6DOF_CONSTRAINT_H
+#define GENERIC_6DOF_CONSTRAINT_H
+
+#include "LinearMath/btVector3.h"
+#include "btJacobianEntry.h"
+#include "btTypedConstraint.h"
+
+class btRigidBody;
+
+
+
+
+//! Rotation Limit structure for generic joints
+class btRotationalLimitMotor
+{
+public:
+    //! limit_parameters
+    //!@{
+    btScalar m_loLimit;//!< joint limit
+    btScalar m_hiLimit;//!< joint limit
+    btScalar m_targetVelocity;//!< target motor velocity
+    btScalar m_maxMotorForce;//!< max force on motor
+    btScalar m_maxLimitForce;//!< max force on limit
+    btScalar m_damping;//!< Damping.
+    btScalar m_limitSoftness;//! Relaxation factor
+    btScalar m_ERP;//!< Error tolerance factor when joint is at limit
+    btScalar m_bounce;//!< restitution factor
+    bool m_enableMotor;
+
+    //!@}
+
+    //! temp_variables
+    //!@{
+    btScalar m_currentLimitError;//!  How much is violated this limit
+    int m_currentLimit;//!< 0=free, 1=at lo limit, 2=at hi limit
+    btScalar m_accumulatedImpulse;
+    //!@}
+
+    btRotationalLimitMotor()
+    {
+    	m_accumulatedImpulse = 0.f;
+        m_targetVelocity = 0;
+        m_maxMotorForce = 0.1f;
+        m_maxLimitForce = 300.0f;
+        m_loLimit = -SIMD_INFINITY;
+        m_hiLimit = SIMD_INFINITY;
+        m_ERP = 0.5f;
+        m_bounce = 0.0f;
+        m_damping = 1.0f;
+        m_limitSoftness = 0.5f;
+        m_currentLimit = 0;
+        m_currentLimitError = 0;
+        m_enableMotor = false;
+    }
+
+    btRotationalLimitMotor(const btRotationalLimitMotor & limot)
+    {
+        m_targetVelocity = limot.m_targetVelocity;
+        m_maxMotorForce = limot.m_maxMotorForce;
+        m_limitSoftness = limot.m_limitSoftness;
+        m_loLimit = limot.m_loLimit;
+        m_hiLimit = limot.m_hiLimit;
+        m_ERP = limot.m_ERP;
+        m_bounce = limot.m_bounce;
+        m_currentLimit = limot.m_currentLimit;
+        m_currentLimitError = limot.m_currentLimitError;
+        m_enableMotor = limot.m_enableMotor;
+    }
+
+
+
+	//! Is limited
+    bool isLimited()
+    {
+    	if(m_loLimit > m_hiLimit) return false;
+    	return true;
+    }
+
+	//! Need apply correction
+    bool needApplyTorques()
+    {
+    	if(m_currentLimit == 0 && m_enableMotor == false) return false;
+    	return true;
+    }
+
+	//! calculates  error
+	/*!
+	calculates m_currentLimit and m_currentLimitError.
+	*/
+	int testLimitValue(btScalar test_value);
+
+	//! apply the correction impulses for two bodies
+    btScalar solveAngularLimits(btScalar timeStep,btVector3& axis, btScalar jacDiagABInv,btRigidBody * body0, btSolverBody& bodyA,btRigidBody * body1,btSolverBody& bodyB);
+
+};
+
+
+
+class btTranslationalLimitMotor
+{
+public:
+	btVector3 m_lowerLimit;//!< the constraint lower limits
+    btVector3 m_upperLimit;//!< the constraint upper limits
+    btVector3 m_accumulatedImpulse;
+    //! Linear_Limit_parameters
+    //!@{
+    btScalar	m_limitSoftness;//!< Softness for linear limit
+    btScalar	m_damping;//!< Damping for linear limit
+    btScalar	m_restitution;//! Bounce parameter for linear limit
+    //!@}
+	bool		m_enableMotor[3];
+    btVector3	m_targetVelocity;//!< target motor velocity
+    btVector3	m_maxMotorForce;//!< max force on motor
+    btVector3	m_currentLimitError;//!  How much is violated this limit
+    int			m_currentLimit[3];//!< 0=free, 1=at lower limit, 2=at upper limit
+
+    btTranslationalLimitMotor()
+    {
+    	m_lowerLimit.setValue(0.f,0.f,0.f);
+    	m_upperLimit.setValue(0.f,0.f,0.f);
+    	m_accumulatedImpulse.setValue(0.f,0.f,0.f);
+
+    	m_limitSoftness = 0.7f;
+    	m_damping = btScalar(1.0f);
+    	m_restitution = btScalar(0.5f);
+		for(int i=0; i < 3; i++) 
+		{
+			m_enableMotor[i] = false;
+			m_targetVelocity[i] = btScalar(0.f);
+			m_maxMotorForce[i] = btScalar(0.f);
+		}
+    }
+
+    btTranslationalLimitMotor(const btTranslationalLimitMotor & other )
+    {
+    	m_lowerLimit = other.m_lowerLimit;
+    	m_upperLimit = other.m_upperLimit;
+    	m_accumulatedImpulse = other.m_accumulatedImpulse;
+
+    	m_limitSoftness = other.m_limitSoftness ;
+    	m_damping = other.m_damping;
+    	m_restitution = other.m_restitution;
+		for(int i=0; i < 3; i++) 
+		{
+			m_enableMotor[i] = other.m_enableMotor[i];
+			m_targetVelocity[i] = other.m_targetVelocity[i];
+			m_maxMotorForce[i] = other.m_maxMotorForce[i];
+		}
+    }
+
+    //! Test limit
+	/*!
+    - free means upper < lower,
+    - locked means upper == lower
+    - limited means upper > lower
+    - limitIndex: first 3 are linear, next 3 are angular
+    */
+    inline bool	isLimited(int limitIndex)
+    {
+       return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]);
+    }
+    inline bool needApplyForce(int limitIndex)
+    {
+    	if(m_currentLimit[limitIndex] == 0 && m_enableMotor[limitIndex] == false) return false;
+    	return true;
+    }
+	int testLimitValue(int limitIndex, btScalar test_value);
+
+
+    btScalar solveLinearAxis(
+    	btScalar timeStep,
+        btScalar jacDiagABInv,
+        btRigidBody& body1,btSolverBody& bodyA,const btVector3 &pointInA,
+        btRigidBody& body2,btSolverBody& bodyB,const btVector3 &pointInB,
+        int limit_index,
+        const btVector3 & axis_normal_on_a,
+		const btVector3 & anchorPos);
+
+
+};
+
+/// btGeneric6DofConstraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space
+/*!
+btGeneric6DofConstraint can leave any of the 6 degree of freedom 'free' or 'locked'.
+currently this limit supports rotational motors<br>
+<ul>
+<li> For Linear limits, use btGeneric6DofConstraint.setLinearUpperLimit, btGeneric6DofConstraint.setLinearLowerLimit. You can set the parameters with the btTranslationalLimitMotor structure accsesible through the btGeneric6DofConstraint.getTranslationalLimitMotor method.
+At this moment translational motors are not supported. May be in the future. </li>
+
+<li> For Angular limits, use the btRotationalLimitMotor structure for configuring the limit.
+This is accessible through btGeneric6DofConstraint.getLimitMotor method,
+This brings support for limit parameters and motors. </li>
+
+<li> Angulars limits have these possible ranges:
+<table border=1 >
+<tr
+
+	<td><b>AXIS</b></td>
+	<td><b>MIN ANGLE</b></td>
+	<td><b>MAX ANGLE</b></td>
+	<td>X</td>
+		<td>-PI</td>
+		<td>PI</td>
+	<td>Y</td>
+		<td>-PI/2</td>
+		<td>PI/2</td>
+	<td>Z</td>
+		<td>-PI/2</td>
+		<td>PI/2</td>
+</tr>
+</table>
+</li>
+</ul>
+
+*/
+class btGeneric6DofConstraint : public btTypedConstraint
+{
+protected:
+
+	//! relative_frames
+    //!@{
+	btTransform	m_frameInA;//!< the constraint space w.r.t body A
+    btTransform	m_frameInB;//!< the constraint space w.r.t body B
+    //!@}
+
+    //! Jacobians
+    //!@{
+    btJacobianEntry	m_jacLinear[3];//!< 3 orthogonal linear constraints
+    btJacobianEntry	m_jacAng[3];//!< 3 orthogonal angular constraints
+    //!@}
+
+	//! Linear_Limit_parameters
+    //!@{
+    btTranslationalLimitMotor m_linearLimits;
+    //!@}
+
+
+    //! hinge_parameters
+    //!@{
+    btRotationalLimitMotor m_angularLimits[3];
+	//!@}
+
+
+protected:
+    //! temporal variables
+    //!@{
+    btScalar m_timeStep;
+    btTransform m_calculatedTransformA;
+    btTransform m_calculatedTransformB;
+    btVector3 m_calculatedAxisAngleDiff;
+    btVector3 m_calculatedAxis[3];
+    btVector3 m_calculatedLinearDiff;
+    
+	btVector3 m_AnchorPos; // point betwen pivots of bodies A and B to solve linear axes
+
+    bool	m_useLinearReferenceFrameA;
+    
+    //!@}
+
+    btGeneric6DofConstraint&	operator=(btGeneric6DofConstraint&	other)
+    {
+        btAssert(0);
+        (void) other;
+        return *this;
+    }
+
+
+	int setAngularLimits(btConstraintInfo2 *info, int row_offset);
+
+	int setLinearLimits(btConstraintInfo2 *info);
+
+    void buildLinearJacobian(
+        btJacobianEntry & jacLinear,const btVector3 & normalWorld,
+        const btVector3 & pivotAInW,const btVector3 & pivotBInW);
+
+    void buildAngularJacobian(btJacobianEntry & jacAngular,const btVector3 & jointAxisW);
+
+	// tests linear limits
+	void calculateLinearInfo();
+
+	//! calcs the euler angles between the two bodies.
+    void calculateAngleInfo();
+
+
+
+public:
+
+	///for backwards compatibility during the transition to 'getInfo/getInfo2'
+	bool		m_useSolveConstraintObsolete;
+
+    btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
+
+    btGeneric6DofConstraint();
+
+	//! Calcs global transform of the offsets
+	/*!
+	Calcs the global transform for the joint offset for body A an B, and also calcs the agle differences between the bodies.
+	\sa btGeneric6DofConstraint.getCalculatedTransformA , btGeneric6DofConstraint.getCalculatedTransformB, btGeneric6DofConstraint.calculateAngleInfo
+	*/
+    void calculateTransforms();
+
+	//! Gets the global transform of the offset for body A
+    /*!
+    \sa btGeneric6DofConstraint.getFrameOffsetA, btGeneric6DofConstraint.getFrameOffsetB, btGeneric6DofConstraint.calculateAngleInfo.
+    */
+    const btTransform & getCalculatedTransformA() const
+    {
+    	return m_calculatedTransformA;
+    }
+
+    //! Gets the global transform of the offset for body B
+    /*!
+    \sa btGeneric6DofConstraint.getFrameOffsetA, btGeneric6DofConstraint.getFrameOffsetB, btGeneric6DofConstraint.calculateAngleInfo.
+    */
+    const btTransform & getCalculatedTransformB() const
+    {
+    	return m_calculatedTransformB;
+    }
+
+    const btTransform & getFrameOffsetA() const
+    {
+    	return m_frameInA;
+    }
+
+    const btTransform & getFrameOffsetB() const
+    {
+    	return m_frameInB;
+    }
+
+
+    btTransform & getFrameOffsetA()
+    {
+    	return m_frameInA;
+    }
+
+    btTransform & getFrameOffsetB()
+    {
+    	return m_frameInB;
+    }
+
+
+	//! performs Jacobian calculation, and also calculates angle differences and axis
+    virtual void	buildJacobian();
+
+	virtual void getInfo1 (btConstraintInfo1* info);
+
+	virtual void getInfo2 (btConstraintInfo2* info);
+
+    virtual	void	solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep);
+
+    void	updateRHS(btScalar	timeStep);
+
+	//! Get the rotation axis in global coordinates
+	/*!
+	\pre btGeneric6DofConstraint.buildJacobian must be called previously.
+	*/
+    btVector3 getAxis(int axis_index) const;
+
+    //! Get the relative Euler angle
+    /*!
+	\pre btGeneric6DofConstraint.buildJacobian must be called previously.
+	*/
+    btScalar getAngle(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.
+	*/
+    bool testAngularLimitMotor(int axis_index);
+
+    void	setLinearLowerLimit(const btVector3& linearLower)
+    {
+    	m_linearLimits.m_lowerLimit = linearLower;
+    }
+
+    void	setLinearUpperLimit(const btVector3& linearUpper)
+    {
+    	m_linearLimits.m_upperLimit = linearUpper;
+    }
+
+    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();
+    }
+
+    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();
+    }
+
+	//! Retrieves the angular limit informacion
+    btRotationalLimitMotor * getRotationalLimitMotor(int index)
+    {
+    	return &m_angularLimits[index];
+    }
+
+    //! Retrieves the  limit informacion
+    btTranslationalLimitMotor * getTranslationalLimitMotor()
+    {
+    	return &m_linearLimits;
+    }
+
+    //first 3 are linear, next 3 are angular
+    void setLimit(int axis, btScalar lo, btScalar hi)
+    {
+    	if(axis<3)
+    	{
+    		m_linearLimits.m_lowerLimit[axis] = lo;
+    		m_linearLimits.m_upperLimit[axis] = hi;
+    	}
+    	else
+    	{
+    		m_angularLimits[axis-3].m_loLimit = lo;
+    		m_angularLimits[axis-3].m_hiLimit = hi;
+    	}
+    }
+
+	//! Test limit
+	/*!
+    - free means upper < lower,
+    - locked means upper == lower
+    - limited means upper > lower
+    - limitIndex: first 3 are linear, next 3 are angular
+    */
+    bool	isLimited(int limitIndex)
+    {
+    	if(limitIndex<3)
+    	{
+			return m_linearLimits.isLimited(limitIndex);
+
+    	}
+        return m_angularLimits[limitIndex-3].isLimited();
+    }
+
+    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);
+
+
+};
+
+#endif //GENERIC_6DOF_CONSTRAINT_H
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp	(revision 6952)
@@ -0,0 +1,666 @@
+/*
+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 "btHingeConstraint.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "LinearMath/btTransformUtil.h"
+#include "LinearMath/btMinMax.h"
+#include <new>
+#include "btSolverBody.h"
+
+//-----------------------------------------------------------------------------
+
+#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);
+}
+
+//-----------------------------------------------------------------------------
+
+btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB,
+									 btVector3& axisInA,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_rbAFrame.getOrigin() = pivotInA;
+	
+	// since no frame is given, assume this to be zero angle and just pick rb transform axis
+	btVector3 rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(0);
+
+	btVector3 rbAxisA2;
+	btScalar projection = axisInA.dot(rbAxisA1);
+	if (projection >= 1.0f - SIMD_EPSILON) {
+		rbAxisA1 = -rbA.getCenterOfMassTransform().getBasis().getColumn(2);
+		rbAxisA2 = rbA.getCenterOfMassTransform().getBasis().getColumn(1);
+	} else if (projection <= -1.0f + SIMD_EPSILON) {
+		rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(2);
+		rbAxisA2 = rbA.getCenterOfMassTransform().getBasis().getColumn(1);      
+	} else {
+		rbAxisA2 = axisInA.cross(rbAxisA1);
+		rbAxisA1 = rbAxisA2.cross(axisInA);
+	}
+
+	m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(),
+									rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(),
+									rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() );
+
+	btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB);
+	btVector3 rbAxisB1 =  quatRotate(rotationArc,rbAxisA1);
+	btVector3 rbAxisB2 =  axisInB.cross(rbAxisB1);	
+	
+	m_rbBFrame.getOrigin() = pivotInB;
+	m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(),
+									rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(),
+									rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() );
+	
+	//start with free
+	m_lowerLimit = btScalar(1e30);
+	m_upperLimit = btScalar(-1e30);
+	m_biasFactor = 0.3f;
+	m_relaxationFactor = 1.0f;
+	m_limitSoftness = 0.9f;
+	m_solveLimit = false;
+	m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f);
+}
+
+//-----------------------------------------------------------------------------
+
+btHingeConstraint::btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,btVector3& axisInA, bool useReferenceFrameA)
+:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA), m_angularOnly(false), m_enableAngularMotor(false), 
+m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER),
+m_useReferenceFrameA(useReferenceFrameA)
+{
+
+	// since no frame is given, assume this to be zero angle and just pick rb transform axis
+	// fixed axis in worldspace
+	btVector3 rbAxisA1, rbAxisA2;
+	btPlaneSpace1(axisInA, rbAxisA1, rbAxisA2);
+
+	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 = rbA.getCenterOfMassTransform().getBasis() * axisInA;
+
+	btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB);
+	btVector3 rbAxisB1 =  quatRotate(rotationArc,rbAxisA1);
+	btVector3 rbAxisB2 = axisInB.cross(rbAxisB1);
+
+
+	m_rbBFrame.getOrigin() = 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() );
+	
+	//start with free
+	m_lowerLimit = btScalar(1e30);
+	m_upperLimit = btScalar(-1e30);
+	m_biasFactor = 0.3f;
+	m_relaxationFactor = 1.0f;
+	m_limitSoftness = 0.9f;
+	m_solveLimit = false;
+	m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f);
+}
+
+//-----------------------------------------------------------------------------
+
+btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, 
+								     const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA)
+:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame),
+m_angularOnly(false),
+m_enableAngularMotor(false),
+m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER),
+m_useReferenceFrameA(useReferenceFrameA)
+{
+	//start with free
+	m_lowerLimit = btScalar(1e30);
+	m_upperLimit = btScalar(-1e30);
+	m_biasFactor = 0.3f;
+	m_relaxationFactor = 1.0f;
+	m_limitSoftness = 0.9f;
+	m_solveLimit = false;
+	m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f);
+}			
+
+//-----------------------------------------------------------------------------
+
+btHingeConstraint::btHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame, bool useReferenceFrameA)
+:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA),m_rbAFrame(rbAFrame),m_rbBFrame(rbAFrame),
+m_angularOnly(false),
+m_enableAngularMotor(false),
+m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER),
+m_useReferenceFrameA(useReferenceFrameA)
+{
+	///not providing rigidbody B means implicitly using worldspace for body B
+
+	m_rbBFrame.getOrigin() = m_rbA.getCenterOfMassTransform()(m_rbAFrame.getOrigin());
+
+	//start with free
+	m_lowerLimit = btScalar(1e30);
+	m_upperLimit = btScalar(-1e30);	
+	m_biasFactor = 0.3f;
+	m_relaxationFactor = 1.0f;
+	m_limitSoftness = 0.9f;
+	m_solveLimit = false;
+	m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f);
+}
+
+//-----------------------------------------------------------------------------
+
+void	btHingeConstraint::buildJacobian()
+{
+	if (m_useSolveConstraintObsolete)
+	{
+		m_appliedImpulse = btScalar(0.);
+
+		if (!m_angularOnly)
+		{
+			btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin();
+			btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin();
+			btVector3 relPos = pivotBInW - pivotAInW;
+
+			btVector3 normal[3];
+			if (relPos.length2() > SIMD_EPSILON)
+			{
+				normal[0] = relPos.normalized();
+			}
+			else
+			{
+				normal[0].setValue(btScalar(1.0),0,0);
+			}
+
+			btPlaneSpace1(normal[0], normal[1], normal[2]);
+
+			for (int i=0;i<3;i++)
+			{
+				new (&m_jac[i]) btJacobianEntry(
+				m_rbA.getCenterOfMassTransform().getBasis().transpose(),
+				m_rbB.getCenterOfMassTransform().getBasis().transpose(),
+				pivotAInW - m_rbA.getCenterOfMassPosition(),
+				pivotBInW - m_rbB.getCenterOfMassPosition(),
+				normal[i],
+				m_rbA.getInvInertiaDiagLocal(),
+				m_rbA.getInvMass(),
+				m_rbB.getInvInertiaDiagLocal(),
+				m_rbB.getInvMass());
+			}
+		}
+
+		//calculate two perpendicular jointAxis, orthogonal to hingeAxis
+		//these two jointAxis require equal angular velocities for both bodies
+
+		//this is unused for now, it's a todo
+		btVector3 jointAxis0local;
+		btVector3 jointAxis1local;
+		
+		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;
+		btVector3 hingeAxisWorld = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2);
+			
+		new (&m_jacAng[0])	btJacobianEntry(jointAxis0,
+			m_rbA.getCenterOfMassTransform().getBasis().transpose(),
+			m_rbB.getCenterOfMassTransform().getBasis().transpose(),
+			m_rbA.getInvInertiaDiagLocal(),
+			m_rbB.getInvInertiaDiagLocal());
+
+		new (&m_jacAng[1])	btJacobianEntry(jointAxis1,
+			m_rbA.getCenterOfMassTransform().getBasis().transpose(),
+			m_rbB.getCenterOfMassTransform().getBasis().transpose(),
+			m_rbA.getInvInertiaDiagLocal(),
+			m_rbB.getInvInertiaDiagLocal());
+
+		new (&m_jacAng[2])	btJacobianEntry(hingeAxisWorld,
+			m_rbA.getCenterOfMassTransform().getBasis().transpose(),
+			m_rbB.getCenterOfMassTransform().getBasis().transpose(),
+			m_rbA.getInvInertiaDiagLocal(),
+			m_rbB.getInvInertiaDiagLocal());
+
+			// clear accumulator
+			m_accLimitImpulse = btScalar(0.);
+
+			// test angular limit
+			testLimit();
+
+		//Compute K = J*W*J' for hinge axis
+		btVector3 axisA =  getRigidBodyA().getCenterOfMassTransform().getBasis() *  m_rbAFrame.getBasis().getColumn(2);
+		m_kHinge =   1.0f / (getRigidBodyA().computeAngularImpulseDenominator(axisA) +
+							 getRigidBodyB().computeAngularImpulseDenominator(axisA));
+
+	}
+}
+
+//-----------------------------------------------------------------------------
+
+void btHingeConstraint::getInfo1(btConstraintInfo1* info)
+{
+	if (m_useSolveConstraintObsolete)
+	{
+		info->m_numConstraintRows = 0;
+		info->nub = 0;
+	}
+	else
+	{
+		info->m_numConstraintRows = 5; // Fixed 3 linear + 2 angular
+		info->nub = 1; 
+		//prepare constraint
+		testLimit();
+		if(getSolveLimit() || getEnableAngularMotor())
+		{
+			info->m_numConstraintRows++; // limit 3rd anguar as well
+			info->nub--; 
+		}
+	}
+} // btHingeConstraint::getInfo1 ()
+
+//-----------------------------------------------------------------------------
+
+void btHingeConstraint::getInfo2 (btConstraintInfo2* info)
+{
+	btAssert(!m_useSolveConstraintObsolete);
+	int i, s = info->rowskip;
+	// transforms in world space
+	btTransform trA = m_rbA.getCenterOfMassTransform()*m_rbAFrame;
+	btTransform trB = m_rbB.getCenterOfMassTransform()*m_rbBFrame;
+	// pivot point
+	btVector3 pivotAInW = trA.getOrigin();
+	btVector3 pivotBInW = trB.getOrigin();
+	// 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();
+	{
+		btVector3* angular0 = (btVector3*)(info->m_J1angularAxis);
+		btVector3* angular1 = (btVector3*)(info->m_J1angularAxis + s);
+		btVector3* angular2 = (btVector3*)(info->m_J1angularAxis + 2 * s);
+		btVector3 a1neg = -a1;
+		a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2);
+	}
+	btVector3 a2 = pivotBInW - m_rbB.getCenterOfMassTransform().getOrigin();
+	{
+		btVector3* angular0 = (btVector3*)(info->m_J2angularAxis);
+		btVector3* angular1 = (btVector3*)(info->m_J2angularAxis + s);
+		btVector3* angular2 = (btVector3*)(info->m_J2angularAxis + 2 * s);
+		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]);
+    }
+	// make rotations around X and Y equal
+	// 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.
+	// get hinge axis (Z)
+	btVector3 ax1 = trA.getBasis().getColumn(2);
+	// get 2 orthos to hinge axis (X, Y)
+	btVector3 p = trA.getBasis().getColumn(0);
+	btVector3 q = trA.getBasis().getColumn(1);
+	// set the two hinge angular rows 
+    int s3 = 3 * info->rowskip;
+    int s4 = 4 * info->rowskip;
+
+	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 ax1,ax2 are the unit length hinge axes as computed from body1 and
+    // body2, 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.
+    btVector3 ax2 = trB.getBasis().getColumn(2);
+	btVector3 u = ax1.cross(ax2);
+	info->m_constraintError[s3] = k * u.dot(p);
+	info->m_constraintError[s4] = k * u.dot(q);
+	// check angular limits
+	int 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);
+		if(powered)
+		{
+            info->cfm[srow] = btScalar(0.0); 
+			btScalar mot_fact = getMotorFactor(m_hingeAngle, lostop, histop, m_motorTargetVelocity, info->fps * info->erp);
+			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 * info->erp;
+			info->m_constraintError[srow] += k * limit_err;
+			info->cfm[srow] = btScalar(0.0);
+			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 = m_rbA.getAngularVelocity().dot(ax1);
+				vel -= m_rbB.getAngularVelocity().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
+}
+
+//-----------------------------------------------------------------------------
+
+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)
+{
+	(void)timeStep;
+
+}
+
+//-----------------------------------------------------------------------------
+
+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 m_referenceSign * angle;
+}
+
+//-----------------------------------------------------------------------------
+
+void btHingeConstraint::testLimit()
+{
+	// Compute limit information
+	m_hingeAngle = getHingeAngle();  
+	m_correction = btScalar(0.);
+	m_limitSign = btScalar(0.);
+	m_solveLimit = false;
+	if (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;
+} // btHingeConstraint::testLimit()
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btHingeConstraint.h	(revision 6952)
@@ -0,0 +1,178 @@
+/*
+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.
+*/
+
+/* Hinge Constraint by Dirk Gregorius. Limits added by Marcus Hennix at Starbreeze Studios */
+
+#ifndef HINGECONSTRAINT_H
+#define HINGECONSTRAINT_H
+
+#include "LinearMath/btVector3.h"
+#include "btJacobianEntry.h"
+#include "btTypedConstraint.h"
+
+class btRigidBody;
+
+/// 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
+{
+#ifdef IN_PARALLELL_SOLVER
+public:
+#endif
+	btJacobianEntry	m_jac[3]; //3 orthogonal linear constraints
+	btJacobianEntry	m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor
+
+	btTransform m_rbAFrame; // constraint axii. Assumes z is hinge axis.
+	btTransform m_rbBFrame;
+
+	btScalar	m_motorTargetVelocity;
+	btScalar	m_maxMotorImpulse;
+
+	btScalar	m_limitSoftness; 
+	btScalar	m_biasFactor; 
+	btScalar    m_relaxationFactor; 
+
+	btScalar    m_lowerLimit;	
+	btScalar    m_upperLimit;	
+	
+	btScalar	m_kHinge;
+
+	btScalar	m_limitSign;
+	btScalar	m_correction;
+
+	btScalar	m_accLimitImpulse;
+	btScalar	m_hingeAngle;
+	btScalar    m_referenceSign;
+
+	bool		m_angularOnly;
+	bool		m_enableAngularMotor;
+	bool		m_solveLimit;
+	bool		m_useSolveConstraintObsolete;
+	bool		m_useReferenceFrameA;
+
+	
+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 btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false);
+
+	btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA = false);
+
+	btHingeConstraint();
+
+	virtual void	buildJacobian();
+
+	virtual void getInfo1 (btConstraintInfo1* info);
+
+	virtual void getInfo2 (btConstraintInfo2* info);
+	
+	virtual	void	solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep);
+
+	void	updateRHS(btScalar	timeStep);
+
+	const btRigidBody& getRigidBodyA() const
+	{
+		return m_rbA;
+	}
+	const btRigidBody& getRigidBodyB() const
+	{
+		return m_rbB;
+	}
+
+	btRigidBody& getRigidBodyA()	
+	{		
+		return m_rbA;	
+	}	
+
+	btRigidBody& getRigidBodyB()	
+	{		
+		return m_rbB;	
+	}	
+	
+	void	setAngularOnly(bool angularOnly)
+	{
+		m_angularOnly = angularOnly;
+	}
+
+	void	enableAngularMotor(bool enableMotor,btScalar targetVelocity,btScalar maxMotorImpulse)
+	{
+		m_enableAngularMotor  = enableMotor;
+		m_motorTargetVelocity = targetVelocity;
+		m_maxMotorImpulse = maxMotorImpulse;
+	}
+
+	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_limitSoftness =  _softness;
+		m_biasFactor = _biasFactor;
+		m_relaxationFactor = _relaxationFactor;
+
+	}
+
+	btScalar	getLowerLimit() const
+	{
+		return m_lowerLimit;
+	}
+
+	btScalar	getUpperLimit() const
+	{
+		return m_upperLimit;
+	}
+
+
+	btScalar getHingeAngle();
+
+	void testLimit();
+
+
+	const btTransform& getAFrame() { return m_rbAFrame; };	
+	const btTransform& getBFrame() { return m_rbBFrame; };
+
+	inline int getSolveLimit()
+	{
+		return m_solveLimit;
+	}
+
+	inline btScalar getLimitSign()
+	{
+		return m_limitSign;
+	}
+
+	inline bool getAngularOnly() 
+	{ 
+		return m_angularOnly; 
+	}
+	inline bool getEnableAngularMotor() 
+	{ 
+		return m_enableAngularMotor; 
+	}
+	inline btScalar getMotorTargetVelosity() 
+	{ 
+		return m_motorTargetVelocity; 
+	}
+	inline btScalar getMaxMotorImpulse() 
+	{ 
+		return m_maxMotorImpulse; 
+	}
+
+};
+
+#endif //HINGECONSTRAINT_H
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btJacobianEntry.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btJacobianEntry.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btJacobianEntry.h	(revision 6952)
@@ -0,0 +1,156 @@
+/*
+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 JACOBIAN_ENTRY_H
+#define JACOBIAN_ENTRY_H
+
+#include "LinearMath/btVector3.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+
+
+//notes:
+// Another memory optimization would be to store m_1MinvJt in the remaining 3 w components
+// which makes the btJacobianEntry memory layout 16 bytes
+// if you only are interested in angular part, just feed massInvA and massInvB zero
+
+/// Jacobian entry is an abstraction that allows to describe constraints
+/// 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
+{
+public:
+	btJacobianEntry() {};
+	//constraint between two different rigidbodies
+	btJacobianEntry(
+		const btMatrix3x3& world2A,
+		const btMatrix3x3& world2B,
+		const btVector3& rel_pos1,const btVector3& rel_pos2,
+		const btVector3& jointAxis,
+		const btVector3& inertiaInvA, 
+		const btScalar massInvA,
+		const btVector3& inertiaInvB,
+		const btScalar massInvB)
+		:m_linearJointAxis(jointAxis)
+	{
+		m_aJ = world2A*(rel_pos1.cross(m_linearJointAxis));
+		m_bJ = world2B*(rel_pos2.cross(-m_linearJointAxis));
+		m_0MinvJt	= inertiaInvA * m_aJ;
+		m_1MinvJt = inertiaInvB * m_bJ;
+		m_Adiag = massInvA + m_0MinvJt.dot(m_aJ) + massInvB + m_1MinvJt.dot(m_bJ);
+
+		btAssert(m_Adiag > btScalar(0.0));
+	}
+
+	//angular constraint between two different rigidbodies
+	btJacobianEntry(const btVector3& jointAxis,
+		const btMatrix3x3& world2A,
+		const btMatrix3x3& world2B,
+		const btVector3& inertiaInvA,
+		const btVector3& inertiaInvB)
+		:m_linearJointAxis(btVector3(btScalar(0.),btScalar(0.),btScalar(0.)))
+	{
+		m_aJ= world2A*jointAxis;
+		m_bJ = world2B*-jointAxis;
+		m_0MinvJt	= inertiaInvA * m_aJ;
+		m_1MinvJt = inertiaInvB * m_bJ;
+		m_Adiag =  m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ);
+
+		btAssert(m_Adiag > btScalar(0.0));
+	}
+
+	//angular constraint between two different rigidbodies
+	btJacobianEntry(const btVector3& axisInA,
+		const btVector3& axisInB,
+		const btVector3& inertiaInvA,
+		const btVector3& inertiaInvB)
+		: m_linearJointAxis(btVector3(btScalar(0.),btScalar(0.),btScalar(0.)))
+		, m_aJ(axisInA)
+		, m_bJ(-axisInB)
+	{
+		m_0MinvJt	= inertiaInvA * m_aJ;
+		m_1MinvJt = inertiaInvB * m_bJ;
+		m_Adiag =  m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ);
+
+		btAssert(m_Adiag > btScalar(0.0));
+	}
+
+	//constraint on one rigidbody
+	btJacobianEntry(
+		const btMatrix3x3& world2A,
+		const btVector3& rel_pos1,const btVector3& rel_pos2,
+		const btVector3& jointAxis,
+		const btVector3& inertiaInvA, 
+		const btScalar massInvA)
+		:m_linearJointAxis(jointAxis)
+	{
+		m_aJ= world2A*(rel_pos1.cross(jointAxis));
+		m_bJ = world2A*(rel_pos2.cross(-jointAxis));
+		m_0MinvJt	= inertiaInvA * m_aJ;
+		m_1MinvJt = btVector3(btScalar(0.),btScalar(0.),btScalar(0.));
+		m_Adiag = massInvA + m_0MinvJt.dot(m_aJ);
+
+		btAssert(m_Adiag > btScalar(0.0));
+	}
+
+	btScalar	getDiagonal() const { return m_Adiag; }
+
+	// for two constraints on the same rigidbody (for example vehicle friction)
+	btScalar	getNonDiagonal(const btJacobianEntry& jacB, const btScalar massInvA) const
+	{
+		const btJacobianEntry& jacA = *this;
+		btScalar lin = massInvA * jacA.m_linearJointAxis.dot(jacB.m_linearJointAxis);
+		btScalar ang = jacA.m_0MinvJt.dot(jacB.m_aJ);
+		return lin + ang;
+	}
+
+	
+
+	// for two constraints on sharing two same rigidbodies (for example two contact points between two rigidbodies)
+	btScalar	getNonDiagonal(const btJacobianEntry& jacB,const btScalar massInvA,const btScalar massInvB) const
+	{
+		const btJacobianEntry& jacA = *this;
+		btVector3 lin = jacA.m_linearJointAxis * jacB.m_linearJointAxis;
+		btVector3 ang0 = jacA.m_0MinvJt * jacB.m_aJ;
+		btVector3 ang1 = jacA.m_1MinvJt * jacB.m_bJ;
+		btVector3 lin0 = massInvA * lin ;
+		btVector3 lin1 = massInvB * lin;
+		btVector3 sum = ang0+ang1+lin0+lin1;
+		return sum[0]+sum[1]+sum[2];
+	}
+
+	btScalar getRelativeVelocity(const btVector3& linvelA,const btVector3& angvelA,const btVector3& linvelB,const btVector3& angvelB)
+	{
+		btVector3 linrel = linvelA - linvelB;
+		btVector3 angvela  = angvelA * m_aJ;
+		btVector3 angvelb  = angvelB * m_bJ;
+		linrel *= m_linearJointAxis;
+		angvela += angvelb;
+		angvela += linrel;
+		btScalar rel_vel2 = angvela[0]+angvela[1]+angvela[2];
+		return rel_vel2 + SIMD_EPSILON;
+	}
+//private:
+
+	btVector3	m_linearJointAxis;
+	btVector3	m_aJ;
+	btVector3	m_bJ;
+	btVector3	m_0MinvJt;
+	btVector3	m_1MinvJt;
+	//Optimization: can be stored in the w/last component of one of the vectors
+	btScalar	m_Adiag;
+
+};
+
+#endif //JACOBIAN_ENTRY_H
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp	(revision 6952)
@@ -0,0 +1,230 @@
+/*
+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 "btPoint2PointConstraint.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include <new>
+
+
+
+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_useSolveConstraintObsolete(false)
+{
+
+}
+
+
+btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA)
+:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)),
+m_useSolveConstraintObsolete(false)
+{
+	
+}
+
+void	btPoint2PointConstraint::buildJacobian()
+{
+	///we need it for both methods
+	{
+		m_appliedImpulse = btScalar(0.);
+
+		btVector3	normal(0,0,0);
+
+		for (int i=0;i<3;i++)
+		{
+			normal[i] = 1;
+			new (&m_jac[i]) btJacobianEntry(
+			m_rbA.getCenterOfMassTransform().getBasis().transpose(),
+			m_rbB.getCenterOfMassTransform().getBasis().transpose(),
+			m_rbA.getCenterOfMassTransform()*m_pivotInA - m_rbA.getCenterOfMassPosition(),
+			m_rbB.getCenterOfMassTransform()*m_pivotInB - m_rbB.getCenterOfMassPosition(),
+			normal,
+			m_rbA.getInvInertiaDiagLocal(),
+			m_rbA.getInvMass(),
+			m_rbB.getInvInertiaDiagLocal(),
+			m_rbB.getInvMass());
+		normal[i] = 0;
+		}
+	}
+
+}
+
+
+void btPoint2PointConstraint::getInfo1 (btConstraintInfo1* info)
+{
+	if (m_useSolveConstraintObsolete)
+	{
+		info->m_numConstraintRows = 0;
+		info->nub = 0;
+	} else
+	{
+		info->m_numConstraintRows = 3;
+		info->nub = 3;
+	}
+}
+
+void btPoint2PointConstraint::getInfo2 (btConstraintInfo2* info)
+{
+	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.
+   
+    // 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()*getPivotInA();
+	{
+		btVector3* angular0 = (btVector3*)(info->m_J1angularAxis);
+		btVector3* angular1 = (btVector3*)(info->m_J1angularAxis+info->rowskip);
+		btVector3* angular2 = (btVector3*)(info->m_J1angularAxis+2*info->rowskip);
+		btVector3 a1neg = -a1;
+		a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2);
+	}
+    
+	/*info->m_J2linearAxis[0] = -1;
+    info->m_J2linearAxis[s+1] = -1;
+    info->m_J2linearAxis[2*s+2] = -1;
+	*/
+	
+	btVector3 a2 = body1_trans.getBasis()*getPivotInB();
+   
+	{
+		btVector3 a2n = -a2;
+		btVector3* angular0 = (btVector3*)(info->m_J2angularAxis);
+		btVector3* angular1 = (btVector3*)(info->m_J2angularAxis+info->rowskip);
+		btVector3* angular2 = (btVector3*)(info->m_J2angularAxis+2*info->rowskip);
+		a2.getSkewSymmetricMatrix(angular0,angular1,angular2);
+	}
+    
+
+
+    // set right hand side
+    btScalar k = info->fps * info->erp;
+    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]);
+		//printf("info->m_constraintError[%d]=%f\n",j,info->m_constraintError[j]);
+    }
+
+	btScalar impulseClamp = m_setting.m_impulseClamp;//
+	for (j=0; j<3; j++)
+    {
+		if (m_setting.m_impulseClamp > 0)
+		{
+			info->m_lowerLimit[j*info->rowskip] = -impulseClamp;
+			info->m_upperLimit[j*info->rowskip] = impulseClamp;
+		}
+	}
+	
+}
+
+
+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;
+		}
+	}
+}
+
+void	btPoint2PointConstraint::updateRHS(btScalar	timeStep)
+{
+	(void)timeStep;
+
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h	(revision 6952)
@@ -0,0 +1,98 @@
+/*
+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 POINT2POINTCONSTRAINT_H
+#define POINT2POINTCONSTRAINT_H
+
+#include "LinearMath/btVector3.h"
+#include "btJacobianEntry.h"
+#include "btTypedConstraint.h"
+
+class btRigidBody;
+
+struct	btConstraintSetting
+{
+	btConstraintSetting()	:
+		m_tau(btScalar(0.3)),
+		m_damping(btScalar(1.)),
+		m_impulseClamp(btScalar(0.))
+	{
+	}
+	btScalar		m_tau;
+	btScalar		m_damping;
+	btScalar		m_impulseClamp;
+};
+
+/// point to point constraint between two rigidbodies each with a pivotpoint that descibes the 'ballsocket' location in local space
+class btPoint2PointConstraint : public btTypedConstraint
+{
+#ifdef IN_PARALLELL_SOLVER
+public:
+#endif
+	btJacobianEntry	m_jac[3]; //3 orthogonal linear constraints
+	
+	btVector3	m_pivotInA;
+	btVector3	m_pivotInB;
+	
+	
+	
+public:
+
+	///for backwards compatibility during the transition to 'getInfo/getInfo2'
+	bool		m_useSolveConstraintObsolete;
+
+	btConstraintSetting	m_setting;
+
+	btPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB);
+
+	btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA);
+
+	btPoint2PointConstraint();
+
+	virtual void	buildJacobian();
+
+	virtual void getInfo1 (btConstraintInfo1* info);
+
+	virtual void getInfo2 (btConstraintInfo2* info);
+
+
+	virtual	void	solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep);
+
+	void	updateRHS(btScalar	timeStep);
+
+	void	setPivotA(const btVector3& pivotA)
+	{
+		m_pivotInA = pivotA;
+	}
+
+	void	setPivotB(const btVector3& pivotB)
+	{
+		m_pivotInB = pivotB;
+	}
+
+	const btVector3& getPivotInA() const
+	{
+		return m_pivotInA;
+	}
+
+	const btVector3& getPivotInB() const
+	{
+		return m_pivotInB;
+	}
+
+
+};
+
+#endif //POINT2POINTCONSTRAINT_H
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp	(revision 6952)
@@ -0,0 +1,1031 @@
+/*
+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.
+*/
+
+//#define COMPUTE_IMPULSE_DENOM 1
+//It is not necessary (redundant) to refresh contact manifolds, this refresh has been moved to the collision algorithms.
+
+#include "btSequentialImpulseConstraintSolver.h"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "btContactConstraint.h"
+#include "btSolve2LinearConstraint.h"
+#include "btContactSolverInfo.h"
+#include "LinearMath/btIDebugDraw.h"
+#include "btJacobianEntry.h"
+#include "LinearMath/btMinMax.h"
+#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
+#include <new>
+#include "LinearMath/btStackAlloc.h"
+#include "LinearMath/btQuickprof.h"
+#include "btSolverBody.h"
+#include "btSolverConstraint.h"
+#include "LinearMath/btAlignedObjectArray.h"
+#include <string.h> //for memset
+
+btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver()
+:m_btSeed2(0)
+{
+
+}
+
+btSequentialImpulseConstraintSolver::~btSequentialImpulseConstraintSolver()
+{
+}
+
+#ifdef USE_SIMD
+#include <emmintrin.h>
+#define vec_splat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e,e,e,e))
+static inline __m128 _vmathVfDot3( __m128 vec0, __m128 vec1 )
+{
+	__m128 result = _mm_mul_ps( vec0, vec1);
+	return _mm_add_ps( vec_splat( result, 0 ), _mm_add_ps( vec_splat( result, 1 ), vec_splat( result, 2 ) ) );
+}
+#endif//USE_SIMD
+
+// Project Gauss Seidel or the equivalent Sequential Impulse
+void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
+{
+#ifdef USE_SIMD
+	__m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse);
+	__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_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));
+	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 upperMinApplied = _mm_sub_ps(upperLimit1,cpAppliedImp);
+	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 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));
+#else
+	resolveSingleConstraintRowGeneric(body1,body2,c);
+#endif
+}
+
+// Project Gauss Seidel or the equivalent Sequential Impulse
+ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGeneric(btSolverBody& body1,btSolverBody& 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;
+	deltaImpulse	-=	deltaVel1Dotn*c.m_jacDiagABInv;
+	deltaImpulse	-=	deltaVel2Dotn*c.m_jacDiagABInv;
+
+	const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse;
+	if (sum < c.m_lowerLimit)
+	{
+		deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse;
+		c.m_appliedImpulse = c.m_lowerLimit;
+	}
+	else if (sum > c.m_upperLimit) 
+	{
+		deltaImpulse = c.m_upperLimit-c.m_appliedImpulse;
+		c.m_appliedImpulse = c.m_upperLimit;
+	}
+	else
+	{
+		c.m_appliedImpulse = sum;
+	}
+	if (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)
+{
+#ifdef USE_SIMD
+	__m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse);
+	__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_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));
+	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,_mm_set1_ps(body1.m_invMass));
+	__m128	linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,_mm_set1_ps(body2.m_invMass));
+	__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));
+#else
+	resolveSingleConstraintRowLowerLimit(body1,body2,c);
+#endif
+}
+
+// Project Gauss Seidel or the equivalent Sequential Impulse
+ void btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimit(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& c)
+{
+	btScalar deltaImpulse = c.m_rhs-btScalar(c.m_appliedImpulse)*c.m_cfm;
+	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);
+
+	deltaImpulse	-=	deltaVel1Dotn*c.m_jacDiagABInv;
+	deltaImpulse	-=	deltaVel2Dotn*c.m_jacDiagABInv;
+	const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse;
+	if (sum < c.m_lowerLimit)
+	{
+		deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse;
+		c.m_appliedImpulse = c.m_lowerLimit;
+	}
+	else
+	{
+		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);
+}
+
+
+
+unsigned long btSequentialImpulseConstraintSolver::btRand2()
+{
+	m_btSeed2 = (1664525L*m_btSeed2 + 1013904223L) & 0xffffffff;
+	return m_btSeed2;
+}
+
+
+
+//See ODE: adam's all-int straightforward(?) dRandInt (0..n-1)
+int btSequentialImpulseConstraintSolver::btRandInt2 (int n)
+{
+	// seems good; xor-fold and modulus
+	const unsigned long un = static_cast<unsigned long>(n);
+	unsigned long r = btRand2();
+
+	// note: probably more aggressive than it needs to be -- might be
+	//       able to get away without one or two of the innermost branches.
+	if (un <= 0x00010000UL) {
+		r ^= (r >> 16);
+		if (un <= 0x00000100UL) {
+			r ^= (r >> 8);
+			if (un <= 0x00000010UL) {
+				r ^= (r >> 4);
+				if (un <= 0x00000004UL) {
+					r ^= (r >> 2);
+					if (un <= 0x00000002UL) {
+						r ^= (r >> 1);
+					}
+				}
+			}
+		}
+	}
+
+	return (int) (r % un);
+}
+
+
+
+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);
+
+	if (rb)
+	{
+		solverBody->m_invMass = rb->getInvMass();
+		solverBody->m_originalBody = rb;
+		solverBody->m_angularFactor = rb->getAngularFactor();
+	} else
+	{
+		solverBody->m_invMass = 0.f;
+		solverBody->m_originalBody = 0;
+		solverBody->m_angularFactor = 1.f;
+	}
+}
+
+
+int		gNumSplitImpulseRecoveries = 0;
+
+btScalar btSequentialImpulseConstraintSolver::restitutionCurve(btScalar rel_vel, btScalar restitution)
+{
+	btScalar rest = restitution * -rel_vel;
+	return rest;
+}
+
+
+
+void	applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection);
+void	applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection)
+{
+	if (colObj && colObj->hasAnisotropicFriction())
+	{
+		// transform to local coordinates
+		btVector3 loc_lateral = frictionDirection * colObj->getWorldTransform().getBasis();
+		const btVector3& friction_scaling = colObj->getAnisotropicFriction();
+		//apply anisotropic friction
+		loc_lateral *= friction_scaling;
+		// ... and transform it back to global coordinates
+		frictionDirection = colObj->getWorldTransform().getBasis() * loc_lateral;
+	}
+}
+
+
+
+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)
+{
+
+
+	btRigidBody* body0=btRigidBody::upcast(colObj0);
+	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_friction = cp.m_combinedFriction;
+	solverConstraint.m_originalContactPoint = 0;
+
+	solverConstraint.m_appliedImpulse = 0.f;
+	//	solverConstraint.m_appliedPushImpulse = 0.f;
+
+	{
+		btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal);
+		solverConstraint.m_relpos1CrossNormal = ftorqueAxis1;
+		solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld()*ftorqueAxis1*body0->getAngularFactor() : btVector3(0,0,0);
+	}
+	{
+		btVector3 ftorqueAxis1 = rel_pos2.cross(-solverConstraint.m_contactNormal);
+		solverConstraint.m_relpos2CrossNormal = ftorqueAxis1;
+		solverConstraint.m_angularComponentB = body1 ? body1->getInvInertiaTensorWorld()*ftorqueAxis1*body1->getAngularFactor() : btVector3(0,0,0);
+	}
+
+#ifdef COMPUTE_IMPULSE_DENOM
+	btScalar denom0 = rb0->computeImpulseDenominator(pos1,solverConstraint.m_contactNormal);
+	btScalar denom1 = rb1->computeImpulseDenominator(pos2,solverConstraint.m_contactNormal);
+#else
+	btVector3 vec;
+	btScalar denom0 = 0.f;
+	btScalar denom1 = 0.f;
+	if (body0)
+	{
+		vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
+		denom0 = body0->getInvMass() + normalAxis.dot(vec);
+	}
+	if (body1)
+	{
+		vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2);
+		denom1 = body1->getInvMass() + normalAxis.dot(vec);
+	}
+
+
+#endif //COMPUTE_IMPULSE_DENOM
+	btScalar denom = relaxation/(denom0+denom1);
+	solverConstraint.m_jacDiagABInv = denom;
+
+#ifdef _USE_JACOBIAN
+	solverConstraint.m_jac =  btJacobianEntry (
+		rel_pos1,rel_pos2,solverConstraint.m_contactNormal,
+		body0->getInvInertiaDiagLocal(),
+		body0->getInvMass(),
+		body1->getInvInertiaDiagLocal(),
+		body1->getInvMass());
+#endif //_USE_JACOBIAN
+
+
+	{
+		btScalar rel_vel;
+		btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(body0?body0->getLinearVelocity():btVector3(0,0,0)) 
+			+ solverConstraint.m_relpos1CrossNormal.dot(body0?body0->getAngularVelocity():btVector3(0,0,0));
+		btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(body1?body1->getLinearVelocity():btVector3(0,0,0)) 
+			+ solverConstraint.m_relpos2CrossNormal.dot(body1?body1->getAngularVelocity():btVector3(0,0,0));
+
+		rel_vel = vel1Dotn+vel2Dotn;
+
+		btScalar positionalError = 0.f;
+
+		btSimdScalar velocityError =  - rel_vel;
+		btSimdScalar	velocityImpulse = velocityError * btSimdScalar(solverConstraint.m_jacDiagABInv);
+		solverConstraint.m_rhs = velocityImpulse;
+		solverConstraint.m_cfm = 0.f;
+		solverConstraint.m_lowerLimit = 0;
+		solverConstraint.m_upperLimit = 1e10f;
+	}
+
+	return solverConstraint;
+}
+
+int	btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body)
+{
+	int solverBodyIdA = -1;
+
+	if (body.getCompanionId() >= 0)
+	{
+		//body has already been converted
+		solverBodyIdA = body.getCompanionId();
+	} else
+	{
+		btRigidBody* rb = btRigidBody::upcast(&body);
+		if (rb && rb->getInvMass())
+		{
+			solverBodyIdA = m_tmpSolverBodyPool.size();
+			btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
+			initSolverBody(&solverBody,&body);
+			body.setCompanionId(solverBodyIdA);
+		} else
+		{
+			return 0;//assume first one is a fixed solver body
+		}
+	}
+	return solverBodyIdA;
+}
+#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())
+		{
+
+			const btVector3& pos1 = cp.getPositionWorldOnA();
+			const btVector3& pos2 = cp.getPositionWorldOnB();
+
+			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);
+				{
+#ifdef COMPUTE_IMPULSE_DENOM
+					btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB);
+					btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB);
+#else							
+					btVector3 vec;
+					btScalar denom0 = 0.f;
+					btScalar denom1 = 0.f;
+					if (rb0)
+					{
+						vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1);
+						denom0 = rb0->getInvMass() + cp.m_normalWorldOnB.dot(vec);
+					}
+					if (rb1)
+					{
+						vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2);
+						denom1 = rb1->getInvMass() + cp.m_normalWorldOnB.dot(vec);
+					}
+#endif //COMPUTE_IMPULSE_DENOM		
+
+					btScalar denom = relaxation/(denom0+denom1);
+					solverConstraint.m_jacDiagABInv = denom;
+				}
+
+				solverConstraint.m_contactNormal = cp.m_normalWorldOnB;
+				solverConstraint.m_relpos1CrossNormal = rel_pos1.cross(cp.m_normalWorldOnB);
+				solverConstraint.m_relpos2CrossNormal = rel_pos2.cross(-cp.m_normalWorldOnB);
+
+
+				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;
+
+
+				solverConstraint.m_friction = cp.m_combinedFriction;
+
+				btScalar restitution = 0.f;
+				
+				if (cp.m_lifeTime>infoGlobal.m_restingContactRestitutionThreshold)
+				{
+					restitution = 0.f;
+				} else
+				{
+					restitution =  restitutionCurve(rel_vel, cp.m_combinedRestitution);
+					if (restitution <= btScalar(0.))
+					{
+						restitution = 0.f;
+					};
+				}
+
+
+				///warm starting (or zero if disabled)
+				if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
+				{
+					solverConstraint.m_appliedImpulse = 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);
+					if (rb1)
+						m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].applyImpulse(solverConstraint.m_contactNormal*rb1->getInvMass(),-solverConstraint.m_angularComponentB,-solverConstraint.m_appliedImpulse);
+				} else
+				{
+					solverConstraint.m_appliedImpulse = 0.f;
+				}
+
+				//							solverConstraint.m_appliedPushImpulse = 0.f;
+
+				{
+					btScalar rel_vel;
+					btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rb0?rb0->getLinearVelocity():btVector3(0,0,0)) 
+						+ solverConstraint.m_relpos1CrossNormal.dot(rb0?rb0->getAngularVelocity():btVector3(0,0,0));
+					btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rb1?rb1->getLinearVelocity():btVector3(0,0,0)) 
+						+ solverConstraint.m_relpos2CrossNormal.dot(rb1?rb1->getAngularVelocity():btVector3(0,0,0));
+
+					rel_vel = vel1Dotn+vel2Dotn;
+
+					btScalar positionalError = 0.f;
+					positionalError = -penetration * infoGlobal.m_erp/infoGlobal.m_timeStep;
+					btScalar	velocityError = restitution - rel_vel;// * damping;
+					btScalar  penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
+					btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
+					solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
+					solverConstraint.m_cfm = 0.f;
+					solverConstraint.m_lowerLimit = 0;
+					solverConstraint.m_upperLimit = 1e10f;
+				}
+
+
+				/////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);
+					}
+
+					if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING)
+					{
+						{
+							btSolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex];
+							if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
+							{
+								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);
+								if (rb1)
+									m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].applyImpulse(frictionConstraint1.m_contactNormal*rb1->getInvMass(),-frictionConstraint1.m_angularComponentB,-frictionConstraint1.m_appliedImpulse);
+							} else
+							{
+								frictionConstraint1.m_appliedImpulse = 0.f;
+							}
+						}
+
+						if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
+						{
+							btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
+							if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
+							{
+								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);
+								if (rb1)
+									m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB].applyImpulse(frictionConstraint2.m_contactNormal*rb1->getInvMass(),-frictionConstraint2.m_angularComponentB,-frictionConstraint2.m_appliedImpulse);
+							} else
+							{
+								frictionConstraint2.m_appliedImpulse = 0.f;
+							}
+						}
+					} else
+					{
+						btSolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex];
+						frictionConstraint1.m_appliedImpulse = 0.f;
+						if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
+						{
+							btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1];
+							frictionConstraint2.m_appliedImpulse = 0.f;
+						}
+					}
+				}
+			}
+
+
+		}
+	}
+}
+
+
+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");
+	(void)stackAlloc;
+	(void)debugDrawer;
+
+
+	if (!(numConstraints + numManifolds))
+	{
+		//		printf("empty\n");
+		return 0.f;
+	}
+
+	if (1)
+	{
+		int j;
+		for (j=0;j<numConstraints;j++)
+		{
+			btTypedConstraint* constraint = constraints[j];
+			constraint->buildJacobian();
+		}
+	}
+
+	btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
+	initSolverBody(&fixedBody,0);
+
+	//btRigidBody* rb0=0,*rb1=0;
+
+	//if (1)
+	{
+		{
+
+			int totalNumRows = 0;
+			int i;
+			//calculate the total number of contraint rows
+			for (i=0;i<numConstraints;i++)
+			{
+
+				btTypedConstraint::btConstraintInfo1 info1;
+				constraints[i]->getInfo1(&info1);
+				totalNumRows += info1.m_numConstraintRows;
+			}
+			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)
+			{
+				constraints[i]->getInfo1(&info1);
+				if (info1.m_numConstraintRows)
+				{
+					btAssert(currentRow<totalNumRows);
+
+					btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow];
+					btTypedConstraint* constraint = constraints[i];
+
+
+
+					btRigidBody& rbA = constraint->getRigidBodyA();
+					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++)
+					{
+						memset(&currentConstraintRow[j],0,sizeof(btSolverConstraint));
+						currentConstraintRow[j].m_lowerLimit = -FLT_MAX;
+						currentConstraintRow[j].m_upperLimit = FLT_MAX;
+						currentConstraintRow[j].m_appliedImpulse = 0.f;
+						currentConstraintRow[j].m_appliedPushImpulse = 0.f;
+						currentConstraintRow[j].m_solverBodyIdA = solverBodyIdA;
+						currentConstraintRow[j].m_solverBodyIdB = solverBodyIdB;
+					}
+
+					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);
+
+
+
+					btTypedConstraint::btConstraintInfo2 info2;
+					info2.fps = 1.f/infoGlobal.m_timeStep;
+					info2.erp = infoGlobal.m_erp;
+					info2.m_J1linearAxis = currentConstraintRow->m_contactNormal;
+					info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal;
+					info2.m_J2linearAxis = 0;
+					info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal;
+					info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this
+					///the size of btSolverConstraint needs be a multiple of btScalar
+					btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint));
+					info2.m_constraintError = &currentConstraintRow->m_rhs;
+					info2.cfm = &currentConstraintRow->m_cfm;
+					info2.m_lowerLimit = &currentConstraintRow->m_lowerLimit;
+					info2.m_upperLimit = &currentConstraintRow->m_upperLimit;
+					constraints[i]->getInfo2(&info2);
+
+					///finalize the constraint setup
+					for ( j=0;j<info1.m_numConstraintRows;j++)
+					{
+						btSolverConstraint& solverConstraint = currentConstraintRow[j];
+
+						{
+							const btVector3& ftorqueAxis1 = solverConstraint.m_relpos1CrossNormal;
+							solverConstraint.m_angularComponentA = constraint->getRigidBodyA().getInvInertiaTensorWorld()*ftorqueAxis1*constraint->getRigidBodyA().getAngularFactor();
+						}
+						{
+							const btVector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal;
+							solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld()*ftorqueAxis2*constraint->getRigidBodyB().getAngularFactor();
+						}
+
+						{
+							btVector3 iMJlA = solverConstraint.m_contactNormal*rbA.getInvMass();
+							btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal;
+							btVector3 iMJlB = solverConstraint.m_contactNormal*rbB.getInvMass();//sign of normal?
+							btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal;
+
+							btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal);
+							sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal);
+							sum += iMJlB.dot(solverConstraint.m_contactNormal);
+							sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal);
+
+							solverConstraint.m_jacDiagABInv = btScalar(1.)/sum;
+						}
+
+
+						///fix rhs
+						///todo: add force/torque accelerators
+						{
+							btScalar rel_vel;
+							btScalar vel1Dotn = solverConstraint.m_contactNormal.dot(rbA.getLinearVelocity()) + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity());
+							btScalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rbB.getLinearVelocity()) + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity());
+
+							rel_vel = vel1Dotn+vel2Dotn;
+
+							btScalar restitution = 0.f;
+							btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2
+							btScalar	velocityError = restitution - rel_vel;// * damping;
+							btScalar	penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv;
+							btScalar	velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv;
+							solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;
+							solverConstraint.m_appliedImpulse = 0.f;
+
+						}
+					}
+				}
+			}
+		}
+
+		{
+			int i;
+			btPersistentManifold* manifold = 0;
+			btCollisionObject* colObj0=0,*colObj1=0;
+
+
+			for (i=0;i<numManifolds;i++)
+			{
+				manifold = manifoldPtr[i];
+				convertContact(manifold,infoGlobal);
+			}
+		}
+	}
+
+	btContactSolverInfo info = infoGlobal;
+
+
+
+	int numConstraintPool = m_tmpSolverContactConstraintPool.size();
+	int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size();
+
+	///@todo: use stack allocator for such temporarily memory, same for solver bodies/constraints
+	m_orderTmpConstraintPool.resize(numConstraintPool);
+	m_orderFrictionConstraintPool.resize(numFrictionPool);
+	{
+		int i;
+		for (i=0;i<numConstraintPool;i++)
+		{
+			m_orderTmpConstraintPool[i] = i;
+		}
+		for (i=0;i<numFrictionPool;i++)
+		{
+			m_orderFrictionConstraintPool[i] = i;
+		}
+	}
+
+	return 0.f;
+
+}
+
+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");
+
+	int numConstraintPool = m_tmpSolverContactConstraintPool.size();
+	int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size();
+
+	//should traverse the contacts random order...
+	int iteration;
+	{
+		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);
+					}
+				}
+			}
+
+
+
+		}
+	}
+	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);
+
+	int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
+	int j;
+
+	for (j=0;j<numPoolConstraints;j++)
+	{
+
+		const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[j];
+		btManifoldPoint* pt = (btManifoldPoint*) solveManifold.m_originalContactPoint;
+		btAssert(pt);
+		pt->m_appliedImpulse = solveManifold.m_appliedImpulse;
+		if (infoGlobal.m_solverMode & SOLVER_USE_FRICTION_WARMSTARTING)
+		{
+			pt->m_appliedImpulseLateral1 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
+			pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse;
+		}
+
+		//do a callback here?
+	}
+
+	if (infoGlobal.m_splitImpulse)
+	{		
+		for ( i=0;i<m_tmpSolverBodyPool.size();i++)
+		{
+			m_tmpSolverBodyPool[i].writebackVelocity(infoGlobal.m_timeStep);
+		}
+	} else
+	{
+		for ( i=0;i<m_tmpSolverBodyPool.size();i++)
+		{
+			m_tmpSolverBodyPool[i].writebackVelocity();
+		}
+	}
+
+
+	m_tmpSolverBodyPool.resize(0);
+	m_tmpSolverContactConstraintPool.resize(0);
+	m_tmpSolverNonContactConstraintPool.resize(0);
+	m_tmpSolverContactFrictionConstraintPool.resize(0);
+
+	return 0.f;
+}
+
+
+
+
+
+
+
+
+
+void	btSequentialImpulseConstraintSolver::reset()
+{
+	m_btSeed2 = 0;
+}
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h	(revision 6952)
@@ -0,0 +1,101 @@
+/*
+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 SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H
+#define SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H
+
+#include "btConstraintSolver.h"
+class btIDebugDraw;
+#include "btContactConstraint.h"
+#include "btSolverBody.h"
+#include "btSolverConstraint.h"
+
+
+
+///The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (iterative LCP) method.
+class btSequentialImpulseConstraintSolver : public btConstraintSolver
+{
+protected:
+
+	btAlignedObjectArray<btSolverBody>	m_tmpSolverBodyPool;
+	btConstraintArray			m_tmpSolverContactConstraintPool;
+	btConstraintArray			m_tmpSolverNonContactConstraintPool;
+	btConstraintArray			m_tmpSolverContactFrictionConstraintPool;
+	btAlignedObjectArray<int>	m_orderTmpConstraintPool;
+	btAlignedObjectArray<int>	m_orderFrictionConstraintPool;
+
+	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);
+	
+	///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);
+	btScalar restitutionCurve(btScalar rel_vel, btScalar restitution);
+
+	void	convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal);
+
+	void	resolveSplitPenetrationImpulseCacheFriendly(
+        btSolverBody& body1,
+        btSolverBody& body2,
+        const btSolverConstraint& contactConstraint,
+        const btContactSolverInfo& solverInfo);
+
+	//internal method
+	int	getOrInitSolverBody(btCollisionObject& body);
+
+	void	resolveSingleConstraintRowGeneric(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);
+
+	void	resolveSingleConstraintRowGenericSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);
+	
+	void	resolveSingleConstraintRowLowerLimit(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);
+	
+	void	resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& body1,btSolverBody& body2,const btSolverConstraint& contactConstraint);
+		
+public:
+
+	
+	btSequentialImpulseConstraintSolver();
+	virtual ~btSequentialImpulseConstraintSolver();
+
+	virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher);
+	
+	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();
+	
+	unsigned long btRand2();
+
+	int btRandInt2 (int n);
+
+	void	setRandSeed(unsigned long seed)
+	{
+		m_btSeed2 = seed;
+	}
+	unsigned long	getRandSeed() const
+	{
+		return m_btSeed2;
+	}
+
+};
+
+#ifndef BT_PREFER_SIMD
+typedef btSequentialImpulseConstraintSolver btSequentialImpulseConstraintSolverPrefered;
+#endif
+
+
+#endif //SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp	(revision 6952)
@@ -0,0 +1,817 @@
+/*
+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.
+*/
+
+/*
+Added by Roman Ponomarev (rponom@gmail.com)
+April 04, 2008
+*/
+
+//-----------------------------------------------------------------------------
+
+#include "btSliderConstraint.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "LinearMath/btTransformUtil.h"
+#include <new>
+
+//-----------------------------------------------------------------------------
+
+void btSliderConstraint::initParams()
+{
+    m_lowerLinLimit = btScalar(1.0);
+    m_upperLinLimit = btScalar(-1.0);
+    m_lowerAngLimit = btScalar(0.);
+    m_upperAngLimit = btScalar(0.);
+	m_softnessDirLin = SLIDER_CONSTRAINT_DEF_SOFTNESS;
+	m_restitutionDirLin = SLIDER_CONSTRAINT_DEF_RESTITUTION;
+	m_dampingDirLin = btScalar(0.);
+	m_softnessDirAng = SLIDER_CONSTRAINT_DEF_SOFTNESS;
+	m_restitutionDirAng = SLIDER_CONSTRAINT_DEF_RESTITUTION;
+	m_dampingDirAng = btScalar(0.);
+	m_softnessOrthoLin = SLIDER_CONSTRAINT_DEF_SOFTNESS;
+	m_restitutionOrthoLin = SLIDER_CONSTRAINT_DEF_RESTITUTION;
+	m_dampingOrthoLin = SLIDER_CONSTRAINT_DEF_DAMPING;
+	m_softnessOrthoAng = SLIDER_CONSTRAINT_DEF_SOFTNESS;
+	m_restitutionOrthoAng = SLIDER_CONSTRAINT_DEF_RESTITUTION;
+	m_dampingOrthoAng = SLIDER_CONSTRAINT_DEF_DAMPING;
+	m_softnessLimLin = SLIDER_CONSTRAINT_DEF_SOFTNESS;
+	m_restitutionLimLin = SLIDER_CONSTRAINT_DEF_RESTITUTION;
+	m_dampingLimLin = SLIDER_CONSTRAINT_DEF_DAMPING;
+	m_softnessLimAng = SLIDER_CONSTRAINT_DEF_SOFTNESS;
+	m_restitutionLimAng = SLIDER_CONSTRAINT_DEF_RESTITUTION;
+	m_dampingLimAng = SLIDER_CONSTRAINT_DEF_DAMPING;
+
+	m_poweredLinMotor = false;
+    m_targetLinMotorVelocity = btScalar(0.);
+    m_maxLinMotorForce = btScalar(0.);
+	m_accumulatedLinMotorImpulse = btScalar(0.0);
+
+	m_poweredAngMotor = false;
+    m_targetAngMotorVelocity = btScalar(0.);
+    m_maxAngMotorForce = btScalar(0.);
+	m_accumulatedAngMotorImpulse = btScalar(0.0);
+
+} // btSliderConstraint::initParams()
+
+//-----------------------------------------------------------------------------
+
+btSliderConstraint::btSliderConstraint()
+        :btTypedConstraint(SLIDER_CONSTRAINT_TYPE),
+		m_useLinearReferenceFrameA(true),
+		m_useSolveConstraintObsolete(false)
+//		m_useSolveConstraintObsolete(true)
+{
+	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)
+{
+	initParams();
+} // btSliderConstraint::btSliderConstraint()
+
+//-----------------------------------------------------------------------------
+
+void btSliderConstraint::buildJacobian()
+{
+	if (!m_useSolveConstraintObsolete) 
+	{
+		return;
+	}
+	if(m_useLinearReferenceFrameA)
+	{
+		buildJacobianInt(m_rbA, m_rbB, m_frameInA, m_frameInB);
+	}
+	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;
+	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;
+	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;
+    //linear part
+    for(i = 0; i < 3; i++)
+    {
+		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;
+	}
+	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)
+{
+	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
+	// the slider axis should be the only unconstrained
+	// rotational axis, the angular velocity of the two bodies perpendicular to
+	// the slider 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 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];
+	info->m_J1angularAxis[2] = p[2];
+	info->m_J1angularAxis[s+0] = q[0];
+	info->m_J1angularAxis[s+1] = q[1];
+	info->m_J1angularAxis[s+2] = q[2];
+
+	info->m_J2angularAxis[0] = -p[0];
+	info->m_J2angularAxis[1] = -p[1];
+	info->m_J2angularAxis[2] = -p[2];
+	info->m_J2angularAxis[s+0] = -q[0];
+	info->m_J2angularAxis[s+1] = -q[1];
+	info->m_J2angularAxis[s+2] = -q[2];
+	// 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 "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.
+	btScalar k = info->fps * info->erp * getSoftnessOrthoAng();
+    btVector3 ax2 = trB.getBasis().getColumn(0);
+	btVector3 u = ax1.cross(ax2);
+	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
+	int srow;
+	// check linear limits linear
+	btScalar limit_err = btScalar(0.0);
+	int limit = 0;
+	if(getSolveLinLimit())
+	{
+		limit_err = getLinDepth() *  signFact;
+		limit = (limit_err > btScalar(0.0)) ? 2 : 1;
+	}
+	int powered = 0;
+	if(getPoweredLinMotor())
+	{
+		powered = 1;
+	}
+	// if the slider has joint limits or motor, add in the extra row
+	if (limit || powered) 
+	{
+		nrow++;
+		srow = nrow * info->rowskip;
+		info->m_J1linearAxis[srow+0] = ax1[0];
+		info->m_J1linearAxis[srow+1] = ax1[1];
+		info->m_J1linearAxis[srow+2] = ax1[2];
+		// linear torque decoupling step:
+		//
+		// we have to be careful that the linear constraint forces (+/- ax1) applied to the two bodies
+		// do not create a torque couple. in other words, the points that the
+		// constraint force is applied at must lie along the same ax1 axis.
+		// 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];
+		// right-hand part
+		btScalar lostop = getLowerLinLimit();
+		btScalar histop = getUpperLinLimit();
+		if(limit && (lostop == histop))
+		{  // the joint motor is ineffective
+			powered = 0;
+		}
+		info->m_constraintError[srow] = 0.;
+		info->m_lowerLimit[srow] = 0.;
+		info->m_upperLimit[srow] = 0.;
+		if(powered)
+		{
+            info->cfm[nrow] = btScalar(0.0); 
+			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();
+			info->m_constraintError[srow] -= signFact * mot_fact * getTargetLinMotorVelocity();
+			info->m_lowerLimit[srow] += -getMaxLinMotorForce() * info->fps;
+			info->m_upperLimit[srow] += getMaxLinMotorForce() * info->fps;
+		}
+		if(limit)
+		{
+			k = info->fps * info->erp;
+			info->m_constraintError[srow] += k * limit_err;
+			info->cfm[srow] = btScalar(0.0); // stop_cfm;
+			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] = -SIMD_INFINITY;
+				info->m_upperLimit[srow] = 0;
+			}
+			else 
+			{ // high limit
+				info->m_lowerLimit[srow] = 0;
+				info->m_upperLimit[srow] = SIMD_INFINITY;
+			}
+			// bounce (we'll use slider parameter abs(1.0 - m_dampingLimLin) for that)
+			btScalar bounce = btFabs(btScalar(1.0) - getDampingLimLin());
+			if(bounce > btScalar(0.0))
+			{
+				btScalar vel = m_rbA.getLinearVelocity().dot(ax1);
+				vel -= m_rbB.getLinearVelocity().dot(ax1);
+				vel *= signFact;
+				// 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] *= getSoftnessLimLin();
+		} // if(limit)
+	} // if linear limit
+	// check angular limits
+	limit_err = btScalar(0.0);
+	limit = 0;
+	if(getSolveAngLimit())
+	{
+		limit_err = getAngDepth();
+		limit = (limit_err > btScalar(0.0)) ? 1 : 2;
+	}
+	// if the slider has joint limits, add in the extra row
+	powered = 0;
+	if(getPoweredAngMotor())
+	{
+		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 = getLowerAngLimit();
+		btScalar histop = getUpperAngLimit();
+		if(limit && (lostop == histop))
+		{  // the joint motor is ineffective
+			powered = 0;
+		}
+		if(powered)
+		{
+            info->cfm[srow] = btScalar(0.0); 
+			btScalar mot_fact = getMotorFactor(m_angPos, m_lowerAngLimit, m_upperAngLimit, getTargetAngMotorVelocity(), info->fps * info->erp);
+			info->m_constraintError[srow] = mot_fact * getTargetAngMotorVelocity();
+			info->m_lowerLimit[srow] = -getMaxAngMotorForce() * info->fps;
+			info->m_upperLimit[srow] = getMaxAngMotorForce() * info->fps;
+		}
+		if(limit)
+		{
+			k = info->fps * info->erp;
+			info->m_constraintError[srow] += k * limit_err;
+			info->cfm[srow] = btScalar(0.0); // stop_cfm;
+			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 = btFabs(btScalar(1.0) - getDampingLimAng());
+			if(bounce > btScalar(0.0))
+			{
+				btScalar vel = m_rbA.getAngularVelocity().dot(ax1);
+				vel -= m_rbB.getAngularVelocity().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] *= getSoftnessLimAng();
+		} // 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);
+		}
+		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;
+		}
+		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();
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSliderConstraint.h	(revision 6952)
@@ -0,0 +1,229 @@
+/*
+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.
+*/
+
+/*
+Added by Roman Ponomarev (rponom@gmail.com)
+April 04, 2008
+
+TODO:
+ - add clamping od accumulated impulse to improve stability
+ - add conversion for ODE constraint solver
+*/
+
+#ifndef SLIDER_CONSTRAINT_H
+#define SLIDER_CONSTRAINT_H
+
+//-----------------------------------------------------------------------------
+
+#include "LinearMath/btVector3.h"
+#include "btJacobianEntry.h"
+#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))
+
+//-----------------------------------------------------------------------------
+
+class btSliderConstraint : public btTypedConstraint
+{
+protected:
+	///for backwards compatibility during the transition to 'getInfo/getInfo2'
+	bool		m_useSolveConstraintObsolete;
+	btTransform	m_frameInA;
+    btTransform	m_frameInB;
+	// use frameA fo define limits, if true
+	bool m_useLinearReferenceFrameA;
+	// linear limits
+	btScalar m_lowerLinLimit;
+	btScalar m_upperLinLimit;
+	// angular limits
+	btScalar m_lowerAngLimit;
+	btScalar m_upperAngLimit;
+	// softness, restitution and damping for different cases
+	// DirLin - moving inside linear limits
+	// LimLin - hitting linear limit
+	// DirAng - moving inside angular limits
+	// LimAng - hitting angular limit
+	// OrthoLin, OrthoAng - against constraint axis
+	btScalar m_softnessDirLin;
+	btScalar m_restitutionDirLin;
+	btScalar m_dampingDirLin;
+	btScalar m_softnessDirAng;
+	btScalar m_restitutionDirAng;
+	btScalar m_dampingDirAng;
+	btScalar m_softnessLimLin;
+	btScalar m_restitutionLimLin;
+	btScalar m_dampingLimLin;
+	btScalar m_softnessLimAng;
+	btScalar m_restitutionLimAng;
+	btScalar m_dampingLimAng;
+	btScalar m_softnessOrthoLin;
+	btScalar m_restitutionOrthoLin;
+	btScalar m_dampingOrthoLin;
+	btScalar m_softnessOrthoAng;
+	btScalar m_restitutionOrthoAng;
+	btScalar m_dampingOrthoAng;
+	
+	// for interlal use
+	bool m_solveLinLim;
+	bool m_solveAngLim;
+
+	btJacobianEntry	m_jacLin[3];
+	btScalar		m_jacLinDiagABInv[3];
+
+    btJacobianEntry	m_jacAng[3];
+
+	btScalar m_timeStep;
+    btTransform m_calculatedTransformA;
+    btTransform m_calculatedTransformB;
+
+	btVector3 m_sliderAxis;
+	btVector3 m_realPivotAInW;
+	btVector3 m_realPivotBInW;
+	btVector3 m_projPivotInW;
+	btVector3 m_delta;
+	btVector3 m_depth;
+	btVector3 m_relPosA;
+	btVector3 m_relPosB;
+
+	btScalar m_linPos;
+	btScalar m_angPos;
+
+	btScalar m_angDepth;
+	btScalar m_kAngle;
+
+	bool	 m_poweredLinMotor;
+    btScalar m_targetLinMotorVelocity;
+    btScalar m_maxLinMotorForce;
+    btScalar m_accumulatedLinMotorImpulse;
+	
+	bool	 m_poweredAngMotor;
+    btScalar m_targetAngMotorVelocity;
+    btScalar m_maxAngMotorForce;
+    btScalar m_accumulatedAngMotorImpulse;
+
+	//------------------------    
+	void initParams();
+public:
+	// constructors
+    btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA);
+    btSliderConstraint();
+	// overrides
+    virtual void	buildJacobian();
+    virtual void getInfo1 (btConstraintInfo1* info);
+	
+	virtual void getInfo2 (btConstraintInfo2* info);
+
+    virtual	void	solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar	timeStep);
+	
+
+	// access
+    const btRigidBody& getRigidBodyA() const { return m_rbA; }
+    const btRigidBody& getRigidBodyB() const { return m_rbB; }
+    const btTransform & getCalculatedTransformA() const { return m_calculatedTransformA; }
+    const btTransform & getCalculatedTransformB() const { return m_calculatedTransformB; }
+    const btTransform & getFrameOffsetA() const { return m_frameInA; }
+    const btTransform & getFrameOffsetB() const { return m_frameInB; }
+    btTransform & getFrameOffsetA() { return m_frameInA; }
+    btTransform & getFrameOffsetB() { return m_frameInB; }
+    btScalar getLowerLinLimit() { return m_lowerLinLimit; }
+    void setLowerLinLimit(btScalar lowerLimit) { m_lowerLinLimit = lowerLimit; }
+    btScalar getUpperLinLimit() { return m_upperLinLimit; }
+    void setUpperLinLimit(btScalar upperLimit) { m_upperLinLimit = upperLimit; }
+    btScalar getLowerAngLimit() { return m_lowerAngLimit; }
+    void setLowerAngLimit(btScalar lowerLimit) { m_lowerAngLimit = lowerLimit; }
+    btScalar getUpperAngLimit() { return m_upperAngLimit; }
+    void setUpperAngLimit(btScalar upperLimit) { m_upperAngLimit = upperLimit; }
+	bool getUseLinearReferenceFrameA() { return m_useLinearReferenceFrameA; }
+	btScalar getSoftnessDirLin() { return m_softnessDirLin; }
+	btScalar getRestitutionDirLin() { return m_restitutionDirLin; }
+	btScalar getDampingDirLin() { return m_dampingDirLin ; }
+	btScalar getSoftnessDirAng() { return m_softnessDirAng; }
+	btScalar getRestitutionDirAng() { return m_restitutionDirAng; }
+	btScalar getDampingDirAng() { return m_dampingDirAng; }
+	btScalar getSoftnessLimLin() { return m_softnessLimLin; }
+	btScalar getRestitutionLimLin() { return m_restitutionLimLin; }
+	btScalar getDampingLimLin() { return m_dampingLimLin; }
+	btScalar getSoftnessLimAng() { return m_softnessLimAng; }
+	btScalar getRestitutionLimAng() { return m_restitutionLimAng; }
+	btScalar getDampingLimAng() { return m_dampingLimAng; }
+	btScalar getSoftnessOrthoLin() { return m_softnessOrthoLin; }
+	btScalar getRestitutionOrthoLin() { return m_restitutionOrthoLin; }
+	btScalar getDampingOrthoLin() { return m_dampingOrthoLin; }
+	btScalar getSoftnessOrthoAng() { return m_softnessOrthoAng; }
+	btScalar getRestitutionOrthoAng() { return m_restitutionOrthoAng; }
+	btScalar getDampingOrthoAng() { return m_dampingOrthoAng; }
+	void setSoftnessDirLin(btScalar softnessDirLin) { m_softnessDirLin = softnessDirLin; }
+	void setRestitutionDirLin(btScalar restitutionDirLin) { m_restitutionDirLin = restitutionDirLin; }
+	void setDampingDirLin(btScalar dampingDirLin) { m_dampingDirLin = dampingDirLin; }
+	void setSoftnessDirAng(btScalar softnessDirAng) { m_softnessDirAng = softnessDirAng; }
+	void setRestitutionDirAng(btScalar restitutionDirAng) { m_restitutionDirAng = restitutionDirAng; }
+	void setDampingDirAng(btScalar dampingDirAng) { m_dampingDirAng = dampingDirAng; }
+	void setSoftnessLimLin(btScalar softnessLimLin) { m_softnessLimLin = softnessLimLin; }
+	void setRestitutionLimLin(btScalar restitutionLimLin) { m_restitutionLimLin = restitutionLimLin; }
+	void setDampingLimLin(btScalar dampingLimLin) { m_dampingLimLin = dampingLimLin; }
+	void setSoftnessLimAng(btScalar softnessLimAng) { m_softnessLimAng = softnessLimAng; }
+	void setRestitutionLimAng(btScalar restitutionLimAng) { m_restitutionLimAng = restitutionLimAng; }
+	void setDampingLimAng(btScalar dampingLimAng) { m_dampingLimAng = dampingLimAng; }
+	void setSoftnessOrthoLin(btScalar softnessOrthoLin) { m_softnessOrthoLin = softnessOrthoLin; }
+	void setRestitutionOrthoLin(btScalar restitutionOrthoLin) { m_restitutionOrthoLin = restitutionOrthoLin; }
+	void setDampingOrthoLin(btScalar dampingOrthoLin) { m_dampingOrthoLin = dampingOrthoLin; }
+	void setSoftnessOrthoAng(btScalar softnessOrthoAng) { m_softnessOrthoAng = softnessOrthoAng; }
+	void setRestitutionOrthoAng(btScalar restitutionOrthoAng) { m_restitutionOrthoAng = restitutionOrthoAng; }
+	void setDampingOrthoAng(btScalar dampingOrthoAng) { m_dampingOrthoAng = dampingOrthoAng; }
+	void setPoweredLinMotor(bool onOff) { m_poweredLinMotor = onOff; }
+	bool getPoweredLinMotor() { return m_poweredLinMotor; }
+	void setTargetLinMotorVelocity(btScalar targetLinMotorVelocity) { m_targetLinMotorVelocity = targetLinMotorVelocity; }
+	btScalar getTargetLinMotorVelocity() { return m_targetLinMotorVelocity; }
+	void setMaxLinMotorForce(btScalar maxLinMotorForce) { m_maxLinMotorForce = maxLinMotorForce; }
+	btScalar getMaxLinMotorForce() { return m_maxLinMotorForce; }
+	void setPoweredAngMotor(bool onOff) { m_poweredAngMotor = onOff; }
+	bool getPoweredAngMotor() { return m_poweredAngMotor; }
+	void setTargetAngMotorVelocity(btScalar targetAngMotorVelocity) { m_targetAngMotorVelocity = targetAngMotorVelocity; }
+	btScalar getTargetAngMotorVelocity() { return m_targetAngMotorVelocity; }
+	void setMaxAngMotorForce(btScalar maxAngMotorForce) { m_maxAngMotorForce = maxAngMotorForce; }
+	btScalar getMaxAngMotorForce() { return m_maxAngMotorForce; }
+	btScalar getLinearPos() { return m_linPos; }
+	
+
+	// access for ODE solver
+	bool getSolveLinLimit() { return m_solveLinLim; }
+	btScalar getLinDepth() { return m_depth[0]; }
+	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);
+	// access for PE Solver
+	btVector3 getAncorInA(void);
+	btVector3 getAncorInB(void);
+};
+
+//-----------------------------------------------------------------------------
+
+#endif //SLIDER_CONSTRAINT_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp	(revision 6952)
@@ -0,0 +1,255 @@
+/*
+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 "btSolve2LinearConstraint.h"
+
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "LinearMath/btVector3.h"
+#include "btJacobianEntry.h"
+
+
+void btSolve2LinearConstraint::resolveUnilateralPairConstraint(
+												   btRigidBody* body1,
+		btRigidBody* body2,
+
+						const btMatrix3x3& world2A,
+						const btMatrix3x3& world2B,
+						
+						const btVector3& invInertiaADiag,
+						const btScalar invMassA,
+						const btVector3& linvelA,const btVector3& angvelA,
+						const btVector3& rel_posA1,
+						const btVector3& invInertiaBDiag,
+						const btScalar invMassB,
+						const btVector3& linvelB,const btVector3& angvelB,
+						const btVector3& rel_posA2,
+
+					  btScalar depthA, const btVector3& normalA, 
+					  const btVector3& rel_posB1,const btVector3& rel_posB2,
+					  btScalar depthB, const btVector3& normalB, 
+					  btScalar& imp0,btScalar& imp1)
+{
+	(void)linvelA;
+	(void)linvelB;
+	(void)angvelB;
+	(void)angvelA;
+
+
+
+	imp0 = btScalar(0.);
+	imp1 = btScalar(0.);
+
+	btScalar len = btFabs(normalA.length()) - btScalar(1.);
+	if (btFabs(len) >= SIMD_EPSILON)
+		return;
+
+	btAssert(len < SIMD_EPSILON);
+
+
+	//this jacobian entry could be re-used for all iterations
+	btJacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA,
+		invInertiaBDiag,invMassB);
+	btJacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA,
+		invInertiaBDiag,invMassB);
+	
+	//const btScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB);
+	//const btScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB);
+
+	const btScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1));
+	const btScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1));
+
+//	btScalar penetrationImpulse = (depth*contactTau*timeCorrection)  * massTerm;//jacDiagABInv
+	btScalar massTerm = btScalar(1.) / (invMassA + invMassB);
+
+
+	// calculate rhs (or error) terms
+	const btScalar dv0 = depthA  * m_tau * massTerm - vel0 * m_damping;
+	const btScalar dv1 = depthB  * m_tau * massTerm - vel1 * m_damping;
+
+
+	// dC/dv * dv = -C
+	
+	// jacobian * impulse = -error
+	//
+
+	//impulse = jacobianInverse * -error
+
+	// inverting 2x2 symmetric system (offdiagonal are equal!)
+	// 
+
+
+	btScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB);
+	btScalar	invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag );
+	
+	//imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet;
+	//imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet;
+
+	imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet;
+	imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet;
+
+	//[a b]								  [d -c]
+	//[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc)
+
+	//[jA nD] * [imp0] = [dv0]
+	//[nD jB]   [imp1]   [dv1]
+
+}
+
+
+
+void btSolve2LinearConstraint::resolveBilateralPairConstraint(
+						btRigidBody* body1,
+						btRigidBody* body2,
+						const btMatrix3x3& world2A,
+						const btMatrix3x3& world2B,
+						
+						const btVector3& invInertiaADiag,
+						const btScalar invMassA,
+						const btVector3& linvelA,const btVector3& angvelA,
+						const btVector3& rel_posA1,
+						const btVector3& invInertiaBDiag,
+						const btScalar invMassB,
+						const btVector3& linvelB,const btVector3& angvelB,
+						const btVector3& rel_posA2,
+
+					  btScalar depthA, const btVector3& normalA, 
+					  const btVector3& rel_posB1,const btVector3& rel_posB2,
+					  btScalar depthB, const btVector3& normalB, 
+					  btScalar& imp0,btScalar& imp1)
+{
+
+	(void)linvelA;
+	(void)linvelB;
+	(void)angvelA;
+	(void)angvelB;
+
+
+
+	imp0 = btScalar(0.);
+	imp1 = btScalar(0.);
+
+	btScalar len = btFabs(normalA.length()) - btScalar(1.);
+	if (btFabs(len) >= SIMD_EPSILON)
+		return;
+
+	btAssert(len < SIMD_EPSILON);
+
+
+	//this jacobian entry could be re-used for all iterations
+	btJacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA,
+		invInertiaBDiag,invMassB);
+	btJacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA,
+		invInertiaBDiag,invMassB);
+	
+	//const btScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB);
+	//const btScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB);
+
+	const btScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1));
+	const btScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1));
+
+	// calculate rhs (or error) terms
+	const btScalar dv0 = depthA  * m_tau - vel0 * m_damping;
+	const btScalar dv1 = depthB  * m_tau - vel1 * m_damping;
+
+	// dC/dv * dv = -C
+	
+	// jacobian * impulse = -error
+	//
+
+	//impulse = jacobianInverse * -error
+
+	// inverting 2x2 symmetric system (offdiagonal are equal!)
+	// 
+
+
+	btScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB);
+	btScalar	invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag );
+	
+	//imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet;
+	//imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet;
+
+	imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet;
+	imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet;
+
+	//[a b]								  [d -c]
+	//[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc)
+
+	//[jA nD] * [imp0] = [dv0]
+	//[nD jB]   [imp1]   [dv1]
+
+	if ( imp0 > btScalar(0.0))
+	{
+		if ( imp1 > btScalar(0.0) )
+		{
+			//both positive
+		}
+		else
+		{
+			imp1 = btScalar(0.);
+
+			// now imp0>0 imp1<0
+			imp0 = dv0 / jacA.getDiagonal();
+			if ( imp0 > btScalar(0.0) )
+			{
+			} else
+			{
+				imp0 = btScalar(0.);
+			}
+		}
+	}
+	else
+	{
+		imp0 = btScalar(0.);
+
+		imp1 = dv1 / jacB.getDiagonal();
+		if ( imp1 <= btScalar(0.0) )
+		{
+			imp1 = btScalar(0.);
+			// now imp0>0 imp1<0
+			imp0 = dv0 / jacA.getDiagonal();
+			if ( imp0 > btScalar(0.0) )
+			{
+			} else
+			{
+				imp0 = btScalar(0.);
+			}
+		} else
+		{
+		}
+	}
+}
+
+
+/*
+void btSolve2LinearConstraint::resolveAngularConstraint(	const btMatrix3x3& invInertiaAWS,
+											const btScalar invMassA,
+											const btVector3& linvelA,const btVector3& angvelA,
+											const btVector3& rel_posA1,
+											const btMatrix3x3& invInertiaBWS,
+											const btScalar invMassB,
+											const btVector3& linvelB,const btVector3& angvelB,
+											const btVector3& rel_posA2,
+
+											btScalar depthA, const btVector3& normalA, 
+											const btVector3& rel_posB1,const btVector3& rel_posB2,
+											btScalar depthB, const btVector3& normalB, 
+											btScalar& imp0,btScalar& imp1)
+{
+
+}
+*/
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h	(revision 6952)
@@ -0,0 +1,107 @@
+/*
+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 SOLVE_2LINEAR_CONSTRAINT_H
+#define SOLVE_2LINEAR_CONSTRAINT_H
+
+#include "LinearMath/btMatrix3x3.h"
+#include "LinearMath/btVector3.h"
+
+
+class btRigidBody;
+
+
+
+/// constraint class used for lateral tyre friction.
+class	btSolve2LinearConstraint
+{
+	btScalar	m_tau;
+	btScalar	m_damping;
+
+public:
+
+	btSolve2LinearConstraint(btScalar tau,btScalar damping)
+	{
+		m_tau = tau;
+		m_damping = damping;
+	}
+	//
+	// solve unilateral constraint (equality, direct method)
+	//
+	void resolveUnilateralPairConstraint(		
+														   btRigidBody* body0,
+		btRigidBody* body1,
+
+		const btMatrix3x3& world2A,
+						const btMatrix3x3& world2B,
+						
+						const btVector3& invInertiaADiag,
+						const btScalar invMassA,
+						const btVector3& linvelA,const btVector3& angvelA,
+						const btVector3& rel_posA1,
+						const btVector3& invInertiaBDiag,
+						const btScalar invMassB,
+						const btVector3& linvelB,const btVector3& angvelB,
+						const btVector3& rel_posA2,
+
+					  btScalar depthA, const btVector3& normalA, 
+					  const btVector3& rel_posB1,const btVector3& rel_posB2,
+					  btScalar depthB, const btVector3& normalB, 
+					  btScalar& imp0,btScalar& imp1);
+
+
+	//
+	// solving 2x2 lcp problem (inequality, direct solution )
+	//
+	void resolveBilateralPairConstraint(
+			btRigidBody* body0,
+						btRigidBody* body1,
+		const btMatrix3x3& world2A,
+						const btMatrix3x3& world2B,
+						
+						const btVector3& invInertiaADiag,
+						const btScalar invMassA,
+						const btVector3& linvelA,const btVector3& angvelA,
+						const btVector3& rel_posA1,
+						const btVector3& invInertiaBDiag,
+						const btScalar invMassB,
+						const btVector3& linvelB,const btVector3& angvelB,
+						const btVector3& rel_posA2,
+
+					  btScalar depthA, const btVector3& normalA, 
+					  const btVector3& rel_posB1,const btVector3& rel_posB2,
+					  btScalar depthB, const btVector3& normalB, 
+					  btScalar& imp0,btScalar& imp1);
+
+/*
+	void resolveAngularConstraint(	const btMatrix3x3& invInertiaAWS,
+						const btScalar invMassA,
+						const btVector3& linvelA,const btVector3& angvelA,
+						const btVector3& rel_posA1,
+						const btMatrix3x3& invInertiaBWS,
+						const btScalar invMassB,
+						const btVector3& linvelB,const btVector3& angvelB,
+						const btVector3& rel_posA2,
+
+					  btScalar depthA, const btVector3& normalA, 
+					  const btVector3& rel_posB1,const btVector3& rel_posB2,
+					  btScalar depthB, const btVector3& normalB, 
+					  btScalar& imp0,btScalar& imp1);
+
+*/
+
+};
+
+#endif //SOLVE_2LINEAR_CONSTRAINT_H
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolverBody.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolverBody.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolverBody.h	(revision 6952)
@@ -0,0 +1,179 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_SOLVER_BODY_H
+#define BT_SOLVER_BODY_H
+
+class	btRigidBody;
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btMatrix3x3.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "LinearMath/btAlignedAllocator.h"
+#include "LinearMath/btTransformUtil.h"
+
+///Until we get other contributions, only use SIMD on Windows, when using Visual Studio 2008 or later, and not double precision
+#ifdef BT_USE_SSE
+#define USE_SIMD 1
+#endif //
+
+
+#ifdef USE_SIMD
+
+struct	btSimdScalar
+{
+	SIMD_FORCE_INLINE	btSimdScalar()
+	{
+
+	}
+
+	SIMD_FORCE_INLINE	btSimdScalar(float	fl)
+	:m_vec128 (_mm_set1_ps(fl))
+	{
+	}
+
+	SIMD_FORCE_INLINE	btSimdScalar(__m128 v128)
+		:m_vec128(v128)
+	{
+	}
+	union
+	{
+		__m128		m_vec128;
+		float		m_floats[4];
+		int			m_ints[4];
+		btScalar	m_unusedPadding;
+	};
+	SIMD_FORCE_INLINE	__m128	get128()
+	{
+		return m_vec128;
+	}
+
+	SIMD_FORCE_INLINE	const __m128	get128() const
+	{
+		return m_vec128;
+	}
+
+	SIMD_FORCE_INLINE	void	set128(__m128 v128)
+	{
+		m_vec128 = v128;
+	}
+
+	SIMD_FORCE_INLINE	operator       __m128()       
+	{ 
+		return m_vec128; 
+	}
+	SIMD_FORCE_INLINE	operator const __m128() const 
+	{ 
+		return m_vec128; 
+	}
+	
+	SIMD_FORCE_INLINE	operator float() const 
+	{ 
+		return m_floats[0]; 
+	}
+
+};
+
+///@brief Return the elementwise product of two btSimdScalar
+SIMD_FORCE_INLINE btSimdScalar 
+operator*(const btSimdScalar& v1, const btSimdScalar& v2) 
+{
+	return btSimdScalar(_mm_mul_ps(v1.get128(),v2.get128()));
+}
+
+///@brief Return the elementwise product of two btSimdScalar
+SIMD_FORCE_INLINE btSimdScalar 
+operator+(const btSimdScalar& v1, const btSimdScalar& v2) 
+{
+	return btSimdScalar(_mm_add_ps(v1.get128(),v2.get128()));
+}
+
+
+#else
+#define btSimdScalar btScalar
+#endif
+
+///The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance.
+ATTRIBUTE_ALIGNED16 (struct)	btSolverBody
+{
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+	btVector3		m_deltaLinearVelocity;
+	btVector3		m_deltaAngularVelocity;
+	btScalar		m_angularFactor;
+	btScalar		m_invMass;
+	btScalar		m_friction;
+	btRigidBody*	m_originalBody;
+	btVector3		m_pushVelocity;
+	//btVector3		m_turnVelocity;	
+
+	
+	SIMD_FORCE_INLINE void	getVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const
+	{
+		if (m_originalBody)
+			velocity = m_originalBody->getLinearVelocity()+m_deltaLinearVelocity + (m_originalBody->getAngularVelocity()+m_deltaAngularVelocity).cross(rel_pos);
+		else
+			velocity.setValue(0,0,0);
+	}
+
+	SIMD_FORCE_INLINE void	getAngularVelocity(btVector3& angVel) const
+	{
+		if (m_originalBody)
+			angVel = m_originalBody->getAngularVelocity()+m_deltaAngularVelocity;
+		else
+			angVel.setValue(0,0,0);
+	}
+
+
+	//Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position
+	SIMD_FORCE_INLINE void applyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,const btScalar impulseMagnitude)
+	{
+		//if (m_invMass)
+		{
+			m_deltaLinearVelocity += linearComponent*impulseMagnitude;
+			m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor);
+		}
+	}
+
+	
+/*
+	
+	void	writebackVelocity()
+	{
+		if (m_invMass)
+		{
+			m_originalBody->setLinearVelocity(m_originalBody->getLinearVelocity()+ m_deltaLinearVelocity);
+			m_originalBody->setAngularVelocity(m_originalBody->getAngularVelocity()+m_deltaAngularVelocity);
+			
+			//m_originalBody->setCompanionId(-1);
+		}
+	}
+	*/
+
+	void	writebackVelocity(btScalar timeStep=0)
+	{
+		if (m_invMass)
+		{
+			m_originalBody->setLinearVelocity(m_originalBody->getLinearVelocity()+m_deltaLinearVelocity);
+			m_originalBody->setAngularVelocity(m_originalBody->getAngularVelocity()+m_deltaAngularVelocity);
+			//m_originalBody->setCompanionId(-1);
+		}
+	}
+	
+
+
+};
+
+#endif //BT_SOLVER_BODY_H
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolverConstraint.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolverConstraint.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btSolverConstraint.h	(revision 6952)
@@ -0,0 +1,94 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_SOLVER_CONSTRAINT_H
+#define BT_SOLVER_CONSTRAINT_H
+
+class	btRigidBody;
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btMatrix3x3.h"
+#include "btJacobianEntry.h"
+
+//#define NO_FRICTION_TANGENTIALS 1
+#include "btSolverBody.h"
+
+
+///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints.
+ATTRIBUTE_ALIGNED16 (struct)	btSolverConstraint
+{
+	BT_DECLARE_ALIGNED_ALLOCATOR();
+
+	btVector3		m_relpos1CrossNormal;
+	btVector3		m_contactNormal;
+
+	btVector3		m_relpos2CrossNormal;
+	//btVector3		m_contactNormal2;//usually m_contactNormal2 == -m_contactNormal
+
+	btVector3		m_angularComponentA;
+	btVector3		m_angularComponentB;
+	
+	mutable btSimdScalar	m_appliedPushImpulse;
+	mutable btSimdScalar	m_appliedImpulse;
+	
+	
+	btScalar	m_friction;
+	btScalar	m_jacDiagABInv;
+	union
+	{
+		int	m_numConsecutiveRowsPerKernel;
+		btScalar	m_unusedPadding0;
+	};
+
+	union
+	{
+		int			m_frictionIndex;
+		btScalar	m_unusedPadding1;
+	};
+	union
+	{
+		int			m_solverBodyIdA;
+		btScalar	m_unusedPadding2;
+	};
+	union
+	{
+		int			m_solverBodyIdB;
+		btScalar	m_unusedPadding3;
+	};
+	
+	union
+	{
+		void*		m_originalContactPoint;
+		btScalar	m_unusedPadding4;
+	};
+
+	btScalar		m_rhs;
+	btScalar		m_cfm;
+	btScalar		m_lowerLimit;
+	btScalar		m_upperLimit;
+
+	enum		btSolverConstraintType
+	{
+		BT_SOLVER_CONTACT_1D = 0,
+		BT_SOLVER_FRICTION_1D
+	};
+};
+
+typedef btAlignedObjectArray<btSolverConstraint>	btConstraintArray;
+
+
+#endif //BT_SOLVER_CONSTRAINT_H
+
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp	(revision 6952)
@@ -0,0 +1,114 @@
+/*
+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 "btTypedConstraint.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+
+static btRigidBody s_fixed(0, 0,0);
+
+#define DEFAULT_DEBUGDRAW_SIZE btScalar(0.3f)
+
+btTypedConstraint::btTypedConstraint(btTypedConstraintType type)
+:m_userConstraintType(-1),
+m_userConstraintId(-1),
+m_constraintType (type),
+m_rbA(s_fixed),
+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)
+: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),
+m_userConstraintId(-1),
+m_constraintType (type),
+m_rbA(rbA),
+m_rbB(rbB),
+m_appliedImpulse(btScalar(0.)),
+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)
+{
+	if(lowLim > uppLim)
+	{
+		return btScalar(1.0f);
+	}
+	else if(lowLim == uppLim)
+	{
+		return btScalar(0.0f);
+	}
+	btScalar lim_fact = btScalar(1.0f);
+	btScalar delta_max = vel / timeFact;
+	if(delta_max < btScalar(0.0f))
+	{
+		if((pos >= lowLim) && (pos < (lowLim - delta_max)))
+		{
+			lim_fact = (lowLim - pos) / delta_max;
+		}
+		else if(pos  < lowLim)
+		{
+			lim_fact = btScalar(0.0f);
+		}
+		else
+		{
+			lim_fact = btScalar(1.0f);
+		}
+	}
+	else if(delta_max > btScalar(0.0f))
+	{
+		if((pos <= uppLim) && (pos > (uppLim - delta_max)))
+		{
+			lim_fact = (uppLim - pos) / delta_max;
+		}
+		else if(pos  > uppLim)
+		{
+			lim_fact = btScalar(0.0f);
+		}
+		else
+		{
+			lim_fact = btScalar(1.0f);
+		}
+	}
+	else
+	{
+			lim_fact = btScalar(0.0f);
+	}
+	return lim_fact;
+} // btTypedConstraint::getMotorFactor()
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btTypedConstraint.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btTypedConstraint.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/ConstraintSolver/btTypedConstraint.h	(revision 6952)
@@ -0,0 +1,176 @@
+/*
+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 TYPED_CONSTRAINT_H
+#define TYPED_CONSTRAINT_H
+
+class btRigidBody;
+#include "LinearMath/btScalar.h"
+#include "btSolverConstraint.h"
+struct  btSolverBody;
+
+
+
+
+enum btTypedConstraintType
+{
+	POINT2POINT_CONSTRAINT_TYPE,
+	HINGE_CONSTRAINT_TYPE,
+	CONETWIST_CONSTRAINT_TYPE,
+	D6_CONSTRAINT_TYPE,
+	SLIDER_CONSTRAINT_TYPE
+};
+
+///TypedConstraint is the baseclass for Bullet constraints and vehicles
+class btTypedConstraint
+{
+	int	m_userConstraintType;
+	int	m_userConstraintId;
+
+	btTypedConstraintType m_constraintType;
+
+	btTypedConstraint&	operator=(btTypedConstraint&	other)
+	{
+		btAssert(0);
+		(void) other;
+		return *this;
+	}
+
+protected:
+	btRigidBody&	m_rbA;
+	btRigidBody&	m_rbB;
+	btScalar	m_appliedImpulse;
+	btScalar	m_dbgDrawSize;
+
+
+public:
+
+	btTypedConstraint(btTypedConstraintType type);
+	virtual ~btTypedConstraint() {};
+	btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA);
+	btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB);
+
+	struct btConstraintInfo1 {
+		int m_numConstraintRows,nub;
+	};
+
+	struct btConstraintInfo2 {
+		// integrator parameters: frames per second (1/stepsize), default error
+		// reduction parameter (0..1).
+		btScalar fps,erp;
+
+		// for the first and second body, pointers to two (linear and angular)
+		// n*3 jacobian sub matrices, stored by rows. these matrices will have
+		// been initialized to 0 on entry. if the second body is zero then the
+		// J2xx pointers may be 0.
+		btScalar *m_J1linearAxis,*m_J1angularAxis,*m_J2linearAxis,*m_J2angularAxis;
+
+		// elements to jump from one row to the next in J's
+		int rowskip;
+
+		// right hand sides of the equation J*v = c + cfm * lambda. cfm is the
+		// "constraint force mixing" vector. c is set to zero on entry, cfm is
+		// set to a constant value (typically very small or zero) value on entry.
+		btScalar *m_constraintError,*cfm;
+
+		// lo and hi limits for variables (set to -/+ infinity on entry).
+		btScalar *m_lowerLimit,*m_upperLimit;
+
+		// findex vector for variables. see the LCP solver interface for a
+		// description of what this does. this is set to -1 on entry.
+		// note that the returned indexes are relative to the first index of
+		// the constraint.
+		int *findex;
+	};
+
+
+	virtual void	buildJacobian() = 0;
+
+	virtual	void	setupSolverConstraint(btConstraintArray& ca, int solverBodyA,int solverBodyB, btScalar timeStep)
+	{
+	}
+	virtual void getInfo1 (btConstraintInfo1* info)=0;
+
+	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);
+	
+	const btRigidBody& getRigidBodyA() const
+	{
+		return m_rbA;
+	}
+	const btRigidBody& getRigidBodyB() const
+	{
+		return m_rbB;
+	}
+
+	btRigidBody& getRigidBodyA() 
+	{
+		return m_rbA;
+	}
+	btRigidBody& getRigidBodyB()
+	{
+		return m_rbB;
+	}
+
+	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;
+	}
+
+	int getUid() const
+	{
+		return m_userConstraintId;   
+	} 
+
+	btScalar	getAppliedImpulse() const
+	{
+		return m_appliedImpulse;
+	}
+
+	btTypedConstraintType getConstraintType () const
+	{
+		return m_constraintType;
+	}
+	
+	void setDbgDrawSize(btScalar dbgDrawSize)
+	{
+		m_dbgDrawSize = dbgDrawSize;
+	}
+	btScalar getDbgDrawSize()
+	{
+		return m_dbgDrawSize;
+	}
+	
+};
+
+#endif //TYPED_CONSTRAINT_H
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/Bullet-C-API.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/Bullet-C-API.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/Bullet-C-API.cpp	(revision 6952)
@@ -0,0 +1,400 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+	Draft high-level generic physics C-API. For low-level access, use the physics SDK native API's.
+	Work in progress, functionality will be added on demand.
+
+	If possible, use the richer Bullet C++ API, by including <src/btBulletDynamicsCommon.h>
+*/
+
+#include "Bullet-C-Api.h"
+#include "btBulletDynamicsCommon.h"
+#include "LinearMath/btAlignedAllocator.h"
+
+
+
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btScalar.h"	
+#include "LinearMath/btMatrix3x3.h"
+#include "LinearMath/btTransform.h"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+#include "BulletCollision/CollisionShapes/btTriangleShape.h"
+
+#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h"
+#include "BulletCollision/NarrowPhaseCollision/btPointCollector.h"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h"
+#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h"
+#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.h"
+#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
+#include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h"
+#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h"
+#include "LinearMath/btStackAlloc.h"
+
+/*
+	Create and Delete a Physics SDK	
+*/
+
+struct	btPhysicsSdk
+{
+
+//	btDispatcher*				m_dispatcher;
+//	btOverlappingPairCache*		m_pairCache;
+//	btConstraintSolver*			m_constraintSolver
+
+	btVector3	m_worldAabbMin;
+	btVector3	m_worldAabbMax;
+
+
+	//todo: version, hardware/optimization settings etc?
+	btPhysicsSdk()
+		:m_worldAabbMin(-1000,-1000,-1000),
+		m_worldAabbMax(1000,1000,1000)
+	{
+
+	}
+
+	
+};
+
+plPhysicsSdkHandle	plNewBulletSdk()
+{
+	void* mem = btAlignedAlloc(sizeof(btPhysicsSdk),16);
+	return (plPhysicsSdkHandle)new (mem)btPhysicsSdk;
+}
+
+void		plDeletePhysicsSdk(plPhysicsSdkHandle	physicsSdk)
+{
+	btPhysicsSdk* phys = reinterpret_cast<btPhysicsSdk*>(physicsSdk);
+	btAlignedFree(phys);	
+}
+
+
+/* Dynamics World */
+plDynamicsWorldHandle plCreateDynamicsWorld(plPhysicsSdkHandle physicsSdkHandle)
+{
+	btPhysicsSdk* physicsSdk = reinterpret_cast<btPhysicsSdk*>(physicsSdkHandle);
+	void* mem = btAlignedAlloc(sizeof(btDefaultCollisionConfiguration),16);
+	btDefaultCollisionConfiguration* collisionConfiguration = new (mem)btDefaultCollisionConfiguration();
+	mem = btAlignedAlloc(sizeof(btCollisionDispatcher),16);
+	btDispatcher*				dispatcher = new (mem)btCollisionDispatcher(collisionConfiguration);
+	mem = btAlignedAlloc(sizeof(btAxisSweep3),16);
+	btBroadphaseInterface*		pairCache = new (mem)btAxisSweep3(physicsSdk->m_worldAabbMin,physicsSdk->m_worldAabbMax);
+	mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16);
+	btConstraintSolver*			constraintSolver = new(mem) btSequentialImpulseConstraintSolver();
+
+	mem = btAlignedAlloc(sizeof(btDiscreteDynamicsWorld),16);
+	return (plDynamicsWorldHandle) new (mem)btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration);
+}
+void           plDeleteDynamicsWorld(plDynamicsWorldHandle world)
+{
+	//todo: also clean up the other allocations, axisSweep, pairCache,dispatcher,constraintSolver,collisionConfiguration
+	btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);
+	btAlignedFree(dynamicsWorld);
+}
+
+void	plStepSimulation(plDynamicsWorldHandle world,	plReal	timeStep)
+{
+	btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);
+	btAssert(dynamicsWorld);
+	dynamicsWorld->stepSimulation(timeStep);
+}
+
+void plAddRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object)
+{
+	btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);
+	btAssert(dynamicsWorld);
+	btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
+	btAssert(body);
+
+	dynamicsWorld->addRigidBody(body);
+}
+
+void plRemoveRigidBody(plDynamicsWorldHandle world, plRigidBodyHandle object)
+{
+	btDynamicsWorld* dynamicsWorld = reinterpret_cast< btDynamicsWorld* >(world);
+	btAssert(dynamicsWorld);
+	btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
+	btAssert(body);
+
+	dynamicsWorld->removeRigidBody(body);
+}
+
+/* Rigid Body  */
+
+plRigidBodyHandle plCreateRigidBody(	void* user_data,  float mass, plCollisionShapeHandle cshape )
+{
+	btTransform trans;
+	trans.setIdentity();
+	btVector3 localInertia(0,0,0);
+	btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);
+	btAssert(shape);
+	if (mass)
+	{
+		shape->calculateLocalInertia(mass,localInertia);
+	}
+	void* mem = btAlignedAlloc(sizeof(btRigidBody),16);
+	btRigidBody::btRigidBodyConstructionInfo rbci(mass, 0,shape,localInertia);
+	btRigidBody* body = new (mem)btRigidBody(rbci);
+	body->setWorldTransform(trans);
+	body->setUserPointer(user_data);
+	return (plRigidBodyHandle) body;
+}
+
+void plDeleteRigidBody(plRigidBodyHandle cbody)
+{
+	btRigidBody* body = reinterpret_cast< btRigidBody* >(cbody);
+	btAssert(body);
+	btAlignedFree( body);
+}
+
+
+/* Collision Shape definition */
+
+plCollisionShapeHandle plNewSphereShape(plReal radius)
+{
+	void* mem = btAlignedAlloc(sizeof(btSphereShape),16);
+	return (plCollisionShapeHandle) new (mem)btSphereShape(radius);
+	
+}
+	
+plCollisionShapeHandle plNewBoxShape(plReal x, plReal y, plReal z)
+{
+	void* mem = btAlignedAlloc(sizeof(btBoxShape),16);
+	return (plCollisionShapeHandle) new (mem)btBoxShape(btVector3(x,y,z));
+}
+
+plCollisionShapeHandle plNewCapsuleShape(plReal radius, plReal height)
+{
+	//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);
+}
+plCollisionShapeHandle plNewConeShape(plReal radius, plReal height)
+{
+	void* mem = btAlignedAlloc(sizeof(btConeShape),16);
+	return (plCollisionShapeHandle) new (mem)btConeShape(radius,height);
+}
+
+plCollisionShapeHandle plNewCylinderShape(plReal radius, plReal height)
+{
+	void* mem = btAlignedAlloc(sizeof(btCylinderShape),16);
+	return (plCollisionShapeHandle) new (mem)btCylinderShape(btVector3(radius,height,radius));
+}
+
+/* Convex Meshes */
+plCollisionShapeHandle plNewConvexHullShape()
+{
+	void* mem = btAlignedAlloc(sizeof(btConvexHullShape),16);
+	return (plCollisionShapeHandle) new (mem)btConvexHullShape();
+}
+
+
+/* Concave static triangle meshes */
+plMeshInterfaceHandle		   plNewMeshInterface()
+{
+	return 0;
+}
+
+plCollisionShapeHandle plNewCompoundShape()
+{
+	void* mem = btAlignedAlloc(sizeof(btCompoundShape),16);
+	return (plCollisionShapeHandle) new (mem)btCompoundShape();
+}
+
+void	plAddChildShape(plCollisionShapeHandle compoundShapeHandle,plCollisionShapeHandle childShapeHandle, plVector3 childPos,plQuaternion childOrn)
+{
+	btCollisionShape* colShape = reinterpret_cast<btCollisionShape*>(compoundShapeHandle);
+	btAssert(colShape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE);
+	btCompoundShape* compoundShape = reinterpret_cast<btCompoundShape*>(colShape);
+	btCollisionShape* childShape = reinterpret_cast<btCollisionShape*>(childShapeHandle);
+	btTransform	localTrans;
+	localTrans.setIdentity();
+	localTrans.setOrigin(btVector3(childPos[0],childPos[1],childPos[2]));
+	localTrans.setRotation(btQuaternion(childOrn[0],childOrn[1],childOrn[2],childOrn[3]));
+	compoundShape->addChildShape(localTrans,childShape);
+}
+
+void plSetEuler(plReal yaw,plReal pitch,plReal roll, plQuaternion orient)
+{
+	btQuaternion orn;
+	orn.setEuler(yaw,pitch,roll);
+	orient[0] = orn.getX();
+	orient[1] = orn.getY();
+	orient[2] = orn.getZ();
+	orient[3] = orn.getW();
+
+}
+
+
+//	extern  void		plAddTriangle(plMeshInterfaceHandle meshHandle, plVector3 v0,plVector3 v1,plVector3 v2);
+//	extern  plCollisionShapeHandle plNewStaticTriangleMeshShape(plMeshInterfaceHandle);
+
+
+void		plAddVertex(plCollisionShapeHandle cshape, plReal x,plReal y,plReal z)
+{
+	btCollisionShape* colShape = reinterpret_cast<btCollisionShape*>( cshape);
+	(void)colShape;
+	btAssert(colShape->getShapeType()==CONVEX_HULL_SHAPE_PROXYTYPE);
+	btConvexHullShape* convexHullShape = reinterpret_cast<btConvexHullShape*>( cshape);
+	convexHullShape->addPoint(btVector3(x,y,z));
+
+}
+
+void plDeleteShape(plCollisionShapeHandle cshape)
+{
+	btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);
+	btAssert(shape);
+	btAlignedFree(shape);
+}
+void plSetScaling(plCollisionShapeHandle cshape, plVector3 cscaling)
+{
+	btCollisionShape* shape = reinterpret_cast<btCollisionShape*>( cshape);
+	btAssert(shape);
+	btVector3 scaling(cscaling[0],cscaling[1],cscaling[2]);
+	shape->setLocalScaling(scaling);	
+}
+
+
+
+void plSetPosition(plRigidBodyHandle object, const plVector3 position)
+{
+	btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
+	btAssert(body);
+	btVector3 pos(position[0],position[1],position[2]);
+	btTransform worldTrans = body->getWorldTransform();
+	worldTrans.setOrigin(pos);
+	body->setWorldTransform(worldTrans);
+}
+
+void plSetOrientation(plRigidBodyHandle object, const plQuaternion orientation)
+{
+	btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
+	btAssert(body);
+	btQuaternion orn(orientation[0],orientation[1],orientation[2],orientation[3]);
+	btTransform worldTrans = body->getWorldTransform();
+	worldTrans.setRotation(orn);
+	body->setWorldTransform(worldTrans);
+}
+
+void	plGetOpenGLMatrix(plRigidBodyHandle object, plReal* matrix)
+{
+	btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
+	btAssert(body);
+	body->getWorldTransform().getOpenGLMatrix(matrix);
+
+}
+
+void	plGetPosition(plRigidBodyHandle object,plVector3 position)
+{
+	btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
+	btAssert(body);
+	const btVector3& pos = body->getWorldTransform().getOrigin();
+	position[0] = pos.getX();
+	position[1] = pos.getY();
+	position[2] = pos.getZ();
+}
+
+void plGetOrientation(plRigidBodyHandle object,plQuaternion orientation)
+{
+	btRigidBody* body = reinterpret_cast< btRigidBody* >(object);
+	btAssert(body);
+	const btQuaternion& orn = body->getWorldTransform().getRotation();
+	orientation[0] = orn.getX();
+	orientation[1] = orn.getY();
+	orientation[2] = orn.getZ();
+	orientation[3] = orn.getW();
+}
+
+
+
+//plRigidBodyHandle plRayCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal);
+
+//	extern  plRigidBodyHandle plObjectCast(plDynamicsWorldHandle world, const plVector3 rayStart, const plVector3 rayEnd, plVector3 hitpoint, plVector3 normal);
+
+double plNearestPoints(float p1[3], float p2[3], float p3[3], float q1[3], float q2[3], float q3[3], float *pa, float *pb, float normal[3])
+{
+	btVector3 vp(p1[0], p1[1], p1[2]);
+	btTriangleShape trishapeA(vp, 
+				  btVector3(p2[0], p2[1], p2[2]), 
+				  btVector3(p3[0], p3[1], p3[2]));
+	trishapeA.setMargin(0.000001f);
+	btVector3 vq(q1[0], q1[1], q1[2]);
+	btTriangleShape trishapeB(vq, 
+				  btVector3(q2[0], q2[1], q2[2]), 
+				  btVector3(q3[0], q3[1], q3[2]));
+	trishapeB.setMargin(0.000001f);
+	
+	// btVoronoiSimplexSolver sGjkSimplexSolver;
+	// btGjkEpaPenetrationDepthSolver penSolverPtr;	
+	
+	static btSimplexSolverInterface sGjkSimplexSolver;
+	sGjkSimplexSolver.reset();
+	
+	static btGjkEpaPenetrationDepthSolver Solver0;
+	static btMinkowskiPenetrationDepthSolver Solver1;
+		
+	btConvexPenetrationDepthSolver* Solver = NULL;
+	
+	Solver = &Solver1;	
+		
+	btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,Solver);
+	
+	convexConvex.m_catchDegeneracies = 1;
+	
+	// btGjkPairDetector convexConvex(&trishapeA ,&trishapeB,&sGjkSimplexSolver,0);
+	
+	btPointCollector gjkOutput;
+	btGjkPairDetector::ClosestPointInput input;
+	
+	btStackAlloc gStackAlloc(1024*1024*2);
+ 
+	input.m_stackAlloc = &gStackAlloc;
+	
+	btTransform tr;
+	tr.setIdentity();
+	
+	input.m_transformA = tr;
+	input.m_transformB = tr;
+	
+	convexConvex.getClosestPoints(input, gjkOutput, 0);
+	
+	
+	if (gjkOutput.m_hasResult)
+	{
+		
+		pb[0] = pa[0] = gjkOutput.m_pointInWorld[0];
+		pb[1] = pa[1] = gjkOutput.m_pointInWorld[1];
+		pb[2] = pa[2] = gjkOutput.m_pointInWorld[2];
+
+		pb[0]+= gjkOutput.m_normalOnBInWorld[0] * gjkOutput.m_distance;
+		pb[1]+= gjkOutput.m_normalOnBInWorld[1] * gjkOutput.m_distance;
+		pb[2]+= gjkOutput.m_normalOnBInWorld[2] * gjkOutput.m_distance;
+		
+		normal[0] = gjkOutput.m_normalOnBInWorld[0];
+		normal[1] = gjkOutput.m_normalOnBInWorld[1];
+		normal[2] = gjkOutput.m_normalOnBInWorld[2];
+
+		return gjkOutput.m_distance;
+	}
+	return -1.0f;	
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btActionInterface.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btActionInterface.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btActionInterface.h	(revision 6952)
@@ -0,0 +1,39 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef _BT_ACTION_INTERFACE_H
+#define _BT_ACTION_INTERFACE_H
+
+class btIDebugDraw;
+class btCollisionWorld;
+
+#include "LinearMath/btScalar.h"
+
+///Basic interface to allow actions such as vehicles and characters to be updated inside a btDynamicsWorld
+class btActionInterface
+{
+	public:
+
+	virtual ~btActionInterface()
+	{
+	}
+
+	virtual void updateAction( btCollisionWorld* collisionWorld, btScalar deltaTimeStep)=0;
+
+	virtual void debugDraw(btIDebugDraw* debugDrawer) = 0;
+
+};
+
+#endif //_BT_ACTION_INTERFACE_H
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btContinuousDynamicsWorld.cpp	(revision 6952)
@@ -0,0 +1,192 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2007 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 "btContinuousDynamicsWorld.h"
+#include "LinearMath/btQuickprof.h"
+
+//collision detection
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
+#include "BulletCollision/CollisionShapes/btCollisionShape.h"
+#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
+
+//rigidbody & constraints
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
+#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
+#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
+
+
+
+#include <stdio.h>
+
+btContinuousDynamicsWorld::btContinuousDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
+:btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration)
+{
+}
+
+btContinuousDynamicsWorld::~btContinuousDynamicsWorld()
+{
+}
+
+	
+void	btContinuousDynamicsWorld::internalSingleStepSimulation( btScalar timeStep)
+{
+	
+	startProfiling(timeStep);
+	
+
+	///update aabbs information
+	updateAabbs();
+	//static int frame=0;
+//	printf("frame %d\n",frame++);
+
+	///apply gravity, predict motion
+	predictUnconstraintMotion(timeStep);
+
+	btDispatcherInfo& dispatchInfo = getDispatchInfo();
+
+	dispatchInfo.m_timeStep = timeStep;
+	dispatchInfo.m_stepCount = 0;
+	dispatchInfo.m_debugDraw = getDebugDrawer();
+
+	///perform collision detection
+	performDiscreteCollisionDetection();
+
+	calculateSimulationIslands();
+
+	
+	getSolverInfo().m_timeStep = timeStep;
+	
+
+
+	///solve contact and other joint constraints
+	solveConstraints(getSolverInfo());
+	
+	///CallbackTriggers();
+	calculateTimeOfImpacts(timeStep);
+
+	btScalar toi = dispatchInfo.m_timeOfImpact;
+//	if (toi < 1.f)
+//		printf("toi = %f\n",toi);
+	if (toi < 0.f)
+		printf("toi = %f\n",toi);
+
+
+	///integrate transforms
+	integrateTransforms(timeStep * toi);
+
+	///update vehicle simulation
+	updateActions(timeStep);
+
+	updateActivationState( timeStep );
+	
+	if(0 != m_internalTickCallback) {
+		(*m_internalTickCallback)(this, timeStep);
+	}
+}
+
+void	btContinuousDynamicsWorld::calculateTimeOfImpacts(btScalar timeStep)
+{
+		///these should be 'temporal' aabbs!
+		updateTemporalAabbs(timeStep);
+		
+		///'toi' is the global smallest time of impact. However, we just calculate the time of impact for each object individually.
+		///so we handle the case moving versus static properly, and we cheat for moving versus moving
+		btScalar toi = 1.f;
+		
+	
+		btDispatcherInfo& dispatchInfo = getDispatchInfo();
+		dispatchInfo.m_timeStep = timeStep;
+		dispatchInfo.m_timeOfImpact = 1.f;
+		dispatchInfo.m_stepCount = 0;
+		dispatchInfo.m_dispatchFunc = btDispatcherInfo::DISPATCH_CONTINUOUS;
+
+		///calculate time of impact for overlapping pairs
+
+
+		btDispatcher* dispatcher = getDispatcher();
+		if (dispatcher)
+			dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1);
+
+		toi = dispatchInfo.m_timeOfImpact;
+
+		dispatchInfo.m_dispatchFunc = btDispatcherInfo::DISPATCH_DISCRETE;
+
+}
+
+void	btContinuousDynamicsWorld::updateTemporalAabbs(btScalar timeStep)
+{
+
+	btVector3 temporalAabbMin,temporalAabbMax;
+
+	for ( int i=0;i<m_collisionObjects.size();i++)
+	{
+		btCollisionObject* colObj = m_collisionObjects[i];
+		
+		btRigidBody* body = btRigidBody::upcast(colObj);
+		if (body)
+		{
+			body->getCollisionShape()->getAabb(m_collisionObjects[i]->getWorldTransform(),temporalAabbMin,temporalAabbMax);
+			const btVector3& linvel = body->getLinearVelocity();
+
+			//make the AABB temporal
+			btScalar temporalAabbMaxx = temporalAabbMax.getX();
+			btScalar temporalAabbMaxy = temporalAabbMax.getY();
+			btScalar temporalAabbMaxz = temporalAabbMax.getZ();
+			btScalar temporalAabbMinx = temporalAabbMin.getX();
+			btScalar temporalAabbMiny = temporalAabbMin.getY();
+			btScalar temporalAabbMinz = temporalAabbMin.getZ();
+
+			// add linear motion
+			btVector3 linMotion = linvel*timeStep;
+		
+			if (linMotion.x() > 0.f)
+				temporalAabbMaxx += linMotion.x(); 
+			else
+				temporalAabbMinx += linMotion.x();
+			if (linMotion.y() > 0.f)
+				temporalAabbMaxy += linMotion.y(); 
+			else
+				temporalAabbMiny += linMotion.y();
+			if (linMotion.z() > 0.f)
+				temporalAabbMaxz += linMotion.z(); 
+			else
+				temporalAabbMinz += linMotion.z();
+
+			//add conservative angular motion
+			btScalar angularMotion(0);// = angvel.length() * GetAngularMotionDisc() * timeStep;
+			btVector3 angularMotion3d(angularMotion,angularMotion,angularMotion);
+			temporalAabbMin = btVector3(temporalAabbMinx,temporalAabbMiny,temporalAabbMinz);
+			temporalAabbMax = btVector3(temporalAabbMaxx,temporalAabbMaxy,temporalAabbMaxz);
+
+			temporalAabbMin -= angularMotion3d;
+			temporalAabbMax += angularMotion3d;
+
+			m_broadphasePairCache->setAabb(body->getBroadphaseHandle(),temporalAabbMin,temporalAabbMax,m_dispatcher1);
+		}
+	}
+
+	//update aabb (of all moved objects)
+
+	m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1);
+	
+
+
+}
+
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btContinuousDynamicsWorld.h	(revision 6952)
@@ -0,0 +1,46 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2007 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_CONTINUOUS_DYNAMICS_WORLD_H
+#define BT_CONTINUOUS_DYNAMICS_WORLD_H
+
+#include "btDiscreteDynamicsWorld.h"
+
+///btContinuousDynamicsWorld adds optional (per object) continuous collision detection for fast moving objects to the btDiscreteDynamicsWorld.
+///This copes with fast moving objects that otherwise would tunnel/miss collisions.
+///Under construction, don't use yet! Please use btDiscreteDynamicsWorld instead.
+class btContinuousDynamicsWorld : public btDiscreteDynamicsWorld
+{
+
+	void	updateTemporalAabbs(btScalar timeStep);
+
+	public:
+
+		btContinuousDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration);
+		virtual ~btContinuousDynamicsWorld();
+		
+		///time stepping with calculation of time of impact for selected fast moving objects
+		virtual void	internalSingleStepSimulation( btScalar timeStep);
+
+		virtual void	calculateTimeOfImpacts(btScalar timeStep);
+
+		virtual btDynamicsWorldType	getWorldType() const
+		{
+			return BT_CONTINUOUS_DYNAMICS_WORLD;
+		}
+
+};
+
+#endif //BT_CONTINUOUS_DYNAMICS_WORLD_H
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp	(revision 6952)
@@ -0,0 +1,1404 @@
+/*
+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 "btDiscreteDynamicsWorld.h"
+
+//collision detection
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
+#include "BulletCollision/CollisionShapes/btCollisionShape.h"
+#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h"
+#include "LinearMath/btTransformUtil.h"
+#include "LinearMath/btQuickprof.h"
+
+//rigidbody & constraints
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
+#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
+#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h"
+#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 "BulletCollision/CollisionShapes/btSphereShape.h"
+#include "BulletCollision/CollisionShapes/btTriangleCallback.h"
+#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
+#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
+#include "LinearMath/btIDebugDraw.h"
+
+
+#include "BulletDynamics/Dynamics/btActionInterface.h"
+#include "LinearMath/btQuickprof.h"
+#include "LinearMath/btMotionState.h"
+
+
+
+
+
+btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration)
+:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration),
+m_constraintSolver(constraintSolver),
+m_gravity(0,-10,0),
+m_localTime(btScalar(1.)/btScalar(60.)),
+m_profileTimings(0)
+{
+	if (!m_constraintSolver)
+	{
+		void* mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16);
+		m_constraintSolver = new (mem) btSequentialImpulseConstraintSolver;
+		m_ownsConstraintSolver = true;
+	} else
+	{
+		m_ownsConstraintSolver = false;
+	}
+
+	{
+		void* mem = btAlignedAlloc(sizeof(btSimulationIslandManager),16);
+		m_islandManager = new (mem) btSimulationIslandManager();
+	}
+
+	m_ownsIslandManager = true;
+}
+
+
+btDiscreteDynamicsWorld::~btDiscreteDynamicsWorld()
+{
+	//only delete it when we created it
+	if (m_ownsIslandManager)
+	{
+		m_islandManager->~btSimulationIslandManager();
+		btAlignedFree( m_islandManager);
+	}
+	if (m_ownsConstraintSolver)
+	{
+
+		m_constraintSolver->~btConstraintSolver();
+		btAlignedFree(m_constraintSolver);
+	}
+}
+
+void	btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep)
+{
+
+	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);
+					}
+				}
+		}
+	}
+}
+
+void	btDiscreteDynamicsWorld::debugDrawWorld()
+{
+	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);
+			}
+		}
+	}
+	bool drawConstraints = false;
+	if (getDebugDrawer())
+	{
+		int mode = getDebugDrawer()->getDebugMode();
+		if(mode  & (btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits))
+		{
+			drawConstraints = true;
+		}
+	}
+	if(drawConstraints)
+	{
+		for(int i = getNumConstraints()-1; i>=0 ;i--)
+		{
+			btTypedConstraint* constraint = getConstraint(i);
+			debugDrawConstraint(constraint);
+		}
+	}
+
+
+
+	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 (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())
+		{
+			for (i=0;i<m_actions.size();i++)
+			{
+				m_actions[i]->debugDraw(m_debugDrawer);
+			}
+		}
+	}
+}
+
+void	btDiscreteDynamicsWorld::clearForces()
+{
+	///@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();
+		}
+	}
+}	
+
+///apply gravity, call this once per timestep
+void	btDiscreteDynamicsWorld::applyGravity()
+{
+	///@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())
+		{
+			body->applyGravity();
+		}
+	}
+}
+
+
+void	btDiscreteDynamicsWorld::synchronizeSingleMotionState(btRigidBody* body)
+{
+	btAssert(body);
+
+	if (body->getMotionState() && !body->isStaticOrKinematicObject())
+	{
+		//we need to call the update at least once, even for sleeping objects
+		//otherwise the 'graphics' transform never updates properly
+		///@todo: add 'dirty' flag
+		//if (body->getActivationState() != ISLAND_SLEEPING)
+		{
+			btTransform interpolatedTransform;
+			btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(),
+				body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(),m_localTime*body->getHitFraction(),interpolatedTransform);
+			body->getMotionState()->setWorldTransform(interpolatedTransform);
+		}
+	}
+}
+
+
+void	btDiscreteDynamicsWorld::synchronizeMotionStates()
+{
+	BT_PROFILE("synchronizeMotionStates");
+	{
+		//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)
+				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);
+			}
+		}
+	}
+	*/
+
+
+}
+
+
+int	btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
+{
+	startProfiling(timeStep);
+
+	BT_PROFILE("stepSimulation");
+
+	int numSimulationSubSteps = 0;
+
+	if (maxSubSteps)
+	{
+		//fixed timestep with interpolation
+		m_localTime += timeStep;
+		if (m_localTime >= fixedTimeStep)
+		{
+			numSimulationSubSteps = int( m_localTime / fixedTimeStep);
+			m_localTime -= numSimulationSubSteps * fixedTimeStep;
+		}
+	} else
+	{
+		//variable timestep
+		fixedTimeStep = timeStep;
+		m_localTime = timeStep;
+		if (btFuzzyZero(timeStep))
+		{
+			numSimulationSubSteps = 0;
+			maxSubSteps = 0;
+		} else
+		{
+			numSimulationSubSteps = 1;
+			maxSubSteps = 1;
+		}
+	}
+
+	//process some debugging flags
+	if (getDebugDrawer())
+	{
+		btIDebugDraw* debugDrawer = getDebugDrawer ();
+		gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0;
+	}
+	if (numSimulationSubSteps)
+	{
+
+		saveKinematicState(fixedTimeStep);
+
+		applyGravity();
+
+		//clamp the number of substeps, to prevent simulation grinding spiralling down to a halt
+		int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps;
+
+		for (int i=0;i<clampedSimulationSteps;i++)
+		{
+			internalSingleStepSimulation(fixedTimeStep);
+			synchronizeMotionStates();
+		}
+
+	} 
+
+	synchronizeMotionStates();
+
+	clearForces();
+
+#ifndef BT_NO_PROFILE
+	CProfileManager::Increment_Frame_Counter();
+#endif //BT_NO_PROFILE
+	
+	return numSimulationSubSteps;
+}
+
+void	btDiscreteDynamicsWorld::internalSingleStepSimulation(btScalar timeStep)
+{
+	
+	BT_PROFILE("internalSingleStepSimulation");
+
+	///apply gravity, predict motion
+	predictUnconstraintMotion(timeStep);
+
+	btDispatcherInfo& dispatchInfo = getDispatchInfo();
+
+	dispatchInfo.m_timeStep = timeStep;
+	dispatchInfo.m_stepCount = 0;
+	dispatchInfo.m_debugDraw = getDebugDrawer();
+
+	///perform collision detection
+	performDiscreteCollisionDetection();
+
+	calculateSimulationIslands();
+
+	
+	getSolverInfo().m_timeStep = timeStep;
+	
+
+
+	///solve contact and other joint constraints
+	solveConstraints(getSolverInfo());
+	
+	///CallbackTriggers();
+
+	///integrate transforms
+	integrateTransforms(timeStep);
+
+	///update vehicle simulation
+	updateActions(timeStep);
+	
+	updateActivationState( timeStep );
+
+	if(0 != m_internalTickCallback) {
+		(*m_internalTickCallback)(this, timeStep);
+	}	
+}
+
+void	btDiscreteDynamicsWorld::setGravity(const btVector3& gravity)
+{
+	m_gravity = gravity;
+	for ( int i=0;i<m_collisionObjects.size();i++)
+	{
+		btCollisionObject* colObj = m_collisionObjects[i];
+		btRigidBody* body = btRigidBody::upcast(colObj);
+		if (body)
+		{
+			body->setGravity(gravity);
+		}
+	}
+}
+
+btVector3 btDiscreteDynamicsWorld::getGravity () const
+{
+	return m_gravity;
+}
+
+
+void	btDiscreteDynamicsWorld::removeRigidBody(btRigidBody* body)
+{
+	removeCollisionObject(body);
+}
+
+void	btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body)
+{
+	if (!body->isStaticOrKinematicObject())
+	{
+		body->setGravity(m_gravity);
+	}
+
+	if (body->getCollisionShape())
+	{
+		bool isDynamic = !(body->isStaticObject() || body->isKinematicObject());
+		short collisionFilterGroup = isDynamic? short(btBroadphaseProxy::DefaultFilter) : short(btBroadphaseProxy::StaticFilter);
+		short collisionFilterMask = isDynamic? 	short(btBroadphaseProxy::AllFilter) : 	short(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
+
+		addCollisionObject(body,collisionFilterGroup,collisionFilterMask);
+	}
+}
+
+void	btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, short group, short mask)
+{
+	if (!body->isStaticOrKinematicObject())
+	{
+		body->setGravity(m_gravity);
+	}
+
+	if (body->getCollisionShape())
+	{
+		addCollisionObject(body,group,mask);
+	}
+}
+
+
+void	btDiscreteDynamicsWorld::updateActions(btScalar timeStep)
+{
+	BT_PROFILE("updateActions");
+	
+	for ( int i=0;i<m_actions.size();i++)
+	{
+		m_actions[i]->updateAction( this, timeStep);
+	}
+}
+	
+	
+void	btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep)
+{
+	BT_PROFILE("updateActivationState");
+
+	for ( int i=0;i<m_collisionObjects.size();i++)
+	{
+		btCollisionObject* colObj = m_collisionObjects[i];
+		btRigidBody* body = btRigidBody::upcast(colObj);
+		if (body)
+		{
+			body->updateDeactivation(timeStep);
+
+			if (body->wantsSleeping())
+			{
+				if (body->isStaticOrKinematicObject())
+				{
+					body->setActivationState(ISLAND_SLEEPING);
+				} else
+				{
+					if (body->getActivationState() == ACTIVE_TAG)
+						body->setActivationState( WANTS_DEACTIVATION );
+					if (body->getActivationState() == ISLAND_SLEEPING) 
+					{
+						body->setAngularVelocity(btVector3(0,0,0));
+						body->setLinearVelocity(btVector3(0,0,0));
+					}
+
+				}
+			} else
+			{
+				if (body->getActivationState() != DISABLE_DEACTIVATION)
+					body->setActivationState( ACTIVE_TAG );
+			}
+		}
+	}
+}
+
+void	btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies)
+{
+	m_constraints.push_back(constraint);
+	if (disableCollisionsBetweenLinkedBodies)
+	{
+		constraint->getRigidBodyA().addConstraintRef(constraint);
+		constraint->getRigidBodyB().addConstraintRef(constraint);
+	}
+}
+
+void	btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint)
+{
+	m_constraints.remove(constraint);
+	constraint->getRigidBodyA().removeConstraintRef(constraint);
+	constraint->getRigidBodyB().removeConstraintRef(constraint);
+}
+
+void	btDiscreteDynamicsWorld::addAction(btActionInterface* action)
+{
+	m_actions.push_back(action);
+}
+
+void	btDiscreteDynamicsWorld::removeAction(btActionInterface* action)
+{
+	m_actions.remove(action);
+}
+
+
+void	btDiscreteDynamicsWorld::addVehicle(btActionInterface* vehicle)
+{
+	addAction(vehicle);
+}
+
+void	btDiscreteDynamicsWorld::removeVehicle(btActionInterface* vehicle)
+{
+	removeAction(vehicle);
+}
+
+void	btDiscreteDynamicsWorld::addCharacter(btActionInterface* character)
+{
+	addAction(character);
+}
+
+void	btDiscreteDynamicsWorld::removeCharacter(btActionInterface* character)
+{
+	removeAction(character);
+}
+
+
+SIMD_FORCE_INLINE	int	btGetConstraintIslandId(const btTypedConstraint* lhs)
+{
+	int islandId;
+	
+	const btCollisionObject& rcolObj0 = lhs->getRigidBodyA();
+	const btCollisionObject& rcolObj1 = lhs->getRigidBodyB();
+	islandId= rcolObj0.getIslandTag()>=0?rcolObj0.getIslandTag():rcolObj1.getIslandTag();
+	return islandId;
+
+}
+
+
+class btSortConstraintOnIslandPredicate
+{
+	public:
+
+		bool operator() ( const btTypedConstraint* lhs, const btTypedConstraint* rhs )
+		{
+			int rIslandId0,lIslandId0;
+			rIslandId0 = btGetConstraintIslandId(rhs);
+			lIslandId0 = btGetConstraintIslandId(lhs);
+			return lIslandId0 < rIslandId0;
+		}
+};
+
+
+
+
+void	btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
+{
+	BT_PROFILE("solveConstraints");
+	
+	struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback
+	{
+
+		btContactSolverInfo&	m_solverInfo;
+		btConstraintSolver*		m_solver;
+		btTypedConstraint**		m_sortedConstraints;
+		int						m_numConstraints;
+		btIDebugDraw*			m_debugDrawer;
+		btStackAlloc*			m_stackAlloc;
+		btDispatcher*			m_dispatcher;
+
+		InplaceSolverIslandCallback(
+			btContactSolverInfo& solverInfo,
+			btConstraintSolver*	solver,
+			btTypedConstraint** sortedConstraints,
+			int	numConstraints,
+			btIDebugDraw*	debugDrawer,
+			btStackAlloc*			stackAlloc,
+			btDispatcher* dispatcher)
+			:m_solverInfo(solverInfo),
+			m_solver(solver),
+			m_sortedConstraints(sortedConstraints),
+			m_numConstraints(numConstraints),
+			m_debugDrawer(debugDrawer),
+			m_stackAlloc(stackAlloc),
+			m_dispatcher(dispatcher)
+		{
+
+		}
+
+		InplaceSolverIslandCallback& operator=(InplaceSolverIslandCallback& other)
+		{
+			btAssert(0);
+			(void)other;
+			return *this;
+		}
+		virtual	void	ProcessIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold**	manifolds,int numManifolds, int islandId)
+		{
+			if (islandId<0)
+			{
+				if (numManifolds + m_numConstraints)
+				{
+					///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id
+					m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,m_solverInfo,m_debugDrawer,m_stackAlloc,m_dispatcher);
+				}
+			} else
+			{
+					//also add all non-contact constraints/joints for this island
+				btTypedConstraint** startConstraint = 0;
+				int numCurConstraints = 0;
+				int i;
+				
+				//find the first constraint for this island
+				for (i=0;i<m_numConstraints;i++)
+				{
+					if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId)
+					{
+						startConstraint = &m_sortedConstraints[i];
+						break;
+					}
+				}
+				//count the number of constraints in this island
+				for (;i<m_numConstraints;i++)
+				{
+					if (btGetConstraintIslandId(m_sortedConstraints[i]) == islandId)
+					{
+						numCurConstraints++;
+					}
+				}
+
+				///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);
+				}
+		
+			}
+		}
+
+	};
+
+	//sorted version of all btTypedConstraint, based on islandId
+	btAlignedObjectArray<btTypedConstraint*>	sortedConstraints;
+	sortedConstraints.resize( m_constraints.size());
+	int i; 
+	for (i=0;i<getNumConstraints();i++)
+	{
+		sortedConstraints[i] = m_constraints[i];
+	}
+
+//	btAssert(0);
+		
+	
+
+	sortedConstraints.quickSort(btSortConstraintOnIslandPredicate());
+	
+	btTypedConstraint** constraintsPtr = getNumConstraints() ? &sortedConstraints[0] : 0;
+	
+	InplaceSolverIslandCallback	solverCallback(	solverInfo,	m_constraintSolver, constraintsPtr,sortedConstraints.size(),	m_debugDrawer,m_stackAlloc,m_dispatcher1);
+	
+	m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds());
+	
+	/// solve all the constraints for this island
+	m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),&solverCallback);
+
+	m_constraintSolver->allSolved(solverInfo, m_debugDrawer, m_stackAlloc);
+}
+
+
+
+
+void	btDiscreteDynamicsWorld::calculateSimulationIslands()
+{
+	BT_PROFILE("calculateSimulationIslands");
+
+	getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher());
+
+	{
+		int i;
+		int numConstraints = int(m_constraints.size());
+		for (i=0;i< numConstraints ; i++ )
+		{
+			btTypedConstraint* constraint = m_constraints[i];
+
+			const btRigidBody* colObj0 = &constraint->getRigidBodyA();
+			const btRigidBody* colObj1 = &constraint->getRigidBodyB();
+
+			if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) &&
+				((colObj1) && (!(colObj1)->isStaticOrKinematicObject())))
+			{
+				if (colObj0->isActive() || colObj1->isActive())
+				{
+
+					getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),
+						(colObj1)->getIslandTag());
+				}
+			}
+		}
+	}
+
+	//Store the island id in each body
+	getSimulationIslandManager()->storeIslandActivationState(getCollisionWorld());
+
+	
+}
+
+
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
+
+class btClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback
+{
+	btCollisionObject* m_me;
+	btScalar m_allowedPenetration;
+	btOverlappingPairCache* m_pairCache;
+	btDispatcher* m_dispatcher;
+
+
+public:
+	btClosestNotMeConvexResultCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : 
+	  btCollisionWorld::ClosestConvexResultCallback(fromA,toA),
+		m_allowedPenetration(0.0f),
+		m_me(me),
+		m_pairCache(pairCache),
+		m_dispatcher(dispatcher)
+	{
+	}
+
+	virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace)
+	{
+		if (convexResult.m_hitCollisionObject == m_me)
+			return 1.0f;
+
+		//ignore result if there is no contact response
+		if(!convexResult.m_hitCollisionObject->hasContactResponse())
+			return 1.0f;
+
+		btVector3 linVelA,linVelB;
+		linVelA = m_convexToWorld-m_convexFromWorld;
+		linVelB = btVector3(0,0,0);//toB.getOrigin()-fromB.getOrigin();
+
+		btVector3 relativeVelocity = (linVelA-linVelB);
+		//don't report time of impact for motion away from the contact normal (or causes minor penetration)
+		if (convexResult.m_hitNormalLocal.dot(relativeVelocity)>=-m_allowedPenetration)
+			return 1.f;
+
+		return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace);
+	}
+
+	virtual bool needsCollision(btBroadphaseProxy* proxy0) const
+	{
+		//don't collide with itself
+		if (proxy0->m_clientObject == m_me)
+			return false;
+
+		///don't do CCD when the collision filters are not matching
+		if (!ClosestConvexResultCallback::needsCollision(proxy0))
+			return false;
+
+		btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject;
+
+		//call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179
+		if (m_dispatcher->needsResponse(m_me,otherObj))
+		{
+			///don't do CCD when there are already contact points (touching contact/penetration)
+			btAlignedObjectArray<btPersistentManifold*> manifoldArray;
+			btBroadphasePair* collisionPair = m_pairCache->findPair(m_me->getBroadphaseHandle(),proxy0);
+			if (collisionPair)
+			{
+				if (collisionPair->m_algorithm)
+				{
+					manifoldArray.resize(0);
+					collisionPair->m_algorithm->getAllContactManifolds(manifoldArray);
+					for (int j=0;j<manifoldArray.size();j++)
+					{
+						btPersistentManifold* manifold = manifoldArray[j];
+						if (manifold->getNumContacts()>0)
+							return false;
+					}
+				}
+			}
+		}
+		return true;
+	}
+
+
+};
+
+///internal debugging variable. this value shouldn't be too high
+int gNumClampedCcdMotions=0;
+
+//#include "stdio.h"
+void	btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep)
+{
+	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);
+//							printf("clamped integration to hit fraction = %f\n",fraction);
+						}
+					}
+				}
+				
+				body->proceedToTransform( predictedTrans);
+			}
+		}
+	}
+}
+
+
+
+
+
+void	btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
+{
+	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());
+			}
+		}
+	}
+}
+
+
+void	btDiscreteDynamicsWorld::startProfiling(btScalar timeStep)
+{
+	(void)timeStep;
+
+#ifndef BT_NO_PROFILE
+	CProfileManager::Reset();
+#endif //BT_NO_PROFILE
+
+}
+
+
+
+
+	
+
+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)
+{
+	bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0;
+	bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0;
+	btScalar dbgDrawSize = constraint->getDbgDrawSize();
+	if(dbgDrawSize <= btScalar(0.f))
+	{
+		return;
+	}
+
+	switch(constraint->getConstraintType())
+	{
+		case POINT2POINT_CONSTRAINT_TYPE:
+			{
+				btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint;
+				btTransform tr;
+				tr.setIdentity();
+				btVector3 pivot = p2pC->getPivotInA();
+				pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot; 
+				tr.setOrigin(pivot);
+				getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+				// that ideally should draw the same frame	
+				pivot = p2pC->getPivotInB();
+				pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot; 
+				tr.setOrigin(pivot);
+				if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+			}
+			break;
+		case HINGE_CONSTRAINT_TYPE:
+			{
+				btHingeConstraint* pHinge = (btHingeConstraint*)constraint;
+				btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame();
+				if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+				tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame();
+				if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+				btScalar minAng = pHinge->getLowerLimit();
+				btScalar maxAng = pHinge->getUpperLimit();
+				if(minAng == maxAng)
+				{
+					break;
+				}
+				bool drawSect = true;
+				if(minAng > maxAng)
+				{
+					minAng = btScalar(0.f);
+					maxAng = SIMD_2_PI;
+					drawSect = false;
+				}
+				if(drawLimits) 
+				{
+					btVector3& center = tr.getOrigin();
+					btVector3 normal = tr.getBasis().getColumn(2);
+					btVector3 axis = tr.getBasis().getColumn(0);
+					getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect);
+				}
+			}
+			break;
+		case CONETWIST_CONSTRAINT_TYPE:
+			{
+				btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint;
+				btTransform tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
+				if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+				tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
+				if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+				if(drawLimits)
+				{
+					//const btScalar length = btScalar(5);
+					const btScalar length = dbgDrawSize;
+					static int nSegments = 8*4;
+					btScalar fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)(nSegments-1)/btScalar(nSegments);
+					btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length);
+					pPrev = tr * pPrev;
+					for (int i=0; i<nSegments; i++)
+					{
+						fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)i/btScalar(nSegments);
+						btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length);
+						pCur = tr * pCur;
+						getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0));
+
+						if (i%(nSegments/8) == 0)
+							getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0));
+
+						pPrev = pCur;
+					}						
+					btScalar tws = pCT->getTwistSpan();
+					btScalar twa = pCT->getTwistAngle();
+					bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f));
+					if(useFrameB)
+					{
+						tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame();
+					}
+					else
+					{
+						tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame();
+					}
+					btVector3 pivot = tr.getOrigin();
+					btVector3 normal = tr.getBasis().getColumn(0);
+					btVector3 axis1 = tr.getBasis().getColumn(1);
+					getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa-tws, -twa+tws, btVector3(0,0,0), true);
+
+				}
+			}
+			break;
+		case D6_CONSTRAINT_TYPE:
+			{
+				btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint;
+				btTransform tr = p6DOF->getCalculatedTransformA();
+				if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+				tr = p6DOF->getCalculatedTransformB();
+				if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+				if(drawLimits) 
+				{
+					tr = p6DOF->getCalculatedTransformA();
+					const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin();
+					btVector3 up = tr.getBasis().getColumn(2);
+					btVector3 axis = tr.getBasis().getColumn(0);
+					btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit;
+					btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit;
+					btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit;
+					btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit;
+					getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0,0,0));
+					axis = tr.getBasis().getColumn(1);
+					btScalar ay = p6DOF->getAngle(1);
+					btScalar az = p6DOF->getAngle(2);
+					btScalar cy = btCos(ay);
+					btScalar sy = btSin(ay);
+					btScalar cz = btCos(az);
+					btScalar sz = btSin(az);
+					btVector3 ref;
+					ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2];
+					ref[1] = -sz*axis[0] + cz*axis[1];
+					ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2];
+					tr = p6DOF->getCalculatedTransformB();
+					btVector3 normal = -tr.getBasis().getColumn(0);
+					btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit;
+					btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit;
+					if(minFi > maxFi)
+					{
+						getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0,0,0), false);
+					}
+					else if(minFi < maxFi)
+					{
+						getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0,0,0), true);
+					}
+					tr = p6DOF->getCalculatedTransformA();
+					btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit;
+					btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit;
+					getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0,0,0));
+				}
+			}
+			break;
+		case SLIDER_CONSTRAINT_TYPE:
+			{
+				btSliderConstraint* pSlider = (btSliderConstraint*)constraint;
+				btTransform tr = pSlider->getCalculatedTransformA();
+				if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+				tr = pSlider->getCalculatedTransformB();
+				if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize);
+				if(drawLimits)
+				{
+					btTransform tr = pSlider->getCalculatedTransformA();
+					btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f);
+					btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f);
+					getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0));
+					btVector3 normal = tr.getBasis().getColumn(0);
+					btVector3 axis = tr.getBasis().getColumn(1);
+					btScalar a_min = pSlider->getLowerAngLimit();
+					btScalar a_max = pSlider->getUpperAngLimit();
+					const btVector3& center = pSlider->getCalculatedTransformB().getOrigin();
+					getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true);
+				}
+			}
+			break;
+		default : 
+			break;
+	}
+	return;
+} // btDiscreteDynamicsWorld::debugDrawConstraint()
+
+
+
+
+
+void	btDiscreteDynamicsWorld::setConstraintSolver(btConstraintSolver* solver)
+{
+	if (m_ownsConstraintSolver)
+	{
+		btAlignedFree( m_constraintSolver);
+	}
+	m_ownsConstraintSolver = false;
+	m_constraintSolver = solver;
+}
+
+btConstraintSolver* btDiscreteDynamicsWorld::getConstraintSolver()
+{
+	return m_constraintSolver;
+}
+
+
+int		btDiscreteDynamicsWorld::getNumConstraints() const
+{
+	return int(m_constraints.size());
+}
+btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index)
+{
+	return m_constraints[index];
+}
+const btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index) const
+{
+	return m_constraints[index];
+}
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h	(revision 6952)
@@ -0,0 +1,179 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_DISCRETE_DYNAMICS_WORLD_H
+#define BT_DISCRETE_DYNAMICS_WORLD_H
+
+#include "btDynamicsWorld.h"
+
+class btDispatcher;
+class btOverlappingPairCache;
+class btConstraintSolver;
+class btSimulationIslandManager;
+class btTypedConstraint;
+class btActionInterface;
+
+class btIDebugDraw;
+#include "LinearMath/btAlignedObjectArray.h"
+
+
+///btDiscreteDynamicsWorld provides discrete rigid body simulation
+///those classes replace the obsolete CcdPhysicsEnvironment/CcdPhysicsController
+class btDiscreteDynamicsWorld : public btDynamicsWorld
+{
+protected:
+
+	btConstraintSolver*	m_constraintSolver;
+
+	btSimulationIslandManager*	m_islandManager;
+
+	btAlignedObjectArray<btTypedConstraint*> m_constraints;
+
+	btVector3	m_gravity;
+
+	//for variable timesteps
+	btScalar	m_localTime;
+	//for variable timesteps
+
+	bool	m_ownsIslandManager;
+	bool	m_ownsConstraintSolver;
+
+	btAlignedObjectArray<btActionInterface*>	m_actions;
+	
+	int	m_profileTimings;
+
+	virtual void	predictUnconstraintMotion(btScalar timeStep);
+	
+	virtual void	integrateTransforms(btScalar timeStep);
+		
+	virtual void	calculateSimulationIslands();
+
+	virtual void	solveConstraints(btContactSolverInfo& solverInfo);
+	
+	void	updateActivationState(btScalar timeStep);
+
+	void	updateActions(btScalar timeStep);
+
+	void	startProfiling(btScalar timeStep);
+
+	virtual void	internalSingleStepSimulation( btScalar timeStep);
+
+
+	virtual void	saveKinematicState(btScalar timeStep);
+
+	void	debugDrawSphere(btScalar radius, const btTransform& transform, const btVector3& color);
+
+
+public:
+
+
+	///this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete those
+	btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration);
+
+	virtual ~btDiscreteDynamicsWorld();
+
+	///if maxSubSteps > 0, it will interpolate motion between fixedTimeStep's
+	virtual int	stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
+
+
+	virtual void	synchronizeMotionStates();
+
+	///this can be useful to synchronize a single rigid body -> graphics object
+	void	synchronizeSingleMotionState(btRigidBody* body);
+
+	virtual void	addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false);
+
+	virtual void	removeConstraint(btTypedConstraint* constraint);
+
+	virtual void	addAction(btActionInterface*);
+
+	virtual void	removeAction(btActionInterface*);
+	
+	btSimulationIslandManager*	getSimulationIslandManager()
+	{
+		return m_islandManager;
+	}
+
+	const btSimulationIslandManager*	getSimulationIslandManager() const 
+	{
+		return m_islandManager;
+	}
+
+	btCollisionWorld*	getCollisionWorld()
+	{
+		return this;
+	}
+
+	virtual void	setGravity(const btVector3& gravity);
+
+	virtual btVector3 getGravity () const;
+
+	virtual void	addRigidBody(btRigidBody* body);
+
+	virtual void	addRigidBody(btRigidBody* body, short group, short mask);
+
+	virtual void	removeRigidBody(btRigidBody* body);
+
+	void	debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color);
+
+	void	debugDrawConstraint(btTypedConstraint* constraint);
+
+	virtual void	debugDrawWorld();
+
+	virtual void	setConstraintSolver(btConstraintSolver* solver);
+
+	virtual btConstraintSolver* getConstraintSolver();
+	
+	virtual	int		getNumConstraints() const;
+
+	virtual btTypedConstraint* getConstraint(int index)	;
+
+	virtual const btTypedConstraint* getConstraint(int index) const;
+
+	
+	virtual btDynamicsWorldType	getWorldType() const
+	{
+		return BT_DISCRETE_DYNAMICS_WORLD;
+	}
+	
+	///the forces on each rigidbody is accumulating together with gravity. clear this after each timestep.
+	virtual void	clearForces();
+
+	///apply gravity, call this once per timestep
+	virtual void	applyGravity();
+
+	virtual void	setNumTasks(int numTasks)
+	{
+        (void) numTasks;
+	}
+
+	///obsolete, use updateActions instead
+	virtual void updateVehicles(btScalar timeStep)
+	{
+		updateActions(timeStep);
+	}
+
+	///obsolete, use addAction instead
+	virtual void	addVehicle(btActionInterface* vehicle);
+	///obsolete, use removeAction instead
+	virtual void	removeVehicle(btActionInterface* vehicle);
+	///obsolete, use addAction instead
+	virtual void	addCharacter(btActionInterface* character);
+	///obsolete, use removeAction instead
+	virtual void	removeCharacter(btActionInterface* character);
+
+};
+
+#endif //BT_DISCRETE_DYNAMICS_WORLD_H
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btDynamicsWorld.h	(revision 6952)
@@ -0,0 +1,141 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_DYNAMICS_WORLD_H
+#define BT_DYNAMICS_WORLD_H
+
+#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
+#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
+
+class btTypedConstraint;
+class btActionInterface;
+class btConstraintSolver;
+class btDynamicsWorld;
+
+
+/// Type for the callback for each tick
+typedef void (*btInternalTickCallback)(btDynamicsWorld *world, btScalar timeStep);
+
+enum btDynamicsWorldType
+{
+	BT_SIMPLE_DYNAMICS_WORLD=1,
+	BT_DISCRETE_DYNAMICS_WORLD=2,
+	BT_CONTINUOUS_DYNAMICS_WORLD=3
+};
+
+///The btDynamicsWorld is the interface class for several dynamics implementation, basic, discrete, parallel, and continuous etc.
+class btDynamicsWorld : public btCollisionWorld
+{
+
+protected:
+		btInternalTickCallback m_internalTickCallback;
+		void*	m_worldUserInfo;
+
+		btContactSolverInfo	m_solverInfo;
+
+public:
+		
+
+		btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase,btCollisionConfiguration* collisionConfiguration)
+		:btCollisionWorld(dispatcher,broadphase,collisionConfiguration), m_internalTickCallback(0), m_worldUserInfo(0)
+		{
+		}
+
+		virtual ~btDynamicsWorld()
+		{
+		}
+		
+		///stepSimulation proceeds the simulation over 'timeStep', units in preferably in seconds.
+		///By default, Bullet will subdivide the timestep in constant substeps of each 'fixedTimeStep'.
+		///in order to keep the simulation real-time, the maximum number of substeps can be clamped to 'maxSubSteps'.
+		///You can disable subdividing the timestep/substepping by passing maxSubSteps=0 as second argument to stepSimulation, but in that case you have to keep the timeStep constant.
+		virtual int		stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))=0;
+			
+		virtual void	debugDrawWorld() = 0;
+				
+		virtual void	addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false) 
+		{ 
+			(void)constraint; (void)disableCollisionsBetweenLinkedBodies;
+		}
+
+		virtual void	removeConstraint(btTypedConstraint* constraint) {(void)constraint;}
+
+		virtual void	addAction(btActionInterface* action) = 0;
+
+		virtual void	removeAction(btActionInterface* action) = 0;
+
+		//once a rigidbody is added to the dynamics world, it will get this gravity assigned
+		//existing rigidbodies in the world get gravity assigned too, during this method
+		virtual void	setGravity(const btVector3& gravity) = 0;
+		virtual btVector3 getGravity () const = 0;
+
+		virtual void	synchronizeMotionStates() = 0;
+
+		virtual void	addRigidBody(btRigidBody* body) = 0;
+
+		virtual void	removeRigidBody(btRigidBody* body) = 0;
+
+		virtual void	setConstraintSolver(btConstraintSolver* solver) = 0;
+
+		virtual btConstraintSolver* getConstraintSolver() = 0;
+		
+		virtual	int		getNumConstraints() const {	return 0;		}
+		
+		virtual btTypedConstraint* getConstraint(int index)		{	(void)index;		return 0;		}
+		
+		virtual const btTypedConstraint* getConstraint(int index) const	{	(void)index;	return 0;	}
+
+		virtual btDynamicsWorldType	getWorldType() const=0;
+
+		virtual void	clearForces() = 0;
+
+		/// Set the callback for when an internal tick (simulation substep) happens, optional user info
+		void setInternalTickCallback(btInternalTickCallback cb,	void* worldUserInfo=0) 
+		{ 
+			m_internalTickCallback = cb; 
+			m_worldUserInfo = worldUserInfo;
+		}
+
+		void	setWorldUserInfo(void* worldUserInfo)
+		{
+			m_worldUserInfo = worldUserInfo;
+		}
+
+		void*	getWorldUserInfo() const
+		{
+			return m_worldUserInfo;
+		}
+
+		btContactSolverInfo& getSolverInfo()
+		{
+			return m_solverInfo;
+		}
+
+
+		///obsolete, use addAction instead.
+		virtual void	addVehicle(btActionInterface* vehicle) {(void)vehicle;}
+		///obsolete, use removeAction instead
+		virtual void	removeVehicle(btActionInterface* vehicle) {(void)vehicle;}
+		///obsolete, use addAction instead.
+		virtual void	addCharacter(btActionInterface* character) {(void)character;}
+		///obsolete, use removeAction instead
+		virtual void	removeCharacter(btActionInterface* character) {(void)character;}
+
+
+};
+
+#endif //BT_DYNAMICS_WORLD_H
+
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.cpp	(revision 6952)
@@ -0,0 +1,316 @@
+/*
+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 "btRigidBody.h"
+#include "BulletCollision/CollisionShapes/btConvexShape.h"
+#include "LinearMath/btMinMax.h"
+#include "LinearMath/btTransformUtil.h"
+#include "LinearMath/btMotionState.h"
+#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
+
+//'temporarily' global variables
+btScalar	gDeactivationTime = btScalar(2.);
+bool	gDisableDeactivation = false;
+static int uniqueId = 0;
+
+
+btRigidBody::btRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo)
+{
+	setupRigidBody(constructionInfo);
+}
+
+btRigidBody::btRigidBody(btScalar mass, btMotionState *motionState, btCollisionShape *collisionShape, const btVector3 &localInertia)
+{
+	btRigidBodyConstructionInfo cinfo(mass,motionState,collisionShape,localInertia);
+	setupRigidBody(cinfo);
+}
+
+void	btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo)
+{
+
+	m_internalType=CO_RIGID_BODY;
+
+	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_gravity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
+	m_gravity_acceleration.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
+	m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
+	m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)),
+	m_linearDamping = btScalar(0.);
+	m_angularDamping = btScalar(0.5);
+	m_linearSleepingThreshold = constructionInfo.m_linearSleepingThreshold;
+	m_angularSleepingThreshold = constructionInfo.m_angularSleepingThreshold;
+	m_optionalMotionState = constructionInfo.m_motionState;
+	m_contactSolverType = 0;
+	m_frictionSolverType = 0;
+	m_additionalDamping = constructionInfo.m_additionalDamping;
+	m_additionalDampingFactor = constructionInfo.m_additionalDampingFactor;
+	m_additionalLinearDampingThresholdSqr = constructionInfo.m_additionalLinearDampingThresholdSqr;
+	m_additionalAngularDampingThresholdSqr = constructionInfo.m_additionalAngularDampingThresholdSqr;
+	m_additionalAngularDampingFactor = constructionInfo.m_additionalAngularDampingFactor;
+
+	if (m_optionalMotionState)
+	{
+		m_optionalMotionState->getWorldTransform(m_worldTransform);
+	} else
+	{
+		m_worldTransform = constructionInfo.m_startWorldTransform;
+	}
+
+	m_interpolationWorldTransform = m_worldTransform;
+	m_interpolationLinearVelocity.setValue(0,0,0);
+	m_interpolationAngularVelocity.setValue(0,0,0);
+	
+	//moved to btCollisionObject
+	m_friction = constructionInfo.m_friction;
+	m_restitution = constructionInfo.m_restitution;
+
+	setCollisionShape( constructionInfo.m_collisionShape );
+	m_debugBodyId = uniqueId++;
+	
+	setMassProps(constructionInfo.m_mass, constructionInfo.m_localInertia);
+    setDamping(constructionInfo.m_linearDamping, constructionInfo.m_angularDamping);
+	updateInertiaTensor();
+
+}
+
+
+void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& predictedTransform) 
+{
+	btTransformUtil::integrateTransform(m_worldTransform,m_linearVelocity,m_angularVelocity,timeStep,predictedTransform);
+}
+
+void			btRigidBody::saveKinematicState(btScalar timeStep)
+{
+	//todo: clamp to some (user definable) safe minimum timestep, to limit maximum angular/linear velocities
+	if (timeStep != btScalar(0.))
+	{
+		//if we use motionstate to synchronize world transforms, get the new kinematic/animated world transform
+		if (getMotionState())
+			getMotionState()->getWorldTransform(m_worldTransform);
+		btVector3 linVel,angVel;
+		
+		btTransformUtil::calculateVelocity(m_interpolationWorldTransform,m_worldTransform,timeStep,m_linearVelocity,m_angularVelocity);
+		m_interpolationLinearVelocity = m_linearVelocity;
+		m_interpolationAngularVelocity = m_angularVelocity;
+		m_interpolationWorldTransform = m_worldTransform;
+		//printf("angular = %f %f %f\n",m_angularVelocity.getX(),m_angularVelocity.getY(),m_angularVelocity.getZ());
+	}
+}
+	
+void	btRigidBody::getAabb(btVector3& aabbMin,btVector3& aabbMax) const
+{
+	getCollisionShape()->getAabb(m_worldTransform,aabbMin,aabbMax);
+}
+
+
+
+
+void btRigidBody::setGravity(const btVector3& acceleration) 
+{
+	if (m_inverseMass != btScalar(0.0))
+	{
+		m_gravity = acceleration * (btScalar(1.0) / m_inverseMass);
+	}
+	m_gravity_acceleration = acceleration;
+}
+
+
+
+
+
+
+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));
+}
+
+
+
+
+///applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping
+void			btRigidBody::applyDamping(btScalar timeStep)
+{
+	//On new damping: see discussion/issue report here: http://code.google.com/p/bullet/issues/detail?id=74
+	//todo: do some performance comparisons (but other parts of the engine are probably bottleneck anyway
+
+//#define USE_OLD_DAMPING_METHOD 1
+#ifdef USE_OLD_DAMPING_METHOD
+	m_linearVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
+	m_angularVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0));
+#else
+	m_linearVelocity *= btPow(btScalar(1)-m_linearDamping, timeStep);
+	m_angularVelocity *= btPow(btScalar(1)-m_angularDamping, timeStep);
+#endif
+
+	if (m_additionalDamping)
+	{
+		//Additional damping can help avoiding lowpass jitter motion, help stability for ragdolls etc.
+		//Such damping is undesirable, so once the overall simulation quality of the rigid body dynamics system has improved, this should become obsolete
+		if ((m_angularVelocity.length2() < m_additionalAngularDampingThresholdSqr) &&
+			(m_linearVelocity.length2() < m_additionalLinearDampingThresholdSqr))
+		{
+			m_angularVelocity *= m_additionalDampingFactor;
+			m_linearVelocity *= m_additionalDampingFactor;
+		}
+	
+
+		btScalar speed = m_linearVelocity.length();
+		if (speed < m_linearDamping)
+		{
+			btScalar dampVel = btScalar(0.005);
+			if (speed > dampVel)
+			{
+				btVector3 dir = m_linearVelocity.normalized();
+				m_linearVelocity -=  dir * dampVel;
+			} else
+			{
+				m_linearVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
+			}
+		}
+
+		btScalar angSpeed = m_angularVelocity.length();
+		if (angSpeed < m_angularDamping)
+		{
+			btScalar angDampVel = btScalar(0.005);
+			if (angSpeed > angDampVel)
+			{
+				btVector3 dir = m_angularVelocity.normalized();
+				m_angularVelocity -=  dir * angDampVel;
+			} else
+			{
+				m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
+			}
+		}
+	}
+}
+
+
+void btRigidBody::applyGravity()
+{
+	if (isStaticOrKinematicObject())
+		return;
+	
+	applyCentralForce(m_gravity);	
+
+}
+
+void btRigidBody::proceedToTransform(const btTransform& newTrans)
+{
+	setCenterOfMassTransform( newTrans );
+}
+	
+
+void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia)
+{
+	if (mass == btScalar(0.))
+	{
+		m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT;
+		m_inverseMass = btScalar(0.);
+	} else
+	{
+		m_collisionFlags &= (~btCollisionObject::CF_STATIC_OBJECT);
+		m_inverseMass = btScalar(1.0) / mass;
+	}
+	
+	m_invInertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x(): btScalar(0.0),
+				   inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y(): btScalar(0.0),
+				   inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z(): btScalar(0.0));
+
+}
+
+	
+
+void btRigidBody::updateInertiaTensor() 
+{
+	m_invInertiaTensorWorld = m_worldTransform.getBasis().scaled(m_invInertiaLocal) * m_worldTransform.getBasis().transpose();
+}
+
+
+void btRigidBody::integrateVelocities(btScalar step) 
+{
+	if (isStaticOrKinematicObject())
+		return;
+
+	m_linearVelocity += m_totalForce * (m_inverseMass * step);
+	m_angularVelocity += m_invInertiaTensorWorld * m_totalTorque * step;
+
+#define MAX_ANGVEL SIMD_HALF_PI
+	/// clamp angular velocity. collision calculations will fail on higher angular velocities	
+	btScalar angvel = m_angularVelocity.length();
+	if (angvel*step > MAX_ANGVEL)
+	{
+		m_angularVelocity *= (MAX_ANGVEL/step) /angvel;
+	}
+
+}
+
+btQuaternion btRigidBody::getOrientation() const
+{
+		btQuaternion orn;
+		m_worldTransform.getBasis().getRotation(orn);
+		return orn;
+}
+	
+	
+void btRigidBody::setCenterOfMassTransform(const btTransform& xform)
+{
+
+	if (isStaticOrKinematicObject())
+	{
+		m_interpolationWorldTransform = m_worldTransform;
+	} else
+	{
+		m_interpolationWorldTransform = xform;
+	}
+	m_interpolationLinearVelocity = getLinearVelocity();
+	m_interpolationAngularVelocity = getAngularVelocity();
+	m_worldTransform = xform;
+	updateInertiaTensor();
+}
+
+
+bool btRigidBody::checkCollideWithOverride(btCollisionObject* co)
+{
+	btRigidBody* otherRb = btRigidBody::upcast(co);
+	if (!otherRb)
+		return true;
+
+	for (int i = 0; i < m_constraintRefs.size(); ++i)
+	{
+		btTypedConstraint* c = m_constraintRefs[i];
+		if (&c->getRigidBodyA() == otherRb || &c->getRigidBodyB() == otherRb)
+			return false;
+	}
+
+	return true;
+}
+
+void btRigidBody::addConstraintRef(btTypedConstraint* c)
+{
+	int index = m_constraintRefs.findLinearSearch(c);
+	if (index == m_constraintRefs.size())
+		m_constraintRefs.push_back(c); 
+
+	m_checkCollideWith = true;
+}
+
+void btRigidBody::removeConstraintRef(btTypedConstraint* c)
+{
+	m_constraintRefs.remove(c);
+	m_checkCollideWith = m_constraintRefs.size() > 0;
+}
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btRigidBody.h	(revision 6952)
@@ -0,0 +1,489 @@
+/*
+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 RIGIDBODY_H
+#define RIGIDBODY_H
+
+#include "LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btTransform.h"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+
+class btCollisionShape;
+class btMotionState;
+class btTypedConstraint;
+
+
+extern btScalar gDeactivationTime;
+extern bool gDisableDeactivation;
+
+
+///The btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape.
+///It is recommended for performance and memory use to share btCollisionShape objects whenever possible.
+///There are 3 types of rigid bodies: 
+///- A) Dynamic rigid bodies, with positive mass. Motion is controlled by rigid body dynamics.
+///- B) Fixed objects with zero mass. They are not moving (basically collision objects)
+///- C) Kinematic objects, which are objects without mass, but the user can move them. There is on-way interaction, and Bullet calculates a velocity based on the timestep and previous and current world transform.
+///Bullet automatically deactivates dynamic rigid bodies, when the velocity is below a threshold for a given time.
+///Deactivated (sleeping) rigid bodies don't take any processing time, except a minor broadphase collision detection impact (to allow active objects to activate/wake up sleeping objects)
+class btRigidBody  : public btCollisionObject
+{
+
+	btMatrix3x3	m_invInertiaTensorWorld;
+	btVector3		m_linearVelocity;
+	btVector3		m_angularVelocity;
+	btScalar		m_inverseMass;
+	btScalar		m_angularFactor;
+
+	btVector3		m_gravity;	
+	btVector3		m_gravity_acceleration;
+	btVector3		m_invInertiaLocal;
+	btVector3		m_totalForce;
+	btVector3		m_totalTorque;
+	
+	btScalar		m_linearDamping;
+	btScalar		m_angularDamping;
+
+	bool			m_additionalDamping;
+	btScalar		m_additionalDampingFactor;
+	btScalar		m_additionalLinearDampingThresholdSqr;
+	btScalar		m_additionalAngularDampingThresholdSqr;
+	btScalar		m_additionalAngularDampingFactor;
+
+
+	btScalar		m_linearSleepingThreshold;
+	btScalar		m_angularSleepingThreshold;
+
+	//m_optionalMotionState allows to automatic synchronize the world transform for active objects
+	btMotionState*	m_optionalMotionState;
+
+	//keep track of typed constraints referencing this rigid body
+	btAlignedObjectArray<btTypedConstraint*> m_constraintRefs;
+
+public:
+
+
+	///The btRigidBodyConstructionInfo structure provides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body.
+	///For dynamic objects, you can use the collision shape to approximate the local inertia tensor, otherwise use the zero vector (default argument)
+	///You can use the motion state to synchronize the world transform between physics and graphics objects. 
+	///And if the motion state is provided, the rigid body will initialize its initial world transform from the motion state,
+	///m_startWorldTransform is only used when you don't provide a motion state.
+	struct	btRigidBodyConstructionInfo
+	{
+		btScalar			m_mass;
+
+		///When a motionState is provided, the rigid body will initialize its world transform from the motion state
+		///In this case, m_startWorldTransform is ignored.
+		btMotionState*		m_motionState;
+		btTransform	m_startWorldTransform;
+
+		btCollisionShape*	m_collisionShape;
+		btVector3			m_localInertia;
+		btScalar			m_linearDamping;
+		btScalar			m_angularDamping;
+
+		///best simulation results when friction is non-zero
+		btScalar			m_friction;
+		///best simulation results using zero restitution.
+		btScalar			m_restitution;
+
+		btScalar			m_linearSleepingThreshold;
+		btScalar			m_angularSleepingThreshold;
+
+		//Additional damping can help avoiding lowpass jitter motion, help stability for ragdolls etc.
+		//Such damping is undesirable, so once the overall simulation quality of the rigid body dynamics system has improved, this should become obsolete
+		bool				m_additionalDamping;
+		btScalar			m_additionalDampingFactor;
+		btScalar			m_additionalLinearDampingThresholdSqr;
+		btScalar			m_additionalAngularDampingThresholdSqr;
+		btScalar			m_additionalAngularDampingFactor;
+
+		
+		btRigidBodyConstructionInfo(	btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0)):
+		m_mass(mass),
+			m_motionState(motionState),
+			m_collisionShape(collisionShape),
+			m_localInertia(localInertia),
+			m_linearDamping(btScalar(0.)),
+			m_angularDamping(btScalar(0.)),
+			m_friction(btScalar(0.5)),
+			m_restitution(btScalar(0.)),
+			m_linearSleepingThreshold(btScalar(0.8)),
+			m_angularSleepingThreshold(btScalar(1.f)),
+			m_additionalDamping(false),
+			m_additionalDampingFactor(btScalar(0.005)),
+			m_additionalLinearDampingThresholdSqr(btScalar(0.01)),
+			m_additionalAngularDampingThresholdSqr(btScalar(0.01)),
+			m_additionalAngularDampingFactor(btScalar(0.01))
+		{
+			m_startWorldTransform.setIdentity();
+		}
+	};
+
+	///btRigidBody constructor using construction info
+	btRigidBody(	const btRigidBodyConstructionInfo& constructionInfo);
+
+	///btRigidBody constructor for backwards compatibility. 
+	///To specify friction (etc) during rigid body construction, please use the other constructor (using btRigidBodyConstructionInfo)
+	btRigidBody(	btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0));
+
+
+	virtual ~btRigidBody()
+        { 
+                //No constraints should point to this rigidbody
+		//Remove constraints from the dynamics world before you delete the related rigidbodies. 
+                btAssert(m_constraintRefs.size()==0); 
+        }
+
+protected:
+
+	///setupRigidBody is only used internally by the constructor
+	void	setupRigidBody(const btRigidBodyConstructionInfo& constructionInfo);
+
+public:
+
+	void			proceedToTransform(const btTransform& newTrans); 
+	
+	///to keep collision detection and dynamics separate we don't store a rigidbody pointer
+	///but a rigidbody is derived from btCollisionObject, so we can safely perform an upcast
+	static const btRigidBody*	upcast(const btCollisionObject* colObj)
+	{
+		if (colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY)
+			return (const btRigidBody*)colObj;
+		return 0;
+	}
+	static btRigidBody*	upcast(btCollisionObject* colObj)
+	{
+		if (colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY)
+			return (btRigidBody*)colObj;
+		return 0;
+	}
+	
+	/// continuous collision detection needs prediction
+	void			predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ;
+	
+	void			saveKinematicState(btScalar step);
+	
+	void			applyGravity();
+	
+	void			setGravity(const btVector3& acceleration);  
+
+	const btVector3&	getGravity() const
+	{
+		return m_gravity_acceleration;
+	}
+
+	void			setDamping(btScalar lin_damping, btScalar ang_damping);
+
+	btScalar getLinearDamping() const
+	{
+		return m_linearDamping;
+	}
+
+	btScalar getAngularDamping() const
+	{
+		return m_angularDamping;
+	}
+
+	btScalar getLinearSleepingThreshold() const
+	{
+		return m_linearSleepingThreshold;
+	}
+
+	btScalar getAngularSleepingThreshold() const
+	{
+		return m_angularSleepingThreshold;
+	}
+
+	void			applyDamping(btScalar timeStep);
+
+	SIMD_FORCE_INLINE const btCollisionShape*	getCollisionShape() const {
+		return m_collisionShape;
+	}
+
+	SIMD_FORCE_INLINE btCollisionShape*	getCollisionShape() {
+			return m_collisionShape;
+	}
+	
+	void			setMassProps(btScalar mass, const btVector3& inertia);
+	
+	btScalar		getInvMass() const { return m_inverseMass; }
+	const btMatrix3x3& getInvInertiaTensorWorld() const { 
+		return m_invInertiaTensorWorld; 
+	}
+		
+	void			integrateVelocities(btScalar step);
+
+	void			setCenterOfMassTransform(const btTransform& xform);
+
+	void			applyCentralForce(const btVector3& force)
+	{
+		m_totalForce += force;
+	}
+
+	const btVector3& getTotalForce()
+	{
+		return m_totalForce;
+	};
+
+	const btVector3& getTotalTorque()
+	{
+		return m_totalTorque;
+	};
+    
+	const btVector3& getInvInertiaDiagLocal() const
+	{
+		return m_invInertiaLocal;
+	};
+
+	void	setInvInertiaDiagLocal(const btVector3& diagInvInertia)
+	{
+		m_invInertiaLocal = diagInvInertia;
+	}
+
+	void	setSleepingThresholds(btScalar linear,btScalar angular)
+	{
+		m_linearSleepingThreshold = linear;
+		m_angularSleepingThreshold = angular;
+	}
+
+	void	applyTorque(const btVector3& torque)
+	{
+		m_totalTorque += torque;
+	}
+	
+	void	applyForce(const btVector3& force, const btVector3& rel_pos) 
+	{
+		applyCentralForce(force);
+		applyTorque(rel_pos.cross(force)*m_angularFactor);
+	}
+	
+	void applyCentralImpulse(const btVector3& impulse)
+	{
+		m_linearVelocity += impulse * m_inverseMass;
+	}
+	
+  	void applyTorqueImpulse(const btVector3& torque)
+	{
+			m_angularVelocity += m_invInertiaTensorWorld * torque;
+	}
+	
+	void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) 
+	{
+		if (m_inverseMass != btScalar(0.))
+		{
+			applyCentralImpulse(impulse);
+			if (m_angularFactor)
+			{
+				applyTorqueImpulse(rel_pos.cross(impulse)*m_angularFactor);
+			}
+		}
+	}
+
+	//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() 
+	{
+		m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
+		m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
+	}
+	
+	void updateInertiaTensor();    
+	
+	const btVector3&     getCenterOfMassPosition() const { 
+		return m_worldTransform.getOrigin(); 
+	}
+	btQuaternion getOrientation() const;
+	
+	const btTransform&  getCenterOfMassTransform() const { 
+		return m_worldTransform; 
+	}
+	const btVector3&   getLinearVelocity() const { 
+		return m_linearVelocity; 
+	}
+	const btVector3&    getAngularVelocity() const { 
+		return m_angularVelocity; 
+	}
+	
+
+	inline void setLinearVelocity(const btVector3& lin_vel)
+	{ 
+		m_linearVelocity = lin_vel; 
+	}
+
+	inline void setAngularVelocity(const btVector3& ang_vel) 
+	{ 
+		m_angularVelocity = ang_vel; 
+	}
+
+	btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const
+	{
+		//we also calculate lin/ang velocity for kinematic objects
+		return m_linearVelocity + m_angularVelocity.cross(rel_pos);
+
+		//for kinematic objects, we could also use use:
+		//		return 	(m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep;
+	}
+
+	void translate(const btVector3& v) 
+	{
+		m_worldTransform.getOrigin() += v; 
+	}
+
+	
+	void	getAabb(btVector3& aabbMin,btVector3& aabbMax) const;
+
+
+
+
+	
+	SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btVector3& pos, const btVector3& normal) const
+	{
+		btVector3 r0 = pos - getCenterOfMassPosition();
+
+		btVector3 c0 = (r0).cross(normal);
+
+		btVector3 vec = (c0 * getInvInertiaTensorWorld()).cross(r0);
+
+		return m_inverseMass + normal.dot(vec);
+
+	}
+
+	SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis) const
+	{
+		btVector3 vec = axis * getInvInertiaTensorWorld();
+		return axis.dot(vec);
+	}
+
+	SIMD_FORCE_INLINE void	updateDeactivation(btScalar timeStep)
+	{
+		if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION))
+			return;
+
+		if ((getLinearVelocity().length2() < m_linearSleepingThreshold*m_linearSleepingThreshold) &&
+			(getAngularVelocity().length2() < m_angularSleepingThreshold*m_angularSleepingThreshold))
+		{
+			m_deactivationTime += timeStep;
+		} else
+		{
+			m_deactivationTime=btScalar(0.);
+			setActivationState(0);
+		}
+
+	}
+
+	SIMD_FORCE_INLINE bool	wantsSleeping()
+	{
+
+		if (getActivationState() == DISABLE_DEACTIVATION)
+			return false;
+
+		//disable deactivation
+		if (gDisableDeactivation || (gDeactivationTime == btScalar(0.)))
+			return false;
+
+		if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION))
+			return true;
+
+		if (m_deactivationTime> gDeactivationTime)
+		{
+			return true;
+		}
+		return false;
+	}
+
+
+	
+	const btBroadphaseProxy*	getBroadphaseProxy() const
+	{
+		return m_broadphaseHandle;
+	}
+	btBroadphaseProxy*	getBroadphaseProxy() 
+	{
+		return m_broadphaseHandle;
+	}
+	void	setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy)
+	{
+		m_broadphaseHandle = broadphaseProxy;
+	}
+
+	//btMotionState allows to automatic synchronize the world transform for active objects
+	btMotionState*	getMotionState()
+	{
+		return m_optionalMotionState;
+	}
+	const btMotionState*	getMotionState() const
+	{
+		return m_optionalMotionState;
+	}
+	void	setMotionState(btMotionState* motionState)
+	{
+		m_optionalMotionState = motionState;
+		if (m_optionalMotionState)
+			motionState->getWorldTransform(m_worldTransform);
+	}
+
+	//for experimental overriding of friction/contact solver func
+	int	m_contactSolverType;
+	int	m_frictionSolverType;
+
+	void	setAngularFactor(btScalar angFac)
+	{
+		m_angularFactor = angFac;
+	}
+	btScalar	getAngularFactor() const
+	{
+		return m_angularFactor;
+	}
+
+	//is this rigidbody added to a btCollisionWorld/btDynamicsWorld/btBroadphase?
+	bool	isInWorld() const
+	{
+		return (getBroadphaseProxy() != 0);
+	}
+
+	virtual bool checkCollideWithOverride(btCollisionObject* co);
+
+	void addConstraintRef(btTypedConstraint* c);
+	void removeConstraintRef(btTypedConstraint* c);
+
+	btTypedConstraint* getConstraintRef(int index)
+	{
+		return m_constraintRefs[index];
+	}
+
+	int getNumConstraintRefs()
+	{
+		return m_constraintRefs.size();
+	}
+
+	int	m_debugBodyId;
+};
+
+
+
+#endif
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp	(revision 6952)
@@ -0,0 +1,243 @@
+/*
+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 "btSimpleDynamicsWorld.h"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
+#include "BulletCollision/CollisionShapes/btCollisionShape.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
+#include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h"
+
+
+/*
+  Make sure this dummy function never changes so that it
+  can be used by probes that are checking whether the
+  library is actually installed.
+*/
+extern "C" 
+{
+	void btBulletDynamicsProbe ();
+	void btBulletDynamicsProbe () {}
+}
+
+
+
+
+btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration)
+:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration),
+m_constraintSolver(constraintSolver),
+m_ownsConstraintSolver(false),
+m_gravity(0,0,-10)
+{
+
+}
+
+
+btSimpleDynamicsWorld::~btSimpleDynamicsWorld()
+{
+	if (m_ownsConstraintSolver)
+		btAlignedFree( m_constraintSolver);
+}
+
+int		btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep)
+{
+	(void)fixedTimeStep;
+	(void)maxSubSteps;
+
+
+	///apply gravity, predict motion
+	predictUnconstraintMotion(timeStep);
+
+	btDispatcherInfo&	dispatchInfo = getDispatchInfo();
+	dispatchInfo.m_timeStep = timeStep;
+	dispatchInfo.m_stepCount = 0;
+	dispatchInfo.m_debugDraw = getDebugDrawer();
+
+	///perform collision detection
+	performDiscreteCollisionDetection();
+
+	///solve contact constraints
+	int numManifolds = m_dispatcher1->getNumManifolds();
+	if (numManifolds)
+	{
+		btPersistentManifold** manifoldPtr = ((btCollisionDispatcher*)m_dispatcher1)->getInternalManifoldPointer();
+		
+		btContactSolverInfo infoGlobal;
+		infoGlobal.m_timeStep = timeStep;
+		m_constraintSolver->prepareSolve(0,numManifolds);
+		m_constraintSolver->solveGroup(0,0,manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_stackAlloc,m_dispatcher1);
+		m_constraintSolver->allSolved(infoGlobal,m_debugDrawer, m_stackAlloc);
+	}
+
+	///integrate transforms
+	integrateTransforms(timeStep);
+		
+	updateAabbs();
+
+	synchronizeMotionStates();
+
+	clearForces();
+
+	return 1;
+
+}
+
+void	btSimpleDynamicsWorld::clearForces()
+{
+	///@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();
+		}
+	}
+}	
+
+
+void	btSimpleDynamicsWorld::setGravity(const btVector3& gravity)
+{
+	m_gravity = gravity;
+	for ( int i=0;i<m_collisionObjects.size();i++)
+	{
+		btCollisionObject* colObj = m_collisionObjects[i];
+		btRigidBody* body = btRigidBody::upcast(colObj);
+		if (body)
+		{
+			body->setGravity(gravity);
+		}
+	}
+}
+
+btVector3 btSimpleDynamicsWorld::getGravity () const
+{
+	return m_gravity;
+}
+
+void	btSimpleDynamicsWorld::removeRigidBody(btRigidBody* body)
+{
+	removeCollisionObject(body);
+}
+
+void	btSimpleDynamicsWorld::addRigidBody(btRigidBody* body)
+{
+	body->setGravity(m_gravity);
+
+	if (body->getCollisionShape())
+	{
+		addCollisionObject(body);
+	}
+}
+
+void	btSimpleDynamicsWorld::updateAabbs()
+{
+	btTransform predictedTrans;
+	for ( int i=0;i<m_collisionObjects.size();i++)
+	{
+		btCollisionObject* colObj = m_collisionObjects[i];
+		btRigidBody* body = btRigidBody::upcast(colObj);
+		if (body)
+		{
+			if (body->isActive() && (!body->isStaticObject()))
+			{
+				btVector3 minAabb,maxAabb;
+				colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb);
+				btBroadphaseInterface* bp = getBroadphase();
+				bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1);
+			}
+		}
+	}
+}
+
+void	btSimpleDynamicsWorld::integrateTransforms(btScalar timeStep)
+{
+	btTransform predictedTrans;
+	for ( int i=0;i<m_collisionObjects.size();i++)
+	{
+		btCollisionObject* colObj = m_collisionObjects[i];
+		btRigidBody* body = btRigidBody::upcast(colObj);
+		if (body)
+		{
+			if (body->isActive() && (!body->isStaticObject()))
+			{
+				body->predictIntegratedTransform(timeStep, predictedTrans);
+				body->proceedToTransform( predictedTrans);
+			}
+		}
+	}
+}
+
+
+
+void	btSimpleDynamicsWorld::predictUnconstraintMotion(btScalar timeStep)
+{
+	for ( int i=0;i<m_collisionObjects.size();i++)
+	{
+		btCollisionObject* colObj = m_collisionObjects[i];
+		btRigidBody* body = btRigidBody::upcast(colObj);
+		if (body)
+		{
+			if (!body->isStaticObject())
+			{
+				if (body->isActive())
+				{
+					body->applyGravity();
+					body->integrateVelocities( timeStep);
+					body->applyDamping(timeStep);
+					body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform());
+				}
+			}
+		}
+	}
+}
+
+
+void	btSimpleDynamicsWorld::synchronizeMotionStates()
+{
+	///@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->getMotionState())
+		{
+			if (body->getActivationState() != ISLAND_SLEEPING)
+			{
+				body->getMotionState()->setWorldTransform(body->getWorldTransform());
+			}
+		}
+	}
+
+}
+
+
+void	btSimpleDynamicsWorld::setConstraintSolver(btConstraintSolver* solver)
+{
+	if (m_ownsConstraintSolver)
+	{
+		btAlignedFree(m_constraintSolver);
+	}
+	m_ownsConstraintSolver = false;
+	m_constraintSolver = solver;
+}
+
+btConstraintSolver* btSimpleDynamicsWorld::getConstraintSolver()
+{
+	return m_constraintSolver;
+}
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Dynamics/btSimpleDynamicsWorld.h	(revision 6952)
@@ -0,0 +1,78 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_SIMPLE_DYNAMICS_WORLD_H
+#define BT_SIMPLE_DYNAMICS_WORLD_H
+
+#include "btDynamicsWorld.h"
+
+class btDispatcher;
+class btOverlappingPairCache;
+class btConstraintSolver;
+
+///The btSimpleDynamicsWorld serves as unit-test and to verify more complicated and optimized dynamics worlds.
+///Please use btDiscreteDynamicsWorld instead (or btContinuousDynamicsWorld once it is finished).
+class btSimpleDynamicsWorld : public btDynamicsWorld
+{
+protected:
+
+	btConstraintSolver*	m_constraintSolver;
+
+	bool	m_ownsConstraintSolver;
+
+	void	predictUnconstraintMotion(btScalar timeStep);
+	
+	void	integrateTransforms(btScalar timeStep);
+		
+	btVector3	m_gravity;
+	
+public:
+
+
+
+	///this btSimpleDynamicsWorld constructor creates dispatcher, broadphase pairCache and constraintSolver
+	btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration);
+
+	virtual ~btSimpleDynamicsWorld();
+		
+	///maxSubSteps/fixedTimeStep for interpolation is currently ignored for btSimpleDynamicsWorld, use btDiscreteDynamicsWorld instead
+	virtual int	stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.));
+
+	virtual void	setGravity(const btVector3& gravity);
+
+	virtual btVector3 getGravity () const;
+
+	virtual void	addRigidBody(btRigidBody* body);
+
+	virtual void	removeRigidBody(btRigidBody* body);
+	
+	virtual void	updateAabbs();
+
+	virtual void	synchronizeMotionStates();
+
+	virtual void	setConstraintSolver(btConstraintSolver* solver);
+
+	virtual btConstraintSolver* getConstraintSolver();
+
+	virtual btDynamicsWorldType	getWorldType() const
+	{
+		return BT_SIMPLE_DYNAMICS_WORLD;
+	}
+
+	virtual void	clearForces();
+
+};
+
+#endif //BT_SIMPLE_DYNAMICS_WORLD_H
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btRaycastVehicle.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btRaycastVehicle.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btRaycastVehicle.cpp	(revision 6952)
@@ -0,0 +1,758 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability 
+ * of this software for any purpose.  
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "LinearMath/btVector3.h"
+#include "btRaycastVehicle.h"
+
+#include "BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btJacobianEntry.h"
+#include "LinearMath/btQuaternion.h"
+#include "BulletDynamics/Dynamics/btDynamicsWorld.h"
+#include "btVehicleRaycaster.h"
+#include "btWheelInfo.h"
+#include "LinearMath/btMinMax.h"
+#include "LinearMath/btIDebugDraw.h"
+#include "BulletDynamics/ConstraintSolver/btContactConstraint.h"
+
+static btRigidBody s_fixedObject( 0,0,0);
+
+btRaycastVehicle::btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis,	btVehicleRaycaster* raycaster )
+:m_vehicleRaycaster(raycaster),
+m_pitchControl(btScalar(0.))
+{
+	m_chassisBody = chassis;
+	m_indexRightAxis = 0;
+	m_indexUpAxis = 2;
+	m_indexForwardAxis = 1;
+	defaultInit(tuning);
+}
+
+
+void btRaycastVehicle::defaultInit(const btVehicleTuning& tuning)
+{
+	(void)tuning;
+	m_currentVehicleSpeedKmHour = btScalar(0.);
+	m_steeringValue = btScalar(0.);
+	
+}
+
+	
+
+btRaycastVehicle::~btRaycastVehicle()
+{
+}
+
+
+//
+// basically most of the code is general for 2 or 4 wheel vehicles, but some of it needs to be reviewed
+//
+btWheelInfo&	btRaycastVehicle::addWheel( const btVector3& connectionPointCS, const btVector3& wheelDirectionCS0,const btVector3& wheelAxleCS, btScalar suspensionRestLength, btScalar wheelRadius,const btVehicleTuning& tuning, bool isFrontWheel)
+{
+
+	btWheelInfoConstructionInfo ci;
+
+	ci.m_chassisConnectionCS = connectionPointCS;
+	ci.m_wheelDirectionCS = wheelDirectionCS0;
+	ci.m_wheelAxleCS = wheelAxleCS;
+	ci.m_suspensionRestLength = suspensionRestLength;
+	ci.m_wheelRadius = wheelRadius;
+	ci.m_suspensionStiffness = tuning.m_suspensionStiffness;
+	ci.m_wheelsDampingCompression = tuning.m_suspensionCompression;
+	ci.m_wheelsDampingRelaxation = tuning.m_suspensionDamping;
+	ci.m_frictionSlip = tuning.m_frictionSlip;
+	ci.m_bIsFrontWheel = isFrontWheel;
+	ci.m_maxSuspensionTravelCm = tuning.m_maxSuspensionTravelCm;
+
+	m_wheelInfo.push_back( btWheelInfo(ci));
+	
+	btWheelInfo& wheel = m_wheelInfo[getNumWheels()-1];
+	
+	updateWheelTransformsWS( wheel , false );
+	updateWheelTransform(getNumWheels()-1,false);
+	return wheel;
+}
+
+
+
+
+const btTransform&	btRaycastVehicle::getWheelTransformWS( int wheelIndex ) const
+{
+	btAssert(wheelIndex < getNumWheels());
+	const btWheelInfo& wheel = m_wheelInfo[wheelIndex];
+	return wheel.m_worldTransform;
+
+}
+
+void	btRaycastVehicle::updateWheelTransform( int wheelIndex , bool interpolatedTransform)
+{
+	
+	btWheelInfo& wheel = m_wheelInfo[ wheelIndex ];
+	updateWheelTransformsWS(wheel,interpolatedTransform);
+	btVector3 up = -wheel.m_raycastInfo.m_wheelDirectionWS;
+	const btVector3& right = wheel.m_raycastInfo.m_wheelAxleWS;
+	btVector3 fwd = up.cross(right);
+	fwd = fwd.normalize();
+//	up = right.cross(fwd);
+//	up.normalize();
+
+	//rotate around steering over de wheelAxleWS
+	btScalar steering = wheel.m_steering;
+	
+	btQuaternion steeringOrn(up,steering);//wheel.m_steering);
+	btMatrix3x3 steeringMat(steeringOrn);
+
+	btQuaternion rotatingOrn(right,-wheel.m_rotation);
+	btMatrix3x3 rotatingMat(rotatingOrn);
+
+	btMatrix3x3 basis2(
+		right[0],fwd[0],up[0],
+		right[1],fwd[1],up[1],
+		right[2],fwd[2],up[2]
+	);
+	
+	wheel.m_worldTransform.setBasis(steeringMat * rotatingMat * basis2);
+	wheel.m_worldTransform.setOrigin(
+		wheel.m_raycastInfo.m_hardPointWS + wheel.m_raycastInfo.m_wheelDirectionWS * wheel.m_raycastInfo.m_suspensionLength
+	);
+}
+
+void btRaycastVehicle::resetSuspension()
+{
+
+	int i;
+	for (i=0;i<m_wheelInfo.size();	i++)
+	{
+			btWheelInfo& wheel = m_wheelInfo[i];
+			wheel.m_raycastInfo.m_suspensionLength = wheel.getSuspensionRestLength();
+			wheel.m_suspensionRelativeVelocity = btScalar(0.0);
+			
+			wheel.m_raycastInfo.m_contactNormalWS = - wheel.m_raycastInfo.m_wheelDirectionWS;
+			//wheel_info.setContactFriction(btScalar(0.0));
+			wheel.m_clippedInvContactDotSuspension = btScalar(1.0);
+	}
+}
+
+void	btRaycastVehicle::updateWheelTransformsWS(btWheelInfo& wheel , bool interpolatedTransform)
+{
+	wheel.m_raycastInfo.m_isInContact = false;
+
+	btTransform chassisTrans = getChassisWorldTransform();
+	if (interpolatedTransform && (getRigidBody()->getMotionState()))
+	{
+		getRigidBody()->getMotionState()->getWorldTransform(chassisTrans);
+	}
+
+	wheel.m_raycastInfo.m_hardPointWS = chassisTrans( wheel.m_chassisConnectionPointCS );
+	wheel.m_raycastInfo.m_wheelDirectionWS = chassisTrans.getBasis() *  wheel.m_wheelDirectionCS ;
+	wheel.m_raycastInfo.m_wheelAxleWS = chassisTrans.getBasis() * wheel.m_wheelAxleCS;
+}
+
+btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel)
+{
+	updateWheelTransformsWS( wheel,false);
+
+	
+	btScalar depth = -1;
+	
+	btScalar raylen = wheel.getSuspensionRestLength()+wheel.m_wheelsRadius;
+
+	btVector3 rayvector = wheel.m_raycastInfo.m_wheelDirectionWS * (raylen);
+	const btVector3& source = wheel.m_raycastInfo.m_hardPointWS;
+	wheel.m_raycastInfo.m_contactPointWS = source + rayvector;
+	const btVector3& target = wheel.m_raycastInfo.m_contactPointWS;
+
+	btScalar param = btScalar(0.);
+	
+	btVehicleRaycaster::btVehicleRaycasterResult	rayResults;
+
+	btAssert(m_vehicleRaycaster);
+
+	void* object = m_vehicleRaycaster->castRay(source,target,rayResults);
+
+	wheel.m_raycastInfo.m_groundObject = 0;
+
+	if (object)
+	{
+		param = rayResults.m_distFraction;
+		depth = raylen * rayResults.m_distFraction;
+		wheel.m_raycastInfo.m_contactNormalWS  = rayResults.m_hitNormalInWorld;
+		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 = object;
+
+
+		btScalar hitDistance = param*raylen;
+		wheel.m_raycastInfo.m_suspensionLength = hitDistance - wheel.m_wheelsRadius;
+		//clamp on max suspension travel
+
+		btScalar  minSuspensionLength = wheel.getSuspensionRestLength() - wheel.m_maxSuspensionTravelCm*btScalar(0.01);
+		btScalar maxSuspensionLength = wheel.getSuspensionRestLength()+ wheel.m_maxSuspensionTravelCm*btScalar(0.01);
+		if (wheel.m_raycastInfo.m_suspensionLength < minSuspensionLength)
+		{
+			wheel.m_raycastInfo.m_suspensionLength = minSuspensionLength;
+		}
+		if (wheel.m_raycastInfo.m_suspensionLength > maxSuspensionLength)
+		{
+			wheel.m_raycastInfo.m_suspensionLength = maxSuspensionLength;
+		}
+
+		wheel.m_raycastInfo.m_contactPointWS = rayResults.m_hitPointInWorld;
+
+		btScalar denominator= wheel.m_raycastInfo.m_contactNormalWS.dot( wheel.m_raycastInfo.m_wheelDirectionWS );
+
+		btVector3 chassis_velocity_at_contactPoint;
+		btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS-getRigidBody()->getCenterOfMassPosition();
+
+		chassis_velocity_at_contactPoint = getRigidBody()->getVelocityInLocalPoint(relpos);
+
+		btScalar projVel = wheel.m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint );
+
+		if ( denominator >= btScalar(-0.1))
+		{
+			wheel.m_suspensionRelativeVelocity = btScalar(0.0);
+			wheel.m_clippedInvContactDotSuspension = btScalar(1.0) / btScalar(0.1);
+		}
+		else
+		{
+			btScalar inv = btScalar(-1.) / denominator;
+			wheel.m_suspensionRelativeVelocity = projVel * inv;
+			wheel.m_clippedInvContactDotSuspension = inv;
+		}
+			
+	} else
+	{
+		//put wheel info as in rest position
+		wheel.m_raycastInfo.m_suspensionLength = wheel.getSuspensionRestLength();
+		wheel.m_suspensionRelativeVelocity = btScalar(0.0);
+		wheel.m_raycastInfo.m_contactNormalWS = - wheel.m_raycastInfo.m_wheelDirectionWS;
+		wheel.m_clippedInvContactDotSuspension = btScalar(1.0);
+	}
+
+	return depth;
+}
+
+
+const btTransform& btRaycastVehicle::getChassisWorldTransform() const
+{
+	/*if (getRigidBody()->getMotionState())
+	{
+		btTransform chassisWorldTrans;
+		getRigidBody()->getMotionState()->getWorldTransform(chassisWorldTrans);
+		return chassisWorldTrans;
+	}
+	*/
+
+	
+	return getRigidBody()->getCenterOfMassTransform();
+}
+
+
+void btRaycastVehicle::updateVehicle( btScalar step )
+{
+	{
+		for (int i=0;i<getNumWheels();i++)
+		{
+			updateWheelTransform(i,false);
+		}
+	}
+
+
+	m_currentVehicleSpeedKmHour = btScalar(3.6) * getRigidBody()->getLinearVelocity().length();
+	
+	const btTransform& chassisTrans = getChassisWorldTransform();
+
+	btVector3 forwardW (
+		chassisTrans.getBasis()[0][m_indexForwardAxis],
+		chassisTrans.getBasis()[1][m_indexForwardAxis],
+		chassisTrans.getBasis()[2][m_indexForwardAxis]);
+
+	if (forwardW.dot(getRigidBody()->getLinearVelocity()) < btScalar(0.))
+	{
+		m_currentVehicleSpeedKmHour *= btScalar(-1.);
+	}
+
+	//
+	// simulate suspension
+	//
+	
+	int i=0;
+	for (i=0;i<m_wheelInfo.size();i++)
+	{
+		btScalar depth; 
+		depth = rayCast( m_wheelInfo[i]);
+	}
+
+	updateSuspension(step);
+
+	
+	for (i=0;i<m_wheelInfo.size();i++)
+	{
+		//apply suspension force
+		btWheelInfo& wheel = m_wheelInfo[i];
+		
+		btScalar suspensionForce = wheel.m_wheelsSuspensionForce;
+		
+		btScalar gMaxSuspensionForce = btScalar(6000.);
+		if (suspensionForce > gMaxSuspensionForce)
+		{
+			suspensionForce = gMaxSuspensionForce;
+		}
+		btVector3 impulse = wheel.m_raycastInfo.m_contactNormalWS * suspensionForce * step;
+		btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS - getRigidBody()->getCenterOfMassPosition();
+		
+		getRigidBody()->applyImpulse(impulse, relpos);
+	
+	}
+	
+
+	
+	updateFriction( step);
+
+	
+	for (i=0;i<m_wheelInfo.size();i++)
+	{
+		btWheelInfo& wheel = m_wheelInfo[i];
+		btVector3 relpos = wheel.m_raycastInfo.m_hardPointWS - getRigidBody()->getCenterOfMassPosition();
+		btVector3 vel = getRigidBody()->getVelocityInLocalPoint( relpos );
+
+		if (wheel.m_raycastInfo.m_isInContact)
+		{
+			const btTransform&	chassisWorldTransform = getChassisWorldTransform();
+
+			btVector3 fwd (
+				chassisWorldTransform.getBasis()[0][m_indexForwardAxis],
+				chassisWorldTransform.getBasis()[1][m_indexForwardAxis],
+				chassisWorldTransform.getBasis()[2][m_indexForwardAxis]);
+
+			btScalar proj = fwd.dot(wheel.m_raycastInfo.m_contactNormalWS);
+			fwd -= wheel.m_raycastInfo.m_contactNormalWS * proj;
+
+			btScalar proj2 = fwd.dot(vel);
+			
+			wheel.m_deltaRotation = (proj2 * step) / (wheel.m_wheelsRadius);
+			wheel.m_rotation += wheel.m_deltaRotation;
+
+		} else
+		{
+			wheel.m_rotation += wheel.m_deltaRotation;
+		}
+		
+		wheel.m_deltaRotation *= btScalar(0.99);//damping of rotation when not in contact
+
+	}
+
+
+
+}
+
+
+void	btRaycastVehicle::setSteeringValue(btScalar steering,int wheel)
+{
+	btAssert(wheel>=0 && wheel < getNumWheels());
+
+	btWheelInfo& wheelInfo = getWheelInfo(wheel);
+	wheelInfo.m_steering = steering;
+}
+
+
+
+btScalar	btRaycastVehicle::getSteeringValue(int wheel) const
+{
+	return getWheelInfo(wheel).m_steering;
+}
+
+
+void	btRaycastVehicle::applyEngineForce(btScalar force, int wheel)
+{
+	btAssert(wheel>=0 && wheel < getNumWheels());
+	btWheelInfo& wheelInfo = getWheelInfo(wheel);
+	wheelInfo.m_engineForce = force;
+}
+
+
+const btWheelInfo&	btRaycastVehicle::getWheelInfo(int index) const
+{
+	btAssert((index >= 0) && (index < 	getNumWheels()));
+	
+	return m_wheelInfo[index];
+}
+
+btWheelInfo&	btRaycastVehicle::getWheelInfo(int index) 
+{
+	btAssert((index >= 0) && (index < 	getNumWheels()));
+	
+	return m_wheelInfo[index];
+}
+
+void btRaycastVehicle::setBrake(btScalar brake,int wheelIndex)
+{
+	btAssert((wheelIndex >= 0) && (wheelIndex < 	getNumWheels()));
+	getWheelInfo(wheelIndex).m_brake = brake;
+}
+
+
+void	btRaycastVehicle::updateSuspension(btScalar deltaTime)
+{
+	(void)deltaTime;
+
+	btScalar chassisMass = btScalar(1.) / m_chassisBody->getInvMass();
+	
+	for (int w_it=0; w_it<getNumWheels(); w_it++)
+	{
+		btWheelInfo &wheel_info = m_wheelInfo[w_it];
+		
+		if ( wheel_info.m_raycastInfo.m_isInContact )
+		{
+			btScalar force;
+			//	Spring
+			{
+				btScalar	susp_length			= wheel_info.getSuspensionRestLength();
+				btScalar	current_length = wheel_info.m_raycastInfo.m_suspensionLength;
+
+				btScalar length_diff = (susp_length - current_length);
+
+				force = wheel_info.m_suspensionStiffness
+					* length_diff * wheel_info.m_clippedInvContactDotSuspension;
+			}
+		
+			// Damper
+			{
+				btScalar projected_rel_vel = wheel_info.m_suspensionRelativeVelocity;
+				{
+					btScalar	susp_damping;
+					if ( projected_rel_vel < btScalar(0.0) )
+					{
+						susp_damping = wheel_info.m_wheelsDampingCompression;
+					}
+					else
+					{
+						susp_damping = wheel_info.m_wheelsDampingRelaxation;
+					}
+					force -= susp_damping * projected_rel_vel;
+				}
+			}
+
+			// RESULT
+			wheel_info.m_wheelsSuspensionForce = force * chassisMass;
+			if (wheel_info.m_wheelsSuspensionForce < btScalar(0.))
+			{
+				wheel_info.m_wheelsSuspensionForce = btScalar(0.);
+			}
+		}
+		else
+		{
+			wheel_info.m_wheelsSuspensionForce = btScalar(0.0);
+		}
+	}
+
+}
+
+
+struct btWheelContactPoint
+{
+	btRigidBody* m_body0;
+	btRigidBody* m_body1;
+	btVector3	m_frictionPositionWorld;
+	btVector3	m_frictionDirectionWorld;
+	btScalar	m_jacDiagABInv;
+	btScalar	m_maxImpulse;
+
+
+	btWheelContactPoint(btRigidBody* body0,btRigidBody* body1,const btVector3& frictionPosWorld,const btVector3& frictionDirectionWorld, btScalar maxImpulse)
+		:m_body0(body0),
+		m_body1(body1),
+		m_frictionPositionWorld(frictionPosWorld),
+		m_frictionDirectionWorld(frictionDirectionWorld),
+		m_maxImpulse(maxImpulse)
+	{
+		btScalar denom0 = body0->computeImpulseDenominator(frictionPosWorld,frictionDirectionWorld);
+		btScalar denom1 = body1->computeImpulseDenominator(frictionPosWorld,frictionDirectionWorld);
+		btScalar	relaxation = 1.f;
+		m_jacDiagABInv = relaxation/(denom0+denom1);
+	}
+
+
+
+};
+
+btScalar calcRollingFriction(btWheelContactPoint& contactPoint);
+btScalar calcRollingFriction(btWheelContactPoint& contactPoint)
+{
+
+	btScalar j1=0.f;
+
+	const btVector3& contactPosWorld = contactPoint.m_frictionPositionWorld;
+
+	btVector3 rel_pos1 = contactPosWorld - contactPoint.m_body0->getCenterOfMassPosition(); 
+	btVector3 rel_pos2 = contactPosWorld - contactPoint.m_body1->getCenterOfMassPosition();
+	
+	btScalar maxImpulse  = contactPoint.m_maxImpulse;
+	
+	btVector3 vel1 = contactPoint.m_body0->getVelocityInLocalPoint(rel_pos1);
+	btVector3 vel2 = contactPoint.m_body1->getVelocityInLocalPoint(rel_pos2);
+	btVector3 vel = vel1 - vel2;
+
+	btScalar vrel = contactPoint.m_frictionDirectionWorld.dot(vel);
+
+	// calculate j that moves us to zero relative velocity
+	j1 = -vrel * contactPoint.m_jacDiagABInv;
+	btSetMin(j1, maxImpulse);
+	btSetMax(j1, -maxImpulse);
+
+	return j1;
+}
+
+
+
+
+btScalar sideFrictionStiffness2 = btScalar(1.0);
+void	btRaycastVehicle::updateFriction(btScalar	timeStep)
+{
+
+		//calculate the impulse, so that the wheels don't move sidewards
+		int numWheel = getNumWheels();
+		if (!numWheel)
+			return;
+
+		m_forwardWS.resize(numWheel);
+		m_axle.resize(numWheel);
+		m_forwardImpulse.resize(numWheel);
+		m_sideImpulse.resize(numWheel);
+		
+		int numWheelsOnGround = 0;
+	
+
+		//collapse all those loops into one!
+		for (int i=0;i<getNumWheels();i++)
+		{
+			btWheelInfo& wheelInfo = m_wheelInfo[i];
+			class btRigidBody* groundObject = (class btRigidBody*) wheelInfo.m_raycastInfo.m_groundObject;
+			if (groundObject)
+				numWheelsOnGround++;
+			m_sideImpulse[i] = btScalar(0.);
+			m_forwardImpulse[i] = btScalar(0.);
+
+		}
+	
+		{
+	
+			for (int i=0;i<getNumWheels();i++)
+			{
+
+				btWheelInfo& wheelInfo = m_wheelInfo[i];
+					
+				class btRigidBody* groundObject = (class btRigidBody*) wheelInfo.m_raycastInfo.m_groundObject;
+
+				if (groundObject)
+				{
+
+					const btTransform& wheelTrans = getWheelTransformWS( i );
+
+					btMatrix3x3 wheelBasis0 = wheelTrans.getBasis();
+					m_axle[i] = btVector3(	
+						wheelBasis0[0][m_indexRightAxis],
+						wheelBasis0[1][m_indexRightAxis],
+						wheelBasis0[2][m_indexRightAxis]);
+					
+					const btVector3& surfNormalWS = wheelInfo.m_raycastInfo.m_contactNormalWS;
+					btScalar proj = m_axle[i].dot(surfNormalWS);
+					m_axle[i] -= surfNormalWS * proj;
+					m_axle[i] = m_axle[i].normalize();
+					
+					m_forwardWS[i] = surfNormalWS.cross(m_axle[i]);
+					m_forwardWS[i].normalize();
+
+				
+					resolveSingleBilateral(*m_chassisBody, wheelInfo.m_raycastInfo.m_contactPointWS,
+							  *groundObject, wheelInfo.m_raycastInfo.m_contactPointWS,
+							  btScalar(0.), m_axle[i],m_sideImpulse[i],timeStep);
+
+					m_sideImpulse[i] *= sideFrictionStiffness2;
+						
+				}
+				
+
+			}
+		}
+
+	btScalar sideFactor = btScalar(1.);
+	btScalar fwdFactor = 0.5;
+
+	bool sliding = false;
+	{
+		for (int wheel =0;wheel <getNumWheels();wheel++)
+		{
+			btWheelInfo& wheelInfo = m_wheelInfo[wheel];
+			class btRigidBody* groundObject = (class btRigidBody*) wheelInfo.m_raycastInfo.m_groundObject;
+
+			btScalar	rollingFriction = 0.f;
+
+			if (groundObject)
+			{
+				if (wheelInfo.m_engineForce != 0.f)
+				{
+					rollingFriction = wheelInfo.m_engineForce* timeStep;
+				} else
+				{
+					btScalar defaultRollingFrictionImpulse = 0.f;
+					btScalar maxImpulse = wheelInfo.m_brake ? wheelInfo.m_brake : defaultRollingFrictionImpulse;
+					btWheelContactPoint contactPt(m_chassisBody,groundObject,wheelInfo.m_raycastInfo.m_contactPointWS,m_forwardWS[wheel],maxImpulse);
+					rollingFriction = calcRollingFriction(contactPt);
+				}
+			}
+
+			//switch between active rolling (throttle), braking and non-active rolling friction (no throttle/break)
+			
+
+
+
+			m_forwardImpulse[wheel] = btScalar(0.);
+			m_wheelInfo[wheel].m_skidInfo= btScalar(1.);
+
+			if (groundObject)
+			{
+				m_wheelInfo[wheel].m_skidInfo= btScalar(1.);
+				
+				btScalar maximp = wheelInfo.m_wheelsSuspensionForce * timeStep * wheelInfo.m_frictionSlip;
+				btScalar maximpSide = maximp;
+
+				btScalar maximpSquared = maximp * maximpSide;
+			
+
+				m_forwardImpulse[wheel] = rollingFriction;//wheelInfo.m_engineForce* timeStep;
+
+				btScalar x = (m_forwardImpulse[wheel] ) * fwdFactor;
+				btScalar y = (m_sideImpulse[wheel] ) * sideFactor;
+				
+				btScalar impulseSquared = (x*x + y*y);
+
+				if (impulseSquared > maximpSquared)
+				{
+					sliding = true;
+					
+					btScalar factor = maximp / btSqrt(impulseSquared);
+					
+					m_wheelInfo[wheel].m_skidInfo *= factor;
+				}
+			} 
+
+		}
+	}
+
+	
+
+
+		if (sliding)
+		{
+			for (int wheel = 0;wheel < getNumWheels(); wheel++)
+			{
+				if (m_sideImpulse[wheel] != btScalar(0.))
+				{
+					if (m_wheelInfo[wheel].m_skidInfo< btScalar(1.))
+					{
+						m_forwardImpulse[wheel] *=	m_wheelInfo[wheel].m_skidInfo;
+						m_sideImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo;
+					}
+				}
+			}
+		}
+
+		// apply the impulses
+		{
+			for (int wheel = 0;wheel<getNumWheels() ; wheel++)
+			{
+				btWheelInfo& wheelInfo = m_wheelInfo[wheel];
+
+				btVector3 rel_pos = wheelInfo.m_raycastInfo.m_contactPointWS - 
+						m_chassisBody->getCenterOfMassPosition();
+
+				if (m_forwardImpulse[wheel] != btScalar(0.))
+				{
+					m_chassisBody->applyImpulse(m_forwardWS[wheel]*(m_forwardImpulse[wheel]),rel_pos);
+				}
+				if (m_sideImpulse[wheel] != btScalar(0.))
+				{
+					class btRigidBody* groundObject = (class btRigidBody*) m_wheelInfo[wheel].m_raycastInfo.m_groundObject;
+
+					btVector3 rel_pos2 = wheelInfo.m_raycastInfo.m_contactPointWS - 
+						groundObject->getCenterOfMassPosition();
+
+					
+					btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel];
+
+					rel_pos[m_indexForwardAxis] *= wheelInfo.m_rollInfluence;
+					m_chassisBody->applyImpulse(sideImp,rel_pos);
+
+					//apply friction impulse on the ground
+					groundObject->applyImpulse(-sideImp,rel_pos2);
+				}
+			}
+		}
+
+	
+}
+
+
+
+void	btRaycastVehicle::debugDraw(btIDebugDraw* debugDrawer)
+{
+
+	for (int v=0;v<this->getNumWheels();v++)
+	{
+		btVector3 wheelColor(0,255,255);
+		if (getWheelInfo(v).m_raycastInfo.m_isInContact)
+		{
+			wheelColor.setValue(0,0,255);
+		} else
+		{
+			wheelColor.setValue(255,0,255);
+		}
+
+		btVector3 wheelPosWS = getWheelInfo(v).m_worldTransform.getOrigin();
+
+		btVector3 axle = btVector3(	
+			getWheelInfo(v).m_worldTransform.getBasis()[0][getRightAxis()],
+			getWheelInfo(v).m_worldTransform.getBasis()[1][getRightAxis()],
+			getWheelInfo(v).m_worldTransform.getBasis()[2][getRightAxis()]);
+
+		//debug wheels (cylinders)
+		debugDrawer->drawLine(wheelPosWS,wheelPosWS+axle,wheelColor);
+		debugDrawer->drawLine(wheelPosWS,getWheelInfo(v).m_raycastInfo.m_contactPointWS,wheelColor);
+
+	}
+}
+
+
+void* btDefaultVehicleRaycaster::castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result)
+{
+//	RayResultCallback& resultCallback;
+
+	btCollisionWorld::ClosestRayResultCallback rayCallback(from,to);
+
+	m_dynamicsWorld->rayTest(from, to, rayCallback);
+
+	if (rayCallback.hasHit())
+	{
+		
+		btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
+        if (body && body->hasContactResponse())
+		{
+			result.m_hitPointInWorld = rayCallback.m_hitPointWorld;
+			result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld;
+			result.m_hitNormalInWorld.normalize();
+			result.m_distFraction = rayCallback.m_closestHitFraction;
+			return body;
+		}
+	}
+	return 0;
+}
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btRaycastVehicle.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btRaycastVehicle.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btRaycastVehicle.h	(revision 6952)
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability 
+ * of this software for any purpose.  
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef RAYCASTVEHICLE_H
+#define RAYCASTVEHICLE_H
+
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
+#include "btVehicleRaycaster.h"
+class btDynamicsWorld;
+#include "LinearMath/btAlignedObjectArray.h"
+#include "btWheelInfo.h"
+#include "BulletDynamics/Dynamics/btActionInterface.h"
+
+class btVehicleTuning;
+
+///rayCast vehicle, very special constraint that turn a rigidbody into a vehicle.
+class btRaycastVehicle : public btActionInterface
+{
+
+		btAlignedObjectArray<btVector3>	m_forwardWS;
+		btAlignedObjectArray<btVector3>	m_axle;
+		btAlignedObjectArray<btScalar>	m_forwardImpulse;
+		btAlignedObjectArray<btScalar>	m_sideImpulse;
+
+public:
+	class btVehicleTuning
+		{
+			public:
+
+			btVehicleTuning()
+				:m_suspensionStiffness(btScalar(5.88)),
+				m_suspensionCompression(btScalar(0.83)),
+				m_suspensionDamping(btScalar(0.88)),
+				m_maxSuspensionTravelCm(btScalar(500.)),
+				m_frictionSlip(btScalar(10.5))
+			{
+			}
+			btScalar	m_suspensionStiffness;
+			btScalar	m_suspensionCompression;
+			btScalar	m_suspensionDamping;
+			btScalar	m_maxSuspensionTravelCm;
+			btScalar	m_frictionSlip;
+
+		};
+private:
+
+	btScalar	m_tau;
+	btScalar	m_damping;
+	btVehicleRaycaster*	m_vehicleRaycaster;
+	btScalar		m_pitchControl;
+	btScalar	m_steeringValue; 
+	btScalar m_currentVehicleSpeedKmHour;
+
+	btRigidBody* m_chassisBody;
+
+	int m_indexRightAxis;
+	int m_indexUpAxis;
+	int	m_indexForwardAxis;
+
+	void defaultInit(const btVehicleTuning& tuning);
+
+public:
+
+	//constructor to create a car from an existing rigidbody
+	btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis,	btVehicleRaycaster* raycaster );
+
+	virtual ~btRaycastVehicle() ;
+
+
+	///btActionInterface interface
+	virtual void updateAction( btCollisionWorld* collisionWorld, btScalar step)
+	{
+		updateVehicle(step);
+	}
+	
+
+	///btActionInterface interface
+	void	debugDraw(btIDebugDraw* debugDrawer);
+			
+	const btTransform& getChassisWorldTransform() const;
+	
+	btScalar rayCast(btWheelInfo& wheel);
+
+	virtual void updateVehicle(btScalar step);
+	
+	
+	void resetSuspension();
+
+	btScalar	getSteeringValue(int wheel) const;
+
+	void	setSteeringValue(btScalar steering,int wheel);
+
+
+	void	applyEngineForce(btScalar force, int wheel);
+
+	const btTransform&	getWheelTransformWS( int wheelIndex ) const;
+
+	void	updateWheelTransform( int wheelIndex, bool interpolatedTransform = true );
+	
+	void	setRaycastWheelInfo( int wheelIndex , bool isInContact, const btVector3& hitPoint, const btVector3& hitNormal,btScalar depth);
+
+	btWheelInfo&	addWheel( const btVector3& connectionPointCS0, const btVector3& wheelDirectionCS0,const btVector3& wheelAxleCS,btScalar suspensionRestLength,btScalar wheelRadius,const btVehicleTuning& tuning, bool isFrontWheel);
+
+	inline int		getNumWheels() const {
+		return int (m_wheelInfo.size());
+	}
+	
+	btAlignedObjectArray<btWheelInfo>	m_wheelInfo;
+
+
+	const btWheelInfo&	getWheelInfo(int index) const;
+
+	btWheelInfo&	getWheelInfo(int index);
+
+	void	updateWheelTransformsWS(btWheelInfo& wheel , bool interpolatedTransform = true);
+
+	
+	void setBrake(btScalar brake,int wheelIndex);
+
+	void	setPitchControl(btScalar pitch)
+	{
+		m_pitchControl = pitch;
+	}
+	
+	void	updateSuspension(btScalar deltaTime);
+
+	virtual void	updateFriction(btScalar	timeStep);
+
+
+
+	inline btRigidBody* getRigidBody()
+	{
+		return m_chassisBody;
+	}
+
+	const btRigidBody* getRigidBody() const
+	{
+		return m_chassisBody;
+	}
+
+	inline int	getRightAxis() const
+	{
+		return m_indexRightAxis;
+	}
+	inline int getUpAxis() const
+	{
+		return m_indexUpAxis;
+	}
+
+	inline int getForwardAxis() const
+	{
+		return m_indexForwardAxis;
+	}
+
+	
+	///Worldspace forward vector
+	btVector3 getForwardVector() const
+	{
+		const btTransform& chassisTrans = getChassisWorldTransform(); 
+
+		btVector3 forwardW ( 
+			  chassisTrans.getBasis()[0][m_indexForwardAxis], 
+			  chassisTrans.getBasis()[1][m_indexForwardAxis], 
+			  chassisTrans.getBasis()[2][m_indexForwardAxis]); 
+
+		return forwardW;
+	}
+
+	///Velocity of vehicle (positive if velocity vector has same direction as foward vector)
+	btScalar	getCurrentSpeedKmHour() const
+	{
+		return m_currentVehicleSpeedKmHour;
+	}
+
+	virtual void	setCoordinateSystem(int rightIndex,int upIndex,int forwardIndex)
+	{
+		m_indexRightAxis = rightIndex;
+		m_indexUpAxis = upIndex;
+		m_indexForwardAxis = forwardIndex;
+	}
+
+
+
+};
+
+class btDefaultVehicleRaycaster : public btVehicleRaycaster
+{
+	btDynamicsWorld*	m_dynamicsWorld;
+public:
+	btDefaultVehicleRaycaster(btDynamicsWorld* world)
+		:m_dynamicsWorld(world)
+	{
+	}
+
+	virtual void* castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result);
+
+};
+
+
+#endif //RAYCASTVEHICLE_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btVehicleRaycaster.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btVehicleRaycaster.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btVehicleRaycaster.h	(revision 6952)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability 
+ * of this software for any purpose.  
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef VEHICLE_RAYCASTER_H
+#define VEHICLE_RAYCASTER_H
+
+#include "LinearMath/btVector3.h"
+
+/// btVehicleRaycaster is provides interface for between vehicle simulation and raycasting
+struct btVehicleRaycaster
+{
+virtual ~btVehicleRaycaster()
+{
+}
+	struct btVehicleRaycasterResult
+	{
+		btVehicleRaycasterResult() :m_distFraction(btScalar(-1.)){};
+		btVector3	m_hitPointInWorld;
+		btVector3	m_hitNormalInWorld;
+		btScalar	m_distFraction;
+	};
+
+	virtual void* castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result) = 0;
+
+};
+
+#endif //VEHICLE_RAYCASTER_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btWheelInfo.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btWheelInfo.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btWheelInfo.cpp	(revision 6952)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability 
+ * of this software for any purpose.  
+ * It is provided "as is" without express or implied warranty.
+*/
+#include "btWheelInfo.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h" // for pointvelocity
+
+
+btScalar btWheelInfo::getSuspensionRestLength() const
+{
+
+	return m_suspensionRestLength1;
+
+}
+
+void	btWheelInfo::updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInfo)
+{
+	(void)raycastInfo;
+
+	
+	if (m_raycastInfo.m_isInContact)
+
+	{
+		btScalar	project= m_raycastInfo.m_contactNormalWS.dot( m_raycastInfo.m_wheelDirectionWS );
+		btVector3	 chassis_velocity_at_contactPoint;
+		btVector3 relpos = m_raycastInfo.m_contactPointWS - chassis.getCenterOfMassPosition();
+		chassis_velocity_at_contactPoint = chassis.getVelocityInLocalPoint( relpos );
+		btScalar projVel = m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint );
+		if ( project >= btScalar(-0.1))
+		{
+			m_suspensionRelativeVelocity = btScalar(0.0);
+			m_clippedInvContactDotSuspension = btScalar(1.0) / btScalar(0.1);
+		}
+		else
+		{
+			btScalar inv = btScalar(-1.) / project;
+			m_suspensionRelativeVelocity = projVel * inv;
+			m_clippedInvContactDotSuspension = inv;
+		}
+		
+	}
+
+	else	// Not in contact : position wheel in a nice (rest length) position
+	{
+		m_raycastInfo.m_suspensionLength = this->getSuspensionRestLength();
+		m_suspensionRelativeVelocity = btScalar(0.0);
+		m_raycastInfo.m_contactNormalWS = -m_raycastInfo.m_wheelDirectionWS;
+		m_clippedInvContactDotSuspension = btScalar(1.0);
+	}
+}
Index: /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btWheelInfo.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btWheelInfo.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletDynamics/Vehicle/btWheelInfo.h	(revision 6952)
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability 
+ * of this software for any purpose.  
+ * It is provided "as is" without express or implied warranty.
+*/
+#ifndef WHEEL_INFO_H
+#define WHEEL_INFO_H
+
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btTransform.h"
+
+class btRigidBody;
+
+struct btWheelInfoConstructionInfo
+{
+	btVector3	m_chassisConnectionCS;
+	btVector3	m_wheelDirectionCS;
+	btVector3	m_wheelAxleCS;
+	btScalar	m_suspensionRestLength;
+	btScalar	m_maxSuspensionTravelCm;
+	btScalar	m_wheelRadius;
+	
+	btScalar		m_suspensionStiffness;
+	btScalar		m_wheelsDampingCompression;
+	btScalar		m_wheelsDampingRelaxation;
+	btScalar		m_frictionSlip;
+	bool m_bIsFrontWheel;
+	
+};
+
+/// btWheelInfo contains information per wheel about friction and suspension.
+struct btWheelInfo
+{
+	struct RaycastInfo
+	{
+		//set by raycaster
+		btVector3	m_contactNormalWS;//contactnormal
+		btVector3	m_contactPointWS;//raycast hitpoint
+		btScalar	m_suspensionLength;
+		btVector3	m_hardPointWS;//raycast starting point
+		btVector3	m_wheelDirectionWS; //direction in worldspace
+		btVector3	m_wheelAxleWS; // axle in worldspace
+		bool		m_isInContact;
+		void*		m_groundObject; //could be general void* ptr
+	};
+
+	RaycastInfo	m_raycastInfo;
+
+	btTransform	m_worldTransform;
+	
+	btVector3	m_chassisConnectionPointCS; //const
+	btVector3	m_wheelDirectionCS;//const
+	btVector3	m_wheelAxleCS; // const or modified by steering
+	btScalar	m_suspensionRestLength1;//const
+	btScalar	m_maxSuspensionTravelCm;
+	btScalar getSuspensionRestLength() const;
+	btScalar	m_wheelsRadius;//const
+	btScalar	m_suspensionStiffness;//const
+	btScalar	m_wheelsDampingCompression;//const
+	btScalar	m_wheelsDampingRelaxation;//const
+	btScalar	m_frictionSlip;
+	btScalar	m_steering;
+	btScalar	m_rotation;
+	btScalar	m_deltaRotation;
+	btScalar	m_rollInfluence;
+
+	btScalar	m_engineForce;
+
+	btScalar	m_brake;
+	
+	bool m_bIsFrontWheel;
+	
+	void*		m_clientInfo;//can be used to store pointer to sync transforms...
+
+	btWheelInfo(btWheelInfoConstructionInfo& ci)
+
+	{
+
+		m_suspensionRestLength1 = ci.m_suspensionRestLength;
+		m_maxSuspensionTravelCm = ci.m_maxSuspensionTravelCm;
+
+		m_wheelsRadius = ci.m_wheelRadius;
+		m_suspensionStiffness = ci.m_suspensionStiffness;
+		m_wheelsDampingCompression = ci.m_wheelsDampingCompression;
+		m_wheelsDampingRelaxation = ci.m_wheelsDampingRelaxation;
+		m_chassisConnectionPointCS = ci.m_chassisConnectionCS;
+		m_wheelDirectionCS = ci.m_wheelDirectionCS;
+		m_wheelAxleCS = ci.m_wheelAxleCS;
+		m_frictionSlip = ci.m_frictionSlip;
+		m_steering = btScalar(0.);
+		m_engineForce = btScalar(0.);
+		m_rotation = btScalar(0.);
+		m_deltaRotation = btScalar(0.);
+		m_brake = btScalar(0.);
+		m_rollInfluence = btScalar(0.1);
+		m_bIsFrontWheel = ci.m_bIsFrontWheel;
+
+	}
+
+	void	updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInfo);
+
+	btScalar	m_clippedInvContactDotSuspension;
+	btScalar	m_suspensionRelativeVelocity;
+	//calculated by suspension
+	btScalar	m_wheelsSuspensionForce;
+	btScalar	m_skidInfo;
+
+};
+
+#endif //WHEEL_INFO_H
+
Index: /code/branches/rocket2/src/external/bullet/BulletLicense.txt
===================================================================
--- /code/branches/rocket2/src/external/bullet/BulletLicense.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/BulletLicense.txt	(revision 6952)
@@ -0,0 +1,17 @@
+/*
+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.
+*/
+
+
+Free for commercial use, but please mail bullet@erwincoumans.com to report projects, and join the forum at
+www.continuousphysics.com/Bullet/phpBB2
Index: /code/branches/rocket2/src/external/bullet/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/bullet/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,36 @@
+ #
+ #             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.
+ #
+
+SET_SOURCE_FILES(BULLET_FILES
+  btBulletCollisionCommon.h
+  btBulletDynamicsCommon.h
+  Bullet-C-Api.h
+)
+ADD_SUBDIRECTORY(BulletCollision)
+ADD_SUBDIRECTORY(BulletDynamics)
+ADD_SUBDIRECTORY(LinearMath)
+
+ORXONOX_ADD_LIBRARY(bullet_orxonox
+  ORXONOX_EXTERNAL
+  NO_DLL_INTERFACE
+  VERSION
+    2.74
+  SOURCE_FILES
+    ${BULLET_FILES}
+)
Index: /code/branches/rocket2/src/external/bullet/ChangeLog
===================================================================
--- /code/branches/rocket2/src/external/bullet/ChangeLog	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/ChangeLog	(revision 6952)
@@ -0,0 +1,716 @@
+Bullet Continuous Collision Detection and Physics Library
+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
+
+2008 November 12
+	- Add compound shape export to BulletColladaConverter
+	Thanks to JamesH for the report: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=12&t=2840
+	- Fix compiler build for Visual Studio 6
+	Thanks to JoF for the report: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2841
+
+2008 November 11
+	- Add CProfileManager::dumpAll() to dump performance statistics to console using printf.
+	- Add support for interaction between btSoftBody and btCollisionObject/btGhostObject
+
+2008 November 8
+	- Fix PosixThreadSupport
+	- Add improved btHeightfieldTerrainShape support and new Demos/TerrainDemo
+	Thanks to tomva, http://code.google.com/p/bullet/issues/detail?id=63&can=1
+	- Moved kinematic character controller from Demos/CharacterDemo into src/BulletDynamics/Character/btKinematicCharacterController.cpp
+
+2008 November 6
+	- reduced default memory pool allocation from 40Mb to 3Mb. This should be more suitable for all platforms, including iPhone
+	- improved CUDA broadphase
+	- IBM Cell SDK 3.x support, fix ibmsdk Makefiles
+	- improved CMake support with 'install' and 'framework option
+	
+2008 November 4
+	- add btAxisSweep::resetPool to avoid non-determinism due to shuffled linked list
+	Thanks to Ole for the contribution, 
+
+2008 October 30
+	- disabled btTriangleMesh duplicate search by default, it is extremely slow
+	- added Extras/IFF binary chunk serialization library as preparation for in-game native platform serialization (planned COLLADA DOM -> IFF converter)
+
+2008 October 20
+	- added SCE Physics Effects box-box collision detection for SPU/BulletMultiThreaded version
+	See Bullet/src/BulletMultiThreaded/SpuNarrowPhaseCollisionTask/boxBoxDistance.cpp
+	Thanks to Sony Computer Entertainment Japan, SCEI for the contribution
+
+2008 October 17
+	- Added btGhostObject support, this helps character controller, explosions, triggers and other local spatial queries
+
+2008 October 10
+	- Moved aabb to btBroadphaseProxy, improves rayTest dramatically. Further raytest improvements using the broadphase acceleration structures are planned
+	- Moved BulletMultiThreaded from Extras to /src/BulletMultiThreaded for better integration
+
+
+2008 October 3
+	- Add support for autoconf automake
+	./autogen.sh and ./configure will create both Makefile and Jamfile. CMake and autogenerated Visual Studio projectfiles remain supported too.
+	- Improved ColladaConverter: plane shape export, and callback for shape construction to allow deletion of memory
+	
+2008 Sept 30
+	- Improved Soft Body support, fixed issues related to soft body colliding against concave triangle meshes
+	- Shared more code between regular version and SPU/BulletMultiThreaded, in particular GJK/EPA
+
+2008 Sept 28
+	- Fixed rotation issues in Dynamic Maya Plugin
+
+2008 Sept 11
+	- Enable CCD motion clamping for btDiscreteDynamicsWorld, to avoid tunneling. A more advanced solution will be implemented in btContinuousDynamicsWorld.
+
+2008 Sept 7
+	- Add btScaledBvhTriangleMeshShape, to allow re-use of btBvhTriangleMeshShape of different sizes, without copying of the BVH data.
+
+2008 Sept 5
+	- Enabled Demos/ForkLiftDemo
+	Thanks Roman Ponomarev.
+
+2008 Sept 4
+	- Added btCudaBroadphase in Extras/CUDA: some research into accelerating Bullet using CUDA.
+	Thanks to the particle demo from the NVidia CUDA SDK.
+	
+2008 Sept 3
+	- Several bug fixes and contributions related to inertia tensor, memory leaks etc.
+	Thanks to Ole K.
+
+2008 Sept 1
+	- Updated CDTestFramework, with latest version of OPCODE Array SAP. See Extras/CDTestFramework
+	Thanks to Pierre Terdiman for the update
+
+2008 August 25
+	- Walt Disney Studios contributes their in-house Maya Plugin for simulating Bullet physics, with options for other engines such as PhysBam or PhysX.
+	Thanks to Nicola Candussi and Arthur Shek
+	
+2008 August 14
+	- Improved performance for btDbvtBroadphase, based on dual dynamic AABB trees (one for static, one for dynamic objects, where objects can move from one to the other tree)
+	Thanks to Nathanael Presson again, for all his work.
+	
+2008 July 31
+	- Added Havok .hkx to COLLADA Physics .dae converter patch+information
+	- Fix btSubsimplexConvexCast
+	Thanks to Nacho, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2422)
+	- Fix in rendering, GL_STENCIL
+	- btTriangleIndexVertexArray indices should be unsigned int/unsigned short int,
+	- Made InternalProcessAllTriangles virtual, thanks to
+	Both thank to Fullmetalcoder, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2401
+	- clamp impulse for btPoint2PointConstraint
+	Thanks to Martijn Reuvers, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2418
+	- Free memory of bvh, pass in scaling factor (optional)
+	Thanks to Roy Eltham, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=2375
+
+2008 July 27
+
+btDbvtBroadphase:
+	- Fixed a performance issues reported by 'reltham'
+	- Added btDbvtBroadphase::optimize() for people who want good performances right
+away or don't do dynamics.
+	- fixed compilation issues when DBVT_BP_PROFILE was set.
+btSoftBody:
+	- Fixed singular matrix issues related to polar decomposition (flat meshes).
+DemoApplication:
+	- Shadows (enable/disable through 'g' or DemoApplication::setShadows(bool)).
+	- Texture can be enable/disable through 'u'
+CDFramework:
+	- fixed compilation issues.
+	All thanks to Nathanael Presson
+
+2008 July 10
+	- Added btMultimaterialTriangleMeshShape and MultiMaterialDemo
+	Thanks to Alex Silverman for the contribution
+
+2008 June 30
+	- Added initial support for kinematic character controller
+	Thanks to John McCutchan
+
+2008 April 14
+	- Added ray cast support for Soft Bodies
+	Thanks to Nathanael Presson for the contribution
+	
+2008 April 9
+	- Cleanup of Stan Melax ConvexHull, removed Extras/ConvexHull, moved sources into LinearMath/BulletCollision
+
+2008 April 4
+	- Added btSliderConstraint and demo
+	Thanks Roman Ponomarev
+	
+2008 April 3
+	- Fixed btMinkowskiSumShape, and added hitpoint to btSubsimplexConvexCast
+
+2008 April 2
+	- Added Extras/CdTestFrameWork
+	Thanks Pierre Terdiman
+
+2008 April 1
+	- Added posix thread (pthread) support
+	Thanks Enrico
+
+2008 March 30
+	- Added Soft Body, cloth, rope and deformable volumes, including demos and interaction
+	Thanks Nathanael Presson for this great contribution
+	
+	2008 March 17
+	- Improved BulletColladaConverter
+	Thanks John McCutchan
+
+2008 March 15
+	- btMultiSapBroadphase in a working state. Needs more optimizations to be fully useable.
+	- Allow btOptimizedBvh to be used for arbitrary objects, not just triangles
+	- added quicksort to btAlignedObjectArray
+	- removed btTypedUserInfo, added btHashMap
+
+2008 March 30
+	- Moved quickstep solver and boxbox into Bullet/src folder
+	Thanks Russell L. Smith for permission to redistribute Open Dynamics Engine quickstep and box-box under the ZLib license	
+
+2008 Feb 27
+	- Added initial version for Character Control Demo
+	- Applied fixes to IBM Cell SDK 3.0 build makefiles
+	Thanks Jochen and mojo for reporting/providing patch: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1922
+
+2008 Feb 8
+	- Bugfixes in ConvexCast support against the world.
+	Thanks to Isgmasa for reporting/providing fix: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1823
+
+2008 Feb 6
+	- Added btCapsuleShapeX and btCapsuleShapeZ for capsules around X and Z axis (default capsule is around Y)
+	
+2008 Feb 3
+	- Added btTypedUserInfo, useful for serialization
+
+2008 Jan 31
+	- Add support for 16 and 32-bit indices for SPU / BulletMultiThreaded version.
+
+2008 Jan 29
+	- Added COLLADA Physics export/serialization/snapshot from any Bullet btDynamicsWorld. Saving the physics world into a text .xml file is useful for debugging etc.
+
+2008 Jan 23
+	- Added Stan Melax Convex Hull utility library in Extras/ConvexHull. This is useful to render non-polyhedral convex objects, and to simplify convex polyhedra.
+	
+2008 Jan 14
+	- Add support for batch raycasting on SPU / BulletMultiThreaded
+	
+2007 Dec 16
+	- Added btRigidBodyConstructionInfo, to make it easier to set individual setting (and leave other untouched) during rigid body construction.
+	Thanks Vangelis Kokkevis for pointing this out.
+	- Fixed memoryleak in the ConstraintDemo and Raytracer demo.
+	- Fixed issue with clearing forces/gravity at the end of the stepSimulation, instead of during internalSingleStepSimulation.
+	Thanks chunky for pointing this out: http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1780
+	- Disabled additional damping in rigid body by default, but enable it in most demos. Set btRigidBodyConstructionInfo m_additionalDamping to true to enable this.
+	- Removed obsolete QUICKPROF BEGIN/END_PROFILE, and enabled BT_PROFILE. Profiling is enabled by default (see Bullet/Demos/OpenGL/DemoApplication.cpp how to use this).
+	User can switch off profiling by enabling define BT_NO_PROFILE in Bullet/src/btQuickprof.h.
+
+2007 Dec 14
+	- Added Hello World and BulletMultiThreaded demos
+	- Add portable version of BulletMultiThreaded, through SequentialThreadSupport (non-parallel but sharing the same code-path)
+	- Add Cmake support for AllBulletDemos
+	
+
+2007 Dec 11
+	- Moved the 'btRigidBody::clearForce' to the end of the stepSimulation, instead of in each substep.
+	See discussion http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1601
+	- Added btConvexPlaneCollisionAlgorithm, makes planes perform better, and prevents tunneling
+	Thanks Andy O'Neil for reporting the performance/functionality issue
+	- Fixes for IBM Cell SDK 3.0
+	Thanks to Jochen Roth for the patch.
+
+2007 Dec 10
+	- Fixes in btHeightfieldTerrainShape
+	Thanks to Jay Lee for the patch.
+
+2007	Dec 9
+	- Only update aabb of active objects
+	Thanks Peter Tchernev for reporting (http://bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1764 )
+	- Added workaround to compile libxml under Visual Studio 2008 Beta 2
+	- Make glui compile under MSVC 9.0 beta (vsnprintf is already defined)
+
+2007 Dec 6
+	- Added DynamicControlDemo, showing dynamic control through constraint motors
+		Thanks to Eddy Boxerman
+	- Add support for generic concave shapes for convex cast.
+	- Added convex cast query to collision world.
+	- Added workaround for OpenGL bug in Mac OS X 10.5.0 (Leopard)
+	- Added concave raycast demo
+		All above thanks to John McCutchan (JMC)
+	- Fixed issues that prevent Linux version to compile. 
+	Thanks to Enrico for reporting and patch, see
+	- Fixed misleading name 'numTriangleIndices' into 'numTriangles'
+	Thanks Sean Tasker for reporting:
+
+2007 Nov 28:
+	- Added raycast against trianglemesh. Will be extended to object cast soon.
+	Thanks John McCutchan (JMC)
+	- make getNumPoints const correct, add const getPoints(). 
+	Thanks Dirk Gregorius
+	- Bugfix: allow btCollisionObjects (non-btRigidBody) to interact properly with btRigidBody for cache-friendly btSequentialImpulseConstraintSolver.
+	Thanks Andy O'Neil for pointing this out.
+	- Bugfix: don't fail if spheres have identical center, use arbitrary separating normal (1,0,0)
+	Thanks Sean Tasker for reporting! http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1681
+
+
+2007, November 20
+	- Added hierarchical profiling
+	- Fixed memory leak in btMultiSapBroadphase,
+	- Fixed hash function (typo, should use 2 proxies)
+	Thanks to Stephen (shatcher) for reporting and fixes! http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1696
+
+2007 Nov 11
+	- Fixed parallel solver (BulletMultiThreaded) friction issue
+	- Terminate Win32 Threads when closing the CcdPhysicsDemo (when USE_PARALLEL_SOLVER/USE_PARALLEL_DISPATCHER is defined)
+
+2007 Nov 6
+	- Added support for 16-bit indices for triangle meshes
+	- Added support for multiple mesh parts using btBvhTriangleMeshShape.
+	Thanks to Tim Johansson
+	
+2007 Oct 22
+	- All memory allocations go through btAlignedAlloc/btAlignedFree. User can override this to verify memory leaks
+	- added a few more demos to AllBulletDemos
+	- fix for one of the constructors of btHingeConstraint
+	Thanks Marcus Hennix
+	
+2007 Oct 20
+	- included glui, a GLUT/OpenGL based toolkit for some graphical user elements
+	Removed dynamic_cast from glui, to allow linkage without rtti
+	- added Box2D framework using glui, allowing all demos to run within one executable
+	Thanks Erin Catto for the FrameWork skeleton (http://www.box2d.org)
+
+2007 Ocy 17
+	- Allow user to pass in their own memory (stack and pool) allocators, through collisionConfiguration. See demos how to use this
+
+2007 Oct 14
+	- Included working version of Cell SPU parallel optimized version for Libspe2 SPU task scheduler.
+	This version compiles and runs on Playstation 3 Linux and IBM CellBlade, see BulletSpuOptimized.pdf for build instructions
+	(Official Playstation 3 developers can request a SPURS version through Sony PS3 Devnet.)
+	Thanks to IBM 'Extreme Blue' project for the contribution
+	http://www-913.ibm.com/employment/us/extremeblue/ 
+	Thanks Minh Cuong Tran, Benjamin Hoeferlin, Frederick Roth and Martina Huellmann
+	for various contributions to get this initial Libspe2 parallel version up and running.
+
+2007 Oct 13
+	- made 'btCollisionShape::calculateLocalInertia' const
+	Thanks to cgripeos, see http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1514
+	- applied a large patch to remove warnings
+	Thanks to Enrico, see http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1568
+	- removed SSE includes, added #incude <string.h> for memset in Extras/quickstep, thanks Eternl Knight
+
+2007 Oct 11
+	- added Hashed Overlapping Pair Cache, recommended by Pierre Terdiman. It works like a charm, thanks Pierre and Erin Catto (code from Box2D)
+	- modified some margins inside btBoxShape, btCylinderShape and btSphereShape
+	- added cone debug rendering (for cones with x, y and z up-axis)
+	- added improvements for optional Extra/quickstep, thanks to Remotion
+	- some performance improvements for Bullet constraint solver
+
+2007 Sept 28
+	- upgraded GIMPACT to version 0.3
+	Thanks to Francisco Leon
+
+2007 Sept 27
+	- added contribution from IBM Extreme Blue project for Libspe2 support. This allow to execute BulletMultiThreaded on Cell SPU under PS3 Linux and Cell Blade. See http://www-913.ibm.com/employment/us/extremeblue
+	Thanks to Minh Cuong Tran, Frederick Roth, Martina Heullmann and Benjamin Hoeferlin.
+
+2007 Sept 13
+	- Improved btGenericD6Constraint. It can be used to create ragdolls (similar to the new btConeTwistConstraint). See GenericJointDemo
+	- Added support for Bullet constraints in the optional Extras/quickstep ODE solver. See CcdPhysicsDemo, enable #COMPARE_WITH_QUICKSTEP and add libquickstep to the dependencies.
+	For both patches/improvements thanks Francisco Leon/projectileman
+		
+2007 Sept 10
+	- removed union from btQuadWordStorage, it caused issues under certain version of gcc/Linux
+
+2007 Sept 10
+	- Reverted constraint solver, due to some issues. Need to review the recent memory allocation changes.
+	- Fixed issue with kinematic objects rotating at low speed: quaternion was de-normalized, passing value > 1 into acosf returns #IND00 invalid values
+	- 16 byte memory alignment for BVH serialization
+	- memory cleanup for btPoolAllocator
+
+2007 Sept 9
+	- Added serialization for BVH/btBvhTriangleMeshShape, including endian swapping. See ConcaveDemo for an example.
+	Thanks to Phil Knight for the contribution.
+	- Fixed issues related to stack allocator/compound collision algorithm
+	Thanks Proctoid, http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=18&t=1460
+	- Increase some default memory pool settings, and added a fallback for the constraints solver to use heap memory
+	- Removed accidential testing code in btScalar.h related to operator new.	
+	- Enable btAxis3Sweep and bt32BitAxis3Sweep to be linked in at the same time, using template
+	
+2007 Sept 7
+	- Replaced several dynamic memory allocations by stack allocation and pool allocations
+	- Added branch-free quantized aabb bounding box overlap check, works better on Playstation 3 and XBox 360
+	Thanks to Phil Knight. Also see www.cellperformance.com for related articles
+	- Collision algorithms and settings for the memory/stack allocator can be done using btDefaultCollisionConfiguration
+	This is an API change. See demos how to modify existing implementations with a one-liner.
+	- Register several collision algorithms by default (sphere-sphere, sphere-box, sphere-triangle)
+	- Use other traveral method for BVH by default, this improves triangle mesh collision performance.
+	
+2007 Aug 31
+	- fixed MSVC 6 build
+	Thanks Proctoid, http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1375
+	- fixed double precision build issues
+	Thanks Alex Silverman, http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1434
+
+2007 Aug 24
+	- fixed bug in btMatrix3x3::transposeTimes(const btMatrix3x3& m) const. Luckily it wasn't used in core parts of the library (yet).
+	Thanks to Jay Lee
+	
+2007 Aug 15
+	- fixed bug in Extras/GIMPACT 0.2 related to moving triangle meshes
+	Thanks Thomas, http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1368
+
+2007 Aug 14
+	- added parallel constraint solver. Works on Playstation 3 Cell SPU and multi core (Win Threads on PC and XBox 360).
+	  See Extras/BulletMultiThreaded for SpuSolverTask subfolder and SpuParallelSolver.cpp
+	  Thanks Marten Svanfeldt (Starbreeze Studios)	
+	- fixed some bugs related to parallel collision detection (Extras/BulletMultiThreaded)
+	  Thanks Marten Svanfeldt (Starbreeze Studios)	
+	
+2007 Aug 2
+	- added compound and concave-convex (swapped) case for BulletMultiThreaded collision detection, thanks to Marten Svanfeldt
+	- refactored broadphase and overlapping pair cache. This allows performance improvement by combining multiple broadphases. This helps add/remove of large batches of objects and large worlds. See also Pierre Terdiman forum topic:
+	http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1329
+
+
+2007 July 27
+	- added Ragdoll Demo
+		Thanks to Marten Svanfeldt (Starbreeze Studios)
+
+	- added Vector Math library for SIMD 3D graphics linear algebra (vector, matrix, quaternion)
+		See Bullet/Extras/vectormathlibrary
+		Supports SIMD SSE, PowerPC PPU and Cell SPU (including PS3 Linux and CellBlade), as well as generic portable scalar version
+		Will be used to improve BulletMultiThreaded performance
+		Open Sourced by Sony Computer Entertainment Inc. under the new BSD license
+	- added SIMD math library
+		4-way SIMD for common math functions like atan2f4, cosf4, floorf4, fabsf4, rsqrtf4 etc. Used by Vector Math library under PPU and SPU.
+		Supports PowerPC (PPU) and Cell SPU, including PS3 Linux and CellBlade.
+		See Bullet/Extras/simdmathlibrary
+		Open sourced by Sony Computer Entertainment Inc. under the new BSD license
+
+	
+2007 July 25
+	- added several patches: per-rigidbody sleeping threshold. added Assert to prevent deletion of rigidbody while constraints are still pointing at it
+		Thanks to Marten Svanfeldt (Starbreeze Studios)
+	
+2007 July 13
+	- fixed relative #include paths again. We can't use "../" relative paths: some compilers choke on it (it causes extreme long paths)
+		Within the libraries, we always need to start with "BulletCollision/" or "BulletDynamics/ or "LinearMath/"
+
+2007 July 10
+	- Updated Bullet User Manual
+
+2007 July 5
+	- added btConeTwistConstraint, especially useful for ragdolls. See Demos/RagdollDemo
+		Thanks to Marten Svanfeldt (Starbreeze Studios)
+
+2007 June 29
+	- btHeightfieldTerrainShape: Added heightfield support, with customizations
+	- Upgraded to GIMPACT 0.2, see Extras/GIMPACT and MovingConcaveDemo
+	- Several patches from Marten Svanfeldt (Starbreeze Studios)
+		Improved collision filtering (in broadphase and rigidbody)
+		Improved debug rendering
+		Allow to set collision filter group/mask in addRigidBody
+		
+		
+2007 June 15
+	- Changed btAlignedObjectArray to call copy constructor/replacement new for duplication, rather then assignment operator (operator=).
+
+2007 June 11
+	- Added multi-threading. Originally for Playstation 3 Cell SPU, but the same code can run using Win32 Threads using fake DMA transfers (memcpy)
+		Libspe2 support for Cell Blade / PS3 Linux is upcoming
+		See Extras/BulletMultiThreaded. Usage: replace btCollisionDispatcher by btSpuGatheringCollisionDispatcher
+
+	- Added managed Bullet library, entirely rewritten in C# for Windows and XBox 360 XNA
+		See Extras/BulletX
+		Thanks to KleMiX, aka Vsevolod Klementjev
+
+2007 May 31
+	- sign-bit went wrong in case of 32-bit broadphase, causing quantization problems. 
+		Thanks DevO for reporting.
+
+2007 May 23
+	- Fixed quantization problem for planar triangle meshes in btOptimizedBvh
+		Thanks Phil Knight for reporting and helping to fix this bug.
+		
+2007 May 20
+	- btAxisSweep3: Fixed a bug in btAxisSweep3 (sweep and prune) related to object removal. Only showed up when at least one btStaticPlaneShape was inserted.
+		Thanks tbp for more details on reproducing case.
+	- btAxisSweep3: Fixed issue with full 32bit precision btAxisSweep3 (define BP_USE_FIXEDPOINT_INT_32), it used only 0xffff/65536 for quantization instead of full integer space (0xffffffff)
+	- btRaycastVehicle: Added 'getForwardVector' and getCurrentSpeedKmHour utility functions
+	- Fixed local scaling issues (btConvexTriangleMeshShape, btBvhTriangleMeshShape, removed scaling from btMatrix3x3). 
+		Thanks Volker for reporting!
+	- Added second filename search, so that starting BspDemo and ConvexDecompositionDemo from within Visual Studio (without setting the starting path) still works
+
+2007 April 22
+	- Added braking functionality to btRaycastVehicle
+	- Removed tons of warnings, under MSVC 2005 compilation in -W4
+	
+2007 March 21
+	- Fixed issues: comma at end of enum causes errors for some compilers
+	- Fixed initialization bug in LocalRayResult (	m_localShapeInfo(localShapeInfo) )
+	
+2007 March 20
+	- Added refit tree to quantized stackless tree, and updated ConcaveDemo as example.
+	
+2007 March 17
+	- Added constraint solver optimizations, avoiding cross products during iterations, and gather rigidbody/constraint info in contiguous memory (btSolverBody/btSolverConstraint)
+	- These optimizations don't give large benefit yet, but it has good potential. Turned on by default. Can be switched off using solver->setSolverMode(SOLVER_RANDMIZE_ORDER).
+	- Enabled anti-jitter for rigid bodies. This is experimental, and can be switched off by setting a global (it is experimental so no proper interface) gJitterVelocityDampingFactor = 1.0;
+	- Fixed bug in islandmanifold.heapSort(btPersistentManifoldSortPredicate()); , thanks Noehrgel for reporting this (affected Sun Solaris)
+	
+2007 March 12
+	- Added compile-time toggle between on 16-bit and 32-bit fixed-point SAP broadphase. 
+		This allows the number of bodies to exceed 32767
+	- Enable useQuantizedAabbCompression on btTriangleMesh, see ColladaDemo
+	
+2007 March 8
+	- Fixed bug in constraint/island sorting (caused by replacing STL by dedicated btAlignedObjectArray with heapSort)
+		Thanks Clemens Unterkofler for pointing this out!
+
+2007 March 6
+	- removed STL from the Bullet library: replace std::vector by btAlignedObjectArray. Also removed the std::set for overlapping pair set, and turned it into an overlapping pair array. The SAP only adds objects, never removed. Removal is postponed for during traversal of overlapping pairs (duplicates and non-overlapping pairs are removed during that traversal).
+	- added heap sort and binary search/linear search to btAlignedObjectArray
+	- fixed wrong cast, thanks Hamstray, http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1015
+
+
+2007 Feb 25
+	- Improved performance of convex collision shapes, cache local AABB instead of recomputation. This fixes issue with very slow performance in larger .bsp levels
+	
+2007 Feb 24
+	- Added compressed/quantized AABB tree, 16 bytes per node, while supporting 32-bit (triangle) indices. 
+	  Should be faster and smaller then original version (quantized aabb check is done in integer space)
+		Original aabb tree nodes are still supported. They are 44 bytes, with full floating point precision and additional subPart index.
+	- added meter-unit scaling support in ColladaConverter.cpp
+
+2007 Feb 21
+	- Build system: updated bullet.pc.in library names
+	- Updated EPA comparison integration (missing parameter)
+	
+2007 Jan 04
+	- fixed optimized AABB tree building: in some cases the tree building fails due to unbalanced trees, which generated stack overflow
+	
+2006 Dec 15
+	- added contribution to allow double precision collision detection/dynamics. Define BT_USE_DOUBLE_PRECISION in your project and libraries that include Bullet
+
+2006 Dec 14
+	- merged contact and non-contact constraint solving into one loop, will improve stability of jointed bodies during collisions
+	- added first draft for hingeConstraint motor
+	
+2006 Dec 8, Erwin Coumans
+	- preparation for SIMD: added btAlignedAllocator and btAlignedObjectArray, to replace stl std::vector, same interface, but compatible with 16 byte alignment
+	- cleaned up dependencies in autogenerated msvc projectfiles
+	- aligned btVector3 on 16 bytes boundary, under win32. see if developers will come up with problems
+
+2006 Dec 04, Erwin Coumans
+	Added btNearCallback. This is similar to Open Dynamics Engine (ODE) dNearCallback, but important differences:
+	- contact points are persistent (lifetime more then one frame, for warmstarting/incremental contact point management)
+	- continuous collision detection, time of impact
+	Added btRigidBody::isInWorld(), returns true if btRigidBody is inside a btCollisionWorld/btDynamicsWorld derived class
+	Added angularFactor to btRigidbody, this helps some character control (no angular impulse applied)
+
+
+2006 Nov 28
+	Moved StackAlloc from EPA into LinearMath/btStackAlloc
+	renamed internal class ConcaveShape into btConcaveShape
+	added btHeightfieldTerrainShape (not completed yet)
+		
+2006 Nov 15 Nathanael Presson
+	Added EPA penetration depth algorithm, Expanding Polytope Algorithm
+	Added Pierre Terdiman penetration depth comparison/test DEMO
+	Fixed Bullet's Minkowski sampling penetration depth solver
+	Contributed by Nathanael Presson
+	
+2006 Nov 11 Francisco León Nájera
+	Added GIMPACT trimesh collision detection: concave versus concave,
+	Contributed by Francisco León Nájera
+
+2006 Nov 2
+	Minor refactoring: btCollisionObject changes from struct into class, added accessor methods
+	Force use of btMotionState to synchronize graphics transform, disabled old btRigidBody constructor that accepts btTransform
+	Renamed treshold into threshold throughout the code
+	
+2006 Oct 30
+	Enable decoupling of physics and graphics framerate using interpolation and internal fixed timestep, based on btMotionState
+	Enabled raycast vehicle demo (still needs tuning)
+	Refresh contact points, even when they are already persistent.
+	Fixed debugDraw colors (thanks pc0de for reporting)
+	Use Dispatcher in ConcaveConvexCollisionAlgorithm (so it uses the registered collision algorithm, not hardcoded convexconcave)
+	Improved performance of constraint solver by precalculating the cross product/impulse arm
+	Added collision comparison code: ODE box-box, also sphere-triangle
+	Added safety check into GJK, and an assert for AABB's that are very large
+	Fixed kinematic support (deriving velocities for animated objects)
+	Updated comparison/optional quickstep solver in Extras
+	UserCollisionAlgorithm demonstrates btTriangleMesh usage (easier trimesh compared to index array version)
+	Removed scaling from btTransform (we only want to deal with rigid transforms)
+	
+2006 Oct 4
+	Fixed minor leak in btOptimizeBVH
+	Cleanup of btRigidBody construction
+	added getW() in btQuaternion
+	assert when setLinearVelocity is called on btRigidBody
+	renamed projectfile library from collada-dom to colladadom (to make VC6 happy)
+	
+2006 Sept 27
+	Big Refactoring: renamed and moved files, create a replacement for CcdPhysicsEnvironment/CcdPhysicsController.
+	All Bullet classes in LinearMath, BulletCollision and BulletDynamics start with bt, and methods start with lowercase.
+	Moved classes into src folder, which is the only include folder needed.
+	Added 2 headerfiles in src: btBulletCollisionCommon.h and btBulletDynamicsCommon.h
+
+2006 Sept 23
+	Fixed 2 bugs, causing crashes when removing objects. Should do better unit-testing. UnionFind and 3D SAP were involved.
+	
+2006 Sept 19
+	Allow programmable friction and contact solver model. User can register their own functions for several interaction types.
+	Improved performance, and removed hardcoded maximum overlaps (switched from C-array to stl::set)
+	
+2006 Sept 16
+	Added Bullet 2.0  User Manual
+	Allow registration of custom user collision algorithms
+
+2006 Sept 10
+	Started cleaning up demos
+	
+2006 Sept 4
+	Fixed concave collision bug (caused instability/missing collisions in meshes/compounds)
+	Fixed memoryleak in OptimizedBvh, added RayTestSingle to CollisionWorld
+	Prepared for VehicleDemo
+	Increased Performance (island generation for sleeping objects took too much time)
+	Better COLLADA 1.4.1 physics conformance in ColladaDemo
+
+2006 August 11
+	Added Quake BspDemo
+	Improved CCD for compound and non-convex objects
+
+2006 August 10
+	Added per-triangle material (friction/restitution) support for non-convex meshes. See ConcaveDemo for usage.
+
+2006 August 9
+	Added CMake support (see http://cmake.org)
+	This can autogenerate makefiles, projectfiles cross platform (including MacOS X Xcode )
+	Just run cmake . in the root folder and it will autogenerate build files
+	
+2006 July 26 Erwin Coumans
+	Upgraded to COLLADA-DOM 1.4.1, latest SVN version
+	ColladaDemo can export snapshots to .dae
+	
+2006 July 24 Erwin Coumans
+	Added Compound CollisionShape support
+	(this is still low performance -> requires stackless tree-versus-tree traversal for better performance)
+
+2006 July 15 Erwin Coumans
+	Added initial support for Parallel execution (collision detection, constraint solving)
+	See ParallelPhysicsEnvironment in Extras\PhysicsInterface\CcdPhysics
+	
+2006 July 10 Erwin Coumans
+	Added MacOS X support (some build issues mainly)
+		
+2006 July 5 Erwin Coumans
+	Improved COLLADA 1.4 physics import, both COLLADA-DOM and FCollada
+
+2006 June 29 Erwin Coumans
+	Refactoring of the broadphase
+	Moved some optional files to Extras: Algebraic ccd and EPA, quickstep
+	Moved the limits on bodies/overlap to 32k and 65k
+	
+2006 June 25 Erwin Coumans
+	Added basic Collision Filtering, during broadphase
+	Allow adding meshes to the TriangleIndexVertexArray,
+	(input for TriangleMeshShape) 
+	Preparation for CompoundShape
+
+2006 June 19 Erwin Coumans
+	Added support for COLLADA Physics Import.
+	Both jam and Visual Studio can compile ColladaDemo
+
+2006 June 18 Dirk Gregorius <dirk@dirkgregorius.de>
+	Started implementing Generic6DOF joint and setup basic interface
+
+
+2006 June 17 Frank Richter <resqu@gmx.ch>
+	Bumped version in configure.ac to 1.5.6 (assuming that "1.5f" is
+	  the next version released).
+	Updated files in mk/autoconf and mk/jam with copies from CS; fixes a 
+	  GLU detection issue on MinGW.
+	Set msvc/bullet_ico.ico as the default application icon.
+	Disabled exceptions for gcc builds.
+	Applied a patch from Michael D. Adams to fix a warning with gcc.
+2006 jUNE 16 Erwin Coumans
+	Constraints now merge simulation islands.
+
+2006 May 24
+	Improved GJK accuracy, fixed GjkConvexCast issue, thanks to ~MyXa~ for reporting
+	
+2006 May 19
+	Added restitution support
+	Moved out Friction and Dynamics info from ManifoldPoint (removed logical dependency)
+	Added a void* m_userPersistentData in ManifoldPoint.
+	Added a ContactDestroyedCallback, to allow user to handle destruction of m_userPersistentData
+
+2006 May 13
+	Fixed some bugs in friction / jacobian calculations. Reported by Dirk Gregorius. Thanks!
+
+2006 May 9
+	Fixed raycasting filtering
+	Moved repository to SVN at https://svn.sourceforge.net/svnroot/bullet
+		
+2006 April 27
+	Moved raycasting to CollisionWorld, to make it more generic
+	Added basic CCD option in the CcdCollisionDemo
+	Fixed 'noResponse' mode, for triggering rigidbodies (useful for Artificial Intelligence queries)
+	Improved Bullet/ODE sample (in Extras)
+		
+2006 April 10
+	Separating Axis Test (SAT) convex hull collision detector, contribution by Simon Hobbs
+	Added SIMD SSE Math classes (for above SAT)
+	Added Mouse picking in CcdPhysicsDemo
+	Improved penetration depth estimation in MinkowskiPenetrationDepthSolver, both accuracy and performance
+	Added Hinge constraint
+	Added quickprof profiling (see http://sourceforge.net/projects/quickprof )
+		
+2006 March 21 Frank Richter <resqu@gmx.ch>
+	Removed VC manifest files.
+	Removed superfluous "grpplugins" projects.
+
+2006 March 20 Erwin Coumans
+	Clamped the acculumated impulse rather then intermediate impulse (within the iteration)
+	Use the persistent contacts for reusing the impulse
+	Separated friction and normal solving for better stability
+	Decreased the default number of iterations of the constraint solver from 10 to 4
+
+2006 March 19 Frank Richter <resqu@gmx.ch>
+	Removed a couple of CSisms from the VC projects.
+	Fixed VC include & lib paths to go to the Addtional* options
+	  instead the command line arguments.
+	Added pkgconfig support.
+
+2006 March 14 Frank Richter <resqu@gmx.ch>
+	Added support for shipped GLUT on MinGW.
+	Fixed GLUT support on MinGW.
+
+2006 March 13 Frank Richter <resqu@gmx.ch>
+	Bolted on Jam-based build system.
+	Generated VC project files.
+	Fixed GCC warnings.
+	Fixed Linux build issues.
+
+2006 March 13
+Added 3D Sweep and Prune Broadphase Collision Detection, Contribution from Simon Hobbs.
+
+2006 March 2
+	Minor change in license to ZLib/LibPNG
+	This makes it legally a bit easier to deploy on Playstation 3
+	Prepared for more generic constraints, added ConstraintsDemo
+
+2006 Feb 23
+	Rearranged files and dependencies to allow for easier standalone Collision Detection without Bullet Dynamics.
+	See Demos/CollisionInterfaceDemo and Extras/ode/ode/test/test_BulletGjk.cpp for examples how to use.
+
+2005 August 6
+	Bullet 0.2 release with demos, sources, doxygen, draft manual
+
+2005 June 1
+	First public release of Bullet
+	
+
+... todo: add history
+
+2003 Initial version (continuous collision detection)
Index: /code/branches/rocket2/src/external/bullet/LICENSE
===================================================================
--- /code/branches/rocket2/src/external/bullet/LICENSE	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LICENSE	(revision 6952)
@@ -0,0 +1,19 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+All files in the Bullet/src folder are under this Zlib license.
+Optional Extras/GIMPACT and Extras/GIMPACTBullet is also under ZLib license. Other optional external libraries in  Extras/Demos have own license,see respective files.
+
+This means Bullet can freely be used in any software, including commercial and console software. A Playstation 3 optimized version is available through Sony.
Index: /code/branches/rocket2/src/external/bullet/LinearMath/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,33 @@
+ADD_SOURCE_FILES(BULLET_FILES
+
+COMPILATION_BEGIN BulletLinearMathCompilation.cpp
+		btConvexHull.cpp
+		btQuickprof.cpp
+		btGeometryUtil.cpp
+		btAlignedAllocator.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
+)
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btAabbUtil2.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btAabbUtil2.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btAabbUtil2.h	(revision 6952)
@@ -0,0 +1,236 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / 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 AABB_UTIL2
+#define AABB_UTIL2
+
+#include "btTransform.h"
+#include "btVector3.h"
+#include "btMinMax.h"
+
+
+
+SIMD_FORCE_INLINE void AabbExpand (btVector3& aabbMin,
+								   btVector3& aabbMax,
+								   const btVector3& expansionMin,
+								   const btVector3& expansionMax)
+{
+	aabbMin = aabbMin + expansionMin;
+	aabbMax = aabbMax + expansionMax;
+}
+
+/// conservative test for overlap between two aabbs
+SIMD_FORCE_INLINE bool TestPointAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1,
+								const btVector3 &point)
+{
+	bool overlap = true;
+	overlap = (aabbMin1.getX() > point.getX() || aabbMax1.getX() < point.getX()) ? false : overlap;
+	overlap = (aabbMin1.getZ() > point.getZ() || aabbMax1.getZ() < point.getZ()) ? false : overlap;
+	overlap = (aabbMin1.getY() > point.getY() || aabbMax1.getY() < point.getY()) ? false : overlap;
+	return overlap;
+}
+
+
+/// conservative test for overlap between two aabbs
+SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1,
+								const btVector3 &aabbMin2, const btVector3 &aabbMax2)
+{
+	bool overlap = true;
+	overlap = (aabbMin1.getX() > aabbMax2.getX() || aabbMax1.getX() < aabbMin2.getX()) ? false : overlap;
+	overlap = (aabbMin1.getZ() > aabbMax2.getZ() || aabbMax1.getZ() < aabbMin2.getZ()) ? false : overlap;
+	overlap = (aabbMin1.getY() > aabbMax2.getY() || aabbMax1.getY() < aabbMin2.getY()) ? false : overlap;
+	return overlap;
+}
+
+/// conservative test for overlap between triangle and aabb
+SIMD_FORCE_INLINE bool TestTriangleAgainstAabb2(const btVector3 *vertices,
+									const btVector3 &aabbMin, const btVector3 &aabbMax)
+{
+	const btVector3 &p1 = vertices[0];
+	const btVector3 &p2 = vertices[1];
+	const btVector3 &p3 = vertices[2];
+
+	if (btMin(btMin(p1[0], p2[0]), p3[0]) > aabbMax[0]) return false;
+	if (btMax(btMax(p1[0], p2[0]), p3[0]) < aabbMin[0]) return false;
+
+	if (btMin(btMin(p1[2], p2[2]), p3[2]) > aabbMax[2]) return false;
+	if (btMax(btMax(p1[2], p2[2]), p3[2]) < aabbMin[2]) return false;
+  
+	if (btMin(btMin(p1[1], p2[1]), p3[1]) > aabbMax[1]) return false;
+	if (btMax(btMax(p1[1], p2[1]), p3[1]) < aabbMin[1]) return false;
+	return true;
+}
+
+
+SIMD_FORCE_INLINE int	btOutcode(const btVector3& p,const btVector3& halfExtent) 
+{
+	return (p.getX()  < -halfExtent.getX() ? 0x01 : 0x0) |    
+		   (p.getX() >  halfExtent.getX() ? 0x08 : 0x0) |
+		   (p.getY() < -halfExtent.getY() ? 0x02 : 0x0) |    
+		   (p.getY() >  halfExtent.getY() ? 0x10 : 0x0) |
+		   (p.getZ() < -halfExtent.getZ() ? 0x4 : 0x0) |    
+		   (p.getZ() >  halfExtent.getZ() ? 0x20 : 0x0);
+}
+
+
+
+SIMD_FORCE_INLINE bool btRayAabb2(const btVector3& rayFrom,
+								  const btVector3& rayInvDirection,
+								  const unsigned int raySign[3],
+								  const btVector3 bounds[2],
+								  btScalar& tmin,
+								  btScalar lambda_min,
+								  btScalar lambda_max)
+{
+	btScalar tmax, tymin, tymax, tzmin, tzmax;
+	tmin = (bounds[raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX();
+	tmax = (bounds[1-raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX();
+	tymin = (bounds[raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY();
+	tymax = (bounds[1-raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY();
+
+	if ( (tmin > tymax) || (tymin > tmax) )
+		return false;
+
+	if (tymin > tmin)
+		tmin = tymin;
+
+	if (tymax < tmax)
+		tmax = tymax;
+
+	tzmin = (bounds[raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ();
+	tzmax = (bounds[1-raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ();
+
+	if ( (tmin > tzmax) || (tzmin > tmax) )
+		return false;
+	if (tzmin > tmin)
+		tmin = tzmin;
+	if (tzmax < tmax)
+		tmax = tzmax;
+	return ( (tmin < lambda_max) && (tmax > lambda_min) );
+}
+
+SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom, 
+								 const btVector3& rayTo, 
+								 const btVector3& aabbMin, 
+								 const btVector3& aabbMax,
+					  btScalar& param, btVector3& normal) 
+{
+	btVector3 aabbHalfExtent = (aabbMax-aabbMin)* btScalar(0.5);
+	btVector3 aabbCenter = (aabbMax+aabbMin)* btScalar(0.5);
+	btVector3	source = rayFrom - aabbCenter;
+	btVector3	target = rayTo - aabbCenter;
+	int	sourceOutcode = btOutcode(source,aabbHalfExtent);
+	int targetOutcode = btOutcode(target,aabbHalfExtent);
+	if ((sourceOutcode & targetOutcode) == 0x0)
+	{
+		btScalar lambda_enter = btScalar(0.0);
+		btScalar lambda_exit  = param;
+		btVector3 r = target - source;
+		int i;
+		btScalar	normSign = 1;
+		btVector3	hitNormal(0,0,0);
+		int bit=1;
+
+		for (int j=0;j<2;j++)
+		{
+			for (i = 0; i != 3; ++i)
+			{
+				if (sourceOutcode & bit)
+				{
+					btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i];
+					if (lambda_enter <= lambda)
+					{
+						lambda_enter = lambda;
+						hitNormal.setValue(0,0,0);
+						hitNormal[i] = normSign;
+					}
+				}
+				else if (targetOutcode & bit) 
+				{
+					btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i];
+					btSetMin(lambda_exit, lambda);
+				}
+				bit<<=1;
+			}
+			normSign = btScalar(-1.);
+		}
+		if (lambda_enter <= lambda_exit)
+		{
+			param = lambda_enter;
+			normal = hitNormal;
+			return true;
+		}
+	}
+	return false;
+}
+
+
+
+SIMD_FORCE_INLINE	void btTransformAabb(const btVector3& halfExtents, btScalar margin,const btTransform& t,btVector3& aabbMinOut,btVector3& aabbMaxOut)
+{
+	btVector3 halfExtentsWithMargin = halfExtents+btVector3(margin,margin,margin);
+	btMatrix3x3 abs_b = t.getBasis().absolute();  
+	btVector3 center = t.getOrigin();
+	btVector3 extent = btVector3(abs_b[0].dot(halfExtentsWithMargin),
+		   abs_b[1].dot(halfExtentsWithMargin),
+		  abs_b[2].dot(halfExtentsWithMargin));
+	aabbMinOut = center - extent;
+	aabbMaxOut = center + extent;
+}
+
+
+SIMD_FORCE_INLINE	void btTransformAabb(const btVector3& localAabbMin,const btVector3& localAabbMax, btScalar margin,const btTransform& trans,btVector3& aabbMinOut,btVector3& aabbMaxOut)
+{
+		btAssert(localAabbMin.getX() <= localAabbMax.getX());
+		btAssert(localAabbMin.getY() <= localAabbMax.getY());
+		btAssert(localAabbMin.getZ() <= localAabbMax.getZ());
+		btVector3 localHalfExtents = btScalar(0.5)*(localAabbMax-localAabbMin);
+		localHalfExtents+=btVector3(margin,margin,margin);
+
+		btVector3 localCenter = btScalar(0.5)*(localAabbMax+localAabbMin);
+		btMatrix3x3 abs_b = trans.getBasis().absolute();  
+		btVector3 center = trans(localCenter);
+		btVector3 extent = btVector3(abs_b[0].dot(localHalfExtents),
+			   abs_b[1].dot(localHalfExtents),
+			  abs_b[2].dot(localHalfExtents));
+		aabbMinOut = center-extent;
+		aabbMaxOut = center+extent;
+}
+
+#define USE_BANCHLESS 1
+#ifdef USE_BANCHLESS
+	//This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360)
+	SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2)
+	{		
+		return static_cast<unsigned int>(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0])
+			& (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2])
+			& (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])),
+			1, 0));
+	}
+#else
+	SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2)
+	{
+		bool overlap = true;
+		overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
+		overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
+		overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
+		return overlap;
+	}
+#endif //USE_BANCHLESS
+
+#endif
+
+
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btAlignedAllocator.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btAlignedAllocator.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btAlignedAllocator.cpp	(revision 6952)
@@ -0,0 +1,205 @@
+/*
+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 "btAlignedAllocator.h"
+
+int gNumAlignedAllocs = 0;
+int gNumAlignedFree = 0;
+int gTotalBytesAlignedAllocs = 0;//detect memory leaks
+
+static void *btAllocDefault(size_t size)
+{
+	return malloc(size);
+}
+
+static void btFreeDefault(void *ptr)
+{
+	free(ptr);
+}
+
+static btAllocFunc *sAllocFunc = btAllocDefault;
+static btFreeFunc *sFreeFunc = btFreeDefault;
+
+
+
+#if defined (BT_HAS_ALIGNED_ALLOCATOR)
+#include <malloc.h>
+static void *btAlignedAllocDefault(size_t size, int alignment)
+{
+	return _aligned_malloc(size, (size_t)alignment);
+}
+
+static void btAlignedFreeDefault(void *ptr)
+{
+	_aligned_free(ptr);
+}
+#elif defined(__CELLOS_LV2__)
+#include <stdlib.h>
+
+static inline void *btAlignedAllocDefault(size_t size, int alignment)
+{
+	return memalign(alignment, size);
+}
+
+static inline void btAlignedFreeDefault(void *ptr)
+{
+	free(ptr);
+}
+#else
+static inline void *btAlignedAllocDefault(size_t size, int alignment)
+{
+  void *ret;
+  char *real;
+  unsigned long offset;
+
+  real = (char *)sAllocFunc(size + sizeof(void *) + (alignment-1));
+  if (real) {
+    offset = (alignment - (unsigned long)(real + sizeof(void *))) & (alignment-1);
+    ret = (void *)((real + sizeof(void *)) + offset);
+    *((void **)(ret)-1) = (void *)(real);
+  } else {
+    ret = (void *)(real);
+  }
+  return (ret);
+}
+
+static inline void btAlignedFreeDefault(void *ptr)
+{
+  void* real;
+
+  if (ptr) {
+    real = *((void **)(ptr)-1);
+    sFreeFunc(real);
+  }
+}
+#endif
+
+
+static btAlignedAllocFunc *sAlignedAllocFunc = btAlignedAllocDefault;
+static btAlignedFreeFunc *sAlignedFreeFunc = btAlignedFreeDefault;
+
+void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc)
+{
+  sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault;
+  sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault;
+}
+
+void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc)
+{
+  sAllocFunc = allocFunc ? allocFunc : btAllocDefault;
+  sFreeFunc = freeFunc ? freeFunc : btFreeDefault;
+}
+
+#ifdef BT_DEBUG_MEMORY_ALLOCATIONS
+//this generic allocator provides the total allocated number of bytes
+#include <stdio.h>
+
+void*   btAlignedAllocInternal  (size_t size, int alignment,int line,char* filename)
+{
+ void *ret;
+ char *real;
+ unsigned long offset;
+
+ gTotalBytesAlignedAllocs += size;
+ gNumAlignedAllocs++;
+
+ 
+ real = (char *)sAllocFunc(size + 2*sizeof(void *) + (alignment-1));
+ if (real) {
+   offset = (alignment - (unsigned long)(real + 2*sizeof(void *))) &
+(alignment-1);
+   ret = (void *)((real + 2*sizeof(void *)) + offset);
+   *((void **)(ret)-1) = (void *)(real);
+       *((int*)(ret)-2) = size;
+
+ } else {
+   ret = (void *)(real);//??
+ }
+
+ printf("allocation#%d at address %x, from %s,line %d, size %d\n",gNumAlignedAllocs,real, filename,line,size);
+
+ int* ptr = (int*)ret;
+ *ptr = 12;
+ return (ret);
+}
+
+void    btAlignedFreeInternal   (void* ptr,int line,char* filename)
+{
+
+ void* real;
+ gNumAlignedFree++;
+
+ if (ptr) {
+   real = *((void **)(ptr)-1);
+       int size = *((int*)(ptr)-2);
+       gTotalBytesAlignedAllocs -= size;
+
+	   printf("free #%d at address %x, from %s,line %d, size %d\n",gNumAlignedFree,real, filename,line,size);
+
+   sFreeFunc(real);
+ } else
+ {
+	 printf("NULL ptr\n");
+ }
+}
+
+#else //BT_DEBUG_MEMORY_ALLOCATIONS
+
+void*	btAlignedAllocInternal	(size_t size, int alignment)
+{
+	gNumAlignedAllocs++;
+  void* ptr;
+#if defined (BT_HAS_ALIGNED_ALLOCATOR) || defined(__CELLOS_LV2__)
+	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;
+}
+
+void	btAlignedFreeInternal	(void* ptr)
+{
+	if (!ptr)
+	{
+		return;
+	}
+
+	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__)
+}
+
+#endif //BT_DEBUG_MEMORY_ALLOCATIONS
+
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btAlignedAllocator.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btAlignedAllocator.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btAlignedAllocator.h	(revision 6952)
@@ -0,0 +1,107 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_ALIGNED_ALLOCATOR
+#define BT_ALIGNED_ALLOCATOR
+
+///we probably replace this with our own aligned memory allocator
+///so we replace _aligned_malloc and _aligned_free with our own
+///that is better portable and more predictable
+
+#include "btScalar.h"
+//#define BT_DEBUG_MEMORY_ALLOCATIONS 1
+#ifdef BT_DEBUG_MEMORY_ALLOCATIONS
+
+#define btAlignedAlloc(a,b) \
+		btAlignedAllocInternal(a,b,__LINE__,__FILE__)
+
+#define btAlignedFree(ptr) \
+		btAlignedFreeInternal(ptr,__LINE__,__FILE__)
+
+void*	btAlignedAllocInternal	(size_t size, int alignment,int line,char* filename);
+
+void	btAlignedFreeInternal	(void* ptr,int line,char* filename);
+
+#else
+	void*	btAlignedAllocInternal	(size_t size, int alignment);
+	void	btAlignedFreeInternal	(void* ptr);
+
+	#define btAlignedAlloc(size,alignment) btAlignedAllocInternal(size,alignment)
+	#define btAlignedFree(ptr) btAlignedFreeInternal(ptr)
+
+#endif
+typedef int	size_type;
+
+typedef void *(btAlignedAllocFunc)(size_t size, int alignment);
+typedef void (btAlignedFreeFunc)(void *memblock);
+typedef void *(btAllocFunc)(size_t size);
+typedef void (btFreeFunc)(void *memblock);
+
+///The developer can let all Bullet memory allocations go through a custom memory allocator, using btAlignedAllocSetCustom
+void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc);
+///If the developer has already an custom aligned allocator, then btAlignedAllocSetCustomAligned can be used. The default aligned allocator pre-allocates extra memory using the non-aligned allocator, and instruments it.
+void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc);
+
+
+///The btAlignedAllocator is a portable class for aligned memory allocations.
+///Default implementations for unaligned and aligned allocations can be overridden by a custom allocator using btAlignedAllocSetCustom and btAlignedAllocSetCustomAligned.
+template < typename T , unsigned Alignment >
+class btAlignedAllocator {
+	
+	typedef btAlignedAllocator< T , Alignment > self_type;
+	
+public:
+
+	//just going down a list:
+	btAlignedAllocator() {}
+	/*
+	btAlignedAllocator( const self_type & ) {}
+	*/
+
+	template < typename Other >
+	btAlignedAllocator( const btAlignedAllocator< Other , Alignment > & ) {}
+
+	typedef const T*         const_pointer;
+	typedef const T&         const_reference;
+	typedef T*               pointer;
+	typedef T&               reference;
+	typedef T                value_type;
+
+	pointer       address   ( reference        ref ) const                           { return &ref; }
+	const_pointer address   ( const_reference  ref ) const                           { return &ref; }
+	pointer       allocate  ( size_type        n   , const_pointer *      hint = 0 ) {
+		(void)hint;
+		return reinterpret_cast< pointer >(btAlignedAlloc( sizeof(value_type) * n , Alignment ));
+	}
+	void          construct ( pointer          ptr , const value_type &   value    ) { new (ptr) value_type( value ); }
+	void          deallocate( pointer          ptr ) {
+		btAlignedFree( reinterpret_cast< void * >( ptr ) );
+	}
+	void          destroy   ( pointer          ptr )                                 { ptr->~value_type(); }
+	
+
+	template < typename O > struct rebind {
+		typedef btAlignedAllocator< O , Alignment > other;
+	};
+	template < typename O >
+	self_type & operator=( const btAlignedAllocator< O , Alignment > & ) { return *this; }
+
+	friend bool operator==( const self_type & , const self_type & ) { return true; }
+};
+
+
+
+#endif //BT_ALIGNED_ALLOCATOR
+
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btAlignedObjectArray.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btAlignedObjectArray.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btAlignedObjectArray.h	(revision 6952)
@@ -0,0 +1,442 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#ifndef BT_OBJECT_ARRAY__
+#define BT_OBJECT_ARRAY__
+
+#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
+#include "btAlignedAllocator.h"
+
+///If the platform doesn't support placement new, you can disable BT_USE_PLACEMENT_NEW
+///then the btAlignedObjectArray doesn't support objects with virtual methods, and non-trivial constructors/destructors
+///You can enable BT_USE_MEMCPY, then swapping elements in the array will use memcpy instead of operator=
+///see discussion here: http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1231 and
+///http://www.continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=1240
+
+#define BT_USE_PLACEMENT_NEW 1
+//#define BT_USE_MEMCPY 1 //disable, because it is cumbersome to find out for each platform where memcpy is defined. It can be in <memory.h> or <string.h> or otherwise...
+
+#ifdef BT_USE_MEMCPY
+#include <memory.h>
+#include <string.h>
+#endif //BT_USE_MEMCPY
+
+#ifdef BT_USE_PLACEMENT_NEW
+#include <new> //for placement new
+#endif //BT_USE_PLACEMENT_NEW
+
+
+///The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods
+///It is developed to replace stl::vector to avoid portability issues, including STL alignment issues to add SIMD/SSE data
+template <typename T> 
+//template <class T> 
+class btAlignedObjectArray
+{
+	btAlignedAllocator<T , 16>	m_allocator;
+
+	int					m_size;
+	int					m_capacity;
+	T*					m_data;
+	//PCK: added this line
+	bool				m_ownsMemory;
+
+	protected:
+		SIMD_FORCE_INLINE	int	allocSize(int size)
+		{
+			return (size ? size*2 : 1);
+		}
+		SIMD_FORCE_INLINE	void	copy(int start,int end, T* dest) const
+		{
+			int i;
+			for (i=start;i<end;++i)
+#ifdef BT_USE_PLACEMENT_NEW
+				new (&dest[i]) T(m_data[i]);
+#else
+				dest[i] = m_data[i];
+#endif //BT_USE_PLACEMENT_NEW
+		}
+
+		SIMD_FORCE_INLINE	void	init()
+		{
+			//PCK: added this line
+			m_ownsMemory = true;
+			m_data = 0;
+			m_size = 0;
+			m_capacity = 0;
+		}
+		SIMD_FORCE_INLINE	void	destroy(int first,int last)
+		{
+			int i;
+			for (i=first; i<last;i++)
+			{
+				m_data[i].~T();
+			}
+		}
+
+		SIMD_FORCE_INLINE	void* allocate(int size)
+		{
+			if (size)
+				return m_allocator.allocate(size);
+			return 0;
+		}
+
+		SIMD_FORCE_INLINE	void	deallocate()
+		{
+			if(m_data)	{
+				//PCK: enclosed the deallocation in this block
+				if (m_ownsMemory)
+				{
+					m_allocator.deallocate(m_data);
+				}
+				m_data = 0;
+			}
+		}
+
+	
+
+
+	public:
+		
+		btAlignedObjectArray()
+		{
+			init();
+		}
+
+		~btAlignedObjectArray()
+		{
+			clear();
+		}
+
+		///Generally it is best to avoid using the copy constructor of an btAlignedObjectArray, and use a (const) reference to the array instead.
+		btAlignedObjectArray(const btAlignedObjectArray& otherArray)
+		{
+			init();
+
+			int otherSize = otherArray.size();
+			resize (otherSize);
+			otherArray.copy(0, otherSize, m_data);
+		}
+
+		
+		
+		/// return the number of elements in the array
+		SIMD_FORCE_INLINE	int size() const
+		{	
+			return m_size;
+		}
+		
+		SIMD_FORCE_INLINE const T& operator[](int n) const
+		{
+			return m_data[n];
+		}
+
+		SIMD_FORCE_INLINE T& operator[](int n)
+		{
+			return m_data[n];
+		}
+		
+
+		///clear the array, deallocated memory. Generally it is better to use array.resize(0), to reduce performance overhead of run-time memory (de)allocations.
+		SIMD_FORCE_INLINE	void	clear()
+		{
+			destroy(0,size());
+			
+			deallocate();
+			
+			init();
+		}
+
+		SIMD_FORCE_INLINE	void	pop_back()
+		{
+			m_size--;
+			m_data[m_size].~T();
+		}
+
+		///resize changes the number of elements in the array. If the new size is larger, the new elements will be constructed using the optional second argument.
+		///when the new number of elements is smaller, the destructor will be called, but memory will not be freed, to reduce performance overhead of run-time memory (de)allocations.
+		SIMD_FORCE_INLINE	void	resize(int newsize, const T& fillData=T())
+		{
+			int curSize = size();
+
+			if (newsize < size())
+			{
+				for(int i = curSize; i < newsize; i++)
+				{
+					m_data[i].~T();
+				}
+			} else
+			{
+				if (newsize > size())
+				{
+					reserve(newsize);
+				}
+#ifdef BT_USE_PLACEMENT_NEW
+				for (int i=curSize;i<newsize;i++)
+				{
+					new ( &m_data[i]) T(fillData);
+				}
+#endif //BT_USE_PLACEMENT_NEW
+
+			}
+
+			m_size = newsize;
+		}
+	
+
+		SIMD_FORCE_INLINE	T&  expand( const T& fillValue=T())
+		{	
+			int sz = size();
+			if( sz == capacity() )
+			{
+				reserve( allocSize(size()) );
+			}
+			m_size++;
+#ifdef BT_USE_PLACEMENT_NEW
+			new (&m_data[sz]) T(fillValue); //use the in-place new (not really allocating heap memory)
+#endif
+
+			return m_data[sz];		
+		}
+
+
+		SIMD_FORCE_INLINE	void push_back(const T& _Val)
+		{	
+			int sz = size();
+			if( sz == capacity() )
+			{
+				reserve( allocSize(size()) );
+			}
+			
+#ifdef BT_USE_PLACEMENT_NEW
+			new ( &m_data[m_size] ) T(_Val);
+#else
+			m_data[size()] = _Val;			
+#endif //BT_USE_PLACEMENT_NEW
+
+			m_size++;
+		}
+
+	
+		/// return the pre-allocated (reserved) elements, this is at least as large as the total number of elements,see size() and reserve()
+		SIMD_FORCE_INLINE	int capacity() const
+		{	
+			return m_capacity;
+		}
+		
+		SIMD_FORCE_INLINE	void reserve(int _Count)
+		{	// determine new minimum length of allocated storage
+			if (capacity() < _Count)
+			{	// not enough room, reallocate
+				T*	s = (T*)allocate(_Count);
+
+				copy(0, size(), s);
+
+				destroy(0,size());
+
+				deallocate();
+				
+				//PCK: added this line
+				m_ownsMemory = true;
+
+				m_data = s;
+				
+				m_capacity = _Count;
+
+			}
+		}
+
+
+		class less
+		{
+			public:
+
+				bool operator() ( const T& a, const T& b )
+				{
+					return ( a < b );
+				}
+		};
+	
+		template <typename L>
+		void quickSortInternal(L CompareFunc,int lo, int hi)
+		{
+		//  lo is the lower index, hi is the upper index
+		//  of the region of array a that is to be sorted
+			int i=lo, j=hi;
+			T x=m_data[(lo+hi)/2];
+
+			//  partition
+			do
+			{    
+				while (CompareFunc(m_data[i],x)) 
+					i++; 
+				while (CompareFunc(x,m_data[j])) 
+					j--;
+				if (i<=j)
+				{
+					swap(i,j);
+					i++; j--;
+				}
+			} while (i<=j);
+
+			//  recursion
+			if (lo<j) 
+				quickSortInternal( CompareFunc, lo, j);
+			if (i<hi) 
+				quickSortInternal( CompareFunc, i, hi);
+		}
+
+
+		template <typename L>
+		void quickSort(L CompareFunc)
+		{
+			//don't sort 0 or 1 elements
+			if (size()>1)
+			{
+				quickSortInternal(CompareFunc,0,size()-1);
+			}
+		}
+
+
+		///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/
+		template <typename L>
+		void downHeap(T *pArr, int k, int n,L CompareFunc)
+		{
+			/*  PRE: a[k+1..N] is a heap */
+			/* POST:  a[k..N]  is a heap */
+			
+			T temp = pArr[k - 1];
+			/* k has child(s) */
+			while (k <= n/2) 
+			{
+				int child = 2*k;
+				
+				if ((child < n) && CompareFunc(pArr[child - 1] , pArr[child]))
+				{
+					child++;
+				}
+				/* pick larger child */
+				if (CompareFunc(temp , pArr[child - 1]))
+				{
+					/* move child up */
+					pArr[k - 1] = pArr[child - 1];
+					k = child;
+				}
+				else
+				{
+					break;
+				}
+			}
+			pArr[k - 1] = temp;
+		} /*downHeap*/
+
+		void	swap(int index0,int index1)
+		{
+#ifdef BT_USE_MEMCPY
+			char	temp[sizeof(T)];
+			memcpy(temp,&m_data[index0],sizeof(T));
+			memcpy(&m_data[index0],&m_data[index1],sizeof(T));
+			memcpy(&m_data[index1],temp,sizeof(T));
+#else
+			T temp = m_data[index0];
+			m_data[index0] = m_data[index1];
+			m_data[index1] = temp;
+#endif //BT_USE_PLACEMENT_NEW
+
+		}
+
+	template <typename L>
+	void heapSort(L CompareFunc)
+	{
+		/* sort a[0..N-1],  N.B. 0 to N-1 */
+		int k;
+		int n = m_size;
+		for (k = n/2; k > 0; k--) 
+		{
+			downHeap(m_data, k, n, CompareFunc);
+		}
+
+		/* a[1..N] is now a heap */
+		while ( n>=1 ) 
+		{
+			swap(0,n-1); /* largest of a[0..n-1] */
+
+
+			n = n - 1;
+			/* restore a[1..i-1] heap */
+			downHeap(m_data, 1, n, CompareFunc);
+		} 
+	}
+
+	///non-recursive binary search, assumes sorted array
+	int	findBinarySearch(const T& key) const
+	{
+		int first = 0;
+		int last = size();
+
+		//assume sorted array
+		while (first <= last) {
+			int mid = (first + last) / 2;  // compute mid point.
+			if (key > m_data[mid]) 
+				first = mid + 1;  // repeat search in top half.
+			else if (key < m_data[mid]) 
+				last = mid - 1; // repeat search in bottom half.
+			else
+				return mid;     // found it. return position /////
+		}
+		return size();    // failed to find key
+	}
+
+
+	int	findLinearSearch(const T& key) const
+	{
+		int index=size();
+		int i;
+
+		for (i=0;i<size();i++)
+		{
+			if (m_data[i] == key)
+			{
+				index = i;
+				break;
+			}
+		}
+		return index;
+	}
+
+	void	remove(const T& key)
+	{
+
+		int findIndex = findLinearSearch(key);
+		if (findIndex<size())
+		{
+			swap( findIndex,size()-1);
+			pop_back();
+		}
+	}
+
+	//PCK: whole function
+	void initializeFromBuffer(void *buffer, int size, int capacity)
+	{
+		clear();
+		m_ownsMemory = false;
+		m_data = (T*)buffer;
+		m_size = size;
+		m_capacity = capacity;
+	}
+
+};
+
+#endif //BT_OBJECT_ARRAY__
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btConvexHull.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btConvexHull.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btConvexHull.cpp	(revision 6952)
@@ -0,0 +1,1174 @@
+/*
+Stan Melax Convex Hull Computation
+Copyright (c) 2003-2006 Stan Melax http://www.melax.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 <string.h>
+
+#include "btConvexHull.h"
+#include "LinearMath/btAlignedObjectArray.h"
+#include "LinearMath/btMinMax.h"
+#include "LinearMath/btVector3.h"
+
+
+
+template <class T>
+void Swap(T &a,T &b)
+{
+	T tmp = a;
+	a=b;
+	b=tmp;
+}
+
+
+//----------------------------------
+
+class int3  
+{
+public:
+	int x,y,z;
+	int3(){};
+	int3(int _x,int _y, int _z){x=_x;y=_y;z=_z;}
+	const int& operator[](int i) const {return (&x)[i];}
+	int& operator[](int i) {return (&x)[i];}
+};
+
+
+//------- btPlane ----------
+
+
+inline btPlane PlaneFlip(const btPlane &plane){return btPlane(-plane.normal,-plane.dist);}
+inline int operator==( const btPlane &a, const btPlane &b ) { return (a.normal==b.normal && a.dist==b.dist); }
+inline int coplanar( const btPlane &a, const btPlane &b ) { return (a==b || a==PlaneFlip(b)); }
+
+
+//--------- Utility Functions ------
+
+btVector3  PlaneLineIntersection(const btPlane &plane, const btVector3 &p0, const btVector3 &p1);
+btVector3  PlaneProject(const btPlane &plane, const btVector3 &point);
+
+btVector3  ThreePlaneIntersection(const btPlane &p0,const btPlane &p1, const btPlane &p2);
+btVector3  ThreePlaneIntersection(const btPlane &p0,const btPlane &p1, const btPlane &p2)
+{
+	btVector3 N1 = p0.normal;
+	btVector3 N2 = p1.normal;
+	btVector3 N3 = p2.normal;
+
+	btVector3 n2n3; n2n3 = N2.cross(N3);
+	btVector3 n3n1; n3n1 = N3.cross(N1);
+	btVector3 n1n2; n1n2 = N1.cross(N2);
+
+	btScalar quotient = (N1.dot(n2n3));
+
+	btAssert(btFabs(quotient) > btScalar(0.000001));
+	
+	quotient = btScalar(-1.) / quotient;
+	n2n3 *= p0.dist;
+	n3n1 *= p1.dist;
+	n1n2 *= p2.dist;
+	btVector3 potentialVertex = n2n3;
+	potentialVertex += n3n1;
+	potentialVertex += n1n2;
+	potentialVertex *= quotient;
+
+	btVector3 result(potentialVertex.getX(),potentialVertex.getY(),potentialVertex.getZ());
+	return result;
+
+}
+
+btScalar   DistanceBetweenLines(const btVector3 &ustart, const btVector3 &udir, const btVector3 &vstart, const btVector3 &vdir, btVector3 *upoint=NULL, btVector3 *vpoint=NULL);
+btVector3  TriNormal(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2);
+btVector3  NormalOf(const btVector3 *vert, const int n);
+
+
+btVector3 PlaneLineIntersection(const btPlane &plane, const btVector3 &p0, const btVector3 &p1)
+{
+	// returns the point where the line p0-p1 intersects the plane n&d
+				static btVector3 dif;
+		dif = p1-p0;
+				btScalar dn= dot(plane.normal,dif);
+				btScalar t = -(plane.dist+dot(plane.normal,p0) )/dn;
+				return p0 + (dif*t);
+}
+
+btVector3 PlaneProject(const btPlane &plane, const btVector3 &point)
+{
+	return point - plane.normal * (dot(point,plane.normal)+plane.dist);
+}
+
+btVector3 TriNormal(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2)
+{
+	// return the normal of the triangle
+	// inscribed by v0, v1, and v2
+	btVector3 cp=cross(v1-v0,v2-v1);
+	btScalar m=cp.length();
+	if(m==0) return btVector3(1,0,0);
+	return cp*(btScalar(1.0)/m);
+}
+
+
+btScalar DistanceBetweenLines(const btVector3 &ustart, const btVector3 &udir, const btVector3 &vstart, const btVector3 &vdir, btVector3 *upoint, btVector3 *vpoint)
+{
+	static btVector3 cp;
+	cp = cross(udir,vdir).normalized();
+
+	btScalar distu = -dot(cp,ustart);
+	btScalar distv = -dot(cp,vstart);
+	btScalar dist = (btScalar)fabs(distu-distv);
+	if(upoint) 
+		{
+		btPlane plane;
+		plane.normal = cross(vdir,cp).normalized();
+		plane.dist = -dot(plane.normal,vstart);
+		*upoint = PlaneLineIntersection(plane,ustart,ustart+udir);
+	}
+	if(vpoint) 
+		{
+		btPlane plane;
+		plane.normal = cross(udir,cp).normalized();
+		plane.dist = -dot(plane.normal,ustart);
+		*vpoint = PlaneLineIntersection(plane,vstart,vstart+vdir);
+	}
+	return dist;
+}
+
+
+
+
+
+
+
+#define COPLANAR   (0)
+#define UNDER      (1)
+#define OVER       (2)
+#define SPLIT      (OVER|UNDER)
+#define PAPERWIDTH (btScalar(0.001))
+
+btScalar planetestepsilon = PAPERWIDTH;
+
+
+
+typedef ConvexH::HalfEdge HalfEdge;
+
+ConvexH::ConvexH(int vertices_size,int edges_size,int facets_size)
+{
+	vertices.resize(vertices_size);
+	edges.resize(edges_size);
+	facets.resize(facets_size);
+}
+
+
+int PlaneTest(const btPlane &p, const btVector3 &v);
+int PlaneTest(const btPlane &p, const btVector3 &v) {
+	btScalar a  = dot(v,p.normal)+p.dist;
+	int   flag = (a>planetestepsilon)?OVER:((a<-planetestepsilon)?UNDER:COPLANAR);
+	return flag;
+}
+
+int SplitTest(ConvexH &convex,const btPlane &plane);
+int SplitTest(ConvexH &convex,const btPlane &plane) {
+	int flag=0;
+	for(int i=0;i<convex.vertices.size();i++) {
+		flag |= PlaneTest(plane,convex.vertices[i]);
+	}
+	return flag;
+}
+
+class VertFlag
+{
+public:
+	unsigned char planetest;
+	unsigned char junk;
+	unsigned char undermap;
+	unsigned char overmap;
+};
+class EdgeFlag 
+{
+public:
+	unsigned char planetest;
+	unsigned char fixes;
+	short undermap;
+	short overmap;
+};
+class PlaneFlag
+{
+public:
+	unsigned char undermap;
+	unsigned char overmap;
+};
+class Coplanar{
+public:
+	unsigned short ea;
+	unsigned char v0;
+	unsigned char v1;
+};
+
+
+
+
+
+
+
+
+template<class T>
+int maxdirfiltered(const T *p,int count,const T &dir,btAlignedObjectArray<int> &allow)
+{
+	btAssert(count);
+	int m=-1;
+	for(int i=0;i<count;i++) 
+		if(allow[i])
+		{
+			if(m==-1 || dot(p[i],dir)>dot(p[m],dir))
+				m=i;
+		}
+	btAssert(m!=-1);
+	return m;
+} 
+
+btVector3 orth(const btVector3 &v);
+btVector3 orth(const btVector3 &v)
+{
+	btVector3 a=cross(v,btVector3(0,0,1));
+	btVector3 b=cross(v,btVector3(0,1,0));
+	if (a.length() > b.length())
+	{
+		return a.normalized();
+	} else {
+		return b.normalized();
+	}
+}
+
+
+template<class T>
+int maxdirsterid(const T *p,int count,const T &dir,btAlignedObjectArray<int> &allow)
+{
+	int m=-1;
+	while(m==-1)
+	{
+		m = maxdirfiltered(p,count,dir,allow);
+		if(allow[m]==3) return m;
+		T u = orth(dir);
+		T v = cross(u,dir);
+		int ma=-1;
+		for(btScalar x = btScalar(0.0) ; x<= btScalar(360.0) ; x+= btScalar(45.0))
+		{
+			btScalar s = btSin(SIMD_RADS_PER_DEG*(x));
+			btScalar c = btCos(SIMD_RADS_PER_DEG*(x));
+			int mb = maxdirfiltered(p,count,dir+(u*s+v*c)*btScalar(0.025),allow);
+			if(ma==m && mb==m)
+			{
+				allow[m]=3;
+				return m;
+			}
+			if(ma!=-1 && ma!=mb)  // Yuck - this is really ugly
+			{
+				int mc = ma;
+				for(btScalar xx = x-btScalar(40.0) ; xx <= x ; xx+= btScalar(5.0))
+				{
+					btScalar s = btSin(SIMD_RADS_PER_DEG*(xx));
+					btScalar c = btCos(SIMD_RADS_PER_DEG*(xx));
+					int md = maxdirfiltered(p,count,dir+(u*s+v*c)*btScalar(0.025),allow);
+					if(mc==m && md==m)
+					{
+						allow[m]=3;
+						return m;
+					}
+					mc=md;
+				}
+			}
+			ma=mb;
+		}
+		allow[m]=0;
+		m=-1;
+	}
+	btAssert(0);
+	return m;
+} 
+
+
+
+
+int operator ==(const int3 &a,const int3 &b);
+int operator ==(const int3 &a,const int3 &b) 
+{
+	for(int i=0;i<3;i++) 
+	{
+		if(a[i]!=b[i]) return 0;
+	}
+	return 1;
+}
+
+
+int above(btVector3* vertices,const int3& t, const btVector3 &p, btScalar epsilon);
+int above(btVector3* vertices,const int3& t, const btVector3 &p, btScalar epsilon) 
+{
+	btVector3 n=TriNormal(vertices[t[0]],vertices[t[1]],vertices[t[2]]);
+	return (dot(n,p-vertices[t[0]]) > epsilon); // EPSILON???
+}
+int hasedge(const int3 &t, int a,int b);
+int hasedge(const int3 &t, int a,int b)
+{
+	for(int i=0;i<3;i++)
+	{
+		int i1= (i+1)%3;
+		if(t[i]==a && t[i1]==b) return 1;
+	}
+	return 0;
+}
+int hasvert(const int3 &t, int v);
+int hasvert(const int3 &t, int v)
+{
+	return (t[0]==v || t[1]==v || t[2]==v) ;
+}
+int shareedge(const int3 &a,const int3 &b);
+int shareedge(const int3 &a,const int3 &b)
+{
+	int i;
+	for(i=0;i<3;i++)
+	{
+		int i1= (i+1)%3;
+		if(hasedge(a,b[i1],b[i])) return 1;
+	}
+	return 0;
+}
+
+class btHullTriangle;
+
+
+
+class btHullTriangle : public int3
+{
+public:
+	int3 n;
+	int id;
+	int vmax;
+	btScalar rise;
+	btHullTriangle(int a,int b,int c):int3(a,b,c),n(-1,-1,-1)
+	{
+		vmax=-1;
+		rise = btScalar(0.0);
+	}
+	~btHullTriangle()
+	{
+	}
+	int &neib(int a,int b);
+};
+
+
+int &btHullTriangle::neib(int a,int b)
+{
+	static int er=-1;
+	int i;
+	for(i=0;i<3;i++) 
+	{
+		int i1=(i+1)%3;
+		int i2=(i+2)%3;
+		if((*this)[i]==a && (*this)[i1]==b) return n[i2];
+		if((*this)[i]==b && (*this)[i1]==a) return n[i2];
+	}
+	btAssert(0);
+	return er;
+}
+void HullLibrary::b2bfix(btHullTriangle* s,btHullTriangle*t)
+{
+	int i;
+	for(i=0;i<3;i++) 
+	{
+		int i1=(i+1)%3;
+		int i2=(i+2)%3;
+		int a = (*s)[i1];
+		int b = (*s)[i2];
+		btAssert(m_tris[s->neib(a,b)]->neib(b,a) == s->id);
+		btAssert(m_tris[t->neib(a,b)]->neib(b,a) == t->id);
+		m_tris[s->neib(a,b)]->neib(b,a) = t->neib(b,a);
+		m_tris[t->neib(b,a)]->neib(a,b) = s->neib(a,b);
+	}
+}
+
+void HullLibrary::removeb2b(btHullTriangle* s,btHullTriangle*t)
+{
+	b2bfix(s,t);
+	deAllocateTriangle(s);
+
+	deAllocateTriangle(t);
+}
+
+void HullLibrary::checkit(btHullTriangle *t)
+{
+	(void)t;
+
+	int i;
+	btAssert(m_tris[t->id]==t);
+	for(i=0;i<3;i++)
+	{
+		int i1=(i+1)%3;
+		int i2=(i+2)%3;
+		int a = (*t)[i1];
+		int b = (*t)[i2];
+
+		// release compile fix
+		(void)i1;
+		(void)i2;
+		(void)a;
+		(void)b;
+
+		btAssert(a!=b);
+		btAssert( m_tris[t->n[i]]->neib(b,a) == t->id);
+	}
+}
+
+btHullTriangle*	HullLibrary::allocateTriangle(int a,int b,int c)
+{
+	void* mem = btAlignedAlloc(sizeof(btHullTriangle),16);
+	btHullTriangle* tr = new (mem)btHullTriangle(a,b,c);
+	tr->id = m_tris.size();
+	m_tris.push_back(tr);
+
+	return tr;
+}
+
+void	HullLibrary::deAllocateTriangle(btHullTriangle* tri)
+{
+	btAssert(m_tris[tri->id]==tri);
+	m_tris[tri->id]=NULL;
+	tri->~btHullTriangle();
+	btAlignedFree(tri);
+}
+
+
+void HullLibrary::extrude(btHullTriangle *t0,int v)
+{
+	int3 t= *t0;
+	int n = m_tris.size();
+	btHullTriangle* ta = allocateTriangle(v,t[1],t[2]);
+	ta->n = int3(t0->n[0],n+1,n+2);
+	m_tris[t0->n[0]]->neib(t[1],t[2]) = n+0;
+	btHullTriangle* tb = allocateTriangle(v,t[2],t[0]);
+	tb->n = int3(t0->n[1],n+2,n+0);
+	m_tris[t0->n[1]]->neib(t[2],t[0]) = n+1;
+	btHullTriangle* tc = allocateTriangle(v,t[0],t[1]);
+	tc->n = int3(t0->n[2],n+0,n+1);
+	m_tris[t0->n[2]]->neib(t[0],t[1]) = n+2;
+	checkit(ta);
+	checkit(tb);
+	checkit(tc);
+	if(hasvert(*m_tris[ta->n[0]],v)) removeb2b(ta,m_tris[ta->n[0]]);
+	if(hasvert(*m_tris[tb->n[0]],v)) removeb2b(tb,m_tris[tb->n[0]]);
+	if(hasvert(*m_tris[tc->n[0]],v)) removeb2b(tc,m_tris[tc->n[0]]);
+	deAllocateTriangle(t0);
+
+}
+
+btHullTriangle* HullLibrary::extrudable(btScalar epsilon)
+{
+	int i;
+	btHullTriangle *t=NULL;
+	for(i=0;i<m_tris.size();i++)
+	{
+		if(!t || (m_tris[i] && t->rise<m_tris[i]->rise))
+		{
+			t = m_tris[i];
+		}
+	}
+	return (t->rise >epsilon)?t:NULL ;
+}
+
+
+
+
+int4 HullLibrary::FindSimplex(btVector3 *verts,int verts_count,btAlignedObjectArray<int> &allow)
+{
+	btVector3 basis[3];
+	basis[0] = btVector3( btScalar(0.01), btScalar(0.02), btScalar(1.0) );      
+	int p0 = maxdirsterid(verts,verts_count, basis[0],allow);   
+	int	p1 = maxdirsterid(verts,verts_count,-basis[0],allow);
+	basis[0] = verts[p0]-verts[p1];
+	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]);
+	if (basis[1].length() > basis[2].length())
+	{
+		basis[1].normalize();
+	} else {
+		basis[1] = basis[2];
+		basis[1].normalize ();
+	}
+	int p2 = maxdirsterid(verts,verts_count,basis[1],allow);
+	if(p2 == p0 || p2 == p1)
+	{
+		p2 = maxdirsterid(verts,verts_count,-basis[1],allow);
+	}
+	if(p2 == p0 || p2 == p1) 
+		return int4(-1,-1,-1,-1);
+	basis[1] = verts[p2] - verts[p0];
+	basis[2] = cross(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);
+	if(p3==p0||p3==p1||p3==p2) 
+		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);}
+	return int4(p0,p1,p2,p3);
+}
+
+int HullLibrary::calchullgen(btVector3 *verts,int verts_count, int vlimit)
+{
+	if(verts_count <4) return 0;
+	if(vlimit==0) vlimit=1000000000;
+	int j;
+	btVector3 bmin(*verts),bmax(*verts);
+	btAlignedObjectArray<int> isextreme;
+	isextreme.reserve(verts_count);
+	btAlignedObjectArray<int> allow;
+	allow.reserve(verts_count);
+
+	for(j=0;j<verts_count;j++) 
+	{
+		allow.push_back(1);
+		isextreme.push_back(0);
+		bmin.setMin (verts[j]);
+		bmax.setMax (verts[j]);
+	}
+	btScalar epsilon = (bmax-bmin).length() * btScalar(0.001);
+	btAssert (epsilon != 0.0);
+
+
+	int4 p = FindSimplex(verts,verts_count,allow);
+	if(p.x==-1) return 0; // simplex failed
+
+
+
+	btVector3 center = (verts[p[0]]+verts[p[1]]+verts[p[2]]+verts[p[3]]) / btScalar(4.0);  // a valid interior point
+	btHullTriangle *t0 = allocateTriangle(p[2],p[3],p[1]); t0->n=int3(2,3,1);
+	btHullTriangle *t1 = allocateTriangle(p[3],p[2],p[0]); t1->n=int3(3,2,0);
+	btHullTriangle *t2 = allocateTriangle(p[0],p[1],p[3]); t2->n=int3(0,1,3);
+	btHullTriangle *t3 = allocateTriangle(p[1],p[0],p[2]); t3->n=int3(1,0,2);
+	isextreme[p[0]]=isextreme[p[1]]=isextreme[p[2]]=isextreme[p[3]]=1;
+	checkit(t0);checkit(t1);checkit(t2);checkit(t3);
+
+	for(j=0;j<m_tris.size();j++)
+	{
+		btHullTriangle *t=m_tris[j];
+		btAssert(t);
+		btAssert(t->vmax<0);
+		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]]);
+	}
+	btHullTriangle *te;
+	vlimit-=4;
+	while(vlimit >0 && ((te=extrudable(epsilon)) != 0))
+	{
+		int3 ti=*te;
+		int v=te->vmax;
+		btAssert(v != -1);
+		btAssert(!isextreme[v]);  // wtf we've already done this vertex
+		isextreme[v]=1;
+		//if(v==p0 || v==p1 || v==p2 || v==p3) continue; // done these already
+		j=m_tris.size();
+		while(j--) {
+			if(!m_tris[j]) continue;
+			int3 t=*m_tris[j];
+			if(above(verts,t,verts[v],btScalar(0.01)*epsilon)) 
+			{
+				extrude(m_tris[j],v);
+			}
+		}
+		// now check for those degenerate cases where we have a flipped triangle or a really skinny triangle
+		j=m_tris.size();
+		while(j--)
+		{
+			if(!m_tris[j]) continue;
+			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) )
+			{
+				btHullTriangle *nb = m_tris[m_tris[j]->n[0]];
+				btAssert(nb);btAssert(!hasvert(*nb,v));btAssert(nb->id<j);
+				extrude(nb,v);
+				j=m_tris.size(); 
+			}
+		} 
+		j=m_tris.size();
+		while(j--)
+		{
+			btHullTriangle *t=m_tris[j];
+			if(!t) continue;
+			if(t->vmax>=0) break;
+			btVector3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]);
+			t->vmax = maxdirsterid(verts,verts_count,n,allow);
+			if(isextreme[t->vmax]) 
+			{
+				t->vmax=-1; // already done that vertex - algorithm needs to be able to terminate.
+			}
+			else
+			{
+				t->rise = dot(n,verts[t->vmax]-verts[(*t)[0]]);
+			}
+		}
+		vlimit --;
+	}
+	return 1;
+}
+
+int HullLibrary::calchull(btVector3 *verts,int verts_count, TUIntArray& tris_out, int &tris_count,int vlimit) 
+{
+	int rc=calchullgen(verts,verts_count,  vlimit) ;
+	if(!rc) return 0;
+	btAlignedObjectArray<int> ts;
+	int i;
+
+	for(i=0;i<m_tris.size();i++)
+	{
+		if(m_tris[i])
+		{
+			for(int j=0;j<3;j++)
+				ts.push_back((*m_tris[i])[j]);
+			deAllocateTriangle(m_tris[i]);
+		}
+	}
+	tris_count = ts.size()/3;
+	tris_out.resize(ts.size());
+	
+	for (i=0;i<ts.size();i++)
+	{
+		tris_out[i] = static_cast<unsigned int>(ts[i]);
+	}
+	m_tris.resize(0);
+
+	return 1;
+}
+
+
+
+
+
+bool HullLibrary::ComputeHull(unsigned int vcount,const btVector3 *vertices,PHullResult &result,unsigned int vlimit)
+{
+	
+	int    tris_count;
+	int ret = calchull( (btVector3 *) vertices, (int) vcount, result.m_Indices, tris_count, static_cast<int>(vlimit) );
+	if(!ret) return false;
+	result.mIndexCount = (unsigned int) (tris_count*3);
+	result.mFaceCount  = (unsigned int) tris_count;
+	result.mVertices   = (btVector3*) vertices;
+	result.mVcount     = (unsigned int) vcount;
+	return true;
+
+}
+
+
+void ReleaseHull(PHullResult &result);
+void ReleaseHull(PHullResult &result)
+{
+	if ( result.m_Indices.size() )
+	{
+		result.m_Indices.clear();
+	}
+
+	result.mVcount = 0;
+	result.mIndexCount = 0;
+	result.mVertices = 0;
+}
+
+
+//*********************************************************************
+//*********************************************************************
+//********  HullLib header
+//*********************************************************************
+//*********************************************************************
+
+//*********************************************************************
+//*********************************************************************
+//********  HullLib implementation
+//*********************************************************************
+//*********************************************************************
+
+HullError HullLibrary::CreateConvexHull(const HullDesc       &desc,           // describes the input request
+																					HullResult           &result)         // contains the resulst
+{
+	HullError ret = QE_FAIL;
+
+
+	PHullResult hr;
+
+	unsigned int vcount = desc.mVcount;
+	if ( vcount < 8 ) vcount = 8;
+
+	btAlignedObjectArray<btVector3> vertexSource;
+	vertexSource.resize(static_cast<int>(vcount));
+
+	btVector3 scale;
+
+	unsigned int ovcount;
+
+	bool ok = CleanupVertices(desc.mVcount,desc.mVertices, desc.mVertexStride, ovcount, &vertexSource[0], desc.mNormalEpsilon, scale ); // normalize point cloud, remove duplicates!
+
+	if ( ok )
+	{
+
+
+//		if ( 1 ) // scale vertices back to their original size.
+		{
+			for (unsigned int i=0; i<ovcount; i++)
+			{
+				btVector3& v = vertexSource[static_cast<int>(i)];
+				v[0]*=scale[0];
+				v[1]*=scale[1];
+				v[2]*=scale[2];
+			}
+		}
+
+		ok = ComputeHull(ovcount,&vertexSource[0],hr,desc.mMaxVertices);
+
+		if ( ok )
+		{
+
+			// re-index triangle mesh so it refers to only used vertices, rebuild a new vertex table.
+			btAlignedObjectArray<btVector3>	vertexScratch;
+			vertexScratch.resize(static_cast<int>(hr.mVcount));
+
+			BringOutYourDead(hr.mVertices,hr.mVcount, &vertexScratch[0], ovcount, &hr.m_Indices[0], hr.mIndexCount );
+
+			ret = QE_OK;
+
+			if ( desc.HasHullFlag(QF_TRIANGLES) ) // if he wants the results as triangle!
+			{
+				result.mPolygons          = false;
+				result.mNumOutputVertices = ovcount;
+				result.m_OutputVertices.resize(static_cast<int>(ovcount));
+				result.mNumFaces          = hr.mFaceCount;
+				result.mNumIndices        = hr.mIndexCount;
+
+				result.m_Indices.resize(static_cast<int>(hr.mIndexCount));
+
+				memcpy(&result.m_OutputVertices[0], &vertexScratch[0], sizeof(btVector3)*ovcount );
+
+  			if ( desc.HasHullFlag(QF_REVERSE_ORDER) )
+				{
+
+					const unsigned int *source = &hr.m_Indices[0];
+					unsigned int *dest   = &result.m_Indices[0];
+
+					for (unsigned int i=0; i<hr.mFaceCount; i++)
+					{
+						dest[0] = source[2];
+						dest[1] = source[1];
+						dest[2] = source[0];
+						dest+=3;
+						source+=3;
+					}
+
+				}
+				else
+				{
+					memcpy(&result.m_Indices[0], &hr.m_Indices[0], sizeof(unsigned int)*hr.mIndexCount);
+				}
+			}
+			else
+			{
+				result.mPolygons          = true;
+				result.mNumOutputVertices = ovcount;
+				result.m_OutputVertices.resize(static_cast<int>(ovcount));
+				result.mNumFaces          = hr.mFaceCount;
+				result.mNumIndices        = hr.mIndexCount+hr.mFaceCount;
+				result.m_Indices.resize(static_cast<int>(result.mNumIndices));
+				memcpy(&result.m_OutputVertices[0], &vertexScratch[0], sizeof(btVector3)*ovcount );
+
+//				if ( 1 )
+				{
+					const unsigned int *source = &hr.m_Indices[0];
+					unsigned int *dest   = &result.m_Indices[0];
+					for (unsigned int i=0; i<hr.mFaceCount; i++)
+					{
+						dest[0] = 3;
+						if ( desc.HasHullFlag(QF_REVERSE_ORDER) )
+						{
+							dest[1] = source[2];
+							dest[2] = source[1];
+							dest[3] = source[0];
+						}
+						else
+						{
+							dest[1] = source[0];
+							dest[2] = source[1];
+							dest[3] = source[2];
+						}
+
+						dest+=4;
+						source+=3;
+					}
+				}
+			}
+			ReleaseHull(hr);
+		}
+	}
+
+	return ret;
+}
+
+
+
+HullError HullLibrary::ReleaseResult(HullResult &result) // release memory allocated for this result, we are done with it.
+{
+	if ( result.m_OutputVertices.size())
+	{
+		result.mNumOutputVertices=0;
+		result.m_OutputVertices.clear();
+	}
+	if ( result.m_Indices.size() )
+	{
+		result.mNumIndices=0;
+		result.m_Indices.clear();
+	}
+	return QE_OK;
+}
+
+
+static void addPoint(unsigned int &vcount,btVector3 *p,btScalar x,btScalar y,btScalar z)
+{
+	// XXX, might be broken
+	btVector3& dest = p[vcount];
+	dest[0] = x;
+	dest[1] = y;
+	dest[2] = z;
+	vcount++;
+}
+
+btScalar GetDist(btScalar px,btScalar py,btScalar pz,const btScalar *p2);
+btScalar GetDist(btScalar px,btScalar py,btScalar pz,const btScalar *p2)
+{
+
+	btScalar dx = px - p2[0];
+	btScalar dy = py - p2[1];
+	btScalar dz = pz - p2[2];
+
+	return dx*dx+dy*dy+dz*dz;
+}
+
+
+
+bool  HullLibrary::CleanupVertices(unsigned int svcount,
+				   const btVector3 *svertices,
+				   unsigned int stride,
+				   unsigned int &vcount,       // output number of vertices
+				   btVector3 *vertices,                 // location to store the results.
+				   btScalar  normalepsilon,
+				   btVector3& scale)
+{
+	if ( svcount == 0 ) return false;
+
+	m_vertexIndexMapping.resize(0);
+
+
+#define EPSILON btScalar(0.000001) /* close enough to consider two btScalaring point numbers to be 'the same'. */
+
+	vcount = 0;
+
+	btScalar recip[3];
+
+	if ( scale )
+	{
+		scale[0] = 1;
+		scale[1] = 1;
+		scale[2] = 1;
+	}
+
+	btScalar bmin[3] = {  FLT_MAX,  FLT_MAX,  FLT_MAX };
+	btScalar bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX };
+
+	const char *vtx = (const char *) svertices;
+
+//	if ( 1 )
+	{
+		for (unsigned int i=0; i<svcount; i++)
+		{
+			const btScalar *p = (const btScalar *) vtx;
+
+			vtx+=stride;
+
+			for (int j=0; j<3; j++)
+			{
+				if ( p[j] < bmin[j] ) bmin[j] = p[j];
+				if ( p[j] > bmax[j] ) bmax[j] = p[j];
+			}
+		}
+	}
+
+	btScalar dx = bmax[0] - bmin[0];
+	btScalar dy = bmax[1] - bmin[1];
+	btScalar dz = bmax[2] - bmin[2];
+
+	btVector3 center;
+
+	center[0] = dx*btScalar(0.5) + bmin[0];
+	center[1] = dy*btScalar(0.5) + bmin[1];
+	center[2] = dz*btScalar(0.5) + bmin[2];
+
+	if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || svcount < 3 )
+	{
+
+		btScalar len = FLT_MAX;
+
+		if ( dx > EPSILON && dx < len ) len = dx;
+		if ( dy > EPSILON && dy < len ) len = dy;
+		if ( dz > EPSILON && dz < len ) len = dz;
+
+		if ( len == FLT_MAX )
+		{
+			dx = dy = dz = btScalar(0.01); // one centimeter
+		}
+		else
+		{
+			if ( dx < EPSILON ) dx = len * btScalar(0.05); // 1/5th the shortest non-zero edge.
+			if ( dy < EPSILON ) dy = len * btScalar(0.05);
+			if ( dz < EPSILON ) dz = len * btScalar(0.05);
+		}
+
+		btScalar x1 = center[0] - dx;
+		btScalar x2 = center[0] + dx;
+
+		btScalar y1 = center[1] - dy;
+		btScalar y2 = center[1] + dy;
+
+		btScalar z1 = center[2] - dz;
+		btScalar z2 = center[2] + dz;
+
+		addPoint(vcount,vertices,x1,y1,z1);
+		addPoint(vcount,vertices,x2,y1,z1);
+		addPoint(vcount,vertices,x2,y2,z1);
+		addPoint(vcount,vertices,x1,y2,z1);
+		addPoint(vcount,vertices,x1,y1,z2);
+		addPoint(vcount,vertices,x2,y1,z2);
+		addPoint(vcount,vertices,x2,y2,z2);
+		addPoint(vcount,vertices,x1,y2,z2);
+
+		return true; // return cube
+
+
+	}
+	else
+	{
+		if ( scale )
+		{
+			scale[0] = dx;
+			scale[1] = dy;
+			scale[2] = dz;
+
+			recip[0] = 1 / dx;
+			recip[1] = 1 / dy;
+			recip[2] = 1 / dz;
+
+			center[0]*=recip[0];
+			center[1]*=recip[1];
+			center[2]*=recip[2];
+
+		}
+
+	}
+
+
+
+	vtx = (const char *) svertices;
+
+	for (unsigned int i=0; i<svcount; i++)
+	{
+		const btVector3 *p = (const btVector3 *)vtx;
+		vtx+=stride;
+
+		btScalar px = p->getX();
+		btScalar py = p->getY();
+		btScalar pz = p->getZ();
+
+		if ( scale )
+		{
+			px = px*recip[0]; // normalize
+			py = py*recip[1]; // normalize
+			pz = pz*recip[2]; // normalize
+		}
+
+//		if ( 1 )
+		{
+			unsigned int j;
+
+			for (j=0; j<vcount; j++)
+			{
+				/// XXX might be broken
+				btVector3& v = vertices[j];
+
+				btScalar x = v[0];
+				btScalar y = v[1];
+				btScalar z = v[2];
+
+				btScalar dx = fabsf(x - px );
+				btScalar dy = fabsf(y - py );
+				btScalar dz = fabsf(z - pz );
+
+				if ( dx < normalepsilon && dy < normalepsilon && dz < normalepsilon )
+				{
+					// ok, it is close enough to the old one
+					// now let us see if it is further from the center of the point cloud than the one we already recorded.
+					// in which case we keep this one instead.
+
+					btScalar dist1 = GetDist(px,py,pz,center);
+					btScalar dist2 = GetDist(v[0],v[1],v[2],center);
+
+					if ( dist1 > dist2 )
+					{
+						v[0] = px;
+						v[1] = py;
+						v[2] = pz;
+						
+					}
+
+					break;
+				}
+			}
+
+			if ( j == vcount )
+			{
+				btVector3& dest = vertices[vcount];
+				dest[0] = px;
+				dest[1] = py;
+				dest[2] = pz;
+				vcount++;
+			}
+			m_vertexIndexMapping.push_back(j);
+		}
+	}
+
+	// ok..now make sure we didn't prune so many vertices it is now invalid.
+//	if ( 1 )
+	{
+		btScalar bmin[3] = {  FLT_MAX,  FLT_MAX,  FLT_MAX };
+		btScalar bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX };
+
+		for (unsigned int i=0; i<vcount; i++)
+		{
+			const btVector3& p = vertices[i];
+			for (int j=0; j<3; j++)
+			{
+				if ( p[j] < bmin[j] ) bmin[j] = p[j];
+				if ( p[j] > bmax[j] ) bmax[j] = p[j];
+			}
+		}
+
+		btScalar dx = bmax[0] - bmin[0];
+		btScalar dy = bmax[1] - bmin[1];
+		btScalar dz = bmax[2] - bmin[2];
+
+		if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || vcount < 3)
+		{
+			btScalar cx = dx*btScalar(0.5) + bmin[0];
+			btScalar cy = dy*btScalar(0.5) + bmin[1];
+			btScalar cz = dz*btScalar(0.5) + bmin[2];
+
+			btScalar len = FLT_MAX;
+
+			if ( dx >= EPSILON && dx < len ) len = dx;
+			if ( dy >= EPSILON && dy < len ) len = dy;
+			if ( dz >= EPSILON && dz < len ) len = dz;
+
+			if ( len == FLT_MAX )
+			{
+				dx = dy = dz = btScalar(0.01); // one centimeter
+			}
+			else
+			{
+				if ( dx < EPSILON ) dx = len * btScalar(0.05); // 1/5th the shortest non-zero edge.
+				if ( dy < EPSILON ) dy = len * btScalar(0.05);
+				if ( dz < EPSILON ) dz = len * btScalar(0.05);
+			}
+
+			btScalar x1 = cx - dx;
+			btScalar x2 = cx + dx;
+
+			btScalar y1 = cy - dy;
+			btScalar y2 = cy + dy;
+
+			btScalar z1 = cz - dz;
+			btScalar z2 = cz + dz;
+
+			vcount = 0; // add box
+
+			addPoint(vcount,vertices,x1,y1,z1);
+			addPoint(vcount,vertices,x2,y1,z1);
+			addPoint(vcount,vertices,x2,y2,z1);
+			addPoint(vcount,vertices,x1,y2,z1);
+			addPoint(vcount,vertices,x1,y1,z2);
+			addPoint(vcount,vertices,x2,y1,z2);
+			addPoint(vcount,vertices,x2,y2,z2);
+			addPoint(vcount,vertices,x1,y2,z2);
+
+			return true;
+		}
+	}
+
+	return true;
+}
+
+void HullLibrary::BringOutYourDead(const btVector3* verts,unsigned int vcount, btVector3* overts,unsigned int &ocount,unsigned int *indices,unsigned indexcount)
+{
+	btAlignedObjectArray<int>tmpIndices;
+	tmpIndices.resize(m_vertexIndexMapping.size());
+	int i;
+
+	for (i=0;i<m_vertexIndexMapping.size();i++)
+	{
+		tmpIndices[i] = m_vertexIndexMapping[i];
+	}
+
+	TUIntArray usedIndices;
+	usedIndices.resize(static_cast<int>(vcount));
+	memset(&usedIndices[0],0,sizeof(unsigned int)*vcount);
+
+	ocount = 0;
+
+	for (i=0; i<indexcount; i++)
+	{
+		unsigned int v = indices[i]; // original array index
+
+		btAssert( v >= 0 && v < vcount );
+
+		if ( usedIndices[static_cast<int>(v)] ) // if already remapped
+		{
+			indices[i] = usedIndices[static_cast<int>(v)]-1; // index to new array
+		}
+		else
+		{
+
+			indices[i] = ocount;      // new index mapping
+
+			overts[ocount][0] = verts[v][0]; // copy old vert to new vert array
+			overts[ocount][1] = verts[v][1];
+			overts[ocount][2] = verts[v][2];
+
+			for (int k=0;k<m_vertexIndexMapping.size();k++)
+			{
+				if (tmpIndices[k]==v)
+					m_vertexIndexMapping[k]=ocount;
+			}
+
+			ocount++; // increment output vert count
+
+			btAssert( ocount >=0 && ocount <= vcount );
+
+			usedIndices[static_cast<int>(v)] = ocount; // assign new index remapping
+
+		
+		}
+	}
+
+	
+}
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btConvexHull.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btConvexHull.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btConvexHull.h	(revision 6952)
@@ -0,0 +1,241 @@
+
+/*
+Stan Melax Convex Hull Computation
+Copyright (c) 2008 Stan Melax http://www.melax.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.
+*/
+
+///includes modifications/improvements by John Ratcliff, see BringOutYourDead below.
+
+#ifndef CD_HULL_H
+#define CD_HULL_H
+
+#include "LinearMath/btVector3.h"
+#include "LinearMath/btAlignedObjectArray.h"
+
+typedef btAlignedObjectArray<unsigned int> TUIntArray;
+
+class HullResult
+{
+public:
+	HullResult(void)
+	{
+		mPolygons = true;
+		mNumOutputVertices = 0;
+		mNumFaces = 0;
+		mNumIndices = 0;
+	}
+	bool                    mPolygons;                  // true if indices represents polygons, false indices are triangles
+	unsigned int            mNumOutputVertices;         // number of vertices in the output hull
+	btAlignedObjectArray<btVector3>	m_OutputVertices;            // array of vertices
+	unsigned int            mNumFaces;                  // the number of faces produced
+	unsigned int            mNumIndices;                // the total number of indices
+	btAlignedObjectArray<unsigned int>    m_Indices;                   // pointer to indices.
+
+// If triangles, then indices are array indexes into the vertex list.
+// If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc..
+};
+
+enum HullFlag
+{
+	QF_TRIANGLES         = (1<<0),             // report results as triangles, not polygons.
+	QF_REVERSE_ORDER     = (1<<1),             // reverse order of the triangle indices.
+	QF_DEFAULT           = QF_TRIANGLES
+};
+
+
+class HullDesc
+{
+public:
+	HullDesc(void)
+	{
+		mFlags          = QF_DEFAULT;
+		mVcount         = 0;
+		mVertices       = 0;
+		mVertexStride   = sizeof(btVector3);
+		mNormalEpsilon  = 0.001f;
+		mMaxVertices	= 4096; // maximum number of points to be considered for a convex hull.
+		mMaxFaces	= 4096;
+	};
+
+	HullDesc(HullFlag flag,
+		 unsigned int vcount,
+		 const btVector3 *vertices,
+		 unsigned int stride = sizeof(btVector3))
+	{
+		mFlags          = flag;
+		mVcount         = vcount;
+		mVertices       = vertices;
+		mVertexStride   = stride;
+		mNormalEpsilon  = btScalar(0.001);
+		mMaxVertices    = 4096;
+	}
+
+	bool HasHullFlag(HullFlag flag) const
+	{
+		if ( mFlags & flag ) return true;
+		return false;
+	}
+
+	void SetHullFlag(HullFlag flag)
+	{
+		mFlags|=flag;
+	}
+
+	void ClearHullFlag(HullFlag flag)
+	{
+		mFlags&=~flag;
+	}
+
+	unsigned int      mFlags;           // flags to use when generating the convex hull.
+	unsigned int      mVcount;          // number of vertices in the input point cloud
+	const btVector3  *mVertices;        // the array of vertices.
+	unsigned int      mVertexStride;    // the stride of each vertex, in bytes.
+	btScalar             mNormalEpsilon;   // the epsilon for removing duplicates.  This is a normalized value, if normalized bit is on.
+	unsigned int      mMaxVertices;     // maximum number of vertices to be considered for the hull!
+	unsigned int      mMaxFaces;
+};
+
+enum HullError
+{
+	QE_OK,            // success!
+	QE_FAIL           // failed.
+};
+
+class btPlane
+{
+	public:
+	btVector3	normal;
+	btScalar	dist;   // distance below origin - the D from plane equasion Ax+By+Cz+D=0
+			btPlane(const btVector3 &n,btScalar d):normal(n),dist(d){}
+			btPlane():normal(),dist(0){}
+	
+};
+
+
+
+class ConvexH 
+{
+  public:
+	class HalfEdge
+	{
+	  public:
+		short ea;         // the other half of the edge (index into edges list)
+		unsigned char v;  // the vertex at the start of this edge (index into vertices list)
+		unsigned char p;  // the facet on which this edge lies (index into facets list)
+		HalfEdge(){}
+		HalfEdge(short _ea,unsigned char _v, unsigned char _p):ea(_ea),v(_v),p(_p){}
+	};
+	ConvexH()
+	{
+	}
+	~ConvexH()
+	{
+	}
+	btAlignedObjectArray<btVector3> vertices;
+	btAlignedObjectArray<HalfEdge> edges;
+	btAlignedObjectArray<btPlane>  facets;
+	ConvexH(int vertices_size,int edges_size,int facets_size);
+};
+
+
+class int4
+{
+public:
+	int x,y,z,w;
+	int4(){};
+	int4(int _x,int _y, int _z,int _w){x=_x;y=_y;z=_z;w=_w;}
+	const int& operator[](int i) const {return (&x)[i];}
+	int& operator[](int i) {return (&x)[i];}
+};
+
+class PHullResult
+{
+public:
+
+	PHullResult(void)
+	{
+		mVcount = 0;
+		mIndexCount = 0;
+		mFaceCount = 0;
+		mVertices = 0;
+	}
+
+	unsigned int mVcount;
+	unsigned int mIndexCount;
+	unsigned int mFaceCount;
+	btVector3*   mVertices;
+	TUIntArray m_Indices;
+};
+
+
+
+///The HullLibrary class can create a convex hull from a collection of vertices, using the ComputeHull method.
+///The btShapeHull class uses this HullLibrary to create a approximate convex mesh given a general (non-polyhedral) convex shape.
+class HullLibrary
+{
+
+	btAlignedObjectArray<class btHullTriangle*> m_tris;
+
+public:
+
+	btAlignedObjectArray<int> m_vertexIndexMapping;
+
+
+	HullError CreateConvexHull(const HullDesc& desc, // describes the input request
+				   HullResult&     result);        // contains the resulst
+	HullError ReleaseResult(HullResult &result); // release memory allocated for this result, we are done with it.
+
+private:
+
+	bool ComputeHull(unsigned int vcount,const btVector3 *vertices,PHullResult &result,unsigned int vlimit);
+
+	class btHullTriangle*	allocateTriangle(int a,int b,int c);
+	void	deAllocateTriangle(btHullTriangle*);
+	void b2bfix(btHullTriangle* s,btHullTriangle*t);
+
+	void removeb2b(btHullTriangle* s,btHullTriangle*t);
+
+	void checkit(btHullTriangle *t);
+
+	btHullTriangle* extrudable(btScalar epsilon);
+
+	int calchull(btVector3 *verts,int verts_count, TUIntArray& tris_out, int &tris_count,int vlimit);
+
+	int calchullgen(btVector3 *verts,int verts_count, int vlimit);
+
+	int4 FindSimplex(btVector3 *verts,int verts_count,btAlignedObjectArray<int> &allow);
+
+	class ConvexH* ConvexHCrop(ConvexH& convex,const btPlane& slice);
+
+	void extrude(class btHullTriangle* t0,int v);
+
+	ConvexH* test_cube();
+
+	//BringOutYourDead (John Ratcliff): When you create a convex hull you hand it a large input set of vertices forming a 'point cloud'. 
+	//After the hull is generated it give you back a set of polygon faces which index the *original* point cloud.
+	//The thing is, often times, there are many 'dead vertices' in the point cloud that are on longer referenced by the hull.
+	//The routine 'BringOutYourDead' find only the referenced vertices, copies them to an new buffer, and re-indexes the hull so that it is a minimal representation.
+	void BringOutYourDead(const btVector3* verts,unsigned int vcount, btVector3* overts,unsigned int &ocount,unsigned int* indices,unsigned indexcount);
+
+	bool CleanupVertices(unsigned int svcount,
+			     const btVector3* svertices,
+			     unsigned int stride,
+			     unsigned int &vcount, // output number of vertices
+			     btVector3* vertices, // location to store the results.
+			     btScalar  normalepsilon,
+			     btVector3& scale);
+};
+
+
+#endif
+
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btDefaultMotionState.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btDefaultMotionState.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btDefaultMotionState.h	(revision 6952)
@@ -0,0 +1,38 @@
+#ifndef DEFAULT_MOTION_STATE_H
+#define DEFAULT_MOTION_STATE_H
+
+///The btDefaultMotionState provides a common implementation to synchronize world transforms with offsets.
+struct	btDefaultMotionState : public btMotionState
+{
+	btTransform m_graphicsWorldTrans;
+	btTransform	m_centerOfMassOffset;
+	btTransform m_startWorldTrans;
+	void*		m_userPointer;
+
+	btDefaultMotionState(const btTransform& startTrans = btTransform::getIdentity(),const btTransform& centerOfMassOffset = btTransform::getIdentity())
+		: m_graphicsWorldTrans(startTrans),
+		m_centerOfMassOffset(centerOfMassOffset),
+		m_startWorldTrans(startTrans),
+		m_userPointer(0)
+
+	{
+	}
+
+	///synchronizes world transform from user to physics
+	virtual void	getWorldTransform(btTransform& centerOfMassWorldTrans ) const 
+	{
+			centerOfMassWorldTrans = 	m_centerOfMassOffset.inverse() * m_graphicsWorldTrans ;
+	}
+
+	///synchronizes world transform from physics to user
+	///Bullet only calls the update of worldtransform for active objects
+	virtual void	setWorldTransform(const btTransform& centerOfMassWorldTrans)
+	{
+			m_graphicsWorldTrans = centerOfMassWorldTrans * m_centerOfMassOffset ;
+	}
+
+	
+
+};
+
+#endif //DEFAULT_MOTION_STATE_H
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btGeometryUtil.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btGeometryUtil.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btGeometryUtil.cpp	(revision 6952)
@@ -0,0 +1,185 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / 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 "btGeometryUtil.h"
+
+
+/*
+  Make sure this dummy function never changes so that it
+  can be used by probes that are checking whether the
+  library is actually installed.
+*/
+extern "C"
+{	
+	void btBulletMathProbe ();
+
+	void btBulletMathProbe () {}
+}
+
+
+bool	btGeometryUtil::isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, btScalar	margin)
+{
+	int numbrushes = planeEquations.size();
+	for (int i=0;i<numbrushes;i++)
+	{
+		const btVector3& N1 = planeEquations[i];
+		btScalar dist = btScalar(N1.dot(point))+btScalar(N1[3])-margin;
+		if (dist>btScalar(0.))
+		{
+			return false;
+		}
+	}
+	return true;
+		
+}
+
+
+bool	btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, btScalar	margin)
+{
+	int numvertices = vertices.size();
+	for (int i=0;i<numvertices;i++)
+	{
+		const btVector3& N1 = vertices[i];
+		btScalar dist = btScalar(planeNormal.dot(N1))+btScalar(planeNormal[3])-margin;
+		if (dist>btScalar(0.))
+		{
+			return false;
+		}
+	}
+	return true;
+}
+
+bool notExist(const btVector3& planeEquation,const btAlignedObjectArray<btVector3>& planeEquations);
+
+bool notExist(const btVector3& planeEquation,const btAlignedObjectArray<btVector3>& planeEquations)
+{
+	int numbrushes = planeEquations.size();
+	for (int i=0;i<numbrushes;i++)
+	{
+		const btVector3& N1 = planeEquations[i];
+		if (planeEquation.dot(N1) > btScalar(0.999))
+		{
+			return false;
+		} 
+	}
+	return true;
+}
+
+void	btGeometryUtil::getPlaneEquationsFromVertices(btAlignedObjectArray<btVector3>& vertices, btAlignedObjectArray<btVector3>& planeEquationsOut )
+{
+		const int numvertices = vertices.size();
+	// brute force:
+	for (int i=0;i<numvertices;i++)
+	{
+		const btVector3& N1 = vertices[i];
+		
+
+		for (int j=i+1;j<numvertices;j++)
+		{
+			const btVector3& N2 = vertices[j];
+				
+			for (int k=j+1;k<numvertices;k++)
+			{
+
+				const btVector3& N3 = vertices[k];
+
+				btVector3 planeEquation,edge0,edge1;
+				edge0 = N2-N1;
+				edge1 = N3-N1;
+				btScalar normalSign = btScalar(1.);
+				for (int ww=0;ww<2;ww++)
+				{
+					planeEquation = normalSign * edge0.cross(edge1);
+					if (planeEquation.length2() > btScalar(0.0001))
+					{
+						planeEquation.normalize();
+						if (notExist(planeEquation,planeEquationsOut))
+						{
+							planeEquation[3] = -planeEquation.dot(N1);
+							
+								//check if inside, and replace supportingVertexOut if needed
+								if (areVerticesBehindPlane(planeEquation,vertices,btScalar(0.01)))
+								{
+									planeEquationsOut.push_back(planeEquation);
+								}
+						}
+					}
+					normalSign = btScalar(-1.);
+				}
+			
+			}
+		}
+	}
+
+}
+
+void	btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray<btVector3>& planeEquations , btAlignedObjectArray<btVector3>& verticesOut )
+{
+	const int numbrushes = planeEquations.size();
+	// brute force:
+	for (int i=0;i<numbrushes;i++)
+	{
+		const btVector3& N1 = planeEquations[i];
+		
+
+		for (int j=i+1;j<numbrushes;j++)
+		{
+			const btVector3& N2 = planeEquations[j];
+				
+			for (int k=j+1;k<numbrushes;k++)
+			{
+
+				const btVector3& N3 = planeEquations[k];
+
+				btVector3 n2n3; n2n3 = N2.cross(N3);
+				btVector3 n3n1; n3n1 = N3.cross(N1);
+				btVector3 n1n2; n1n2 = N1.cross(N2);
+				
+				if ( ( n2n3.length2() > btScalar(0.0001) ) &&
+					 ( n3n1.length2() > btScalar(0.0001) ) &&
+					 ( n1n2.length2() > btScalar(0.0001) ) )
+				{
+					//point P out of 3 plane equations:
+
+					//	d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 )  
+					//P =  -------------------------------------------------------------------------  
+					//   N1 . ( N2 * N3 )  
+
+
+					btScalar quotient = (N1.dot(n2n3));
+					if (btFabs(quotient) > btScalar(0.000001))
+					{
+						quotient = btScalar(-1.) / quotient;
+						n2n3 *= N1[3];
+						n3n1 *= N2[3];
+						n1n2 *= N3[3];
+						btVector3 potentialVertex = n2n3;
+						potentialVertex += n3n1;
+						potentialVertex += n1n2;
+						potentialVertex *= quotient;
+
+						//check if inside, and replace supportingVertexOut if needed
+						if (isPointInsidePlanes(planeEquations,potentialVertex,btScalar(0.01)))
+						{
+							verticesOut.push_back(potentialVertex);
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btGeometryUtil.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btGeometryUtil.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btGeometryUtil.h	(revision 6952)
@@ -0,0 +1,42 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#ifndef BT_GEOMETRY_UTIL_H
+#define BT_GEOMETRY_UTIL_H
+
+#include "btVector3.h"
+#include "btAlignedObjectArray.h"
+
+///The btGeometryUtil helper class provides a few methods to convert between plane equations and vertices.
+class btGeometryUtil
+{
+	public:
+	
+	
+		static void	getPlaneEquationsFromVertices(btAlignedObjectArray<btVector3>& vertices, btAlignedObjectArray<btVector3>& planeEquationsOut );
+
+		static void	getVerticesFromPlaneEquations(const btAlignedObjectArray<btVector3>& planeEquations , btAlignedObjectArray<btVector3>& verticesOut );
+	
+		static bool	isInside(const btAlignedObjectArray<btVector3>& vertices, const btVector3& planeNormal, btScalar	margin);
+		
+		static bool	isPointInsidePlanes(const btAlignedObjectArray<btVector3>& planeEquations, const btVector3& point, btScalar	margin);
+
+		static bool	areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray<btVector3>& vertices, btScalar	margin);
+
+};
+
+
+#endif //BT_GEOMETRY_UTIL_H
+
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btHashMap.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btHashMap.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btHashMap.h	(revision 6952)
@@ -0,0 +1,303 @@
+#ifndef BT_HASH_MAP_H
+#define BT_HASH_MAP_H
+
+#include "btAlignedObjectArray.h"
+
+const int BT_HASH_NULL=0xffffffff;
+
+template <class Value>
+class btHashKey
+{
+	int	m_uid;
+public:
+
+	btHashKey(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;
+	}
+
+	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.
+///A basic sample of how to use btHashMap is located in Demos\BasicDemo\main.cpp
+template <class Key, class Value>
+class btHashMap
+{
+
+	btAlignedObjectArray<int>		m_hashTable;
+	btAlignedObjectArray<int>		m_next;
+	btAlignedObjectArray<Value>		m_valueArray;
+
+
+
+	void	growTables(const Key& key)
+	{
+		int newCapacity = m_valueArray.capacity();
+
+		if (m_hashTable.size() < newCapacity)
+		{
+			//grow hashtable and next table
+			int curHashtableSize = m_hashTable.size();
+
+			m_hashTable.resize(newCapacity);
+			m_next.resize(newCapacity);
+
+			int i;
+
+			for (i= 0; i < newCapacity; ++i)
+			{
+				m_hashTable[i] = BT_HASH_NULL;
+			}
+			for (i = 0; i < newCapacity; ++i)
+			{
+				m_next[i] = BT_HASH_NULL;
+			}
+
+			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
+				m_next[i] = m_hashTable[hashValue];
+				m_hashTable[hashValue] = i;
+			}
+
+
+		}
+	}
+
+	public:
+
+	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))
+		{
+			return;
+		}
+		int count = m_valueArray.size();
+		int oldCapacity = m_valueArray.capacity();
+		m_valueArray.push_back(value);
+		int newCapacity = m_valueArray.capacity();
+		if (oldCapacity < newCapacity)
+		{
+			growTables(key);
+			//hash with new capacity
+			hash = key.getHash() & (m_valueArray.capacity()-1);
+		}
+		m_next[count] = m_hashTable[hash];
+		m_hashTable[hash] = count;
+	}
+
+	void remove(const Key& key) {
+
+		int hash = key.getHash() & (m_valueArray.capacity()-1);
+
+		int pairIndex = findIndex(key);
+		
+		if (pairIndex ==BT_HASH_NULL)
+		{
+			return;
+		}
+
+		// Remove the pair from the hash table.
+		int index = m_hashTable[hash];
+		btAssert(index != BT_HASH_NULL);
+
+		int previous = BT_HASH_NULL;
+		while (index != pairIndex)
+		{
+			previous = index;
+			index = m_next[index];
+		}
+
+		if (previous != BT_HASH_NULL)
+		{
+			btAssert(m_next[previous] == pairIndex);
+			m_next[previous] = m_next[pairIndex];
+		}
+		else
+		{
+			m_hashTable[hash] = m_next[pairIndex];
+		}
+
+		// We now move the last pair into spot of the
+		// pair being removed. We need to fix the hash
+		// table indices to support the move.
+
+		int lastPairIndex = m_valueArray.size() - 1;
+
+		// If the removed pair is the last pair, we are done.
+		if (lastPairIndex == pairIndex)
+		{
+			m_valueArray.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);
+
+		index = m_hashTable[lastHash];
+		btAssert(index != BT_HASH_NULL);
+
+		previous = BT_HASH_NULL;
+		while (index != lastPairIndex)
+		{
+			previous = index;
+			index = m_next[index];
+		}
+
+		if (previous != BT_HASH_NULL)
+		{
+			btAssert(m_next[previous] == lastPairIndex);
+			m_next[previous] = m_next[lastPairIndex];
+		}
+		else
+		{
+			m_hashTable[lastHash] = m_next[lastPairIndex];
+		}
+
+		// Copy the last pair into the remove pair's spot.
+		m_valueArray[pairIndex] = m_valueArray[lastPairIndex];
+
+		// Insert the last pair into the hash table
+		m_next[pairIndex] = m_hashTable[lastHash];
+		m_hashTable[lastHash] = pairIndex;
+
+		m_valueArray.pop_back();
+
+	}
+
+
+	int size() const
+	{
+		return m_valueArray.size();
+	}
+
+	const Value* getAtIndex(int index) const
+	{
+		btAssert(index < m_valueArray.size());
+
+		return &m_valueArray[index];
+	}
+
+	Value* getAtIndex(int index)
+	{
+		btAssert(index < m_valueArray.size());
+
+		return &m_valueArray[index];
+	}
+
+	Value* operator[](const Key& key) {
+		return find(key);
+	}
+
+	const Value*	find(const Key& key) const
+	{
+		int index = findIndex(key);
+		if (index == BT_HASH_NULL)
+		{
+			return NULL;
+		}
+		return &m_valueArray[index];
+	}
+
+	Value*	find(const Key& key)
+	{
+		int index = findIndex(key);
+		if (index == BT_HASH_NULL)
+		{
+			return NULL;
+		}
+		return &m_valueArray[index];
+	}
+
+
+	int	findIndex(const Key& key) const
+	{
+		int hash = key.getHash() & (m_valueArray.capacity()-1);
+
+		if (hash >= m_hashTable.size())
+		{
+			return BT_HASH_NULL;
+		}
+
+		int index = m_hashTable[hash];
+		while ((index != BT_HASH_NULL) && (key.getUid() == key.getKey(m_valueArray[index]).getUid()) == false)
+		{
+			index = m_next[index];
+		}
+		return index;
+	}
+
+	void	clear()
+	{
+		m_hashTable.clear();
+		m_next.clear();
+		m_valueArray.clear();
+	}
+
+};
+
+#endif //BT_HASH_MAP_H
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btIDebugDraw.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btIDebugDraw.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btIDebugDraw.h	(revision 6952)
@@ -0,0 +1,297 @@
+/*
+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.
+*/
+
+
+#ifndef IDEBUG_DRAW__H
+#define IDEBUG_DRAW__H
+
+#include "btVector3.h"
+#include "btTransform.h"
+
+
+///The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations.
+///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.
+class	btIDebugDraw
+{
+	public:
+
+	enum	DebugDrawModes
+	{
+		DBG_NoDebug=0,
+		DBG_DrawWireframe = 1,
+		DBG_DrawAabb=2,
+		DBG_DrawFeaturesText=4,
+		DBG_DrawContactPoints=8,
+		DBG_NoDeactivation=16,
+		DBG_NoHelpText = 32,
+		DBG_DrawText=64,
+		DBG_ProfileTimings = 128,
+		DBG_EnableSatComparison = 256,
+		DBG_DisableBulletLCP = 512,
+		DBG_EnableCCD = 1024,
+		DBG_DrawConstraints = (1 << 11),
+		DBG_DrawConstraintLimits = (1 << 12),
+		DBG_MAX_DEBUG_DRAW_MODE
+	};
+
+	virtual ~btIDebugDraw() {};
+
+	virtual void    drawLine(const btVector3& from,const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
+	{
+		drawLine (from, to, fromColor);
+	}
+
+	virtual void	drawBox (const btVector3& boxMin, const btVector3& boxMax, const btVector3& color, btScalar alpha)
+	{
+	}
+
+	virtual void	drawSphere (const btVector3& p, btScalar radius, const btVector3& color)
+	{
+	}
+
+	virtual void	drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0;
+	
+	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)
+	{
+		drawTriangle(v0,v1,v2,color,alpha);
+	}
+	virtual	void	drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& color, btScalar /*alpha*/)
+	{
+		drawLine(v0,v1,color);
+		drawLine(v1,v2,color);
+		drawLine(v2,v0,color);
+	}
+
+	virtual void	drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)=0;
+
+	virtual void	reportErrorWarning(const char* warningString) = 0;
+
+	virtual void	draw3dText(const btVector3& location,const char* textString) = 0;
+	
+	virtual void	setDebugMode(int debugMode) =0;
+	
+	virtual int		getDebugMode() const = 0;
+
+	inline void drawAabb(const btVector3& from,const btVector3& to,const btVector3& color)
+	{
+
+		btVector3 halfExtents = (to-from)* 0.5f;
+		btVector3 center = (to+from) *0.5f;
+		int i,j;
+
+		btVector3 edgecoord(1.f,1.f,1.f),pa,pb;
+		for (i=0;i<4;i++)
+		{
+			for (j=0;j<3;j++)
+			{
+				pa = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],		
+					edgecoord[2]*halfExtents[2]);
+				pa+=center;
+
+				int othercoord = j%3;
+				edgecoord[othercoord]*=-1.f;
+				pb = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1],	
+					edgecoord[2]*halfExtents[2]);
+				pb+=center;
+
+				drawLine(pa,pb,color);
+			}
+			edgecoord = btVector3(-1.f,-1.f,-1.f);
+			if (i<3)
+				edgecoord[i]*=-1.f;
+		}
+	}
+	void drawTransform(const btTransform& transform, btScalar orthoLen)
+	{
+		btVector3 start = transform.getOrigin();
+		drawLine(start, start+transform.getBasis() * btVector3(orthoLen, 0, 0), btVector3(0.7f,0,0));
+		drawLine(start, start+transform.getBasis() * btVector3(0, orthoLen, 0), btVector3(0,0.7f,0));
+		drawLine(start, start+transform.getBasis() * btVector3(0, 0, orthoLen), btVector3(0,0,0.7f));
+	}
+
+	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))
+	{
+		const btVector3& vx = axis;
+		btVector3 vy = normal.cross(axis);
+		btScalar step = stepDegrees * SIMD_RADS_PER_DEG;
+		int nSteps = (int)((maxAngle - minAngle) / step);
+		if(!nSteps) nSteps = 1;
+		btVector3 prev = center + radiusA * vx * btCos(minAngle) + radiusB * vy * btSin(minAngle);
+		if(drawSect)
+		{
+			drawLine(center, prev, color);
+		}
+		for(int i = 1; i <= nSteps; i++)
+		{
+			btScalar angle = minAngle + (maxAngle - minAngle) * btScalar(i) / btScalar(nSteps);
+			btVector3 next = center + radiusA * vx * btCos(angle) + radiusB * vy * btSin(angle);
+			drawLine(prev, next, color);
+			prev = next;
+		}
+		if(drawSect)
+		{
+			drawLine(center, prev, color);
+		}
+	}
+	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))
+	{
+		btVector3 vA[74];
+		btVector3 vB[74];
+		btVector3 *pvA = vA, *pvB = vB, *pT;
+		btVector3 npole = center + up * radius;
+		btVector3 spole = center - up * radius;
+		btVector3 arcStart;
+		btScalar step = stepDegrees * SIMD_RADS_PER_DEG;
+		const btVector3& kv = up;
+		const btVector3& iv = axis;
+		btVector3 jv = kv.cross(iv);
+		bool drawN = false;
+		bool drawS = false;
+		if(minTh <= -SIMD_HALF_PI)
+		{
+			minTh = -SIMD_HALF_PI + step;
+			drawN = true;
+		}
+		if(maxTh >= SIMD_HALF_PI)
+		{
+			maxTh = SIMD_HALF_PI - step;
+			drawS = true;
+		}
+		if(minTh > maxTh)
+		{
+			minTh = -SIMD_HALF_PI + step;
+			maxTh =  SIMD_HALF_PI - step;
+			drawN = drawS = true;
+		}
+		int n_hor = (int)((maxTh - minTh) / step) + 1;
+		if(n_hor < 2) n_hor = 2;
+		btScalar step_h = (maxTh - minTh) / btScalar(n_hor - 1);
+		bool isClosed = false;
+		if(minPs > maxPs)
+		{
+			minPs = -SIMD_PI + step;
+			maxPs =  SIMD_PI;
+			isClosed = true;
+		}
+		else if((maxPs - minPs) >= SIMD_PI * btScalar(2.f))
+		{
+			isClosed = true;
+		}
+		else
+		{
+			isClosed = false;
+		}
+		int n_vert = (int)((maxPs - minPs) / step) + 1;
+		if(n_vert < 2) n_vert = 2;
+		btScalar step_v = (maxPs - minPs) / btScalar(n_vert - 1);
+		for(int i = 0; i < n_hor; i++)
+		{
+			btScalar th = minTh + btScalar(i) * step_h;
+			btScalar sth = radius * btSin(th);
+			btScalar cth = radius * btCos(th);
+			for(int j = 0; j < n_vert; j++)
+			{
+				btScalar psi = minPs + btScalar(j) * step_v;
+				btScalar sps = btSin(psi);
+				btScalar cps = btCos(psi);
+				pvB[j] = center + cth * cps * iv + cth * sps * jv + sth * kv;
+				if(i)
+				{
+					drawLine(pvA[j], pvB[j], color);
+				}
+				else if(drawS)
+				{
+					drawLine(spole, pvB[j], color);
+				}
+				if(j)
+				{
+					drawLine(pvB[j-1], pvB[j], color);
+				}
+				else
+				{
+					arcStart = pvB[j];
+				}
+				if((i == (n_hor - 1)) && drawN)
+				{
+					drawLine(npole, pvB[j], color);
+				}
+				if(isClosed)
+				{
+					if(j == (n_vert-1))
+					{
+						drawLine(arcStart, pvB[j], color);
+					}
+				}
+				else
+				{
+					if(((!i) || (i == (n_hor-1))) && ((!j) || (j == (n_vert-1))))
+					{
+						drawLine(center, pvB[j], color);
+					}
+				}
+			}
+			pT = pvA; pvA = pvB; pvB = pT;
+		}
+	}
+	
+	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);
+		drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMin[2]), color);
+		drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMin[2]), color);
+		drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMin[2]), color);
+		drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
+		drawLine(btVector3(bbMax[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
+		drawLine(btVector3(bbMax[0], bbMax[1], bbMin[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
+		drawLine(btVector3(bbMin[0], bbMax[1], bbMin[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
+		drawLine(btVector3(bbMin[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
+		drawLine(btVector3(bbMax[0], bbMin[1], bbMax[2]), btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
+		drawLine(btVector3(bbMax[0], bbMax[1], bbMax[2]), btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
+		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)
+	{
+		drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), color);
+		drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), color);
+		drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), color);
+		drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), color);
+		drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMin[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
+		drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMin[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
+		drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMin[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
+		drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMin[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
+		drawLine(trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), color);
+		drawLine(trans * btVector3(bbMax[0], bbMin[1], bbMax[2]), trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), color);
+		drawLine(trans * btVector3(bbMax[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), color);
+		drawLine(trans * btVector3(bbMin[0], bbMax[1], bbMax[2]), trans * btVector3(bbMin[0], bbMin[1], bbMax[2]), color);
+	}
+};
+
+
+#endif //IDEBUG_DRAW__H
+
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btList.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btList.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btList.h	(revision 6952)
@@ -0,0 +1,73 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / 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 GEN_LIST_H
+#define GEN_LIST_H
+
+class btGEN_Link {
+public:
+    btGEN_Link() : m_next(0), m_prev(0) {}
+    btGEN_Link(btGEN_Link *next, btGEN_Link *prev) : m_next(next), m_prev(prev) {}
+    
+    btGEN_Link *getNext() const { return m_next; }  
+    btGEN_Link *getPrev() const { return m_prev; }  
+
+    bool isHead() const { return m_prev == 0; }
+    bool isTail() const { return m_next == 0; }
+
+    void insertBefore(btGEN_Link *link) {
+        m_next         = link;
+        m_prev         = link->m_prev;
+        m_next->m_prev = this;
+        m_prev->m_next = this;
+    } 
+
+    void insertAfter(btGEN_Link *link) {
+        m_next         = link->m_next;
+        m_prev         = link;
+        m_next->m_prev = this;
+        m_prev->m_next = this;
+    } 
+
+    void remove() { 
+        m_next->m_prev = m_prev; 
+        m_prev->m_next = m_next;
+    }
+
+private:  
+    btGEN_Link  *m_next;
+    btGEN_Link  *m_prev;
+};
+
+class btGEN_List {
+public:
+    btGEN_List() : m_head(&m_tail, 0), m_tail(0, &m_head) {}
+
+    btGEN_Link *getHead() const { return m_head.getNext(); } 
+    btGEN_Link *getTail() const { return m_tail.getPrev(); } 
+
+    void addHead(btGEN_Link *link) { link->insertAfter(&m_head); }
+    void addTail(btGEN_Link *link) { link->insertBefore(&m_tail); }
+    
+private:
+    btGEN_Link m_head;
+    btGEN_Link m_tail;
+};
+
+#endif
+
+
+
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btMatrix3x3.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btMatrix3x3.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btMatrix3x3.h	(revision 6952)
@@ -0,0 +1,618 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / 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 btMatrix3x3_H
+#define btMatrix3x3_H
+
+#include "btScalar.h"
+
+#include "btVector3.h"
+#include "btQuaternion.h"
+
+
+
+/**@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. */
+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 */
+	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);
+		}
+
+	/** @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
+	 **/
+	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
+		btScalar ci ( btCos(eulerX)); 
+		btScalar cj ( btCos(eulerY)); 
+		btScalar ch ( btCos(eulerZ)); 
+		btScalar si ( btSin(eulerX)); 
+		btScalar sj ( btSin(eulerY)); 
+		btScalar sh ( btSin(eulerZ)); 
+		btScalar cc = ci * ch; 
+		btScalar cs = ci * sh; 
+		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()
+		{ 
+			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, 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;
+			int q = 1;
+			int r = 2;
+			btScalar max = btFabs(m_el[0][1]);
+			btScalar v = btFabs(m_el[0][2]);
+			if (v > max)
+			{
+			   q = 2;
+			   r = 1;
+			   max = v;
+			}
+			v = btFabs(m_el[1][2]);
+			if (v > max)
+			{
+			   p = 1;
+			   q = 2;
+			   r = 0;
+			   max = v;
+			}
+
+			btScalar t = threshold * (btFabs(m_el[0][0]) + btFabs(m_el[1][1]) + btFabs(m_el[2][2]));
+			if (max <= t)
+			{
+			   if (max <= SIMD_EPSILON * t)
+			   {
+				  return;
+			   }
+			   step = 1;
+			}
+
+			// compute Jacobi rotation J which leads to a zero for element [p][q] 
+			btScalar mpq = m_el[p][q];
+			btScalar theta = (m_el[q][q] - m_el[p][p]) / (2 * mpq);
+			btScalar theta2 = theta * theta;
+			btScalar cos;
+			btScalar sin;
+			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;
+			}
+			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;
+			}
+
+			// apply rotation to matrix (this = J^T * this * J)
+			m_el[p][q] = m_el[q][p] = 0;
+			m_el[p][p] -= t * mpq;
+			m_el[q][q] += t * mpq;
+			btScalar mrp = m_el[r][p];
+			btScalar mrq = m_el[r][q];
+			m_el[r][p] = m_el[p][r] = cos * mrp - sin * mrq;
+			m_el[r][q] = m_el[q][r] = cos * mrq + sin * mrp;
+
+			// apply rotation to rot (rot = rot * J)
+			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;
+			}
+		 }
+		}
+
+
+		
+	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];
+	};
+	
+	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
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btMinMax.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btMinMax.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btMinMax.h	(revision 6952)
@@ -0,0 +1,69 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / 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 GEN_MINMAX_H
+#define GEN_MINMAX_H
+
+template <class T>
+SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b) 
+{
+  return a < b ? a : b ;
+}
+
+template <class T>
+SIMD_FORCE_INLINE const T& btMax(const T& a, const T& b) 
+{
+  return  a > b ? a : b;
+}
+
+template <class T>
+SIMD_FORCE_INLINE const T& GEN_clamped(const T& a, const T& lb, const T& ub) 
+{
+	return a < lb ? lb : (ub < a ? ub : a); 
+}
+
+template <class T>
+SIMD_FORCE_INLINE void btSetMin(T& a, const T& b) 
+{
+    if (b < a) 
+	{
+		a = b;
+	}
+}
+
+template <class T>
+SIMD_FORCE_INLINE void btSetMax(T& a, const T& b) 
+{
+    if (a < b) 
+	{
+		a = b;
+	}
+}
+
+template <class T>
+SIMD_FORCE_INLINE void GEN_clamp(T& a, const T& lb, const T& ub) 
+{
+	if (a < lb) 
+	{
+		a = lb; 
+	}
+	else if (ub < a) 
+	{
+		a = ub;
+	}
+}
+
+#endif
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btMotionState.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btMotionState.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btMotionState.h	(revision 6952)
@@ -0,0 +1,40 @@
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef BT_MOTIONSTATE_H
+#define BT_MOTIONSTATE_H
+
+#include "btTransform.h"
+
+///The btMotionState interface class allows the dynamics world to synchronize and interpolate the updated world transforms with graphics
+///For optimizations, potentially only moving objects get synchronized (using setWorldPosition/setWorldOrientation)
+class	btMotionState
+{
+	public:
+		
+		virtual ~btMotionState()
+		{
+			
+		}
+		
+		virtual void	getWorldTransform(btTransform& worldTrans ) const =0;
+
+		//Bullet only calls the update of worldtransform for active objects
+		virtual void	setWorldTransform(const btTransform& worldTrans)=0;
+		
+	
+};
+
+#endif //BT_MOTIONSTATE_H
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btPoolAllocator.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btPoolAllocator.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btPoolAllocator.h	(revision 6952)
@@ -0,0 +1,102 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans  http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose, 
+including commercial applications, and to alter it and redistribute it freely, 
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+
+#ifndef _BT_POOL_ALLOCATOR_H
+#define _BT_POOL_ALLOCATOR_H
+
+#include "btScalar.h"
+#include "btAlignedAllocator.h"
+
+///The btPoolAllocator class allows to efficiently allocate a large pool of objects, instead of dynamically allocating them separately.
+class btPoolAllocator
+{
+	int				m_elemSize;
+	int				m_maxElements;
+	int				m_freeCount;
+	void*			m_firstFree;
+	unsigned char*	m_pool;
+
+public:
+
+	btPoolAllocator(int elemSize, int maxElements)
+		:m_elemSize(elemSize),
+		m_maxElements(maxElements)
+	{
+		m_pool = (unsigned char*) btAlignedAlloc( static_cast<unsigned int>(m_elemSize*m_maxElements),16);
+
+		unsigned char* p = m_pool;
+        m_firstFree = p;
+        m_freeCount = m_maxElements;
+        int count = m_maxElements;
+        while (--count) {
+            *(void**)p = (p + m_elemSize);
+            p += m_elemSize;
+        }
+        *(void**)p = 0;
+    }
+
+	~btPoolAllocator()
+	{
+		btAlignedFree( m_pool);
+	}
+
+	int	getFreeCount() const
+	{
+		return m_freeCount;
+	}
+
+	void*	allocate(int size)
+	{
+		// release mode fix
+		(void)size;
+		btAssert(!size || size<=m_elemSize);
+		btAssert(m_freeCount>0);
+        void* result = m_firstFree;
+        m_firstFree = *(void**)m_firstFree;
+        --m_freeCount;
+        return result;
+	}
+
+	bool validPtr(void* ptr)
+	{
+		if (ptr) {
+			if (((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize))
+			{
+				return true;
+			}
+		}
+		return false;
+	}
+
+	void	freeMemory(void* ptr)
+	{
+		 if (ptr) {
+            btAssert((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize);
+
+            *(void**)ptr = m_firstFree;
+            m_firstFree = ptr;
+            ++m_freeCount;
+        }
+	}
+
+	int	getElementSize() const
+	{
+		return m_elemSize;
+	}
+
+
+};
+
+#endif //_BT_POOL_ALLOCATOR_H
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btQuadWord.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btQuadWord.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btQuadWord.h	(revision 6952)
@@ -0,0 +1,180 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD_QUADWORD_H
+#define SIMD_QUADWORD_H
+
+#include "btScalar.h"
+#include "btMinMax.h"
+
+
+#if defined (__CELLOS_LV2) && defined (__SPU__)
+#include <altivec.h>
+#endif
+
+/**@brief The btQuadWord class is base class for btVector3 and btQuaternion. 
+ * Some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword.
+ */
+#ifndef USE_LIBSPE2
+ATTRIBUTE_ALIGNED16(class) btQuadWord
+#else
+class btQuadWord
+#endif
+{
+protected:
+
+#if defined (__SPU__) && defined (__CELLOS_LV2__)
+	union {
+		vec_float4 mVec128;
+		btScalar	m_floats[4];
+	};
+public:
+	vec_float4	get128() const
+	{
+		return mVec128;
+	}
+protected:
+#else //__CELLOS_LV2__ __SPU__
+	btScalar	m_floats[4];
+#endif //__CELLOS_LV2__ __SPU__
+
+	public:
+  
+
+  /**@brief Return the x value */
+		SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; }
+  /**@brief Return the y value */
+		SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; }
+  /**@brief Return the z value */
+		SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; }
+  /**@brief Set the x value */
+		SIMD_FORCE_INLINE void	setX(btScalar x) { m_floats[0] = x;};
+  /**@brief Set the y value */
+		SIMD_FORCE_INLINE void	setY(btScalar y) { m_floats[1] = y;};
+  /**@brief Set the z value */
+		SIMD_FORCE_INLINE void	setZ(btScalar z) { m_floats[2] = z;};
+  /**@brief Set the w value */
+		SIMD_FORCE_INLINE void	setW(btScalar w) { m_floats[3] = w;};
+  /**@brief Return the x value */
+		SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; }
+  /**@brief Return the y value */
+		SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; }
+  /**@brief Return the z value */
+		SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; }
+  /**@brief Return the w value */
+		SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; }
+
+	//SIMD_FORCE_INLINE btScalar&       operator[](int i)       { return (&m_floats[0])[i];	}      
+	//SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; }
+	///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons.
+	SIMD_FORCE_INLINE	operator       btScalar *()       { return &m_floats[0]; }
+	SIMD_FORCE_INLINE	operator const btScalar *() const { return &m_floats[0]; }
+
+	SIMD_FORCE_INLINE	bool	operator==(const btQuadWord& other) const
+	{
+		return ((m_floats[3]==other.m_floats[3]) && (m_floats[2]==other.m_floats[2]) && (m_floats[1]==other.m_floats[1]) && (m_floats[0]==other.m_floats[0]));
+	}
+
+	SIMD_FORCE_INLINE	bool	operator!=(const btQuadWord& other) const
+	{
+		return !(*this == other);
+	}
+
+  /**@brief Set x,y,z and zero w 
+   * @param x Value of x
+   * @param y Value of y
+   * @param z Value of z
+   */
+		SIMD_FORCE_INLINE void 	setValue(const btScalar& x, const btScalar& y, const btScalar& z)
+		{
+			m_floats[0]=x;
+			m_floats[1]=y;
+			m_floats[2]=z;
+			m_floats[3] = 0.f;
+		}
+
+/*		void getValue(btScalar *m) const 
+		{
+			m[0] = m_floats[0];
+			m[1] = m_floats[1];
+			m[2] = m_floats[2];
+		}
+*/
+/**@brief Set the values 
+   * @param x Value of x
+   * @param y Value of y
+   * @param z Value of z
+   * @param w Value of w
+   */
+		SIMD_FORCE_INLINE void	setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
+		{
+			m_floats[0]=x;
+			m_floats[1]=y;
+			m_floats[2]=z;
+			m_floats[3]=w;
+		}
+  /**@brief No initialization constructor */
+		SIMD_FORCE_INLINE btQuadWord()
+		//	:m_floats[0](btScalar(0.)),m_floats[1](btScalar(0.)),m_floats[2](btScalar(0.)),m_floats[3](btScalar(0.))
+		{
+		}
+ 
+  /**@brief Three argument constructor (zeros w)
+   * @param x Value of x
+   * @param y Value of y
+   * @param z Value of z
+   */
+		SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z)		
+		{
+			m_floats[0] = x, m_floats[1] = y, m_floats[2] = z, m_floats[3] = 0.0f;
+		}
+
+/**@brief Initializing constructor
+   * @param x Value of x
+   * @param y Value of y
+   * @param z Value of z
+   * @param w Value of w
+   */
+		SIMD_FORCE_INLINE btQuadWord(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) 
+		{
+			m_floats[0] = x, m_floats[1] = y, m_floats[2] = z, m_floats[3] = w;
+		}
+
+  /**@brief Set each element to the max of the current values and the values of another btQuadWord
+   * @param other The other btQuadWord to compare with 
+   */
+		SIMD_FORCE_INLINE void	setMax(const btQuadWord& other)
+		{
+			btSetMax(m_floats[0], other.m_floats[0]);
+			btSetMax(m_floats[1], other.m_floats[1]);
+			btSetMax(m_floats[2], other.m_floats[2]);
+			btSetMax(m_floats[3], other.m_floats[3]);
+		}
+  /**@brief Set each element to the min of the current values and the values of another btQuadWord
+   * @param other The other btQuadWord to compare with 
+   */
+		SIMD_FORCE_INLINE void	setMin(const btQuadWord& other)
+		{
+			btSetMin(m_floats[0], other.m_floats[0]);
+			btSetMin(m_floats[1], other.m_floats[1]);
+			btSetMin(m_floats[2], other.m_floats[2]);
+			btSetMin(m_floats[3], other.m_floats[3]);
+		}
+
+
+
+};
+
+#endif //SIMD_QUADWORD_H
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btQuaternion.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btQuaternion.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btQuaternion.h	(revision 6952)
@@ -0,0 +1,401 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD__QUATERNION_H_
+#define SIMD__QUATERNION_H_
+
+
+#include "btVector3.h"
+#include "btQuadWord.h"
+
+/**@brief The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform. */
+class btQuaternion : public btQuadWord {
+public:
+  /**@brief No initialization constructor */
+	btQuaternion() {}
+
+	//		template <typename btScalar>
+	//		explicit Quaternion(const btScalar *v) : Tuple4<btScalar>(v) {}
+  /**@brief Constructor from scalars */
+	btQuaternion(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w) 
+		: btQuadWord(x, y, z, w) 
+	{}
+  /**@brief Axis angle Constructor
+   * @param axis The axis which the rotation is around
+   * @param angle The magnitude of the rotation around the angle (Radians) */
+	btQuaternion(const btVector3& axis, const btScalar& angle) 
+	{ 
+		setRotation(axis, angle); 
+	}
+  /**@brief Constructor from Euler angles
+   * @param yaw Angle around Y unless BT_EULER_DEFAULT_ZYX defined then Z
+   * @param pitch Angle around X unless BT_EULER_DEFAULT_ZYX defined then Y
+   * @param roll Angle around Z unless BT_EULER_DEFAULT_ZYX defined then X */
+	btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
+	{ 
+#ifndef BT_EULER_DEFAULT_ZYX
+		setEuler(yaw, pitch, roll); 
+#else
+		setEulerZYX(yaw, pitch, roll); 
+#endif 
+	}
+  /**@brief Set the rotation using axis angle notation 
+   * @param axis The axis around which to rotate
+   * @param angle The magnitude of the rotation in Radians */
+	void setRotation(const btVector3& axis, const btScalar& angle)
+	{
+		btScalar d = axis.length();
+		btAssert(d != btScalar(0.0));
+		btScalar s = btSin(angle * btScalar(0.5)) / d;
+		setValue(axis.x() * s, axis.y() * s, axis.z() * s, 
+			btCos(angle * btScalar(0.5)));
+	}
+  /**@brief Set the quaternion using Euler angles
+   * @param yaw Angle around Y
+   * @param pitch Angle around X
+   * @param roll Angle around Z */
+	void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
+	{
+		btScalar halfYaw = btScalar(yaw) * btScalar(0.5);  
+		btScalar halfPitch = btScalar(pitch) * btScalar(0.5);  
+		btScalar halfRoll = btScalar(roll) * btScalar(0.5);  
+		btScalar cosYaw = btCos(halfYaw);
+		btScalar sinYaw = btSin(halfYaw);
+		btScalar cosPitch = btCos(halfPitch);
+		btScalar sinPitch = btSin(halfPitch);
+		btScalar cosRoll = btCos(halfRoll);
+		btScalar sinRoll = btSin(halfRoll);
+		setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw,
+			cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw,
+			sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw,
+			cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw);
+	}
+  /**@brief Set the quaternion using euler angles 
+   * @param yaw Angle around Z
+   * @param pitch Angle around Y
+   * @param roll Angle around X */
+	void setEulerZYX(const btScalar& yaw, const btScalar& pitch, const btScalar& roll)
+	{
+		btScalar halfYaw = btScalar(yaw) * btScalar(0.5);  
+		btScalar halfPitch = btScalar(pitch) * btScalar(0.5);  
+		btScalar halfRoll = btScalar(roll) * btScalar(0.5);  
+		btScalar cosYaw = btCos(halfYaw);
+		btScalar sinYaw = btSin(halfYaw);
+		btScalar cosPitch = btCos(halfPitch);
+		btScalar sinPitch = btSin(halfPitch);
+		btScalar cosRoll = btCos(halfRoll);
+		btScalar sinRoll = btSin(halfRoll);
+		setValue(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, //x
+                         cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, //y
+                         cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, //z
+                         cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); //formerly yzx
+	}
+  /**@brief Add two quaternions
+   * @param q The quaternion to add to this one */
+	SIMD_FORCE_INLINE	btQuaternion& operator+=(const btQuaternion& q)
+	{
+		m_floats[0] += q.x(); m_floats[1] += q.y(); m_floats[2] += q.z(); m_floats[3] += q.m_floats[3];
+		return *this;
+	}
+
+  /**@brief Subtract out a quaternion
+   * @param q The quaternion to subtract from this one */
+	btQuaternion& operator-=(const btQuaternion& q) 
+	{
+		m_floats[0] -= q.x(); m_floats[1] -= q.y(); m_floats[2] -= q.z(); m_floats[3] -= q.m_floats[3];
+		return *this;
+	}
+
+  /**@brief Scale this quaternion
+   * @param s The scalar to scale by */
+	btQuaternion& operator*=(const btScalar& s)
+	{
+		m_floats[0] *= s; m_floats[1] *= s; m_floats[2] *= s; m_floats[3] *= s;
+		return *this;
+	}
+
+  /**@brief Multiply this quaternion by q on the right
+   * @param q The other quaternion 
+   * Equivilant to this = this * q */
+	btQuaternion& operator*=(const btQuaternion& q)
+	{
+		setValue(m_floats[3] * q.x() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.z() - m_floats[2] * q.y(),
+			m_floats[3] * q.y() + m_floats[1] * q.m_floats[3] + m_floats[2] * q.x() - m_floats[0] * q.z(),
+			m_floats[3] * q.z() + m_floats[2] * q.m_floats[3] + m_floats[0] * q.y() - m_floats[1] * q.x(),
+			m_floats[3] * q.m_floats[3] - m_floats[0] * q.x() - m_floats[1] * q.y() - m_floats[2] * q.z());
+		return *this;
+	}
+  /**@brief Return the dot product between this quaternion and another
+   * @param q The other quaternion */
+	btScalar dot(const btQuaternion& q) const
+	{
+		return m_floats[0] * q.x() + m_floats[1] * q.y() + m_floats[2] * q.z() + m_floats[3] * q.m_floats[3];
+	}
+
+  /**@brief Return the length squared of the quaternion */
+	btScalar length2() const
+	{
+		return dot(*this);
+	}
+
+  /**@brief Return the length of the quaternion */
+	btScalar length() const
+	{
+		return btSqrt(length2());
+	}
+
+  /**@brief Normalize the quaternion 
+   * Such that x^2 + y^2 + z^2 +w^2 = 1 */
+	btQuaternion& normalize() 
+	{
+		return *this /= length();
+	}
+
+  /**@brief Return a scaled version of this quaternion
+   * @param s The scale factor */
+	SIMD_FORCE_INLINE btQuaternion
+	operator*(const btScalar& s) const
+	{
+		return btQuaternion(x() * s, y() * s, z() * s, m_floats[3] * s);
+	}
+
+
+  /**@brief Return an inversely scaled versionof this quaternion
+   * @param s The inverse scale factor */
+	btQuaternion operator/(const btScalar& s) const
+	{
+		btAssert(s != btScalar(0.0));
+		return *this * (btScalar(1.0) / s);
+	}
+
+  /**@brief Inversely scale this quaternion
+   * @param s The scale factor */
+	btQuaternion& operator/=(const btScalar& s) 
+	{
+		btAssert(s != btScalar(0.0));
+		return *this *= btScalar(1.0) / s;
+	}
+
+  /**@brief Return a normalized version of this quaternion */
+	btQuaternion normalized() const 
+	{
+		return *this / length();
+	} 
+  /**@brief Return the angle between this quaternion and the other 
+   * @param q The other quaternion */
+	btScalar angle(const btQuaternion& q) const 
+	{
+		btScalar s = btSqrt(length2() * q.length2());
+		btAssert(s != btScalar(0.0));
+		return btAcos(dot(q) / s);
+	}
+  /**@brief Return the angle of rotation represented by this quaternion */
+	btScalar getAngle() const 
+	{
+		btScalar s = btScalar(2.) * btAcos(m_floats[3]);
+		return s;
+	}
+
+
+  /**@brief Return the inverse of this quaternion */
+	btQuaternion inverse() const
+	{
+		return btQuaternion(-m_floats[0], -m_floats[1], -m_floats[2], m_floats[3]);
+	}
+
+  /**@brief Return the sum of this quaternion and the other 
+   * @param q2 The other quaternion */
+	SIMD_FORCE_INLINE btQuaternion
+	operator+(const btQuaternion& q2) const
+	{
+		const btQuaternion& q1 = *this;
+		return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_floats[3] + q2.m_floats[3]);
+	}
+
+  /**@brief Return the difference between this quaternion and the other 
+   * @param q2 The other quaternion */
+	SIMD_FORCE_INLINE btQuaternion
+	operator-(const btQuaternion& q2) const
+	{
+		const btQuaternion& q1 = *this;
+		return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_floats[3] - q2.m_floats[3]);
+	}
+
+  /**@brief Return the negative of this quaternion 
+   * This simply negates each element */
+	SIMD_FORCE_INLINE btQuaternion operator-() const
+	{
+		const btQuaternion& q2 = *this;
+		return btQuaternion( - q2.x(), - q2.y(),  - q2.z(),  - q2.m_floats[3]);
+	}
+  /**@todo document this and it's use */
+	SIMD_FORCE_INLINE btQuaternion farthest( 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 
+   * @param t The ratio between this and q to interpolate.  If t = 0 the result is this, if t=1 the result is q.
+   * Slerp interpolates assuming constant velocity.  */
+	btQuaternion slerp(const btQuaternion& q, const btScalar& t) const
+	{
+		btScalar theta = angle(q);
+		if (theta != btScalar(0.0))
+		{
+			btScalar d = btScalar(1.0) / btSin(theta);
+			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);
+		}
+		else
+		{
+			return *this;
+		}
+	}
+
+	static const btQuaternion&	getIdentity()
+	{
+		static const btQuaternion identityQuat(btScalar(0.),btScalar(0.),btScalar(0.),btScalar(1.));
+		return identityQuat;
+	}
+
+	SIMD_FORCE_INLINE const btScalar& getW() const { return m_floats[3]; }
+
+	
+};
+
+
+/**@brief Return the negative of a quaternion */
+SIMD_FORCE_INLINE btQuaternion
+operator-(const btQuaternion& q)
+{
+	return btQuaternion(-q.x(), -q.y(), -q.z(), -q.w());
+}
+
+
+
+/**@brief Return the product of two quaternions */
+SIMD_FORCE_INLINE btQuaternion
+operator*(const btQuaternion& q1, const btQuaternion& q2) {
+	return btQuaternion(q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(),
+		q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(),
+		q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(),
+		q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z()); 
+}
+
+SIMD_FORCE_INLINE btQuaternion
+operator*(const btQuaternion& q, const btVector3& w)
+{
+	return btQuaternion( q.w() * w.x() + q.y() * w.z() - q.z() * w.y(),
+		q.w() * w.y() + q.z() * w.x() - q.x() * w.z(),
+		q.w() * w.z() + q.x() * w.y() - q.y() * w.x(),
+		-q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); 
+}
+
+SIMD_FORCE_INLINE btQuaternion
+operator*(const btVector3& w, const btQuaternion& q)
+{
+	return btQuaternion( w.x() * q.w() + w.y() * q.z() - w.z() * q.y(),
+		w.y() * q.w() + w.z() * q.x() - w.x() * q.z(),
+		w.z() * q.w() + w.x() * q.y() - w.y() * q.x(),
+		-w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); 
+}
+
+/**@brief Calculate the dot product between two quaternions */
+SIMD_FORCE_INLINE btScalar 
+dot(const btQuaternion& q1, const btQuaternion& q2) 
+{ 
+	return q1.dot(q2); 
+}
+
+
+/**@brief Return the length of a quaternion */
+SIMD_FORCE_INLINE btScalar
+length(const btQuaternion& q) 
+{ 
+	return q.length(); 
+}
+
+/**@brief Return the angle between two quaternions*/
+SIMD_FORCE_INLINE btScalar
+angle(const btQuaternion& q1, const btQuaternion& q2) 
+{ 
+	return q1.angle(q2); 
+}
+
+/**@brief Return the inverse of a quaternion*/
+SIMD_FORCE_INLINE btQuaternion
+inverse(const btQuaternion& q) 
+{
+	return q.inverse();
+}
+
+/**@brief Return the result of spherical linear interpolation betwen two quaternions 
+ * @param q1 The first quaternion
+ * @param q2 The second quaternion 
+ * @param t The ration between q1 and q2.  t = 0 return q1, t=1 returns q2 
+ * Slerp assumes constant velocity between positions. */
+SIMD_FORCE_INLINE btQuaternion
+slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t) 
+{
+	return q1.slerp(q2, t);
+}
+
+SIMD_FORCE_INLINE btVector3 
+quatRotate(const btQuaternion& rotation, const btVector3& v) 
+{
+	btQuaternion q = rotation * v;
+	q *= rotation.inverse();
+	return btVector3(q.getX(),q.getY(),q.getZ());
+}
+
+SIMD_FORCE_INLINE btQuaternion 
+shortestArcQuat(const btVector3& v0, const btVector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized
+{
+	btVector3 c = v0.cross(v1);
+	btScalar  d = v0.dot(v1);
+
+	if (d < -1.0 + SIMD_EPSILON)
+		return btQuaternion(0.0f,1.0f,0.0f,0.0f); // just pick any vector
+
+	btScalar  s = btSqrt((1.0f + d) * 2.0f);
+	btScalar rs = 1.0f / s;
+
+	return btQuaternion(c.getX()*rs,c.getY()*rs,c.getZ()*rs,s * 0.5f);
+}
+
+SIMD_FORCE_INLINE btQuaternion 
+shortestArcQuatNormalize2(btVector3& v0,btVector3& v1)
+{
+	v0.normalize();
+	v1.normalize();
+	return shortestArcQuat(v0,v1);
+}
+
+#endif
+
+
+
+
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btQuickprof.cpp
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btQuickprof.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btQuickprof.cpp	(revision 6952)
@@ -0,0 +1,346 @@
+/*
+
+/***************************************************************************************************
+**
+** profile.cpp
+**
+** Real-Time Hierarchical Profiling for Game Programming Gems 3
+**
+** by Greg Hjelstrom & Byon Garrabrant
+**
+***************************************************************************************************/
+
+// Credits: The Clock class was inspired by the Timer classes in 
+// Ogre (www.ogre3d.org).
+
+#include "LinearMath/btQuickprof.h"
+
+
+#ifdef USE_BT_CLOCK
+
+static btClock gProfileClock;
+
+inline void Profile_Get_Ticks(unsigned long int * ticks)
+{
+	*ticks = gProfileClock.getTimeMicroseconds();
+}
+
+inline float Profile_Get_Tick_Rate(void)
+{
+//	return 1000000.f;
+	return 1000.f;
+
+}
+
+
+
+/***************************************************************************************************
+**
+** CProfileNode
+**
+***************************************************************************************************/
+
+/***********************************************************************************************
+ * INPUT:                                                                                      *
+ * name - pointer to a static string which is the name of this profile node                    *
+ * parent - parent pointer                                                                     *
+ *                                                                                             *
+ * WARNINGS:                                                                                   *
+ * The name is assumed to be a static pointer, only the pointer is stored and compared for     *
+ * efficiency reasons.                                                                         *
+ *=============================================================================================*/
+CProfileNode::CProfileNode( const char * name, CProfileNode * parent ) :
+	Name( name ),
+	TotalCalls( 0 ),
+	TotalTime( 0 ),
+	StartTime( 0 ),
+	RecursionCounter( 0 ),
+	Parent( parent ),
+	Child( NULL ),
+	Sibling( NULL )
+{
+	Reset();
+}
+
+
+void	CProfileNode::CleanupMemory()
+{
+	delete ( Child);
+	Child = NULL;
+	delete ( Sibling);
+	Sibling = NULL;
+}
+
+CProfileNode::~CProfileNode( void )
+{
+	delete ( Child);
+	delete ( Sibling);
+}
+
+
+/***********************************************************************************************
+ * INPUT:                                                                                      *
+ * name - static string pointer to the name of the node we are searching for                   *
+ *                                                                                             *
+ * WARNINGS:                                                                                   *
+ * All profile names are assumed to be static strings so this function uses pointer compares   *
+ * to find the named node.                                                                     *
+ *=============================================================================================*/
+CProfileNode * CProfileNode::Get_Sub_Node( const char * name )
+{
+	// Try to find this sub node
+	CProfileNode * child = Child;
+	while ( child ) {
+		if ( child->Name == name ) {
+			return child;
+		}
+		child = child->Sibling;
+	}
+
+	// We didn't find it, so add it
+	
+	CProfileNode * node = new CProfileNode( name, this );
+	node->Sibling = Child;
+	Child = node;
+	return node;
+}
+
+
+void	CProfileNode::Reset( void )
+{
+	TotalCalls = 0;
+	TotalTime = 0.0f;
+	
+
+	if ( Child ) {
+		Child->Reset();
+	}
+	if ( Sibling ) {
+		Sibling->Reset();
+	}
+}
+
+
+void	CProfileNode::Call( void )
+{
+	TotalCalls++;
+	if (RecursionCounter++ == 0) {
+		Profile_Get_Ticks(&StartTime);
+	}
+}
+
+
+bool	CProfileNode::Return( void )
+{
+	if ( --RecursionCounter == 0 && TotalCalls != 0 ) { 
+		unsigned long int time;
+		Profile_Get_Ticks(&time);
+		time-=StartTime;
+		TotalTime += (float)time / Profile_Get_Tick_Rate();
+	}
+	return ( RecursionCounter == 0 );
+}
+
+
+/***************************************************************************************************
+**
+** CProfileIterator
+**
+***************************************************************************************************/
+CProfileIterator::CProfileIterator( CProfileNode * start )
+{
+	CurrentParent = start;
+	CurrentChild = CurrentParent->Get_Child();
+}
+
+
+void	CProfileIterator::First(void)
+{
+	CurrentChild = CurrentParent->Get_Child();
+}
+
+
+void	CProfileIterator::Next(void)
+{
+	CurrentChild = CurrentChild->Get_Sibling();
+}
+
+
+bool	CProfileIterator::Is_Done(void)
+{
+	return CurrentChild == NULL;
+}
+
+
+void	CProfileIterator::Enter_Child( int index )
+{
+	CurrentChild = CurrentParent->Get_Child();
+	while ( (CurrentChild != NULL) && (index != 0) ) {
+		index--;
+		CurrentChild = CurrentChild->Get_Sibling();
+	}
+
+	if ( CurrentChild != NULL ) {
+		CurrentParent = CurrentChild;
+		CurrentChild = CurrentParent->Get_Child();
+	}
+}
+
+
+void	CProfileIterator::Enter_Parent( void )
+{
+	if ( CurrentParent->Get_Parent() != NULL ) {
+		CurrentParent = CurrentParent->Get_Parent();
+	}
+	CurrentChild = CurrentParent->Get_Child();
+}
+
+
+/***************************************************************************************************
+**
+** CProfileManager
+**
+***************************************************************************************************/
+
+CProfileNode	CProfileManager::Root( "Root", NULL );
+CProfileNode *	CProfileManager::CurrentNode = &CProfileManager::Root;
+int				CProfileManager::FrameCounter = 0;
+unsigned long int			CProfileManager::ResetTime = 0;
+
+
+/***********************************************************************************************
+ * CProfileManager::Start_Profile -- Begin a named profile                                    *
+ *                                                                                             *
+ * Steps one level deeper into the tree, if a child already exists with the specified name     *
+ * then it accumulates the profiling; otherwise a new child node is added to the profile tree. *
+ *                                                                                             *
+ * INPUT:                                                                                      *
+ * name - name of this profiling record                                                        *
+ *                                                                                             *
+ * WARNINGS:                                                                                   *
+ * The string used is assumed to be a static string; pointer compares are used throughout      *
+ * the profiling code for efficiency.                                                          *
+ *=============================================================================================*/
+void	CProfileManager::Start_Profile( const char * name )
+{
+	if (name != CurrentNode->Get_Name()) {
+		CurrentNode = CurrentNode->Get_Sub_Node( name );
+	} 
+	
+	CurrentNode->Call();
+}
+
+
+/***********************************************************************************************
+ * CProfileManager::Stop_Profile -- Stop timing and record the results.                       *
+ *=============================================================================================*/
+void	CProfileManager::Stop_Profile( void )
+{
+	// Return will indicate whether we should back up to our parent (we may
+	// be profiling a recursive function)
+	if (CurrentNode->Return()) {
+		CurrentNode = CurrentNode->Get_Parent();
+	}
+}
+
+
+/***********************************************************************************************
+ * CProfileManager::Reset -- Reset the contents of the profiling system                       *
+ *                                                                                             *
+ *    This resets everything except for the tree structure.  All of the timing data is reset.  *
+ *=============================================================================================*/
+void	CProfileManager::Reset( void )
+{ 
+	gProfileClock.reset();
+	Root.Reset();
+    Root.Call();
+	FrameCounter = 0;
+	Profile_Get_Ticks(&ResetTime);
+}
+
+
+/***********************************************************************************************
+ * CProfileManager::Increment_Frame_Counter -- Increment the frame counter                    *
+ *=============================================================================================*/
+void CProfileManager::Increment_Frame_Counter( void )
+{
+	FrameCounter++;
+}
+
+
+/***********************************************************************************************
+ * CProfileManager::Get_Time_Since_Reset -- returns the elapsed time since last reset         *
+ *=============================================================================================*/
+float CProfileManager::Get_Time_Since_Reset( void )
+{
+	unsigned long int time;
+	Profile_Get_Ticks(&time);
+	time -= ResetTime;
+	return (float)time / Profile_Get_Tick_Rate();
+}
+
+#include <stdio.h>
+
+void	CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spacing)
+{
+	profileIterator->First();
+	if (profileIterator->Is_Done())
+		return;
+
+	float accumulated_time=0,parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time();
+	int i;
+	int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset();
+	for (i=0;i<spacing;i++)	printf(".");
+	printf("----------------------------------\n");
+	for (i=0;i<spacing;i++)	printf(".");
+	printf("Profiling: %s (total running time: %.3f ms) ---\n",	profileIterator->Get_Current_Parent_Name(), parent_time );
+	float totalTime = 0.f;
+
+	
+	int numChildren = 0;
+	
+	for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next())
+	{
+		numChildren++;
+		float current_total_time = profileIterator->Get_Current_Total_Time();
+		accumulated_time += current_total_time;
+		float fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f;
+		{
+			int i;	for (i=0;i<spacing;i++)	printf(".");
+		}
+		printf("%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n",i, profileIterator->Get_Current_Name(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls());
+		totalTime += current_total_time;
+		//recurse into children
+	}
+
+	if (parent_time < accumulated_time)
+	{
+		printf("what's wrong\n");
+	}
+	for (i=0;i<spacing;i++)	printf(".");
+	printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:",parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time);
+	
+	for (i=0;i<numChildren;i++)
+	{
+		profileIterator->Enter_Child(i);
+		dumpRecursive(profileIterator,spacing+3);
+		profileIterator->Enter_Parent();
+	}
+}
+
+
+
+void	CProfileManager::dumpAll()
+{
+	CProfileIterator* profileIterator = 0;
+	profileIterator = CProfileManager::Get_Iterator();
+
+	dumpRecursive(profileIterator,0);
+
+	CProfileManager::Release_Iterator(profileIterator);
+}
+
+
+
+#endif //USE_BT_CLOCK
+
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btQuickprof.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btQuickprof.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btQuickprof.h	(revision 6952)
@@ -0,0 +1,370 @@
+
+/***************************************************************************************************
+**
+** Real-Time Hierarchical Profiling for Game Programming Gems 3
+**
+** by Greg Hjelstrom & Byon Garrabrant
+**
+***************************************************************************************************/
+
+// Credits: The Clock class was inspired by the Timer classes in 
+// Ogre (www.ogre3d.org).
+
+
+
+#ifndef QUICK_PROF_H
+#define QUICK_PROF_H
+
+//To disable built-in profiling, please comment out next line
+//#define BT_NO_PROFILE 1
+#ifndef BT_NO_PROFILE
+
+#include "btScalar.h"
+#include "LinearMath/btAlignedAllocator.h"
+#include <new>
+
+
+
+
+//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.
+class btClock
+{
+public:
+	btClock()
+	{
+#ifdef USE_WINDOWS_TIMERS
+		QueryPerformanceFrequency(&mClockFrequency);
+#endif
+		reset();
+	}
+
+	~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
+	}
+
+	/// 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
+	}
+
+	/// 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 
+	}
+
+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__
+
+};
+
+#endif //USE_BT_CLOCK
+
+
+
+
+///A node in the Profile Hierarchy Tree
+class	CProfileNode {
+
+public:
+	CProfileNode( const char * name, CProfileNode * parent );
+	~CProfileNode( void );
+
+	CProfileNode * Get_Sub_Node( const char * name );
+
+	CProfileNode * Get_Parent( void )		{ return Parent; }
+	CProfileNode * Get_Sibling( void )		{ return Sibling; }
+	CProfileNode * Get_Child( void )			{ return Child; }
+
+	void				CleanupMemory();
+	void				Reset( void );
+	void				Call( void );
+	bool				Return( void );
+
+	const char *	Get_Name( void )				{ return Name; }
+	int				Get_Total_Calls( void )		{ return TotalCalls; }
+	float				Get_Total_Time( void )		{ return TotalTime; }
+
+protected:
+
+	const char *	Name;
+	int				TotalCalls;
+	float				TotalTime;
+	unsigned long int			StartTime;
+	int				RecursionCounter;
+
+	CProfileNode *	Parent;
+	CProfileNode *	Child;
+	CProfileNode *	Sibling;
+};
+
+///An iterator to navigate through the tree
+class CProfileIterator
+{
+public:
+	// Access all the children of the current parent
+	void				First(void);
+	void				Next(void);
+	bool				Is_Done(void);
+	bool                Is_Root(void) { return (CurrentParent->Get_Parent() == 0); }
+
+	void				Enter_Child( int index );		// Make the given child the new parent
+	void				Enter_Largest_Child( void );	// Make the largest child the new parent
+	void				Enter_Parent( void );			// Make the current parent's parent the new parent
+
+	// Access the current child
+	const char *	Get_Current_Name( void )			{ return CurrentChild->Get_Name(); }
+	int				Get_Current_Total_Calls( void )	{ return CurrentChild->Get_Total_Calls(); }
+	float				Get_Current_Total_Time( void )	{ return CurrentChild->Get_Total_Time(); }
+
+	// Access the current parent
+	const char *	Get_Current_Parent_Name( void )			{ return CurrentParent->Get_Name(); }
+	int				Get_Current_Parent_Total_Calls( void )	{ return CurrentParent->Get_Total_Calls(); }
+	float				Get_Current_Parent_Total_Time( void )	{ return CurrentParent->Get_Total_Time(); }
+
+protected:
+
+	CProfileNode *	CurrentParent;
+	CProfileNode *	CurrentChild;
+
+	CProfileIterator( CProfileNode * start );
+	friend	class		CProfileManager;
+};
+
+
+///The Manager for the Profile system
+class	CProfileManager {
+public:
+	static	void						Start_Profile( const char * name );
+	static	void						Stop_Profile( void );
+
+	static	void						CleanupMemory(void)
+	{
+		Root.CleanupMemory();
+	}
+
+	static	void						Reset( void );
+	static	void						Increment_Frame_Counter( void );
+	static	int						Get_Frame_Count_Since_Reset( void )		{ return FrameCounter; }
+	static	float						Get_Time_Since_Reset( void );
+
+	static	CProfileIterator *	Get_Iterator( void )	
+	{ 
+		
+		return new CProfileIterator( &Root ); 
+	}
+	static	void						Release_Iterator( CProfileIterator * iterator ) { delete ( iterator); }
+
+	static void	dumpRecursive(CProfileIterator* profileIterator, int spacing);
+
+	static void	dumpAll();
+
+private:
+	static	CProfileNode			Root;
+	static	CProfileNode *			CurrentNode;
+	static	int						FrameCounter;
+	static	unsigned long int					ResetTime;
+};
+
+
+///ProfileSampleClass is a simple way to profile a function's scope
+///Use the BT_PROFILE macro at the start of scope to time
+class	CProfileSample {
+public:
+	CProfileSample( const char * name )
+	{ 
+		CProfileManager::Start_Profile( name ); 
+	}
+
+	~CProfileSample( void )					
+	{ 
+		CProfileManager::Stop_Profile(); 
+	}
+};
+
+
+#define	BT_PROFILE( name )			CProfileSample __profile( name )
+
+#else
+
+#define	BT_PROFILE( name )
+
+#endif //#ifndef BT_NO_PROFILE
+
+
+
+#endif //QUICK_PROF_H
+
+
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btRandom.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btRandom.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btRandom.h	(revision 6952)
@@ -0,0 +1,42 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / 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 GEN_RANDOM_H
+#define GEN_RANDOM_H
+
+#ifdef MT19937
+
+#include <limits.h>
+#include <mt19937.h>
+
+#define GEN_RAND_MAX UINT_MAX
+
+SIMD_FORCE_INLINE void         GEN_srand(unsigned int seed) { init_genrand(seed); }
+SIMD_FORCE_INLINE unsigned int GEN_rand()                   { return genrand_int32(); }
+
+#else
+
+#include <stdlib.h>
+
+#define GEN_RAND_MAX RAND_MAX
+
+SIMD_FORCE_INLINE void         GEN_srand(unsigned int seed) { srand(seed); } 
+SIMD_FORCE_INLINE unsigned int GEN_rand()                   { return rand(); }
+
+#endif
+
+#endif
+
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btScalar.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btScalar.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btScalar.h	(revision 6952)
@@ -0,0 +1,443 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD___SCALAR_H
+#define SIMD___SCALAR_H
+
+#include <math.h>
+
+#include <stdlib.h>//size_t for MSVC 6.0
+
+#include <cstdlib>
+#include <cfloat>
+#include <float.h>
+
+#define BT_BULLET_VERSION 274
+
+inline int	btGetVersion()
+{
+	return BT_BULLET_VERSION;
+}
+
+#if defined(DEBUG) || defined (_DEBUG)
+#define BT_DEBUG
+#endif
+
+
+#ifdef WIN32
+
+		#if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300)
+
+			#define SIMD_FORCE_INLINE inline
+			#define ATTRIBUTE_ALIGNED16(a) a
+			#define ATTRIBUTE_ALIGNED128(a) a
+		#else
+			//#define BT_HAS_ALIGNED_ALLOCATOR
+			#pragma warning(disable : 4324) // disable padding warning
+//			#pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning.
+//			#pragma warning(disable:4996) //Turn off warnings about deprecated C routines
+//			#pragma warning(disable:4786) // Disable the "debug name too long" warning
+
+			#define SIMD_FORCE_INLINE __forceinline
+			#define ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a
+			#define ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a
+		#ifdef _XBOX
+			#define BT_USE_VMX128
+
+			#include <ppcintrinsics.h>
+ 			#define BT_HAVE_NATIVE_FSEL
+ 			#define btFsel(a,b,c) __fsel((a),(b),(c))
+		#else
+
+#if (defined (WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (BT_USE_DOUBLE_PRECISION))
+			#define BT_USE_SSE
+			#include <emmintrin.h>
+#endif
+
+		#endif//_XBOX
+
+		#endif //__MINGW32__
+
+		#include <assert.h>
+#ifdef BT_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
+	
+#if defined	(__CELLOS_LV2__)
+		#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)  _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)
+		#define btUnlikely(_c) __builtin_expect((_c), 0)
+		
+
+#else
+	//non-windows systems
+
+		#define SIMD_FORCE_INLINE inline
+		///@todo: check out alignment methods for other platforms/compilers
+		///#define ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16)))
+		///#define ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128)))
+		#define ATTRIBUTE_ALIGNED16(a) a
+		#define ATTRIBUTE_ALIGNED128(a) a
+		#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
+
+
+#endif // LIBSPE2
+
+#endif	//__CELLOS_LV2__
+#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;
+#else
+typedef float btScalar;
+#endif
+
+
+
+#define BT_DECLARE_ALIGNED_ALLOCATOR() \
+   SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes)   { return btAlignedAlloc(sizeInBytes,16); }   \
+   SIMD_FORCE_INLINE void  operator delete(void* ptr)         { btAlignedFree(ptr); }   \
+   SIMD_FORCE_INLINE void* operator new(size_t, void* ptr)   { return ptr; }   \
+   SIMD_FORCE_INLINE void  operator delete(void*, void*)      { }   \
+   SIMD_FORCE_INLINE void* operator new[](size_t sizeInBytes)   { return btAlignedAlloc(sizeInBytes,16); }   \
+   SIMD_FORCE_INLINE void  operator delete[](void* ptr)         { btAlignedFree(ptr); }   \
+   SIMD_FORCE_INLINE void* operator new[](size_t, void* ptr)   { return ptr; }   \
+   SIMD_FORCE_INLINE void  operator delete[](void*, void*)      { }   \
+
+
+
+#if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS)
+		
+SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { return sqrt(x); }
+SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); }
+SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); }
+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 btAtan(btScalar x) { return atan(x); }
+SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); }
+SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return exp(x); }
+SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return log(x); }
+SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); }
+
+#else
+		
+SIMD_FORCE_INLINE btScalar btSqrt(btScalar y) 
+{ 
+#ifdef USE_APPROXIMATION
+    double x, z, tempf;
+    unsigned long *tfptr = ((unsigned long *)&tempf) + 1;
+
+	tempf = y;
+	*tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
+	x =  tempf;
+	z =  y*btScalar(0.5);                        /* hoist out the /2    */
+	x = (btScalar(1.5)*x)-(x*x)*(x*z);         /* iteration formula     */
+	x = (btScalar(1.5)*x)-(x*x)*(x*z);
+	x = (btScalar(1.5)*x)-(x*x)*(x*z);
+	x = (btScalar(1.5)*x)-(x*x)*(x*z);
+	x = (btScalar(1.5)*x)-(x*x)*(x*z);
+	return x*y;
+#else
+	return sqrtf(y); 
+#endif
+}
+SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); }
+SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cosf(x); }
+SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); }
+SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); }
+SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { 
+	btAssert(x <= btScalar(1.));
+	return acosf(x); 
+}
+SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { 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); }
+SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
+SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
+  #if defined( __MINGW32__ )
+  SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); }
+  #else
+  SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
+  #endif
+	
+#endif
+
+#define SIMD_2_PI         btScalar(6.283185307179586232)
+#define SIMD_PI           (SIMD_2_PI * btScalar(0.5))
+#define SIMD_HALF_PI      (SIMD_2_PI * btScalar(0.25))
+#define SIMD_RADS_PER_DEG (SIMD_2_PI / btScalar(360.0))
+#define SIMD_DEGS_PER_RAD  (btScalar(360.0) / SIMD_2_PI)
+
+#ifdef BT_USE_DOUBLE_PRECISION
+#define SIMD_EPSILON      DBL_EPSILON
+#define SIMD_INFINITY     DBL_MAX
+#else
+#define SIMD_EPSILON      FLT_EPSILON
+#define SIMD_INFINITY     FLT_MAX
+#endif
+
+SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x) 
+{
+	btScalar coeff_1 = SIMD_PI / 4.0f;
+	btScalar coeff_2 = 3.0f * coeff_1;
+	btScalar abs_y = btFabs(y);
+	btScalar angle;
+	if (x >= 0.0f) {
+		btScalar r = (x - abs_y) / (x + abs_y);
+		angle = coeff_1 - coeff_1 * r;
+	} else {
+		btScalar r = (x + abs_y) / (abs_y - x);
+		angle = coeff_2 - coeff_1 * r;
+	}
+	return (y < 0.0f) ? -angle : angle;
+}
+
+SIMD_FORCE_INLINE bool      btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; }
+
+SIMD_FORCE_INLINE bool	btEqual(btScalar a, btScalar eps) {
+	return (((a) <= eps) && !((a) < -eps));
+}
+SIMD_FORCE_INLINE bool	btGreaterEqual (btScalar a, btScalar eps) {
+	return (!((a) <= eps));
+}
+
+
+SIMD_FORCE_INLINE int       btIsNegative(btScalar x) {
+    return x < btScalar(0.0) ? 1 : 0;
+}
+
+SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; }
+SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; }
+
+#define BT_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
+
+#ifndef btFsel
+SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c)
+{
+	return a >= 0 ? b : c;
+}
+#endif
+#define btFsels(a,b,c) (btScalar)btFsel(a,b,c)
+
+
+SIMD_FORCE_INLINE bool btMachineIsLittleEndian()
+{
+   long int i = 1;
+   const char *p = (const char *) &i;
+   if (p[0] == 1)  // Lowest address contains the least significant byte
+	   return true;
+   else
+	   return false;
+}
+
+
+
+///btSelect avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360
+///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html
+SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) 
+{
+    // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero
+    // Rely on positive value or'ed with its negative having sign bit on
+    // and zero value or'ed with its negative (which is still zero) having sign bit off 
+    // Use arithmetic shift right, shifting the sign bit through all 32 bits
+    unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
+    unsigned testEqz = ~testNz;
+    return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); 
+}
+SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero)
+{
+    unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31);
+    unsigned testEqz = ~testNz; 
+    return static_cast<int>((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz));
+}
+SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero)
+{
+#ifdef BT_HAVE_NATIVE_FSEL
+    return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero);
+#else
+    return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; 
+#endif
+}
+
+template<typename T> SIMD_FORCE_INLINE void btSwap(T& a, T& b)
+{
+	T tmp = a;
+	a = b;
+	b = tmp;
+}
+
+
+//PCK: endian swapping functions
+SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val)
+{
+	return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8)  | ((val & 0x000000ff) << 24));
+}
+
+SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val)
+{
+	return static_cast<unsigned short>(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8));
+}
+
+SIMD_FORCE_INLINE unsigned btSwapEndian(int val)
+{
+	return btSwapEndian((unsigned)val);
+}
+
+SIMD_FORCE_INLINE unsigned short btSwapEndian(short val)
+{
+	return btSwapEndian((unsigned short) val);
+}
+
+///btSwapFloat uses using char pointers to swap the endianness
+////btSwapFloat/btSwapDouble will NOT return a float, because the machine might 'correct' invalid floating point values
+///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754. 
+///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception. 
+///In most systems, running user mode code, you wouldn't get an exception, but instead the hardware/os/runtime will 'fix' the number for you. 
+///so instead of returning a float/double, we return integer/long long integer
+SIMD_FORCE_INLINE unsigned int  btSwapEndianFloat(float d)
+{
+    unsigned int a = 0;
+    unsigned char *dst = (unsigned char *)&a;
+    unsigned char *src = (unsigned char *)&d;
+
+    dst[0] = src[3];
+    dst[1] = src[2];
+    dst[2] = src[1];
+    dst[3] = src[0];
+    return a;
+}
+
+// unswap using char pointers
+SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a) 
+{
+    float d = 0.0f;
+    unsigned char *src = (unsigned char *)&a;
+    unsigned char *dst = (unsigned char *)&d;
+
+    dst[0] = src[3];
+    dst[1] = src[2];
+    dst[2] = src[1];
+    dst[3] = src[0];
+
+    return d;
+}
+
+
+// swap using char pointers
+SIMD_FORCE_INLINE void  btSwapEndianDouble(double d, unsigned char* dst)
+{
+    unsigned char *src = (unsigned char *)&d;
+
+    dst[0] = src[7];
+    dst[1] = src[6];
+    dst[2] = src[5];
+    dst[3] = src[4];
+    dst[4] = src[3];
+    dst[5] = src[2];
+    dst[6] = src[1];
+    dst[7] = src[0];
+
+}
+
+// unswap using char pointers
+SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char *src) 
+{
+    double d = 0.0;
+    unsigned char *dst = (unsigned char *)&d;
+
+    dst[0] = src[7];
+    dst[1] = src[6];
+    dst[2] = src[5];
+    dst[3] = src[4];
+    dst[4] = src[3];
+    dst[5] = src[2];
+    dst[6] = src[1];
+    dst[7] = src[0];
+
+	return d;
+}
+
+
+#endif //SIMD___SCALAR_H
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btStackAlloc.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btStackAlloc.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btStackAlloc.h	(revision 6952)
@@ -0,0 +1,116 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / 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.
+*/
+
+/*
+StackAlloc extracted from GJK-EPA collision solver by Nathanael Presson
+Nov.2006
+*/
+
+#ifndef BT_STACK_ALLOC
+#define BT_STACK_ALLOC
+
+#include "btScalar.h" //for btAssert
+#include "btAlignedAllocator.h"
+
+///The btBlock class is an internal structure for the btStackAlloc memory allocator.
+struct btBlock
+{
+	btBlock*			previous;
+	unsigned char*		address;
+};
+
+///The StackAlloc class provides some fast stack-based memory allocator (LIFO last-in first-out)
+class btStackAlloc
+{
+public:
+
+	btStackAlloc(unsigned int size)	{ ctor();create(size); }
+	~btStackAlloc()		{ destroy(); }
+	
+	inline void		create(unsigned int size)
+	{
+		destroy();
+		data		=  (unsigned char*) btAlignedAlloc(size,16);
+		totalsize	=	size;
+	}
+	inline void		destroy()
+	{
+		btAssert(usedsize==0);
+		//Raise(L"StackAlloc is still in use");
+
+		if(usedsize==0)
+		{
+			if(!ischild && data)		
+				btAlignedFree(data);
+
+			data				=	0;
+			usedsize			=	0;
+		}
+		
+	}
+
+	int	getAvailableMemory() const
+	{
+		return static_cast<int>(totalsize - usedsize);
+	}
+
+	unsigned char*			allocate(unsigned int size)
+	{
+		const unsigned int	nus(usedsize+size);
+		if(nus<totalsize)
+		{
+			usedsize=nus;
+			return(data+(usedsize-size));
+		}
+		btAssert(0);
+		//&& (L"Not enough memory"));
+		
+		return(0);
+	}
+	SIMD_FORCE_INLINE btBlock*		beginBlock()
+	{
+		btBlock*	pb = (btBlock*)allocate(sizeof(btBlock));
+		pb->previous	=	current;
+		pb->address		=	data+usedsize;
+		current			=	pb;
+		return(pb);
+	}
+	SIMD_FORCE_INLINE void		endBlock(btBlock* block)
+	{
+		btAssert(block==current);
+		//Raise(L"Unmatched blocks");
+		if(block==current)
+		{
+			current		=	block->previous;
+			usedsize	=	(unsigned int)((block->address-data)-sizeof(btBlock));
+		}
+	}
+
+private:
+	void		ctor()
+	{
+		data		=	0;
+		totalsize	=	0;
+		usedsize	=	0;
+		current		=	0;
+		ischild		=	false;
+	}
+	unsigned char*		data;
+	unsigned int		totalsize;
+	unsigned int		usedsize;
+	btBlock*	current;
+	bool		ischild;
+};
+
+#endif //BT_STACK_ALLOC
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btTransform.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btTransform.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btTransform.h	(revision 6952)
@@ -0,0 +1,243 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / 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 btTransform_H
+#define btTransform_H
+
+#include "btVector3.h"
+#include "btMatrix3x3.h"
+
+
+/**@brief The btTransform class supports rigid transforms with only translation and rotation and no scaling/shear.
+ *It can be used in combination with btVector3, btQuaternion and btMatrix3x3 linear algebra classes. */
+class btTransform {
+	
+
+public:
+	
+  /**@brief No initialization constructor */
+	btTransform() {}
+  /**@brief Constructor from btQuaternion (optional btVector3 )
+   * @param q Rotation from quaternion 
+   * @param c Translation from Vector (default 0,0,0) */
+	explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q, 
+		const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0))) 
+		: m_basis(q),
+		m_origin(c)
+	{}
+
+  /**@brief Constructor from btMatrix3x3 (optional btVector3)
+   * @param b Rotation from Matrix 
+   * @param c Translation from Vector default (0,0,0)*/
+	explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b, 
+		const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0)))
+		: m_basis(b),
+		m_origin(c)
+	{}
+  /**@brief Copy constructor */
+	SIMD_FORCE_INLINE btTransform (const btTransform& other)
+		: m_basis(other.m_basis),
+		m_origin(other.m_origin)
+	{
+	}
+  /**@brief Assignment Operator */
+	SIMD_FORCE_INLINE btTransform& operator=(const btTransform& other)
+	{
+		m_basis = other.m_basis;
+		m_origin = other.m_origin;
+		return *this;
+	}
+
+
+  /**@brief Set the current transform as the value of the product of two transforms
+   * @param t1 Transform 1
+   * @param t2 Transform 2
+   * This = Transform1 * Transform2 */
+		SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) {
+			m_basis = t1.m_basis * t2.m_basis;
+			m_origin = t1(t2.m_origin);
+		}
+
+/*		void multInverseLeft(const btTransform& t1, const btTransform& t2) {
+			btVector3 v = t2.m_origin - t1.m_origin;
+			m_basis = btMultTransposeLeft(t1.m_basis, t2.m_basis);
+			m_origin = v * t1.m_basis;
+		}
+		*/
+
+/**@brief Return the transform of the vector */
+	SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const
+	{
+		return btVector3(m_basis[0].dot(x) + m_origin.x(), 
+			m_basis[1].dot(x) + m_origin.y(), 
+			m_basis[2].dot(x) + m_origin.z());
+	}
+
+  /**@brief Return the transform of the vector */
+	SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const
+	{
+		return (*this)(x);
+	}
+
+  /**@brief Return the transform of the btQuaternion */
+	SIMD_FORCE_INLINE btQuaternion operator*(const btQuaternion& q) const
+	{
+		return getRotation() * q;
+	}
+
+  /**@brief Return the basis matrix for the rotation */
+	SIMD_FORCE_INLINE btMatrix3x3&       getBasis()          { return m_basis; }
+  /**@brief Return the basis matrix for the rotation */
+	SIMD_FORCE_INLINE const btMatrix3x3& getBasis()    const { return m_basis; }
+
+  /**@brief Return the origin vector translation */
+	SIMD_FORCE_INLINE btVector3&         getOrigin()         { return m_origin; }
+  /**@brief Return the origin vector translation */
+	SIMD_FORCE_INLINE const btVector3&   getOrigin()   const { return m_origin; }
+
+  /**@brief Return a quaternion representing the rotation */
+	btQuaternion getRotation() const { 
+		btQuaternion q;
+		m_basis.getRotation(q);
+		return q;
+	}
+	
+	
+  /**@brief Set from an array 
+   * @param m A pointer to a 15 element array (12 rotation(row major padded on the right by 1), and 3 translation */
+	void setFromOpenGLMatrix(const btScalar *m)
+	{
+		m_basis.setFromOpenGLSubMatrix(m);
+		m_origin.setValue(m[12],m[13],m[14]);
+	}
+
+  /**@brief Fill an array representation
+   * @param m A pointer to a 15 element array (12 rotation(row major padded on the right by 1), and 3 translation */
+	void getOpenGLMatrix(btScalar *m) const 
+	{
+		m_basis.getOpenGLSubMatrix(m);
+		m[12] = m_origin.x();
+		m[13] = m_origin.y();
+		m[14] = m_origin.z();
+		m[15] = btScalar(1.0);
+	}
+
+  /**@brief Set the translational element
+   * @param origin The vector to set the translation to */
+	SIMD_FORCE_INLINE void setOrigin(const btVector3& origin) 
+	{ 
+		m_origin = origin;
+	}
+
+	SIMD_FORCE_INLINE btVector3 invXform(const btVector3& inVec) const;
+
+
+  /**@brief Set the rotational element by btMatrix3x3 */
+	SIMD_FORCE_INLINE void setBasis(const btMatrix3x3& basis)
+	{ 
+		m_basis = basis;
+	}
+
+  /**@brief Set the rotational element by btQuaternion */
+	SIMD_FORCE_INLINE void setRotation(const btQuaternion& q)
+	{
+		m_basis.setRotation(q);
+	}
+
+
+  /**@brief Set this transformation to the identity */
+	void setIdentity()
+	{
+		m_basis.setIdentity();
+		m_origin.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0));
+	}
+
+  /**@brief Multiply this Transform by another(this = this * another) 
+   * @param t The other transform */
+	btTransform& operator*=(const btTransform& t) 
+	{
+		m_origin += m_basis * t.m_origin;
+		m_basis *= t.m_basis;
+		return *this;
+	}
+
+  /**@brief Return the inverse of this transform */
+	btTransform inverse() const
+	{ 
+		btMatrix3x3 inv = m_basis.transpose();
+		return btTransform(inv, inv * -m_origin);
+	}
+
+  /**@brief Return the inverse of this transform times the other transform
+   * @param t The other transform 
+   * return this.inverse() * the other */
+	btTransform inverseTimes(const btTransform& t) const;  
+
+  /**@brief Return the product of this transform and the other */
+	btTransform operator*(const btTransform& t) const;
+
+  /**@brief Return an identity transform */
+	static const btTransform&	getIdentity()
+	{
+		static const btTransform identityTransform(btMatrix3x3::getIdentity());
+		return identityTransform;
+	}
+	
+private:
+  ///Storage for the rotation
+	btMatrix3x3 m_basis;
+  ///Storage for the translation
+	btVector3   m_origin;
+};
+
+
+SIMD_FORCE_INLINE btVector3
+btTransform::invXform(const btVector3& inVec) const
+{
+	btVector3 v = inVec - m_origin;
+	return (m_basis.transpose() * v);
+}
+
+SIMD_FORCE_INLINE btTransform 
+btTransform::inverseTimes(const btTransform& t) const  
+{
+	btVector3 v = t.getOrigin() - m_origin;
+		return btTransform(m_basis.transposeTimes(t.m_basis),
+			v * m_basis);
+}
+
+SIMD_FORCE_INLINE btTransform 
+btTransform::operator*(const btTransform& t) const
+{
+	return btTransform(m_basis * t.m_basis, 
+		(*this)(t.m_origin));
+}
+
+/**@brief Test if two transforms have all elements equal */
+SIMD_FORCE_INLINE bool operator==(const btTransform& t1, const btTransform& t2)
+{
+   return ( t1.getBasis()  == t2.getBasis() &&
+            t1.getOrigin() == t2.getOrigin() );
+}
+
+
+#endif
+
+
+
+
+
+
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btTransformUtil.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btTransformUtil.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btTransformUtil.h	(revision 6952)
@@ -0,0 +1,247 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD_TRANSFORM_UTIL_H
+#define SIMD_TRANSFORM_UTIL_H
+
+#include "btTransform.h"
+#define ANGULAR_MOTION_THRESHOLD btScalar(0.5)*SIMD_HALF_PI
+
+
+
+#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)
+{
+	return btVector3(supportDir.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(),
+      supportDir.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(),
+      supportDir.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); 
+}
+
+
+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);
+  }
+}
+
+
+
+/// Utils related to temporal transforms
+class btTransformUtil
+{
+
+public:
+
+	static void integrateTransform(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep,btTransform& predictedTransform)
+	{
+		predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep);
+//	#define QUATERNION_DERIVATIVE
+	#ifdef QUATERNION_DERIVATIVE
+		btQuaternion predictedOrn = curTrans.getRotation();
+		predictedOrn += (angvel * predictedOrn) * (timeStep * btScalar(0.5));
+		predictedOrn.normalize();
+	#else
+		//Exponential map
+		//google for "Practical Parameterization of Rotations Using the Exponential Map", F. Sebastian Grassia
+
+		btVector3 axis;
+		btScalar	fAngle = angvel.length(); 
+		//limit the angular motion
+		if (fAngle*timeStep > ANGULAR_MOTION_THRESHOLD)
+		{
+			fAngle = ANGULAR_MOTION_THRESHOLD / timeStep;
+		}
+
+		if ( fAngle < btScalar(0.001) )
+		{
+			// use Taylor's expansions of sync function
+			axis   = angvel*( btScalar(0.5)*timeStep-(timeStep*timeStep*timeStep)*(btScalar(0.020833333333))*fAngle*fAngle );
+		}
+		else
+		{
+			// sync(fAngle) = sin(c*fAngle)/t
+			axis   = angvel*( btSin(btScalar(0.5)*fAngle*timeStep)/fAngle );
+		}
+		btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*btScalar(0.5) ));
+		btQuaternion orn0 = curTrans.getRotation();
+
+		btQuaternion predictedOrn = dorn * orn0;
+		predictedOrn.normalize();
+	#endif
+		predictedTransform.setRotation(predictedOrn);
+	}
+
+	static void	calculateVelocityQuaternion(const btVector3& pos0,const btVector3& pos1,const btQuaternion& orn0,const btQuaternion& orn1,btScalar timeStep,btVector3& linVel,btVector3& angVel)
+	{
+		linVel = (pos1 - pos0) / timeStep;
+		btVector3 axis;
+		btScalar  angle;
+		if (orn0 != orn1)
+		{
+			calculateDiffAxisAngleQuaternion(orn0,orn1,axis,angle);
+			angVel = axis * angle / timeStep;
+		} else
+		{
+			angVel.setValue(0,0,0);
+		}
+	}
+
+	static void calculateDiffAxisAngleQuaternion(const btQuaternion& orn0,const btQuaternion& orn1a,btVector3& axis,btScalar& angle)
+	{
+		btQuaternion orn1 = orn0.farthest(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());
+		axis[3] = btScalar(0.);
+		//check for axis length
+		btScalar len = axis.length2();
+		if (len < SIMD_EPSILON*SIMD_EPSILON)
+			axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));
+		else
+			axis /= btSqrt(len);
+	}
+
+	static void	calculateVelocity(const btTransform& transform0,const btTransform& transform1,btScalar timeStep,btVector3& linVel,btVector3& angVel)
+	{
+		linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep;
+		btVector3 axis;
+		btScalar  angle;
+		calculateDiffAxisAngle(transform0,transform1,axis,angle);
+		angVel = axis * angle / timeStep;
+	}
+
+	static void calculateDiffAxisAngle(const btTransform& transform0,const btTransform& transform1,btVector3& axis,btScalar& angle)
+	{
+		btMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse();
+		btQuaternion dorn;
+		dmat.getRotation(dorn);
+
+		///floating point inaccuracy can lead to w component > 1..., which breaks 
+		dorn.normalize();
+		
+		angle = dorn.getAngle();
+		axis = btVector3(dorn.x(),dorn.y(),dorn.z());
+		axis[3] = btScalar(0.);
+		//check for axis length
+		btScalar len = axis.length2();
+		if (len < SIMD_EPSILON*SIMD_EPSILON)
+			axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.));
+		else
+			axis /= btSqrt(len);
+	}
+
+};
+
+
+///The btConvexSeparatingDistanceUtil can help speed up convex collision detection 
+///by conservatively updating a cached separating distance/vector instead of re-calculating the closest distance
+class	btConvexSeparatingDistanceUtil
+{
+	btQuaternion	m_ornA;
+	btQuaternion	m_ornB;
+	btVector3	m_posA;
+	btVector3	m_posB;
+	
+	btVector3	m_separatingNormal;
+
+	btScalar	m_boundingRadiusA;
+	btScalar	m_boundingRadiusB;
+	btScalar	m_separatingDistance;
+
+public:
+
+	btConvexSeparatingDistanceUtil(btScalar	boundingRadiusA,btScalar	boundingRadiusB)
+		:m_boundingRadiusA(boundingRadiusA),
+		m_boundingRadiusB(boundingRadiusB),
+		m_separatingDistance(0.f)
+	{
+	}
+
+	btScalar	getConservativeSeparatingDistance()
+	{
+		return m_separatingDistance;
+	}
+
+	void	updateSeparatingDistance(const btTransform& transA,const btTransform& transB)
+	{
+		const btVector3& toPosA = transA.getOrigin();
+		const btVector3& toPosB = transB.getOrigin();
+		btQuaternion toOrnA = transA.getRotation();
+		btQuaternion toOrnB = transB.getRotation();
+
+		if (m_separatingDistance>0.f)
+		{
+			
+
+			btVector3 linVelA,angVelA,linVelB,angVelB;
+			btTransformUtil::calculateVelocityQuaternion(m_posA,toPosA,m_ornA,toOrnA,btScalar(1.),linVelA,angVelA);
+			btTransformUtil::calculateVelocityQuaternion(m_posB,toPosB,m_ornB,toOrnB,btScalar(1.),linVelB,angVelB);
+			btScalar maxAngularProjectedVelocity = angVelA.length() * m_boundingRadiusA + angVelB.length() * m_boundingRadiusB;
+			btVector3 relLinVel = (linVelB-linVelA);
+			btScalar relLinVelocLength = (linVelB-linVelA).dot(m_separatingNormal);
+			if (relLinVelocLength<0.f)
+			{
+				relLinVelocLength = 0.f;
+			}
+	
+			btScalar	projectedMotion = maxAngularProjectedVelocity +relLinVelocLength;
+			m_separatingDistance -= projectedMotion;
+		}
+	
+		m_posA = toPosA;
+		m_posB = toPosB;
+		m_ornA = toOrnA;
+		m_ornB = toOrnB;
+	}
+
+	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;
+	}
+
+};
+
+
+#endif //SIMD_TRANSFORM_UTIL_H
+
Index: /code/branches/rocket2/src/external/bullet/LinearMath/btVector3.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/LinearMath/btVector3.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/LinearMath/btVector3.h	(revision 6952)
@@ -0,0 +1,638 @@
+/*
+Copyright (c) 2003-2006 Gino van den Bergen / 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 SIMD__VECTOR3_H
+#define SIMD__VECTOR3_H
+
+
+#include "btScalar.h"
+#include "btScalar.h"
+#include "btMinMax.h"
+/**@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
+{
+public:
+
+#if defined (__SPU__) && defined (__CELLOS_LV2__)
+	union {
+		vec_float4 mVec128;
+		btScalar	m_floats[4];
+	};
+public:
+	vec_float4	get128() const
+	{
+		return mVec128;
+	}
+public:
+#else //__CELLOS_LV2__ __SPU__
+#ifdef BT_USE_SSE // WIN32
+	union {
+		__m128 mVec128;
+		btScalar	m_floats[4];
+	};
+	SIMD_FORCE_INLINE	__m128	get128() const
+	{
+		return mVec128;
+	}
+	SIMD_FORCE_INLINE	void	set128(__m128 v128)
+	{
+		mVec128 = v128;
+	}
+#else
+	btScalar	m_floats[4];
+#endif
+#endif //__CELLOS_LV2__ __SPU__
+
+	public:
+
+  /**@brief No initialization constructor */
+	SIMD_FORCE_INLINE btVector3() {}
+
+ 
+	
+  /**@brief Constructor from scalars 
+   * @param x X value
+   * @param y Y value 
+   * @param z Z value 
+   */
+	SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z)
+	{
+		m_floats[0] = x;
+		m_floats[1] = y;
+		m_floats[2] = z;
+		m_floats[3] = btScalar(0.);
+	}
+
+	
+/**@brief Add a vector to this one 
+ * @param The vector to add to this one */
+	SIMD_FORCE_INLINE btVector3& operator+=(const btVector3& v)
+	{
+
+		m_floats[0] += v.m_floats[0]; m_floats[1] += v.m_floats[1];m_floats[2] += v.m_floats[2];
+		return *this;
+	}
+
+
+  /**@brief Subtract a vector from this one
+   * @param The vector to subtract */
+	SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v) 
+	{
+		m_floats[0] -= v.m_floats[0]; m_floats[1] -= v.m_floats[1];m_floats[2] -= v.m_floats[2];
+		return *this;
+	}
+  /**@brief Scale the vector
+   * @param s Scale factor */
+	SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s)
+	{
+		m_floats[0] *= s; m_floats[1] *= s;m_floats[2] *= s;
+		return *this;
+	}
+
+  /**@brief Inversely scale the vector 
+   * @param s Scale factor to divide by */
+	SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s) 
+	{
+		btFullAssert(s != btScalar(0.0));
+		return *this *= btScalar(1.0) / s;
+	}
+
+  /**@brief Return the dot product
+   * @param v The other vector in the dot product */
+	SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const
+	{
+		return m_floats[0] * v.m_floats[0] + m_floats[1] * v.m_floats[1] +m_floats[2] * v.m_floats[2];
+	}
+
+  /**@brief Return the length of the vector squared */
+	SIMD_FORCE_INLINE btScalar length2() const
+	{
+		return dot(*this);
+	}
+
+  /**@brief Return the length of the vector */
+	SIMD_FORCE_INLINE btScalar length() const
+	{
+		return btSqrt(length2());
+	}
+
+  /**@brief Return the distance squared between the ends of this and another vector
+   * This is symantically treating the vector like a point */
+	SIMD_FORCE_INLINE btScalar distance2(const btVector3& v) const;
+
+  /**@brief Return the distance between the ends of this and another vector
+   * This is symantically treating the vector like a point */
+	SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const;
+
+  /**@brief Normalize this vector 
+   * x^2 + y^2 + z^2 = 1 */
+	SIMD_FORCE_INLINE btVector3& normalize() 
+	{
+		return *this /= length();
+	}
+
+  /**@brief Return a normalized version of this vector */
+	SIMD_FORCE_INLINE btVector3 normalized() const;
+
+  /**@brief Rotate 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 );
+
+  /**@brief Return the angle between this and another vector
+   * @param v The other vector */
+	SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const 
+	{
+		btScalar s = btSqrt(length2() * v.length2());
+		btFullAssert(s != btScalar(0.0));
+		return btAcos(dot(v) / s);
+	}
+  /**@brief Return a vector will the absolute values of each element */
+	SIMD_FORCE_INLINE btVector3 absolute() const 
+	{
+		return btVector3(
+			btFabs(m_floats[0]), 
+			btFabs(m_floats[1]), 
+			btFabs(m_floats[2]));
+	}
+  /**@brief Return the cross product between this and another vector 
+   * @param v The other vector */
+	SIMD_FORCE_INLINE btVector3 cross(const btVector3& v) const
+	{
+		return btVector3(
+			m_floats[1] * v.m_floats[2] -m_floats[2] * v.m_floats[1],
+			m_floats[2] * v.m_floats[0] - m_floats[0] * v.m_floats[2],
+			m_floats[0] * v.m_floats[1] - m_floats[1] * v.m_floats[0]);
+	}
+
+	SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const
+	{
+		return m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) + 
+			m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) + 
+			m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]);
+	}
+
+  /**@brief Return the axis with the smallest value 
+   * Note return values are 0,1,2 for x, y, or z */
+	SIMD_FORCE_INLINE int minAxis() const
+	{
+		return m_floats[0] < m_floats[1] ? (m_floats[0] <m_floats[2] ? 0 : 2) : (m_floats[1] <m_floats[2] ? 1 : 2);
+	}
+
+  /**@brief Return the axis with the largest value 
+   * Note return values are 0,1,2 for x, y, or z */
+	SIMD_FORCE_INLINE int maxAxis() const 
+	{
+		return m_floats[0] < m_floats[1] ? (m_floats[1] <m_floats[2] ? 2 : 1) : (m_floats[0] <m_floats[2] ? 2 : 0);
+	}
+
+	SIMD_FORCE_INLINE int furthestAxis() const
+	{
+		return absolute().minAxis();
+	}
+
+	SIMD_FORCE_INLINE int closestAxis() const 
+	{
+		return absolute().maxAxis();
+	}
+
+	SIMD_FORCE_INLINE void setInterpolate3(const btVector3& v0, const btVector3& v1, btScalar rt)
+	{
+		btScalar s = btScalar(1.0) - rt;
+		m_floats[0] = s * v0.m_floats[0] + rt * v1.m_floats[0];
+		m_floats[1] = s * v0.m_floats[1] + rt * v1.m_floats[1];
+		m_floats[2] = s * v0.m_floats[2] + rt * v1.m_floats[2];
+		//don't do the unused w component
+		//		m_co[3] = s * v0[3] + rt * v1[3];
+	}
+
+  /**@brief Return the linear interpolation between this and another vector 
+   * @param v The other vector 
+   * @param t The ration of this to v (t = 0 => return this, t=1 => return other) */
+	SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const 
+	{
+		return btVector3(m_floats[0] + (v.m_floats[0] - m_floats[0]) * t,
+			m_floats[1] + (v.m_floats[1] - m_floats[1]) * t,
+			m_floats[2] + (v.m_floats[2] -m_floats[2]) * t);
+	}
+
+  /**@brief Elementwise multiply this vector by the other 
+   * @param v The other vector */
+	SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v)
+	{
+		m_floats[0] *= v.m_floats[0]; m_floats[1] *= v.m_floats[1];m_floats[2] *= v.m_floats[2];
+		return *this;
+	}
+
+	 /**@brief Return the x value */
+		SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; }
+  /**@brief Return the y value */
+		SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; }
+  /**@brief Return the z value */
+		SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; }
+  /**@brief Set the x value */
+		SIMD_FORCE_INLINE void	setX(btScalar x) { m_floats[0] = x;};
+  /**@brief Set the y value */
+		SIMD_FORCE_INLINE void	setY(btScalar y) { m_floats[1] = y;};
+  /**@brief Set the z value */
+		SIMD_FORCE_INLINE void	setZ(btScalar z) {m_floats[2] = z;};
+  /**@brief Set the w value */
+		SIMD_FORCE_INLINE void	setW(btScalar w) { m_floats[3] = w;};
+  /**@brief Return the x value */
+		SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; }
+  /**@brief Return the y value */
+		SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; }
+  /**@brief Return the z value */
+		SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; }
+  /**@brief Return the w value */
+		SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; }
+
+	//SIMD_FORCE_INLINE btScalar&       operator[](int i)       { return (&m_floats[0])[i];	}      
+	//SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; }
+	///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons.
+	SIMD_FORCE_INLINE	operator       btScalar *()       { return &m_floats[0]; }
+	SIMD_FORCE_INLINE	operator const btScalar *() const { return &m_floats[0]; }
+
+	SIMD_FORCE_INLINE	bool	operator==(const btVector3& other) const
+	{
+		return ((m_floats[3]==other.m_floats[3]) && (m_floats[2]==other.m_floats[2]) && (m_floats[1]==other.m_floats[1]) && (m_floats[0]==other.m_floats[0]));
+	}
+
+	SIMD_FORCE_INLINE	bool	operator!=(const btVector3& other) const
+	{
+		return !(*this == other);
+	}
+
+	 /**@brief Set each element to the max of the current values and the values of another btVector3
+   * @param other The other btVector3 to compare with 
+   */
+		SIMD_FORCE_INLINE void	setMax(const btVector3& other)
+		{
+			btSetMax(m_floats[0], other.m_floats[0]);
+			btSetMax(m_floats[1], other.m_floats[1]);
+			btSetMax(m_floats[2], other.m_floats[2]);
+			btSetMax(m_floats[3], other.w());
+		}
+  /**@brief Set each element to the min of the current values and the values of another btVector3
+   * @param other The other btVector3 to compare with 
+   */
+		SIMD_FORCE_INLINE void	setMin(const btVector3& other)
+		{
+			btSetMin(m_floats[0], other.m_floats[0]);
+			btSetMin(m_floats[1], other.m_floats[1]);
+			btSetMin(m_floats[2], other.m_floats[2]);
+			btSetMin(m_floats[3], other.w());
+		}
+
+		SIMD_FORCE_INLINE void 	setValue(const btScalar& x, const btScalar& y, const btScalar& z)
+		{
+			m_floats[0]=x;
+			m_floats[1]=y;
+			m_floats[2]=z;
+			m_floats[3] = 0.f;
+		}
+
+		void	getSkewSymmetricMatrix(btVector3* v0,btVector3* v1,btVector3* v2) const
+		{
+			v0->setValue(0.		,-z()		,y());
+			v1->setValue(z()	,0.			,-x());
+			v2->setValue(-y()	,x()	,0.);
+		}
+
+};
+
+/**@brief Return the sum of two vectors (Point symantics)*/
+SIMD_FORCE_INLINE btVector3 
+operator+(const btVector3& v1, const btVector3& v2) 
+{
+	return btVector3(v1.m_floats[0] + v2.m_floats[0], v1.m_floats[1] + v2.m_floats[1], v1.m_floats[2] + v2.m_floats[2]);
+}
+
+/**@brief Return the elementwise product of two vectors */
+SIMD_FORCE_INLINE btVector3 
+operator*(const btVector3& v1, const btVector3& v2) 
+{
+	return btVector3(v1.m_floats[0] * v2.m_floats[0], v1.m_floats[1] * v2.m_floats[1], v1.m_floats[2] * v2.m_floats[2]);
+}
+
+/**@brief Return the difference between two vectors */
+SIMD_FORCE_INLINE btVector3 
+operator-(const btVector3& v1, const btVector3& v2)
+{
+	return btVector3(v1.m_floats[0] - v2.m_floats[0], v1.m_floats[1] - v2.m_floats[1], v1.m_floats[2] - v2.m_floats[2]);
+}
+/**@brief Return the negative of the vector */
+SIMD_FORCE_INLINE btVector3 
+operator-(const btVector3& v)
+{
+	return btVector3(-v.m_floats[0], -v.m_floats[1], -v.m_floats[2]);
+}
+
+/**@brief Return the vector scaled by s */
+SIMD_FORCE_INLINE btVector3 
+operator*(const btVector3& v, const btScalar& s)
+{
+	return btVector3(v.m_floats[0] * s, v.m_floats[1] * s, v.m_floats[2] * s);
+}
+
+/**@brief Return the vector scaled by s */
+SIMD_FORCE_INLINE btVector3 
+operator*(const btScalar& s, const btVector3& v)
+{ 
+	return v * s; 
+}
+
+/**@brief Return the vector inversely scaled by s */
+SIMD_FORCE_INLINE btVector3
+operator/(const btVector3& v, const btScalar& s)
+{
+	btFullAssert(s != btScalar(0.0));
+	return v * (btScalar(1.0) / s);
+}
+
+/**@brief Return the vector inversely scaled by s */
+SIMD_FORCE_INLINE btVector3
+operator/(const btVector3& v1, const btVector3& v2)
+{
+	return btVector3(v1.m_floats[0] / v2.m_floats[0],v1.m_floats[1] / v2.m_floats[1],v1.m_floats[2] / v2.m_floats[2]);
+}
+
+/**@brief Return the dot product between two vectors */
+SIMD_FORCE_INLINE btScalar 
+dot(const btVector3& v1, const btVector3& v2) 
+{ 
+	return v1.dot(v2); 
+}
+
+
+/**@brief Return the distance squared between two vectors */
+SIMD_FORCE_INLINE btScalar
+distance2(const btVector3& v1, const btVector3& v2) 
+{ 
+	return v1.distance2(v2); 
+}
+
+
+/**@brief Return the distance between two vectors */
+SIMD_FORCE_INLINE btScalar
+distance(const btVector3& v1, const btVector3& v2) 
+{ 
+	return v1.distance(v2); 
+}
+
+/**@brief Return the angle between two vectors */
+SIMD_FORCE_INLINE btScalar
+angle(const btVector3& v1, const btVector3& v2) 
+{ 
+	return v1.angle(v2); 
+}
+
+/**@brief Return the cross product of two vectors */
+SIMD_FORCE_INLINE btVector3 
+cross(const btVector3& v1, const btVector3& v2) 
+{ 
+	return v1.cross(v2); 
+}
+
+SIMD_FORCE_INLINE btScalar
+triple(const btVector3& v1, const btVector3& v2, const btVector3& v3)
+{
+	return v1.triple(v2, v3);
+}
+
+/**@brief Return the linear interpolation between two vectors
+ * @param v1 One vector 
+ * @param v2 The other vector 
+ * @param t The ration of this to v (t = 0 => return v1, t=1 => return v2) */
+SIMD_FORCE_INLINE btVector3 
+lerp(const btVector3& v1, const btVector3& v2, const btScalar& t)
+{
+	return v1.lerp(v2, t);
+}
+
+
+
+SIMD_FORCE_INLINE btScalar btVector3::distance2(const btVector3& v) const
+{
+	return (v - *this).length2();
+}
+
+SIMD_FORCE_INLINE btScalar btVector3::distance(const btVector3& v) const
+{
+	return (v - *this).length();
+}
+
+SIMD_FORCE_INLINE btVector3 btVector3::normalized() const
+{
+	return *this / length();
+} 
+
+SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar angle )
+{
+	// wAxis must be a unit lenght vector
+
+	btVector3 o = wAxis * wAxis.dot( *this );
+	btVector3 x = *this - o;
+	btVector3 y;
+
+	y = wAxis.cross( *this );
+
+	return ( o + x * btCos( angle ) + y * btSin( angle ) );
+}
+
+class btVector4 : public btVector3
+{
+public:
+
+	SIMD_FORCE_INLINE btVector4() {}
+
+
+	SIMD_FORCE_INLINE btVector4(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w) 
+		: btVector3(x,y,z)
+	{
+		m_floats[3] = w;
+	}
+
+
+	SIMD_FORCE_INLINE btVector4 absolute4() const 
+	{
+		return btVector4(
+			btFabs(m_floats[0]), 
+			btFabs(m_floats[1]), 
+			btFabs(m_floats[2]),
+			btFabs(m_floats[3]));
+	}
+
+
+
+	btScalar	getW() const { return m_floats[3];}
+
+
+		SIMD_FORCE_INLINE int maxAxis4() const
+	{
+		int maxIndex = -1;
+		btScalar maxVal = btScalar(-1e30);
+		if (m_floats[0] > maxVal)
+		{
+			maxIndex = 0;
+			maxVal = m_floats[0];
+		}
+		if (m_floats[1] > maxVal)
+		{
+			maxIndex = 1;
+			maxVal = m_floats[1];
+		}
+		if (m_floats[2] > maxVal)
+		{
+			maxIndex = 2;
+			maxVal =m_floats[2];
+		}
+		if (m_floats[3] > maxVal)
+		{
+			maxIndex = 3;
+			maxVal = m_floats[3];
+		}
+		
+		
+		
+
+		return maxIndex;
+
+	}
+
+
+	SIMD_FORCE_INLINE int minAxis4() const
+	{
+		int minIndex = -1;
+		btScalar minVal = btScalar(1e30);
+		if (m_floats[0] < minVal)
+		{
+			minIndex = 0;
+			minVal = m_floats[0];
+		}
+		if (m_floats[1] < minVal)
+		{
+			minIndex = 1;
+			minVal = m_floats[1];
+		}
+		if (m_floats[2] < minVal)
+		{
+			minIndex = 2;
+			minVal =m_floats[2];
+		}
+		if (m_floats[3] < minVal)
+		{
+			minIndex = 3;
+			minVal = m_floats[3];
+		}
+		
+		return minIndex;
+
+	}
+
+
+	SIMD_FORCE_INLINE int closestAxis4() const 
+	{
+		return absolute4().maxAxis4();
+	}
+
+	
+ 
+
+  /**@brief Set x,y,z and zero w 
+   * @param x Value of x
+   * @param y Value of y
+   * @param z Value of z
+   */
+		
+
+/*		void getValue(btScalar *m) const 
+		{
+			m[0] = m_floats[0];
+			m[1] = m_floats[1];
+			m[2] =m_floats[2];
+		}
+*/
+/**@brief Set the values 
+   * @param x Value of x
+   * @param y Value of y
+   * @param z Value of z
+   * @param w Value of w
+   */
+		SIMD_FORCE_INLINE void	setValue(const btScalar& x, const btScalar& y, const btScalar& z,const btScalar& w)
+		{
+			m_floats[0]=x;
+			m_floats[1]=y;
+			m_floats[2]=z;
+			m_floats[3]=w;
+		}
+
+
+ 
+
+};
+
+
+///btSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization
+SIMD_FORCE_INLINE void	btSwapScalarEndian(const btScalar& sourceVal, btScalar& destVal)
+{
+	#ifdef BT_USE_DOUBLE_PRECISION
+	unsigned char* dest = (unsigned char*) &destVal;
+	unsigned char* src  = (unsigned char*) &sourceVal;
+	dest[0] = src[7];
+    dest[1] = src[6];
+    dest[2] = src[5];
+    dest[3] = src[4];
+    dest[4] = src[3];
+    dest[5] = src[2];
+    dest[6] = src[1];
+    dest[7] = src[0];
+#else
+	unsigned char* dest = (unsigned char*) &destVal;
+	unsigned char* src  = (unsigned char*) &sourceVal;
+	dest[0] = src[3];
+    dest[1] = src[2];
+    dest[2] = src[1];
+    dest[3] = src[0];
+#endif //BT_USE_DOUBLE_PRECISION
+}
+///btSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization
+SIMD_FORCE_INLINE void	btSwapVector3Endian(const btVector3& sourceVec, btVector3& destVec)
+{
+	for (int i=0;i<4;i++)
+	{
+		btSwapScalarEndian(sourceVec[i],destVec[i]);
+	}
+
+}
+
+///btUnSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization
+SIMD_FORCE_INLINE void	btUnSwapVector3Endian(btVector3& vector)
+{
+
+	btVector3	swappedVec;
+	for (int i=0;i<4;i++)
+	{
+		btSwapScalarEndian(vector[i],swappedVec[i]);
+	}
+	vector = swappedVec;
+}
+
+#endif //SIMD__VECTOR3_H
Index: /code/branches/rocket2/src/external/bullet/NEWS
===================================================================
--- /code/branches/rocket2/src/external/bullet/NEWS	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/NEWS	(revision 6952)
@@ -0,0 +1,4 @@
+
+For news, visit the Bullet Physics Forum at
+http://www.continuousphysics.com/Bullet/phpBB2/viewforum.php?f=9
+
Index: /code/branches/rocket2/src/external/bullet/README
===================================================================
--- /code/branches/rocket2/src/external/bullet/README	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/README	(revision 6952)
@@ -0,0 +1,7 @@
+
+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
Index: /code/branches/rocket2/src/external/bullet/VERSION
===================================================================
--- /code/branches/rocket2/src/external/bullet/VERSION	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/VERSION	(revision 6952)
@@ -0,0 +1,1 @@
+2.73
Index: /code/branches/rocket2/src/external/bullet/btBulletCollisionCommon.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/btBulletCollisionCommon.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/btBulletCollisionCommon.h	(revision 6952)
@@ -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 BULLET_COLLISION_COMMON_H
+#define BULLET_COLLISION_COMMON_H
+
+///Common headerfile includes for Bullet Collision Detection
+
+///Bullet's btCollisionWorld and btCollisionObject definitions
+#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
+
+///Collision Shapes
+#include "BulletCollision/CollisionShapes/btBoxShape.h"
+#include "BulletCollision/CollisionShapes/btSphereShape.h"
+#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
+#include "BulletCollision/CollisionShapes/btCylinderShape.h"
+#include "BulletCollision/CollisionShapes/btConeShape.h"
+#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
+#include "BulletCollision/CollisionShapes/btConvexHullShape.h"
+#include "BulletCollision/CollisionShapes/btTriangleMesh.h"
+#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h"
+#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
+#include "BulletCollision/CollisionShapes/btTriangleMeshShape.h"
+#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
+#include "BulletCollision/CollisionShapes/btCompoundShape.h"
+#include "BulletCollision/CollisionShapes/btTetrahedronShape.h"
+#include "BulletCollision/CollisionShapes/btEmptyShape.h"
+#include "BulletCollision/CollisionShapes/btMultiSphereShape.h"
+#include "BulletCollision/CollisionShapes/btUniformScalingShape.h"
+
+///Narrowphase Collision Detector
+#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h"
+
+//btSphereBoxCollisionAlgorithm is broken, use gjk for now
+//#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h"
+#include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h"
+
+///Dispatching and generation of collision pairs (broadphase)
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
+#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
+#include "BulletCollision/BroadphaseCollision/btAxisSweep3.h"
+#include "BulletCollision/BroadphaseCollision/btMultiSapBroadphase.h"
+#include "BulletCollision/BroadphaseCollision/btDbvtBroadphase.h"
+
+///Math library & Utils
+#include "LinearMath/btQuaternion.h"
+#include "LinearMath/btTransform.h"
+#include "LinearMath/btDefaultMotionState.h"
+#include "LinearMath/btQuickprof.h"
+#include "LinearMath/btIDebugDraw.h"
+
+#endif //BULLET_COLLISION_COMMON_H
+
Index: /code/branches/rocket2/src/external/bullet/btBulletDynamicsCommon.h
===================================================================
--- /code/branches/rocket2/src/external/bullet/btBulletDynamicsCommon.h	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/btBulletDynamicsCommon.h	(revision 6952)
@@ -0,0 +1,46 @@
+/*
+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 BULLET_DYNAMICS_COMMON_H
+#define BULLET_DYNAMICS_COMMON_H
+
+///Common headerfile includes for Bullet Dynamics, including Collision Detection
+#include "btBulletCollisionCommon.h"
+
+#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h"
+#include "BulletDynamics/Dynamics/btContinuousDynamicsWorld.h"
+
+#include "BulletDynamics/Dynamics/btSimpleDynamicsWorld.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+
+#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btHingeConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h"
+#include "BulletDynamics/ConstraintSolver/btSliderConstraint.h"
+
+#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
+
+
+///Vehicle simulation, with wheel contact simulated by raycasts
+#include "BulletDynamics/Vehicle/btRaycastVehicle.h"
+
+
+
+
+
+
+#endif //BULLET_DYNAMICS_COMMON_H
+
Index: /code/branches/rocket2/src/external/bullet/changes_orxonox.diff
===================================================================
--- /code/branches/rocket2/src/external/bullet/changes_orxonox.diff	(revision 6952)
+++ /code/branches/rocket2/src/external/bullet/changes_orxonox.diff	(revision 6952)
@@ -0,0 +1,17 @@
+Index: btScalar.h
+===================================================================
+--- btScalar.h	(revision 2882)
++++ btScalar.h	(working copy)
+@@ -236,7 +236,11 @@
+ SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); }
+ SIMD_FORCE_INLINE btScalar btExp(btScalar x) { return expf(x); }
+ SIMD_FORCE_INLINE btScalar btLog(btScalar x) { return logf(x); }
+-SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
++  #if defined( __MINGW32__ )
++  SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return pow(x,y); }
++  #else
++  SIMD_FORCE_INLINE btScalar btPow(btScalar x,btScalar y) { return powf(x,y); }
++  #endif
+
+ #endif
+
Index: /code/branches/rocket2/src/external/ceguilua/AUTHORS_CEGUI
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/AUTHORS_CEGUI	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/AUTHORS_CEGUI	(revision 6952)
@@ -0,0 +1,112 @@
+Crazy Eddie's GUI System Mk-2
+http://www.cegui.org.uk
+
+Copyright ©2004 - 2008 CEGUI Team & Contributing Authors
+
+
+The following is a list of primary authors and contributors for Crazy Eddie's
+GUI System Mk-2.
+
+
+CEGUI Team
+---------
+James O'Sullivan (_mental_)
+Tomas Lindquist Olsen (lindquist)
+Paul D Turner (crayzed / CrazyEddie)
+Patrick Kooman (scriptkid)
+Paul Schifferer (Exsortis)
+Olivier Delannoy (Dalfy)
+
+CEGUI Tools Team
+----------------
+
+Frederico Jeronimo (fjeronimo). See:
+- http://www.cegui.org.uk/phpBB2/viewtopic.php?t=2766
+- http://www.cegui.org.uk/phpBB2/viewtopic.php?t=2785
+- http://www.cegui.org.uk/phpBB2/viewtopic.php?t=2799
+- http://www.cegui.org.uk/phpBB2/viewtopic.php?t=2816
+
+Main Contributors
+-----------------
+The following have made large, important, or on-going contributions to the
+system (these people may have made additional contributions than those
+specifically mentioned)...
+
+Lars Rinde:
+- Original TaharezLook graphics design.
+
+'Blakharaz':
+- Initial XmlHandlerHelper class and general cleanup of original XML parsing
+code.
+
+Jeff Leigh:
+- Original CEGUI::ColourManipulator class (now re-factored into CEGUI::colour
+class) and related fixes.
+
+Jose A Milan:
+- Refactoring of XML handling classes to remove public dependency on Xerces-C++.
+- Initial updates to Ogre renderer to support Ogre 1.0.
+
+Magnus Osterlind:
+- Direct3D 9 GUI renderer module.
+
+Steve Streeting:
+- TabControl widget base classes & related 'TaharezLook' classes.
+
+Mark Strom:
+- OpenGL GUI renderer module.
+
+Thomas Suter:
+- Irrlicht GUI renderer module.
+
+Andrew Zabolotny:
+- Font class rewrite.
+
+
+Other Contributors
+------------------
+The following have contributed patches, bug reports, and other such valuable
+things...
+
+Tupone Alfredo
+Geoff Carlton
+Clay Culver
+Paul Downey
+Jeff Doyle
+Jan Eickmann
+Andrzej Krzysztof Haczewski
+Markus Henschel
+Erik Hjortsberg
+Rafal Jastrzebski
+Chris Kang
+Peter Newman
+Chris Osborn
+Shane Parker
+Andrea Santambrogio
+James Turner
+Chris Weaver
+Christopher Wedman
+armaduck
+genva
+Te'ja
+Xavier
+
+
+Special Thanks
+--------------
+Shawn Carroll	- For his tutorial series.
+Chris McGuirk	- For his C#.Net port.
+Shane Parker	- For giving permission to use his "Vanilla GUI" imagery.
+
+Everyone on the GameDev.Net forums who looked at earlier versions of the system
+and gave constructive criticism.
+
+Everyone on the Ogre forums who encouraged the development of this Mk-2 version
+of the system.
+
+
+Have I Missed You?
+------------------
+If you feel that we have missed you from some section of this list, then please
+contact us (team@cegui.org.uk) and let us know who you are and what you did,
+and we'll correct the mistake as soon as possible.
Index: /code/branches/rocket2/src/external/ceguilua/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,86 @@
+ #
+ #             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.
+ #
+
+SET(CEGUILUA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ceguilua-${CEGUI_VERSION}/ceguilua)
+SET(CEGUILUA_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
+
+SET(CEGUILUA_FILES
+  ${CEGUILUA_DIR}/CEGUILua.cpp
+  ${CEGUILUA_DIR}/CEGUILuaFunctor.cpp
+  ${CEGUILUA_DIR}/required.cpp
+  ${CEGUILUA_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lua_CEGUI.cpp
+
+  ${CEGUILUA_DIR}/CEGUILua.h
+  ${CEGUILUA_DIR}/CEGUILuaFunctor.h
+  ${CEGUILUA_DIR}/required.h
+)
+
+INCLUDE(CompareVersionStrings)
+
+# Copy package files incrementally until the version is met
+SET(CEGUILUA_VERSIONS 0.5.0 0.6.0 0.6.1 0.6.2)
+# Only copy on version change
+IF(NOT "${_CEGUI_VERSION_REF}" STREQUAL "${CEGUI_VERSION}"
+   OR NOT EXISTS ${CEGUILUA_BINARY_DIR}/exceptions.lua)
+  SET(_CEGUI_VERSION_REF ${CEGUI_VERSION} CACHE INTERNAL "Do not edit")
+  FOREACH(_version ${CEGUILUA_VERSIONS})
+    COMPARE_VERSION_STRINGS(${_version} ${CEGUI_VERSION} _compare_result)
+    IF(_compare_result EQUAL 1)
+      BREAK() # _version > CEGUI_VERSION
+    ENDIF()
+
+    ADD_SUBDIRECTORY(ceguilua-${_version}) # Sets parent scope variable _package_files
+    FOREACH(_file ${_package_files})
+      CONFIGURE_FILE(ceguilua-${_version}/package/${_file} ${CEGUILUA_BINARY_DIR}/${_file} COPYONLY)
+    ENDFOREACH(_file)
+  ENDFOREACH(_version)
+ENDIF()
+
+# Create the tolua bind file. We could use the orignal file though, but it is 1.6MB...
+ADD_CUSTOM_COMMAND(
+  OUTPUT ${CEGUILUA_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lua_CEGUI.cpp
+  COMMAND tolua++app_orxonox -n CEGUI
+                             -w ${CEGUILUA_BINARY_DIR}
+                             -o ${CMAKE_CFG_INTDIR}/lua_CEGUI.cpp
+                             -L exceptions.lua
+                             -s ${TOLUA_PARSER_SOURCE}
+                                CEGUI.pkg
+  DEPENDS              ${TOLUA_PARSER_DEPENDENCIES}
+  WORKING_DIRECTORY    ${RUNTIME_LIBRARY_DIRECTORY}
+  COMMENT "Generating tolua bind files for package CEGUILua"
+)
+
+SOURCE_GROUP("Source" FILES ${CEGUILUA_FILES})
+
+SET(CEGUILUA_LIBRARY ceguilua_orxonox)
+SET(CEGUILUA_LIBRARY ${CEGUILUA_LIBRARY} PARENT_SCOPE)
+ORXONOX_ADD_LIBRARY(${CEGUILUA_LIBRARY}
+  ORXONOX_EXTERNAL
+  NO_SOURCE_GROUPS
+  DEFINE_SYMBOL
+    "CEGUILUA_EXPORTS"
+  VERSION
+    ${CEGUI_VERSION}
+  LINK_LIBRARIES
+    tolua++_orxonox
+    ${LUA_LIBRARIES}
+    ${CEGUI_LIBRARY}
+  SOURCE_FILES
+    ${CEGUILUA_FILES}
+)
Index: /code/branches/rocket2/src/external/ceguilua/COPYING
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/COPYING	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/COPYING	(revision 6952)
@@ -0,0 +1,20 @@
+The MIT License
+
+Copyright (c) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Index: /code/branches/rocket2/src/external/ceguilua/ChangeLog
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ChangeLog	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ChangeLog	(revision 6952)
@@ -0,0 +1,130 @@
+Crazy Eddie's GUI System Mk-2
+http://www.cegui.org.uk
+
+Copyright 2004 - 2008 CEGUI Team & Contributing Authors
+
+
+The following is a high-level view of changes made to the system between releases.
+
+All changes not related to the lua script module have been deleted!
+
+Release 0.6.2
+=============
+Added: Support for TreeEventArgs in the lua scripting module (patch from kripken, http://www.cegui.org.uk/phpBB2/viewtopic.php?t=3704)
+Added: Added ability to specify a function to be used as the error handler in calls to lua_pcall.  See: http://www.cegui.org.uk/mantis/view.php?id=239
+
+Modified: Forward CEGUI::ScriptException from within the CEGUI::System script execution functions as opposed to translating them into less useful CEGUI::GenericException.  See: http://www.cegui.org.uk/phpBB2/viewtopic.php?t=3595
+
+Bug Fix: Event connection objects returned to lua subscribeEvent calls did not have the connected or disconnect members available for use (making the connection object useless).
+Bug Fix: Lua script module based 'executeScriptedEventHandler was still not returning correct value (missed when I did the LuaFunctor version of the same, see: http://www.cegui.org.uk/mantis/view.php?id=225 for original issue).
+Bug Fix: ScriptModule bindings were destroyed out of sequence meaning event handlers could still be fired that needed CEGUI bindings to exist.  See: http://www.cegui.org.uk/mantis/view.php?id=245.
+Bug Fix: The C++ side of the lua based event mechanism would always return true as if the event were handled, even if some other boolean value (i.e. false) were returned from the lua side.  See: http://www.cegui.org.uk/mantis/view.php?id=225
+
+
+Release 0.6.1
+=============
+Modified: On linux, use installed system versions of tolua++ and TinyXML libraries if available (can be disabled to force continued use of internal versions).  See: http://www.cegui.org.uk/mantis/view.php?id=198
+
+Bug Fix: Need to bring in CEGUIConfig.h when building CEGUILua.cpp in case we're on a Mac.
+Bug Fix: uncomment part of cegui.lua configuration script that allows use of option to have Ogre in samples.
+Bug Fix: tolua++cegui generator missing Lua_CFLAGS in autotools build.
+
+
+Release 0.6.0
+=============
+Added: Levia's GroupBox to the Lua module.
+Added: Warning log level to the Lua module.
+
+Modified: tolua++cegui changes in exception handlers.
+
+Bug Fix: Lua 5.1 removes table.setn - update code to use alternate method of ensuring table is indeed empty.
+Bug Fix: Lua was not correctly detected on (K)Ubuntu type systems (http://www.cegui.org.uk/mantis/view.php?id=138)
+Bug Fix: Support lua 5.1 in CEGUILua.cpp (not sure of generator status with 5.1) (http://www.cegui.org.uk/mantis/view.php?id=161)
+Bug Fix: warnings of unused local variables in lua_CEGUI.cpp fixed.
+Bug Fix: Fixed Memory Leak in Lua Scripting Module when it throws and helper object has already been created.
+
+
+Release 0.5.0 (Final)
+=====================
+Added: Missing functions in WindowFactoryManager Lua bindings. Incomplete FalagardWindowMapping binding as well.
+Added: Lua binding for OutStream: FileStream (minimal std::ofstream).
+Added: XML writing function in Lua bindings.
+
+Modified: Renamed tolua++bin/remake_pkg..bat to remove extra period
+
+
+Release 0.5.0-RC2
+=================
+Modified: Removed static Makefile for tolua++cegui generator tool and switched to autotools style build, with enable/disable configure option, for tolua++cegui generator tool
+Modified: Moved tolua++ into it's own dir, removed lua_and_tolua++
+Modified: Externalised our use of the Lua library
+Modified: LuaScriptModule public headers no longer need include lua.h included.
+
+Bug Fix: Corrected some mistakes in the Falagard Lua bindings
+Bug Fix: Lua bindings was missing ImagesetManager::createImagesetFromImageFile + some missing tolua_throws modifiers
+
+
+Release 0.5.0-RC1
+=================
+CEGUI MK2 has moved to the MIT license.
+
+Added: small script to recreate the binding generator for tolua++
+Added: customized tolua++ binary. For exception handling support in generated binding code.
+Added: Documentation for some of the new features in the bundled tolua++ generator.
+Added: When subscribing to events from "inside" Lua a self object can be registered as well to be passed along with the EventArgs.
+Added: Major update of the LuaScriptModule to support anonymous functions.
+Added: Default resource group support to ScriptingModule, and implemented it's use in the CEGUILua module.
+Added: Lots of missing members in the Lua bindings.
+Added: bat files to make it easier for Windows users to regenerate the Lua bindings and tolua++cegui.
+
+Modified: The "Lua and tolua++" module has been made a DLL on Windows machines.
+Modified: In the lua module, updated Window with casting helpers as member functions. eg. w:toFrameWindow()
+Modified: Updated to tolua++ 1.0.92
+Modified: Moved LuaFunctor into its own files
+Modified: Reimplemented the "late binding" effect from the v04 Lua module. In v04 the function is always looked up by name. In CVS HEAD the actual Lua function is referenced, but now this will only occur the first time the event is triggered. This means that it's no longer necessary to have a function defined to subscribe it to an event. As long as the function has been created before the event occurs everything will be good Smile
+Modified: Moved subscribeScriptedEvent into ScriptModule to allow more customized script subscription functionality.
+Modified: Removal of "tolua_outside" stuff that was no longer needed.
+Modified: The script module now throws ScriptException.
+Modified: The bundled tolua++cegui binding generator will now generate a lua_CEGUI.cpp that compiles out-of-the-box on Windows
+
+Bug Fix: Bug in LuaScriptModule where executeScriptFile did not unload the file data buffer correctly in case of an exception (thanks gcarlton).
+
+
+Release 0.4.1
+=============
+
+
+Release 0.4.0
+=============
+Added: Missing Lua bindings for some System based Tooltip stuff.
+Added: Missing Lua bindings for Menusystem widgets.
+Added: Lua module 'toKeyEventArgs' helper 
+Added: Support to the Lua module for FontFlags to allow direct loading of TTF fonts from script without using .font files.
+
+Modified: Lua scripting module renamed to CEGUILua (Win32 systems).
+
+Bug Fix: Fixed some uint/ColourRect/String CEGUILua issues.
+
+
+Release 0.3.0
+=============
+Added: Lua based ScriptModule (including optional embedded lua and toloua++) for Win32 and Linux users.
+Added: resourceGroup parameter to executeScriptFile methods.
+
+
+Release 0.2.1
+=============
+
+
+Release 0.2.0
+=============
+Added: CEGUI::System constructor overload to allow custom ResourceProvider to be specified when also using a ScriptModule.
+
+
+Release 0.1.1
+=============
+
+
+Release 0.1.0
+=============
+Initial release.
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,34 @@
+SET(_package_files
+  exceptions.lua Basic.pkg FontManager.pkg InputEvent.pkg OutStream.pkg
+  System.pkg WindowManager.pkg CEGUI.pkg HelperFunctions.pkg Iterators.pkg
+  PropertyHelper.pkg Texture.pkg CoordConverter.pkg Image.pkg Key.pkg
+  Renderer.pkg UnifiedCoordSystem.pkg EventSet.pkg Imageset.pkg Logger.pkg
+  Scheme.pkg Window.pkg Font.pkg ImagesetManager.pkg MouseCursor.pkg
+  SchemeManager.pkg WindowFactoryManager.pkg
+
+  elements/ButtonBase.pkg elements/Checkbox.pkg elements/ComboDropList.pkg
+  elements/Combobox.pkg elements/DragContainer.pkg elements/Editbox.pkg
+  elements/FrameWindow.pkg elements/GUISheet.pkg elements/ItemEntry.pkg
+  elements/ItemListBase.pkg elements/ItemListbox.pkg elements/ListHeader.pkg
+  elements/ListHeaderSegment.pkg elements/Listbox.pkg elements/ListboxItem.pkg
+  elements/ListboxTextItem.pkg elements/MenuBase.pkg elements/MenuItem.pkg
+  elements/Menubar.pkg elements/MultiColumnList.pkg
+  elements/MultiLineEditbox.pkg elements/PopupMenu.pkg elements/ProgressBar.pkg
+  elements/PushButton.pkg elements/RadioButton.pkg elements/ScrollablePane.pkg
+  elements/Scrollbar.pkg elements/ScrolledContainer.pkg
+  elements/ScrolledItemListBase.pkg elements/Slider.pkg elements/Spinner.pkg
+  elements/TabButton.pkg elements/TabControl.pkg elements/Thumb.pkg
+  elements/Titlebar.pkg elements/Tooltip.pkg
+
+  falagard/Dimension.pkg falagard/Enums.pkg falagard/FalagardComponentBase.pkg
+  falagard/FrameComponent.pkg falagard/ImageryComponent.pkg
+  falagard/ImagerySection.pkg falagard/LayerSpecification.pkg
+  falagard/NamedArea.pkg falagard/PropertyDefinition.pkg
+  falagard/PropertyDefinitionBase.pkg falagard/PropertyInitialiser.pkg
+  falagard/PropertyLinkDefinition.pkg falagard/SectionSpecification.pkg
+  falagard/StateImagery.pkg falagard/TextComponent.pkg
+  falagard/WidgetComponent.pkg falagard/WidgetLookFeel.pkg
+  falagard/WidgetLookManager.pkg
+
+  PARENT_SCOPE
+)
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/CEGUILua.cpp
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/CEGUILua.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/CEGUILua.cpp	(revision 6952)
@@ -0,0 +1,312 @@
+/***********************************************************************
+	filename: CEGUILua.cpp
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+	
+	purpose:  Implementation for LuaScriptModule class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUI.h"
+#include "CEGUIPropertyHelper.h"
+#include "CEGUILua.h"
+#include "CEGUILuaFunctor.h"
+#include <vector>
+
+// include Lua libs and tolua++
+extern "C" {
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+}
+
+#include "tolua/tolua++.h"
+
+// prototype for bindings initialisation function
+int tolua_CEGUI_open(lua_State* tolua_S);
+
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*************************************************************************
+	Constructor (creates Lua state)
+*************************************************************************/
+LuaScriptModule::LuaScriptModule()
+{
+    #if LUA_VERSION_NUM >= 501
+        static const luaL_Reg lualibs[] = {
+            {"", luaopen_base},
+            {LUA_LOADLIBNAME, luaopen_package},
+            {LUA_TABLIBNAME, luaopen_table},
+            {LUA_IOLIBNAME, luaopen_io},
+            {LUA_OSLIBNAME, luaopen_os},
+            {LUA_STRLIBNAME, luaopen_string},
+            {LUA_MATHLIBNAME, luaopen_math},
+        #if defined(DEBUG) || defined (_DEBUG)
+                {LUA_DBLIBNAME, luaopen_debug},
+        #endif
+            {0, 0}
+        };
+    #endif /* LUA_VERSION_NUM >= 501 */
+
+	// create a lua state
+	d_ownsState = true;
+	d_state = lua_open();
+
+	// init all standard libraries
+    #if LUA_VERSION_NUM >= 501
+            const luaL_Reg *lib = lualibs;
+            for (; lib->func; lib++)
+            {
+                lua_pushcfunction(d_state, lib->func);
+                lua_pushstring(d_state, lib->name);
+                lua_call(d_state, 1, 0);
+            }
+    #else /* LUA_VERSION_NUM >= 501 */
+	    luaopen_base(d_state);
+	    luaopen_io(d_state);
+	    luaopen_string(d_state);
+	    luaopen_table(d_state);
+	    luaopen_math(d_state);
+        #if defined(DEBUG) || defined (_DEBUG)
+	        luaopen_debug(d_state);
+        #endif
+    #endif /* LUA_VERSION_NUM >= 501 */
+
+	setModuleIdentifierString();
+}
+
+
+/*************************************************************************
+	Constructor (uses given Lua state)
+*************************************************************************/
+LuaScriptModule::LuaScriptModule(lua_State* state)
+{
+	// just use the given state
+	d_ownsState = false;
+	d_state = state;
+
+	setModuleIdentifierString();
+}
+
+
+/*************************************************************************
+	Destructor
+*************************************************************************/
+LuaScriptModule::~LuaScriptModule()
+{
+	if ( d_ownsState && d_state )
+	{
+		lua_close( d_state );
+	}
+}
+
+
+/*************************************************************************
+	Execute script file
+*************************************************************************/
+void LuaScriptModule::executeScriptFile(const String& filename, const String& resourceGroup)
+{
+	// load file
+	RawDataContainer raw;
+	System::getSingleton().getResourceProvider()->loadRawDataContainer(filename,
+        raw, resourceGroup.empty() ? d_defaultResourceGroup : resourceGroup);
+
+	// load code into lua
+	int top = lua_gettop(d_state);
+	int loaderr = luaL_loadbuffer(d_state, (char*)raw.getDataPtr(), raw.getSize(), filename.c_str());
+	System::getSingleton().getResourceProvider()->unloadRawDataContainer( raw );
+	if (loaderr)
+	{
+	    String errMsg = lua_tostring(d_state,-1);
+		lua_settop(d_state,top);
+		throw ScriptException("Unable to execute Lua script file: '"+filename+"'\n\n"+errMsg+"\n");
+	}
+    
+    // call it
+	if (lua_pcall(d_state,0,0,0))
+	{
+	    String errMsg = lua_tostring(d_state,-1);
+		lua_settop(d_state,top);
+		throw ScriptException("Unable to execute Lua script file: '"+filename+"'\n\n"+errMsg+"\n");
+	}
+
+	lua_settop(d_state,top); // just in case :P
+}
+
+
+/*************************************************************************
+	Execute global script function
+*************************************************************************/
+int	LuaScriptModule::executeScriptGlobal(const String& function_name)
+{
+    int top = lua_gettop(d_state);
+
+    // get the function from lua
+    lua_getglobal(d_state, function_name.c_str());
+
+    // is it a function
+    if (!lua_isfunction(d_state,-1))
+    {
+        lua_settop(d_state,top);
+        throw ScriptException("Unable to get Lua global: '"+function_name+"' as name not represent a global Lua function" );
+    }
+
+    // call it
+    int error = lua_pcall(d_state,0,1,0);		
+
+    // handle errors
+    if (error)
+    {
+        String errMsg = lua_tostring(d_state,-1);
+        lua_pop(d_state,1);
+        throw ScriptException("Unable to evaluate Lua global: '"+function_name+"\n\n"+errMsg+"\n");
+    }
+
+    // get return value
+    if (!lua_isnumber(d_state,-1))
+    {
+        // log that return value is invalid. return -1 and move on.
+        lua_settop(d_state,top);
+        ScriptException("Unable to get Lua global : '"+function_name+"' return value as it's not a number" );
+        return -1;
+    }
+
+    int ret = (int)lua_tonumber(d_state,-1);
+    lua_pop(d_state,1);
+
+    // return it
+    return ret;
+}
+
+
+/*************************************************************************
+	Execute scripted event handler
+*************************************************************************/
+bool LuaScriptModule::executeScriptedEventHandler(const String& handler_name, const EventArgs& e)
+{
+    LuaFunctor::pushNamedFunction(d_state, handler_name);
+
+    // push EventArgs as the first parameter
+    tolua_pushusertype(d_state,(void*)&e,"const CEGUI::EventArgs");
+
+    // call it
+    int error = lua_pcall(d_state,1,0,0);
+
+    // handle errors
+    if (error)
+    {
+        String errStr(lua_tostring(d_state,-1));
+        lua_pop(d_state,1);
+        throw ScriptException("Unable to evaluate the Lua event handler: '"+handler_name+"'\n\n"+errStr+"\n");
+    }
+
+    return true;
+}
+
+
+/*************************************************************************
+	Execute script code string
+*************************************************************************/
+void LuaScriptModule::executeString(const String& str)
+{
+    int top = lua_gettop(d_state);
+
+    // load code into lua and call it
+    int error =	luaL_loadbuffer(d_state, str.c_str(), str.length(), str.c_str()) || lua_pcall(d_state,0,0,0);
+
+    // handle errors
+    if (error)
+    {
+        String errMsg = lua_tostring(d_state,-1);
+        lua_settop(d_state,top);
+        throw ScriptException("Unable to execute Lua script string: '"+str+"'\n\n"+errMsg+"\n");
+    }
+}
+	
+
+/*************************************************************************
+	Create Lua bindings
+*************************************************************************/
+void LuaScriptModule::createBindings(void)
+{
+	CEGUI::Logger::getSingleton().logEvent( "---- Creating Lua bindings ----" );
+	// init CEGUI module
+	tolua_CEGUI_open(d_state);
+}
+
+
+/*************************************************************************
+	Destroy Lua bindings
+*************************************************************************/
+void LuaScriptModule::destroyBindings(void)
+{
+	CEGUI::Logger::getSingleton().logEvent( "---- Destroying Lua bindings ----" );
+	// is this ok ?
+	lua_pushnil(d_state);
+	lua_setglobal(d_state,"CEGUI");
+}
+
+
+/*************************************************************************
+	Set the ID string for the module
+*************************************************************************/
+void LuaScriptModule::setModuleIdentifierString()
+{
+    // set ID string
+    d_identifierString = "CEGUI::LuaScriptModule - Official Lua based scripting module for CEGUI";
+}
+
+
+/*************************************************************************
+	Subscribe to a scripted event handler
+*************************************************************************/
+Event::Connection LuaScriptModule::subscribeEvent(EventSet* target, const String& event_name, const String& subscriber_name)
+{
+    // do the real subscription
+    LuaFunctor functor(d_state,subscriber_name,LUA_NOREF);
+    Event::Connection con = target->subscribeEvent(event_name, Event::Subscriber(functor));
+    // make sure we don't release the reference we just made when this call returns
+    functor.index = LUA_NOREF;
+
+    // return the event connection
+    return con;
+}
+
+
+/*************************************************************************
+	Subscribe to a scripted event handler
+*************************************************************************/
+Event::Connection LuaScriptModule::subscribeEvent(EventSet* target, const String& event_name, Event::Group group, const String& subscriber_name)
+{
+    // do the real subscription
+    LuaFunctor functor(d_state,subscriber_name,LUA_NOREF);
+    Event::Connection con = target->subscribeEvent(event_name, group, Event::Subscriber(functor));
+
+    // return the event connection
+    return con;
+}
+
+} // namespace CEGUI
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/CEGUILua.h
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/CEGUILua.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/CEGUILua.h	(revision 6952)
@@ -0,0 +1,253 @@
+/***********************************************************************
+	filename: CEGUILua.h
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+	
+	purpose:  Defines interface for LuaScriptModule class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#ifndef _CEGUILua_h_
+#define _CEGUILua_h_
+
+
+/*************************************************************************
+	Import / Export control macros
+*************************************************************************/
+#if defined( __WIN32__ ) || defined( _WIN32 )
+#   ifdef CEGUILUA_EXPORTS
+#       define CEGUILUA_API __declspec(dllexport)
+#   else
+#       if defined( __MINGW32__ )
+#           define CEGUILUA_API
+#       else
+#           define CEGUILUA_API __declspec(dllimport)
+#       endif
+#   endif
+#else
+#   define CEGUILUA_API
+#endif
+
+
+#include "CEGUIScriptModule.h"
+
+struct lua_State;
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*!
+\brief
+	Interface for the LuaScriptModule class
+*/
+class CEGUILUA_API LuaScriptModule : public CEGUI::ScriptModule
+{
+public:
+	/*************************************************************************
+		Construction and Destruction
+	*************************************************************************/
+	/*!
+	\brief
+		Constructor for LuaScriptModule class which create a lua_State
+	*/
+	LuaScriptModule();
+
+
+	/*!
+	\brief
+		Constructor for LuaScriptModule class which takes a lua_State
+
+	\param state
+		Pointer to the lua_State that the script module should attach to.
+	*/
+	LuaScriptModule(lua_State* state);
+
+
+	/*!
+	\brief
+		Destructor for LuaScriptModule class.
+	*/
+	~LuaScriptModule();
+
+
+	/*************************************************************************
+		Script Execution Functions
+	*************************************************************************/
+	/*!
+	\brief
+		Execute a script file.
+
+	\param filename
+		String object holding the filename of the script file that is to be executed
+		
+	\param resourceGroup
+		Resource group idendifier to be passed to the ResourceProvider when loading the script file.
+	*/
+	void executeScriptFile(const String& filename, const String& resourceGroup);
+
+
+	/*!
+	\brief
+		Execute a scripted global function.  The function should not take any parameters and should return an integer.
+
+	\param function_name
+		String object holding the name of the function, in the global script environment, that
+		is to be executed.
+
+	\return
+		The integer value returned from the script function.
+	*/
+	int executeScriptGlobal(const String& function_name);
+
+
+    /*!
+    \brief
+        Execute a scripted global 'event handler' function by looking it up by name.
+
+    \param handler_name
+        String object holding the name of the scripted handler function.
+        If this string contains dots '.' it will be parsed as tables containing a function field.
+        For example: 'mytable.subtable.func'
+
+    \param e
+        EventArgs based object that should be passed, by any appropriate means, to the scripted function.
+
+    \return
+        - true if the event was handled.
+        - false if the event was not handled.
+    */
+    bool executeScriptedEventHandler(const String& handler_name, const EventArgs& e);
+
+
+    /*!
+    \brief
+        Execute script code contained in the given CEGUI::String object.
+
+    \param str
+        String object holding the valid script code that should be executed.
+
+    \return
+        Nothing.
+    */
+    void executeString(const String& str);
+
+    /*************************************************************************
+        Event subscription
+    *************************************************************************/
+    /*!
+    \brief
+            Subscribes the named Event to a scripted funtion
+
+    \param target
+            The target EventSet for the subscription.
+
+    \param name
+            String object containing the name of the Event to subscribe to.
+
+    \param subscriber_name
+            String object containing the name of the script funtion that is to be subscribed to the Event.
+
+    \return
+            Connection object that can be used to check the status of the Event connection and to disconnect (unsubscribe) from the Event.
+
+    \exception UnknownObjectException	Thrown if an Event named \a name is not in the EventSet
+    */
+    Event::Connection	subscribeEvent(EventSet* target, const String& name, const String& subscriber_name);
+
+    /*!
+    \brief
+            Subscribes the specified group of the named Event to a scripted funtion.
+
+    \param target
+            The target EventSet for the subscription.
+
+    \param name
+            String object containing the name of the Event to subscribe to.
+
+    \param group
+            Group which is to be subscribed to.  Subscription groups are called in ascending order.
+
+    \param subscriber_name
+            String object containing the name of the script funtion that is to be subscribed to the Event.
+
+    \return
+            Connection object that can be used to check the status of the Event connection and to disconnect (unsubscribe) from the Event.
+
+    \exception UnknownObjectException	Thrown if an Event named \a name is not in the EventSet
+    */
+    Event::Connection	subscribeEvent(EventSet* target, const String& name, Event::Group group, const String& subscriber_name);
+
+    /*************************************************************************
+        Bindings creation / destruction
+    *************************************************************************/
+    /*!
+    \brief
+        Method called during system initialisation, prior to running any scripts via the ScriptModule, to enable the ScriptModule
+        to perform any operations required to complete initialisation or binding of the script language to the gui system objects.
+
+    \return
+        Nothing.
+    */
+    void createBindings(void);
+
+
+    /*!
+    \brief
+        Method called during system destruction, after all scripts have been run via the ScriptModule, to enable the ScriptModule
+        to perform any operations required to cleanup bindings of the script language to the gui system objects, as set-up in the
+        earlier createBindings call.
+
+    \return
+        Nothing.
+    */
+    void destroyBindings(void);
+
+    /*************************************************************************
+        Accessor type functions
+    *************************************************************************/
+    /*!
+    \brief
+        Method used to get a pointer to the lua_State that the script module is attached to.
+
+    \return
+        A pointer to the lua_State that the script module is attached to.
+    */
+    lua_State* getLuaState(void) const {return d_state;}
+
+private:
+    /*************************************************************************
+        Implementation Functions
+    *************************************************************************/
+    void setModuleIdentifierString();
+
+    /*************************************************************************
+        Implementation Data
+    *************************************************************************/
+    bool d_ownsState;      //!< true when the attached lua_State was created by this script module
+    lua_State* d_state;    //!< The lua_State that this script module uses.
+};
+
+} // namespace CEGUI
+
+#endif // end of guard _CEGUILua_h_
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/CEGUILuaFunctor.cpp
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/CEGUILuaFunctor.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/CEGUILuaFunctor.cpp	(revision 6952)
@@ -0,0 +1,259 @@
+/***********************************************************************
+    filename: CEGUILuaFunctor.cpp
+    created:  Thu Jan 26 2006
+    author:   Tomas Lindquist Olsen <tomas@famolsen.dk>
+
+    purpose:  Implementation for LuaFunctor class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUILuaFunctor.h"
+#include "CEGUILogger.h"
+#include "CEGUIExceptions.h"
+#include "CEGUIPropertyHelper.h"
+
+// include Lua libs and tolua++
+extern "C" {
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+}
+
+#include "tolua/tolua++.h"
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*************************************************************************
+    Constructor
+*************************************************************************/
+LuaFunctor::LuaFunctor(lua_State* state, int func, int selfIndex) :
+    L(state),
+    index(func),
+    self(selfIndex),
+    needs_lookup(false)
+{
+}
+
+/*************************************************************************
+    Constructor
+*************************************************************************/
+LuaFunctor::LuaFunctor(lua_State* state, const String& func, int selfIndex) :
+    L(state),
+    index(LUA_NOREF),
+    self(selfIndex),
+    needs_lookup(true),
+    function_name(func)
+{
+}
+
+/*************************************************************************
+    Constructor
+*************************************************************************/
+LuaFunctor::LuaFunctor(const LuaFunctor& cp) :
+    L(cp.L),
+    index(cp.index),
+    self(cp.self),
+    needs_lookup(cp.needs_lookup),
+    function_name(cp.function_name)
+{
+}
+
+/*************************************************************************
+    Destructor
+*************************************************************************/
+LuaFunctor::~LuaFunctor()
+{
+    if (self!=LUA_NOREF)
+    {
+        luaL_unref(L, LUA_REGISTRYINDEX, self);
+    }
+    if (index!=LUA_NOREF)
+    {
+        luaL_unref(L, LUA_REGISTRYINDEX, index);
+    }
+}
+
+/*************************************************************************
+    Call operator
+*************************************************************************/
+bool LuaFunctor::operator()(const EventArgs& args) const
+{
+    // is this a late binding?
+    if (needs_lookup)
+    {
+        pushNamedFunction(L, function_name);
+        // reference function
+        index = luaL_ref(L, LUA_REGISTRYINDEX);
+        needs_lookup = false;
+        CEGUI_LOGINSANE("Late binding of callback '"+function_name+"' performed");
+        function_name.clear();
+    }
+
+    // retrieve function
+    lua_rawgeti(L, LUA_REGISTRYINDEX, index);
+
+    // possibly self as well?
+    int nargs = 1;
+    if (self != LUA_NOREF)
+    {
+        lua_rawgeti(L, LUA_REGISTRYINDEX, self);
+        ++nargs;
+    }
+
+    // push EventArgs  parameter
+    tolua_pushusertype(L, (void*)&args, "const CEGUI::EventArgs");
+
+    // call it
+    int error = lua_pcall(L, nargs, 0, 0);
+
+    // handle errors
+    if (error)
+    {
+        String errStr(lua_tostring(L, -1));
+        lua_pop(L, 1);
+        throw ScriptException("Unable to call Lua event handler:\n\n"+errStr+"\n");
+    }
+
+    return true;
+}
+
+/*************************************************************************
+    do event subscription by reference instead of by name
+*************************************************************************/
+Event::Connection LuaFunctor::SubscribeEvent(EventSet* self, const String& event_name, int funcIndex, int selfIndex, lua_State* L)
+{
+    // should we pass a self to the callback?
+    int thisIndex = LUA_NOREF;
+    if (selfIndex != LUA_NOREF)
+    {
+        // reference self
+        thisIndex = luaL_ref(L, LUA_REGISTRYINDEX);
+    }
+
+    // do the real subscription
+    int type = lua_type(L,-1);
+    Event::Connection con;
+    if (type == LUA_TFUNCTION)
+    {
+        // reference function
+        int index = luaL_ref(L, LUA_REGISTRYINDEX);
+        LuaFunctor functor(L,index,thisIndex);
+        con = self->subscribeEvent(String(event_name), Event::Subscriber(functor));
+        // make sure we don't release the reference(s) we just made when this call returns
+        functor.index = LUA_NOREF;
+        functor.self = LUA_NOREF;
+    }
+    else if (type == LUA_TSTRING)
+    {
+        const char* str = lua_tostring(L, -1);
+        LuaFunctor functor(L,String(str),thisIndex);
+        con = self->subscribeEvent(String(event_name), Event::Subscriber(functor));
+        // make sure we don't release the reference we just (maybe) made when this call returns
+        functor.self = LUA_NOREF;
+    }
+    else
+    {
+        luaL_error(L,"bad function passed to subscribe function. must be a real function, or a string for late binding");
+    }
+
+    // return the event connection
+    return con;
+}
+
+/*************************************************************************
+    Pushes a named function on the stack
+*************************************************************************/
+void LuaFunctor::pushNamedFunction(lua_State* L, const String& handler_name)
+{
+    int top = lua_gettop(L);
+
+    // do we have any dots in the handler name? if so we grab the function as a table field
+    String::size_type i = handler_name.find_first_of((utf32)'.');
+    if (i!=String::npos)
+    {
+        // split the rest of the string up in parts seperated by '.'
+        // TODO: count the dots and size the vector accordingly from the beginning.
+        std::vector<String> parts;
+        String::size_type start = 0;
+        do
+        {
+            parts.push_back(handler_name.substr(start,i-start));
+            start = i+1;
+            i = handler_name.find_first_of((utf32)'.',start);
+        } while(i!=String::npos);
+
+        // add last part
+        parts.push_back(handler_name.substr(start));
+
+        // first part is the global
+        lua_getglobal(L, parts[0].c_str());
+        if (!lua_istable(L,-1))
+        {
+            lua_settop(L,top);
+            throw ScriptException("Unable to get the Lua event handler: '"+handler_name+"' as first part is not a table");
+        }
+
+        // if there is more than two parts, we have more tables to go through
+        std::vector<String>::size_type visz = parts.size();
+        if (visz-- > 2) // avoid subtracting one later on
+        {
+            // go through all the remaining parts to (hopefully) have a valid Lua function in the end
+            std::vector<String>::size_type vi = 1;
+            while (vi<visz)
+            {
+                // push key, and get the next table
+                lua_pushstring(L,parts[vi].c_str());
+                lua_gettable(L,-2);
+                if (!lua_istable(L,-1))
+                {
+                    lua_settop(L,top);
+                    throw ScriptException("Unable to get the Lua event handler: '"+handler_name+"' as part #"+PropertyHelper::uintToString(uint(vi+1))+" ("+parts[vi]+") is not a table");
+                }
+                // get rid of the last table and move on
+                lua_remove(L,-2);
+                vi++;
+            }
+        }
+
+        // now we are ready to get the function to call ... phew :)
+        lua_pushstring(L,parts[visz].c_str());
+        lua_gettable(L,-2);
+        lua_remove(L,-2); // get rid of the table
+    }
+    // just a regular global function
+    else
+    {
+        lua_getglobal(L, handler_name.c_str());
+    }
+
+    // is it a function
+    if (!lua_isfunction(L,-1))
+    {
+        lua_settop(L,top);
+        throw ScriptException("The Lua event handler: '"+handler_name+"' does not represent a Lua function");
+    }
+}
+
+} // namespace CEGUI
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/CEGUILuaFunctor.h
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/CEGUILuaFunctor.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/CEGUILuaFunctor.h	(revision 6952)
@@ -0,0 +1,85 @@
+/***********************************************************************
+    filename: CEGUILuaFunctor.h
+    created:  Thu Jan 26 2006
+    author:   Tomas Lindquist Olsen <tomas@famolsen.dk>
+
+    purpose:  Defines interface for LuaFunctor class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#ifndef _CEGUILuaFunctor_h_
+#define _CEGUILuaFunctor_h_
+
+#include "CEGUIEventSet.h"
+
+struct lua_State;
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+// forward declaration
+class LuaScriptModule;
+
+/*!
+\brief
+    Functor class used for subscribing Lua functions to CEGUI events
+*/
+class LuaFunctor
+{
+public:
+    LuaFunctor(lua_State* state, int func, int selfIndex);
+    LuaFunctor(lua_State* state, const String& func, int selfIndex);
+    LuaFunctor(const LuaFunctor& cp);
+    ~LuaFunctor();
+
+    bool operator()(const EventArgs& args) const;
+
+    /*!
+    \brief
+        function used to subscribe any Lua function as event handler.
+        References using the Lua registry.
+        To be called from Lua only.
+    */
+    static Event::Connection SubscribeEvent(EventSet* self, const String& eventName, int funcIndex, int selfIndex, lua_State* L);
+
+    /*!
+    \brief
+        Pushes the Lua function named \param name on top of the Lua stack.
+        The name may contain '.' (dots) character for (nested) table values.
+    */
+    static void pushNamedFunction(lua_State* L, const String& name);
+
+private:
+    lua_State* L;
+    mutable int index;
+    int self;
+    mutable bool needs_lookup;
+    mutable String function_name;
+
+    friend class LuaScriptModule;
+};
+
+} // namespace CEGUI
+
+#endif // end of guard _CEGUILuaFunctor_h_
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/changes_orxonox.diff
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/changes_orxonox.diff	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/changes_orxonox.diff	(revision 6952)
@@ -0,0 +1,103 @@
+--- CEGUILua.cpp	Thu Jan 29 20:08:43 2009
++++ CEGUILua.cpp	Thu Jan 29 10:23:36 2009
+@@ -40,7 +40,7 @@
+ #include "lauxlib.h"
+ }
+ 
+-#include "tolua++.h"
++#include "tolua/tolua++.h"
+ 
+ // prototype for bindings initialisation function
+ int tolua_CEGUI_open(lua_State* tolua_S);
+@@ -55,19 +55,45 @@
+ *************************************************************************/
+ LuaScriptModule::LuaScriptModule()
+ {
++    #if LUA_VERSION_NUM >= 501
++        static const luaL_Reg lualibs[] = {
++            {"", luaopen_base},
++            {LUA_LOADLIBNAME, luaopen_package},
++            {LUA_TABLIBNAME, luaopen_table},
++            {LUA_IOLIBNAME, luaopen_io},
++            {LUA_OSLIBNAME, luaopen_os},
++            {LUA_STRLIBNAME, luaopen_string},
++            {LUA_MATHLIBNAME, luaopen_math},
++        #if defined(DEBUG) || defined (_DEBUG)
++                {LUA_DBLIBNAME, luaopen_debug},
++        #endif
++            {0, 0}
++        };
++    #endif /* LUA_VERSION_NUM >= 501 */
++
+ 	// create a lua state
+ 	d_ownsState = true;
+ 	d_state = lua_open();
+ 
+ 	// init all standard libraries
+-	luaopen_base(d_state);
+-	luaopen_io(d_state);
+-	luaopen_string(d_state);
+-	luaopen_table(d_state);
+-	luaopen_math(d_state);
+-#if defined(DEBUG) || defined (_DEBUG)
+-	luaopen_debug(d_state);
+-#endif
++    #if LUA_VERSION_NUM >= 501
++            const luaL_Reg *lib = lualibs;
++            for (; lib->func; lib++)
++            {
++                lua_pushcfunction(d_state, lib->func);
++                lua_pushstring(d_state, lib->name);
++                lua_call(d_state, 1, 0);
++            }
++    #else /* LUA_VERSION_NUM >= 501 */
++	    luaopen_base(d_state);
++	    luaopen_io(d_state);
++	    luaopen_string(d_state);
++	    luaopen_table(d_state);
++	    luaopen_math(d_state);
++        #if defined(DEBUG) || defined (_DEBUG)
++	        luaopen_debug(d_state);
++        #endif
++    #endif /* LUA_VERSION_NUM >= 501 */
+ 
+ 	setModuleIdentifierString();
+ }
+--- CEGUILua.h	Thu Jan 29 20:08:23 2009
++++ CEGUILua.h	Thu Jan 29 10:18:39 2009
+@@ -38,7 +38,11 @@
+ #   ifdef CEGUILUA_EXPORTS
+ #       define CEGUILUA_API __declspec(dllexport)
+ #   else
+-#       define CEGUILUA_API __declspec(dllimport)
++#       if defined( __MINGW32__ )
++#           define CEGUILUA_API
++#       else
++#           define CEGUILUA_API __declspec(dllimport)
++#       endif
+ #   endif
+ #else
+ #   define CEGUILUA_API
+--- CEGUILuaFunctor.cpp	Thu Jan 29 20:08:38 2009
++++ CEGUILuaFunctor.cpp	Thu Jan 29 10:21:45 2009
+@@ -39,7 +39,7 @@
+ #include "lauxlib.h"
+ }
+ 
+-#include "tolua++.h"
++#include "tolua/tolua++.h"
+ 
+ // Start of CEGUI namespace section
+ namespace CEGUI
+--- required.h	Thu Jan 29 20:08:32 2009
++++ required.h	Thu Jan 29 15:01:58 2009
+@@ -36,6 +36,9 @@
+ #define __operator_decrement    operator--
+ #define __operator_dereference  operator*
+ 
++//This is used to keep compilers happy
++#define CEGUIDeadException(e) &
++
+ #define LuaFunctorSubscribeEvent CEGUI::LuaFunctor::SubscribeEvent
+ 
+ #if defined(_MSC_VER) && !defined(snprintf)
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/required.cpp
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/required.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/required.cpp	(revision 6952)
@@ -0,0 +1,88 @@
+/***********************************************************************
+	filename: required.cpp
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+	
+	purpose:  Implementation of helper functions
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUI.h"
+#include "required.h"
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*************************************************************************
+	Functions for getting Thumb range pairs as two return values
+*************************************************************************/
+
+// returns horizontal range as two values for lua
+void ceguiLua_Thumb_getHorzRange(Thumb* wnd, float* min, float* max)
+{
+	std::pair<float,float> range_pair = wnd->getHorzRange();
+	*min = range_pair.first;
+	*max = range_pair.second;
+}
+
+
+// returns vertical range as two values for lua
+void ceguiLua_Thumb_getVertRange(Thumb* wnd, float* min, float* max)
+{
+	std::pair<float,float> range_pair = wnd->getVertRange();
+	*min = range_pair.first;
+	*max = range_pair.second;
+}
+
+
+/*************************************************************************
+	Functions for creating list box items
+*************************************************************************/
+
+// allocates and returns a new ListboxTextItem
+ListboxTextItem* ceguiLua_createListboxTextItem(const String& text, uint item_id, void* item_data, bool disabled, bool auto_delete)
+{
+	return new ListboxTextItem(text,item_id,item_data,disabled,auto_delete);
+}
+
+
+/************************************************************************
+    OutStream
+*************************************************************************/
+void ceguiLua_FileStream_open(FileStream* os, const char* filename)
+{
+    os->open(filename, std::ios::binary);
+}
+
+
+/************************************************************************
+    CEGUI::System::getSystemKeys alternative
+*************************************************************************/
+bool ceguiLua_System_isSystemKeyDown(const System* sys, SystemKey k)
+{
+    return (k & sys->getSystemKeys()) != 0;
+}
+
+
+} // namespace CEGUI
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/required.h
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/required.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/ceguilua/required.h	(revision 6952)
@@ -0,0 +1,113 @@
+/***********************************************************************
+	filename: required.h
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+	
+	purpose:  Header that includes the necessary stuff needed for the Lua bindings
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUI.h"
+#include "CEGUILua.h"
+#include "CEGUILuaFunctor.h"
+#include <fstream>
+
+#define __operator_increment    operator++
+#define __operator_decrement    operator--
+#define __operator_dereference  operator*
+
+//This is used to keep compilers happy
+#define CEGUIDeadException(e) &
+
+#define LuaFunctorSubscribeEvent CEGUI::LuaFunctor::SubscribeEvent
+
+#if defined(_MSC_VER) && !defined(snprintf)
+#   define snprintf   _snprintf
+#endif
+
+typedef CEGUI::String string;
+
+namespace CEGUI
+{
+
+typedef Event::Connection EventConnection;
+
+/*************************************************************************
+	Functions for getting Thumb range pairs as two return values
+*************************************************************************/
+void ceguiLua_Thumb_getHorzRange(Thumb* wnd, float* min, float* max);
+void ceguiLua_Thumb_getVertRange(Thumb* wnd, float* min, float* max);
+
+
+/*************************************************************************
+	Functions for creating list box items
+*************************************************************************/
+ListboxTextItem* ceguiLua_createListboxTextItem(const String& text, uint item_id, void* item_data, bool disabled, bool auto_delete);
+
+
+/************************************************************************
+    Stuff needed to make the iterators work
+*************************************************************************/
+typedef PropertySet::Iterator PropertyIterator;
+typedef EventSet::Iterator EventIterator;
+typedef WindowManager::WindowIterator WindowIterator;
+typedef WindowFactoryManager::WindowFactoryIterator WindowFactoryIterator;
+typedef WindowFactoryManager::FalagardMappingIterator FalagardMappingIterator;
+typedef WindowFactoryManager::FalagardWindowMapping FalagardWindowMapping;
+typedef ImagesetManager::ImagesetIterator ImagesetIterator;
+typedef Imageset::ImageIterator ImageIterator;
+typedef SchemeManager::SchemeIterator SchemeIterator;
+typedef FontManager::FontIterator FontIterator;
+
+template <typename T>
+inline PropertyIterator ceguiLua_getPropertyIterator(const T* self)
+{
+    return static_cast<const PropertySet*>(self)->getIterator();
+}
+
+template <typename T>
+inline EventIterator ceguiLua_getEventIterator(const T* self)
+{
+    return static_cast<const EventSet*>(self)->getIterator();
+}
+
+
+/************************************************************************
+    OutStream
+*************************************************************************/
+typedef std::ofstream FileStream;
+void ceguiLua_FileStream_open(FileStream*, const char* filename);
+
+
+/************************************************************************
+    CEGUI::System::getSystemKeys alternative
+*************************************************************************/
+bool ceguiLua_System_isSystemKeyDown(const System* sys, SystemKey k);
+
+}
+
+// the binding file generates alot of
+// warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
+#if defined(_MSC_VER)
+#   pragma warning(disable : 4800)
+#endif
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Basic.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Basic.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Basic.pkg	(revision 6952)
@@ -0,0 +1,190 @@
+/***********************************************************************
+    Vector2
+***********************************************************************/
+class Vector2
+{
+    // rename 'd_x' and 'd_y' to just 'x' and 'y'
+    float d_x @ x;
+    float d_y @ y;
+
+    Vector2 operator+ (const Vector2& vec) const;
+    Vector2 operator- (const Vector2& vec) const;
+    Vector2 operator* (const Vector2& vec) const;
+    bool operator== (const Vector2& vec) const;
+
+    Vector2();
+    Vector2(float x, float y);
+};
+
+// do a simple copy of Point to Vector2
+$[
+CEGUI.Point = CEGUI.Vector2
+$]
+
+
+
+/***********************************************************************
+	Size
+***********************************************************************/
+class Size
+{
+	// rename 'd_width' and 'd_height' to just 'width' and 'height'
+	float d_width @ width;
+	float d_height @ height;
+
+	bool operator== (const Size& sz) const;
+
+	Size();
+	Size(float w, float h);
+};
+
+
+
+/***********************************************************************
+	Rect
+***********************************************************************/
+class Rect
+{
+	// remove member variable 'd_' prefix
+	float d_top @ top;
+	float d_bottom @ bottom;
+	float d_left @ left;
+	float d_right @ right;
+
+	Vector2 getPosition() const;
+	float getWidth() const;
+	float getHeight() const;
+	Size getSize() const;
+
+	Rect getIntersection(const Rect& rect) const;
+	bool isPointInRect(const Vector2& p) const;
+
+	void setPosition(const Vector2& p);
+	void setWidth(float w);
+	void setHeight(float h);
+	void setSize(const Size& sz);
+
+	Rect& offset(const Vector2& p);
+	Rect& constrainSizeMax(const Size& sz);
+	Rect& constrainSizeMin(const Size& sz);
+	Rect& constrainSize(const Size& min, const Size& max);
+
+	bool operator== (const Rect& r) const;
+
+	Rect();
+	Rect(float l, float t, float r, float b);
+};
+
+
+
+/***********************************************************************
+	colour
+***********************************************************************/
+class colour
+{
+	float getAlpha() const;
+	float getRed() const;
+	float getGreen() const;
+	float getBlue() const;
+	float getHue() const;
+	float getSaturation() const;
+	float getLumination() const;
+
+	void set(float r, float g, float b, float a);
+	void setAlpha(float a);
+	void setRed(float r);
+	void setGreen(float g);
+	void setBlue(float b);
+	void setRGB(float r, float g, float b);
+	void setHSL(float hue, float saturation, float luminance, float alpha=1);
+
+	colour operator+ (const colour& c) const;
+	colour operator- (const colour& c) const;
+	//colour operator* (const colour& c) const; // gives a warning about argb_t to colour conversion
+	bool operator== (const colour& c) const;
+
+	colour();
+	colour(float r, float g, float b, float a);
+};
+
+
+
+/***********************************************************************
+	ColourRect
+***********************************************************************/
+class ColourRect
+{
+	colour d_top_left @ top_left;
+	colour d_top_right @ top_right;
+	colour d_bottom_left @ bottom_left;
+	colour d_bottom_right @ bottom_right;
+
+	void	setAlpha(float alpha);
+	void	setTopAlpha(float alpha);
+	void	setBottomAlpha(float alpha);
+	void	setLeftAlpha(float alpha);
+	void	setRightAlpha(float alpha);
+	void	modulateAlpha(float alpha);
+
+	void	setColours(const colour& col);
+
+	bool	isMonochromatic() const;
+
+	ColourRect getSubRectangle( float left, float right, float top, float bottom ) const;
+	colour getColourAtPoint( float x, float y ) const;
+
+	//ColourRect& operator*= (const ColourRect& other); // no support for *= operators
+
+	ColourRect();
+	ColourRect(const colour& col);
+	ColourRect(const colour& top_left, const colour& top_right, const colour& bottom_left, const colour& bottom_right);
+};
+
+
+
+/************************************************************************
+    String
+*************************************************************************/
+class String
+{
+    static const unsigned long npos;
+
+    unsigned long size() const;
+    unsigned long length() const;
+    bool empty() const;
+    unsigned long capacity() const;
+
+    unsigned long& operator[] (unsigned long i);
+    unsigned long& at(unsigned long i);
+    string c_str() const;
+
+    void reserve(unsigned long num=0);
+    void resize(unsigned long num);
+    void resize(unsigned long num, unsigned long codepoint);
+
+    void clear();
+    String& erase();
+    // default len is different from usual to handle ambiguity issue
+    String& erase(unsigned long idx, unsigned long len=1);
+
+    String& replace(unsigned long begin, unsigned long len, const String&s);
+    //String& replace(unsigned long begin, unsigned long len, unsigned long codepoint);
+
+    void swap(String& s);
+    String& insert(unsigned long pos, const String& s);
+    //String& insert(unsigned long pos, unsigned long codepoint);
+
+    unsigned long find(unsigned long codepoint, unsigned long idx=0) const;
+    unsigned long rfind(unsigned long codepoint, unsigned long idx=-1) const;
+    unsigned long find(const String& sub, unsigned long idx=0) const;
+    unsigned long rfind(const String& sub, unsigned long idx=-1) const;
+
+    String substr(unsigned long idx=0, unsigned long len=-1) const;
+
+    void push_back(unsigned long codepoint);
+
+    String();
+    String(unsigned long num, unsigned long codepoint);
+    String(string s);
+    String(const String& s);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/CEGUI.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/CEGUI.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/CEGUI.pkg	(revision 6952)
@@ -0,0 +1,116 @@
+// include the header that makes these files generate valid code
+$#include "ceguilua/required.h"
+$#include "CEGUIPropertyHelper.h"
+
+// start the CEGUI namespace and include everything inside that
+namespace CEGUI
+{
+
+$pfile "Basic.pkg"
+$pfile "UnifiedCoordSystem.pkg"
+$pfile "Logger.pkg"
+
+$pfile "Font.pkg"
+$pfile "FontManager.pkg"
+
+$pfile "Image.pkg"
+$pfile "Texture.pkg"
+$pfile "Imageset.pkg"
+$pfile "ImagesetManager.pkg"
+
+$pfile "Iterators.pkg"
+
+$pfile "Key.pkg"
+$pfile "InputEvent.pkg"
+$pfile "EventSet.pkg"
+
+$pfile "MouseCursor.pkg"
+$pfile "Window.pkg"
+$pfile "CoordConverter.pkg"
+$pfile "Renderer.pkg"
+$pfile "System.pkg"
+
+$pfile "WindowManager.pkg"
+$pfile "WindowFactoryManager.pkg"
+
+$pfile "Scheme.pkg"
+$pfile "SchemeManager.pkg"
+
+$pfile "PropertyHelper.pkg"
+
+// elements
+$pfile "elements/GUISheet.pkg"
+
+$pfile "elements/ButtonBase.pkg"
+$pfile "elements/Checkbox.pkg"
+$pfile "elements/PushButton.pkg"
+$pfile "elements/Thumb.pkg"
+$pfile "elements/RadioButton.pkg"
+
+$pfile "elements/TabButton.pkg"
+$pfile "elements/TabControl.pkg"
+
+$pfile "elements/Titlebar.pkg"
+$pfile "elements/FrameWindow.pkg"
+
+$pfile "elements/Tooltip.pkg"
+
+$pfile "elements/DragContainer.pkg"
+
+$pfile "elements/Scrollbar.pkg"
+$pfile "elements/ScrolledContainer.pkg"
+$pfile "elements/ScrollablePane.pkg"
+
+$pfile "elements/Slider.pkg"
+
+$pfile "elements/Spinner.pkg"
+
+$pfile "elements/ProgressBar.pkg"
+
+$pfile "elements/Editbox.pkg"
+$pfile "elements/MultiLineEditbox.pkg"
+
+$pfile "elements/ListboxItem.pkg"
+$pfile "elements/ListboxTextItem.pkg"
+
+$pfile "elements/Combobox.pkg"
+$pfile "elements/Listbox.pkg"
+$pfile "elements/ComboDropList.pkg"
+
+$pfile "elements/ListHeaderSegment.pkg"
+$pfile "elements/ListHeader.pkg"
+$pfile "elements/MultiColumnList.pkg"
+
+$pfile "elements/ItemEntry.pkg"
+$pfile "elements/ItemListBase.pkg"
+$pfile "elements/MenuBase.pkg"
+$pfile "elements/Menubar.pkg"
+$pfile "elements/PopupMenu.pkg"
+$pfile "elements/MenuItem.pkg"
+$pfile "elements/ScrolledItemListBase.pkg"
+$pfile "elements/ItemListbox.pkg"
+
+$pfile "falagard/Enums.pkg"
+$pfile "falagard/Dimension.pkg"
+$pfile "falagard/NamedArea.pkg"
+$pfile "falagard/PropertyDefinitionBase.pkg"
+$pfile "falagard/PropertyDefinition.pkg"
+$pfile "falagard/PropertyInitialiser.pkg"
+$pfile "falagard/PropertyLinkDefinition.pkg"
+$pfile "falagard/FalagardComponentBase.pkg"
+$pfile "falagard/FrameComponent.pkg"
+$pfile "falagard/ImageryComponent.pkg"
+$pfile "falagard/TextComponent.pkg"
+$pfile "falagard/ImagerySection.pkg"
+$pfile "falagard/SectionSpecification.pkg"
+$pfile "falagard/LayerSpecification.pkg"
+$pfile "falagard/StateImagery.pkg"
+$pfile "falagard/WidgetComponent.pkg"
+$pfile "falagard/WidgetLookFeel.pkg"
+$pfile "falagard/WidgetLookManager.pkg"
+
+$pfile "HelperFunctions.pkg"
+
+$pfile "OutStream.pkg"
+
+}
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/CoordConverter.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/CoordConverter.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/CoordConverter.pkg	(revision 6952)
@@ -0,0 +1,30 @@
+/***********************************************************************
+    CoordConverter utility class
+***********************************************************************/
+class CoordConverter
+{
+    static float windowToScreenX(const Window& window, const UDim& x);
+    static float windowToScreenX(const Window& window, const float x);
+
+    static float windowToScreenY(const Window& window, const UDim& y);
+    static float windowToScreenY(const Window& window, const float y);
+
+    static Vector2 windowToScreen(const Window& window, const UVector2& vec);
+    static Vector2 windowToScreen(const Window& window, const Vector2& vec);
+
+    static Rect windowToScreen(const Window& window, const URect& rect);
+    static Rect windowToScreen(const Window& window, const Rect& rect);
+
+    static float screenToWindowX(const Window& window, const UDim& x);
+    static float screenToWindowX(const Window& window, const float x);
+
+    static float screenToWindowY(const Window& window, const UDim& y);
+    static float screenToWindowY(const Window& window, const float y);
+
+    static Vector2 screenToWindow(const Window& window, const UVector2& vec);
+    static Vector2 screenToWindow(const Window& window, const Vector2& vec);
+
+    static Rect screenToWindow(const Window& window, const URect& rect);
+    static Rect screenToWindow(const Window& window, const Rect& rect);
+
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/EventSet.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/EventSet.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/EventSet.pkg	(revision 6952)
@@ -0,0 +1,46 @@
+/************************************************************************
+    Event
+*************************************************************************/
+class Event
+{
+    string getName() const;
+};
+
+class EventConnection
+{
+//    bool connected() const;
+//    void disconnect();
+};
+
+
+/***********************************************************************
+	EventSet
+***********************************************************************/
+class EventSet
+{
+	void addEvent(string name);
+	void removeEvent(string name);
+	void removeAllEvents();
+	bool isEventPresent(string name);
+
+	tolua_throws|CEGUI::UnknownObjectException,error| tolua_outside EventConnection LuaFunctorSubscribeEvent @ subscribeEvent(string name, lua_Object funcIndex, lua_Object selfIndex=LUA_NOREF, lua_State*);
+
+	tolua_throws|CEGUI::UnknownObjectException,error| EventConnection subscribeScriptedEvent @ subscribeEvent(string name, string callback_name);
+
+	void fireEvent(string name, EventArgs& args, string eventnamespace="");
+
+	bool isMuted() const;
+	void setMutedState(bool setting);
+
+    tolua_outside EventIterator ceguiLua_getEventIterator @ getEventIterator() const;
+};
+
+
+
+/***********************************************************************
+	GlobalEventSet
+***********************************************************************/
+class GlobalEventSet : public EventSet
+{
+	static GlobalEventSet& getSingleton();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Font.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Font.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Font.pkg	(revision 6952)
@@ -0,0 +1,53 @@
+/***********************************************************************
+	TextFormatting
+***********************************************************************/
+enum TextFormatting
+{
+	LeftAligned,
+	RightAligned,
+	Centred,
+	Justified,
+	WordWrapLeftAligned,
+	WordWrapRightAligned,
+	WordWrapCentred,
+	WordWrapJustified
+};
+
+
+/***********************************************************************
+	Font
+***********************************************************************/
+class Font //: public PropertySet
+{
+	//////////////////////////////////////////////
+	// PropertySet
+	void setProperty(string name, string value);
+	string getProperty(string name) const;
+	string getPropertyDefault(string name) const;
+	string getPropertyHelp(string name) const;
+
+	bool isPropertyPresent(string name) const;
+	bool isPropertyDefault(string name) const;
+
+    tolua_outside PropertyIterator ceguiLua_getPropertyIterator @ getPropertyIterator() const;
+
+    static void setDefaultResourceGroup(string resourceGroup);
+    static string getDefaultResourceGroup();
+
+    void load ();
+
+	bool isCodepointAvailable(unsigned long cp) const;
+
+	void setNativeResolution(const Size& sz);
+	void notifyScreenResolution(const Size& sz);
+
+	float getTextExtent(string text, float xscale=1);
+	float getLineSpacing(float yscale=1) const;
+	float getFontHeight(float yscale=1) const;
+
+	unsigned long getCharAtPixel(string text, unsigned long start_char, float pixel, float xscale=1);
+	unsigned long getCharAtPixel(string text, float pixel, float xscale=1);
+
+	unsigned long getFormattedLineCount(string text, const Rect& format_area, TextFormatting fmt, float xscale=1);
+	float getFormattedTextExtent(string text, const Rect& format_area, TextFormatting fmt, float xscale=1);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/FontManager.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/FontManager.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/FontManager.pkg	(revision 6952)
@@ -0,0 +1,21 @@
+/***********************************************************************
+	FontManager
+***********************************************************************/
+class FontManager
+{
+	static FontManager& getSingleton();
+
+	tolua_throws|CEGUI::AlreadyExistsException,error|CEGUI::InvalidRequestException,error| Font* createFont(string type, string name, string fontname, string resourcegroup="");
+	tolua_throws|CEGUI::AlreadyExistsException,error|CEGUI::InvalidRequestException,error| Font* createFont(string filename, string resourcegroup="");
+
+	void destroyFont(string name);
+	void destroyFont(Font* font);
+	void destroyAllFonts();
+
+	bool isFontPresent(string name) const;
+	Font* getFont(string name) const;
+
+	void notifyScreenResolution(const Size& sz);
+
+    FontIterator getIterator() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/HelperFunctions.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/HelperFunctions.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/HelperFunctions.pkg	(revision 6952)
@@ -0,0 +1,235 @@
+/****************************************************
+	EventArgs casting helper functions.
+	These are not part of the core CEGUI API, merely here for
+	convenience
+*****************************************************/
+$[
+
+function CEGUI.toMouseCursorEventArgs(e)
+    return tolua.cast(e,"const CEGUI::MouseCursorEventArgs")
+end
+
+function CEGUI.toWindowEventArgs(e)
+    return tolua.cast(e,"const CEGUI::WindowEventArgs")
+end
+
+function CEGUI.toActivationEventArgs(e)
+    return tolua.cast(e,"const CEGUI::ActivationEventArgs")
+end
+
+function CEGUI.toHeaderSequenceEventArgs(e)
+    return tolua.cast(e,"const CEGUI::HeaderSequenceEventArgs")
+end
+
+function CEGUI.toMouseEventArgs(e)
+    return tolua.cast(e,"const CEGUI::MouseEventArgs")
+end
+
+function CEGUI.toKeyEventArgs(e)
+    return tolua.cast(e,"const CEGUI::KeyEventArgs")
+end
+
+function CEGUI.toDragDropEventArgs(e)
+    return tolua.cast(e,"const CEGUI::DragDropEventArgs")
+end
+
+CEGUI.EventArgs.toMouseCursorEventArgs      = CEGUI.toMouseCursorEventArgs
+CEGUI.EventArgs.toWindowEventArgs           = CEGUI.toWindowEventArgs
+CEGUI.EventArgs.toActivationEventArgs       = CEGUI.toActivationEventArgs
+CEGUI.EventArgs.toHeaderSequenceEventArgs   = CEGUI.toHeaderSequenceEventArgs
+CEGUI.EventArgs.toMouseEventArgs            = CEGUI.toMouseEventArgs
+CEGUI.EventArgs.toKeyEventArgs              = CEGUI.toKeyEventArgs
+CEGUI.EventArgs.toDragDropEventArgs         = CEGUI.toDragDropEventArgs
+
+$]
+
+
+/****************************************************
+	Functions for easy casting CEGUI::Window class
+	to the widget classes derived from it.
+	
+	all widget types gets these and they are made available as:
+	CEGUI.toButtonBase and CEGUI.Window:toButtonBase
+	etc...
+*****************************************************/
+$[
+
+function CEGUI.toButtonBase(w)
+    return tolua.cast(w,"CEGUI::ButtonBase")
+end
+
+function CEGUI.toCheckbox(w)
+    return tolua.cast(w,"CEGUI::Checkbox")
+end
+
+function CEGUI.toCombobox(w)
+    return tolua.cast(w,"CEGUI::Combobox")
+end
+
+function CEGUI.toComboDropList(w)
+    return tolua.cast(w,"CEGUI::ComboDropList")
+end
+
+function CEGUI.toDragContainer(w)
+    return tolua.cast(w,"CEGUI::DragContainer")
+end
+
+function CEGUI.toEditbox(w)
+    return tolua.cast(w,"CEGUI::Editbox")
+end
+
+function CEGUI.toFrameWindow(w)
+    return tolua.cast(w,"CEGUI::FrameWindow")
+end
+
+function CEGUI.toGUISheet(w)
+    return tolua.cast(w,"CEGUI::GUISheet")
+end
+
+function CEGUI.toItemEntry(w)
+    return tolua.cast(w,"CEGUI::ItemEntry")
+end
+
+function CEGUI.toItemListBase(w)
+    return tolua.cast(w,"CEGUI::ItemListBase")
+end
+
+function CEGUI.toItemListbox(w)
+    return tolua.cast(w,"CEGUI::ItemListbox")
+end
+
+function CEGUI.toListbox(w)
+    return tolua.cast(w,"CEGUI::Listbox")
+end
+
+function CEGUI.toListHeader(w)
+    return tolua.cast(w,"CEGUI::ListHeader")
+end
+
+function CEGUI.toListHeaderSegment(w)
+    return tolua.cast(w,"CEGUI::ListHeaderSegment")
+end
+
+function CEGUI.toMenubar(w)
+    return tolua.cast(w,"CEGUI::Menubar")
+end
+
+function CEGUI.toMenuBase(w)
+    return tolua.cast(w,"CEGUI::MenuBase")
+end
+
+function CEGUI.toMenuItem(w)
+    return tolua.cast(w,"CEGUI::MenuItem")
+end
+
+function CEGUI.toMultiColumnList(w)
+    return tolua.cast(w,"CEGUI::MultiColumnList")
+end
+
+function CEGUI.toMultiLineEditbox(w)
+    return tolua.cast(w,"CEGUI::MultiLineEditbox")
+end
+
+function CEGUI.toPopupMenu(w)
+    return tolua.cast(w,"CEGUI::PopupMenu")
+end
+
+function CEGUI.toProgressBar(w)
+    return tolua.cast(w,"CEGUI::ProgressBar")
+end
+
+function CEGUI.toPushButton(w)
+    return tolua.cast(w,"CEGUI::PushButton")
+end
+
+function CEGUI.toRadioButton(w)
+    return tolua.cast(w,"CEGUI::RadioButton")
+end
+
+function CEGUI.toScrollablePane(w)
+    return tolua.cast(w,"CEGUI::ScrollablePane")
+end
+
+function CEGUI.toScrollbar(w)
+    return tolua.cast(w,"CEGUI::Scrollbar")
+end
+
+function CEGUI.toScrolledContainer(w)
+    return tolua.cast(w,"CEGUI::ScrolledContainer")
+end
+
+function CEGUI.toScrolledItemListBase(w)
+    return tolua.cast(w,"CEGUI::ScrolledItemListBase")
+end
+
+function CEGUI.toSlider(w)
+    return tolua.cast(w,"CEGUI::Slider")
+end
+
+function CEGUI.toSpinner(w)
+    return tolua.cast(w,"CEGUI::Spinner")
+end
+
+function CEGUI.toTabButton(w)
+    return tolua.cast(w,"CEGUI::TabButton")
+end
+
+function CEGUI.toTabControl(w)
+    return tolua.cast(w,"CEGUI::TabControl")
+end
+
+function CEGUI.toTabPane(w)
+    return tolua.cast(w,"CEGUI::TabPane")
+end
+
+function CEGUI.toThumb(w)
+    return tolua.cast(w,"CEGUI::Thumb")
+end
+
+function CEGUI.toTooltip(w)
+    return tolua.cast(w,"CEGUI::Tooltip")
+end
+
+CEGUI.Window.toButtonBase = CEGUI.toButtonBase
+CEGUI.Window.toCheckbox = CEGUI.toCheckbox
+CEGUI.Window.toCombobox = CEGUI.toCombobox
+CEGUI.Window.toComboDropList = CEGUI.toComboDropList
+CEGUI.Window.toDragContainer = CEGUI.toDragContainer
+CEGUI.Window.toEditbox = CEGUI.toEditbox
+CEGUI.Window.toFrameWindow = CEGUI.toFrameWindow
+CEGUI.Window.toGUISheet = CEGUI.toGUISheet
+CEGUI.Window.toItemEntry = CEGUI.toItemEntry
+CEGUI.Window.toItemListBase = CEGUI.toItemListBase
+CEGUI.Window.toItemListbox = CEGUI.toItemListBase
+CEGUI.Window.toListbox = CEGUI.toListbox
+CEGUI.Window.toListHeader = CEGUI.toListHeader
+CEGUI.Window.toListHeaderSegment = CEGUI.toListHeaderSegment
+CEGUI.Window.toMenubar = CEGUI.toMenubar
+CEGUI.Window.toMenuBase = CEGUI.toMenuBase
+CEGUI.Window.toMenuItem = CEGUI.toMenuItem
+CEGUI.Window.toMultiColumnList = CEGUI.toMultiColumnList
+CEGUI.Window.toMultiLineEditbox = CEGUI.toMultiLineEditbox
+CEGUI.Window.toPopupMenu = CEGUI.toPopupMenu
+CEGUI.Window.toProgressBar = CEGUI.toProgressBar
+CEGUI.Window.toPushButton = CEGUI.toPushButton
+CEGUI.Window.toRadioButton = CEGUI.toRadioButton
+CEGUI.Window.toScrollablePane = CEGUI.toScrollablePane
+CEGUI.Window.toScrollbar = CEGUI.toScrollbar
+CEGUI.Window.toScrolledContainer = CEGUI.toScrolledContainer
+CEGUI.Window.toScrolledItemListBase = CEGUI.toScrolledItemListBase
+CEGUI.Window.toSlider = CEGUI.toSlider
+CEGUI.Window.toSpinner = CEGUI.toSpinner
+CEGUI.Window.toTabButton = CEGUI.toTabButton
+CEGUI.Window.toTabControl = CEGUI.toTabControl
+CEGUI.Window.toTabPane = CEGUI.toTabPane
+CEGUI.Window.toThumb = CEGUI.toThumb
+CEGUI.Window.toTooltip = CEGUI.toTooltip
+
+$]
+
+
+/****************************************************
+	Helper to create a ListboxTextItem.
+	Mimics the constructor
+*****************************************************/
+ListboxTextItem* ceguiLua_createListboxTextItem @ createListboxTextItem(string text, unsigned int item_id=0, void* item_data=0, bool disabled=false, bool auto_delete=true);
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Image.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Image.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Image.pkg	(revision 6952)
@@ -0,0 +1,15 @@
+/***********************************************************************
+	Image
+***********************************************************************/
+class Image
+{
+	Size getSize() const;
+	float getWidth() const;
+	float getHeight() const;
+	Vector2 getOffsets() const;
+	float getOffsetX() const;
+	float getOffsetY() const;
+	string getName() const;
+	string getImagesetName() const;
+	Rect getSourceTextureArea() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Imageset.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Imageset.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Imageset.pkg	(revision 6952)
@@ -0,0 +1,31 @@
+/***********************************************************************
+	Imageset
+***********************************************************************/
+class Imageset
+{
+	Texture* getTexture() const;
+	string getName() const;
+	unsigned int getImageCount() const;
+	bool isImageDefined(string name) const;
+	const Image& getImage(string name) const;
+	void undefineImage(string name);
+	void undefineAllImages();
+	Size getImageSize(string name) const;
+	float getImageWidth(string name) const;
+	float getImageHeight(string name) const;
+	Vector2 getImageOffset(string name) const;
+	float getImageOffsetX(string name) const;
+	float getImageOffsetY(string name) const;
+	void defineImage(string name, const Vector2& pos, const Size& size, const Vector2& render_offset);
+	void defineImage(string name, const Rect& rect, const Vector2& render_offset);
+	bool isAutoScaled() const;
+	void setAutoScalingEnabled(bool setting);
+	Size getNativeResolution() const;
+	void setNativeResolution(const Size& sz);
+	void notifyScreenResolution(const Size& sz);
+
+    ImageIterator getIterator() const;
+
+    static void setDefaultResourceGroup(string resourceGroup);
+    static string getDefaultResourceGroup();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/ImagesetManager.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/ImagesetManager.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/ImagesetManager.pkg	(revision 6952)
@@ -0,0 +1,22 @@
+/***********************************************************************
+	ImagesetManager
+***********************************************************************/
+class ImagesetManager
+{
+	static ImagesetManager& getSingleton();
+
+	tolua_throws|CEGUI::Exception,error| Imageset* createImageset(string name, Texture* texture);
+	tolua_throws|CEGUI::Exception,error| Imageset* createImageset(string filename, string resourcegroup="");
+	tolua_throws|CEGUI::Exception,error| Imageset* createImagesetFromImageFile(string name, string filename, string resourcegroup="");
+
+	void destroyImageset(Imageset* imageset);
+	void destroyImageset(string name);
+	void destroyAllImagesets();
+
+	tolua_throws|CEGUI::Exception,nil| Imageset* getImageset(string name) const;
+	bool isImagesetPresent(string name) const;
+
+	void notifyScreenResolution(const Size& size);
+
+    ImagesetIterator getIterator() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/InputEvent.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/InputEvent.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/InputEvent.pkg	(revision 6952)
@@ -0,0 +1,118 @@
+/***********************************************************************
+	EventArgs
+***********************************************************************/
+class EventArgs
+{
+	bool handled;
+
+	EventArgs();
+};
+
+
+
+/***********************************************************************
+	MouseCursorEventArgs
+***********************************************************************/
+class MouseCursorEventArgs : public EventArgs
+{
+	MouseCursor* mouseCursor;
+	const Image* image;
+
+	MouseCursorEventArgs(MouseCursor* cursor);
+};
+
+
+
+/***********************************************************************
+	WindowEventArgs
+***********************************************************************/
+class WindowEventArgs : public EventArgs
+{
+	Window* window;
+
+	WindowEventArgs(Window* wnd);
+};
+
+
+
+/***********************************************************************
+	ActivationEventArgs
+***********************************************************************/
+class ActivationEventArgs : public WindowEventArgs
+{
+	Window* otherWindow;
+
+	ActivationEventArgs(Window* wnd);
+};
+
+
+
+/***********************************************************************
+	HeaderSequenceEventArgs
+***********************************************************************/
+class HeaderSequenceEventArgs : public WindowEventArgs
+{
+	// remove 'd_' member variable prefix
+	unsigned int d_oldIdx @ oldIdx;
+	unsigned int d_newIdx @ newIdx;
+
+	HeaderSequenceEventArgs(Window* wnd, unsigned int old_index, unsigned int new_index);
+};
+
+
+
+/***********************************************************************
+	MouseButton
+***********************************************************************/
+enum MouseButton
+{
+	LeftButton,
+	RightButton,
+	MiddleButton,
+	X1Button,
+	X2Button,
+	MouseButtonCount,
+	NoButton
+};
+
+
+
+/***********************************************************************
+	MouseEventArgs
+***********************************************************************/
+class MouseEventArgs : public WindowEventArgs
+{
+	Vector2 position;
+	Vector2 moveDelta;
+	MouseButton button;
+	unsigned int sysKeys;
+	float wheelChange;
+
+	MouseEventArgs(Window* wnd);
+};
+
+
+
+/***********************************************************************
+	KeyEventArgs
+***********************************************************************/
+class KeyEventArgs : public WindowEventArgs
+{
+	unsigned long codepoint;
+	Key::Scan scancode;
+	unsigned int sysKeys;
+
+	KeyEventArgs(Window* wnd);
+};
+
+
+
+/************************************************************************
+    DragDropEventArgs
+*************************************************************************/
+class DragDropEventArgs : public WindowEventArgs
+{
+    DragContainer* dragDropItem;
+
+    DragDropEventArgs(Window* wnd);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Iterators.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Iterators.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Iterators.pkg	(revision 6952)
@@ -0,0 +1,295 @@
+/************************************************************************
+    Lua iterator implementation
+*************************************************************************/
+$[
+
+function CEGUI.iterator_impl_next(p)
+    if p:isAtEnd() then
+        return nil;
+    end
+    local k,v = p:key(), p:value();
+    p:next();
+    return k,v;
+end
+
+function CEGUI.iterator_impl(self)
+   return CEGUI.iterator_impl_next, self; 
+end
+
+$]
+
+
+
+/************************************************************************
+    PropertyIterator
+*************************************************************************/
+class Property
+{
+    string getHelp() const;
+    string getName() const;
+};
+
+class PropertyIterator
+{
+    string getCurrentKey @ key() const;
+    Property* getCurrentValue @ value() const;
+
+    bool isAtEnd() const;
+    bool isAtStart() const;
+
+    PropertyIterator& __operator_increment @ next();
+    PropertyIterator& __operator_decrement @ previous();
+    bool operator== (const PropertyIterator& rhs) const;
+
+    void toStart();
+    void toEnd();
+
+    PropertyIterator(const PropertyIterator& org);
+};
+
+// lua iterator
+$[
+
+CEGUI.PropertyIterator.iterator = CEGUI.iterator_impl;
+
+$]
+
+
+
+/************************************************************************
+    EventIterator
+*************************************************************************/
+class EventIterator
+{
+    string getCurrentKey @ key() const;
+    Event* getCurrentValue @ value() const;
+
+    bool isAtEnd() const;
+    bool isAtStart() const;
+
+    EventIterator& __operator_increment @ next();
+    EventIterator& __operator_decrement @ previous();
+    bool operator== (const EventIterator& rhs) const;
+
+    void toStart();
+    void toEnd();
+
+    EventIterator(const EventIterator& org);
+};
+
+// lua iterator
+$[
+
+CEGUI.EventIterator.iterator = CEGUI.iterator_impl;
+
+$]
+
+
+
+/************************************************************************
+    WindowIterator
+*************************************************************************/
+class WindowIterator
+{
+    string getCurrentKey @ key() const;
+    Window* getCurrentValue @ value() const;
+
+    bool isAtEnd() const;
+    bool isAtStart() const;
+
+    WindowIterator& __operator_increment @ next();
+    WindowIterator& __operator_decrement @ previous();
+    bool operator== (const WindowIterator& rhs) const;
+
+    void toStart();
+    void toEnd();
+
+    WindowIterator(const WindowIterator& org);
+};
+
+// lua iterator
+$[
+
+CEGUI.WindowIterator.iterator = CEGUI.iterator_impl;
+
+$]
+
+
+
+/************************************************************************
+    WindowFactoryIterator
+*************************************************************************/
+class WindowFactoryIterator
+{
+    string getCurrentKey @ key() const;
+    WindowFactory* getCurrentValue @ value() const;
+
+    bool isAtEnd() const;
+    bool isAtStart() const;
+
+    WindowFactoryIterator& __operator_increment @ next();
+    WindowFactoryIterator& __operator_decrement @ previous();
+    bool operator== (const WindowFactoryIterator& rhs) const;
+
+    void toStart();
+    void toEnd();
+
+    WindowFactoryIterator(const WindowFactoryIterator& org);
+};
+
+// lua iterator
+$[
+
+CEGUI.WindowFactoryIterator.iterator = CEGUI.iterator_impl;
+
+$]
+
+
+
+/************************************************************************
+    FalagardMappingIterator
+*************************************************************************/
+class FalagardMappingIterator
+{
+    string getCurrentKey @ key() const;
+    FalagardWindowMapping getCurrentValue @ value() const;
+
+    bool isAtEnd() const;
+    bool isAtStart() const;
+
+    FalagardMappingIterator& __operator_increment @ next();
+    FalagardMappingIterator& __operator_decrement @ previous();
+    bool operator== (const FalagardMappingIterator& rhs) const;
+
+    void toStart();
+    void toEnd();
+
+    FalagardMappingIterator(const FalagardMappingIterator& org);
+};
+
+// lua iterator
+$[
+
+CEGUI.FalagardMappingIterator.iterator = CEGUI.iterator_impl;
+
+$]
+
+
+
+/************************************************************************
+    ImagesetIterator
+*************************************************************************/
+class ImagesetIterator
+{
+    string getCurrentKey @ key() const;
+    Imageset* getCurrentValue @ value() const;
+
+    bool isAtEnd() const;
+    bool isAtStart() const;
+
+    ImagesetIterator& __operator_increment @ next();
+    ImagesetIterator& __operator_decrement @ previous();
+    bool operator== (const ImagesetIterator& rhs) const;
+
+    void toStart();
+    void toEnd();
+
+    ImagesetIterator(const ImagesetIterator& org);
+};
+
+// lua iterator
+$[
+
+CEGUI.ImagesetIterator.iterator = CEGUI.iterator_impl;
+
+$]
+
+
+
+/************************************************************************
+    ImageIterator
+*************************************************************************/
+class ImageIterator
+{
+    string getCurrentKey @ key() const;
+    Image getCurrentValue @ value() const;
+
+    bool isAtEnd() const;
+    bool isAtStart() const;
+
+    ImageIterator& __operator_increment @ next();
+    ImageIterator& __operator_decrement @ previous();
+    bool operator== (const ImageIterator& rhs) const;
+
+    void toStart();
+    void toEnd();
+
+    ImageIterator(const ImageIterator& org);
+};
+
+// lua iterator
+$[
+
+CEGUI.ImageIterator.iterator = CEGUI.iterator_impl;
+
+$]
+
+
+
+/************************************************************************
+    SchemeIterator
+*************************************************************************/
+class SchemeIterator
+{
+    string getCurrentKey @ key() const;
+    Scheme* getCurrentValue @ value() const;
+
+    bool isAtEnd() const;
+    bool isAtStart() const;
+
+    SchemeIterator& __operator_increment @ next();
+    SchemeIterator& __operator_decrement @ previous();
+    bool operator== (const SchemeIterator& rhs) const;
+
+    void toStart();
+    void toEnd();
+
+    SchemeIterator(const SchemeIterator& org);
+};
+
+// lua iterator
+$[
+
+CEGUI.SchemeIterator.iterator = CEGUI.iterator_impl;
+
+$]
+
+
+
+/************************************************************************
+    FontIterator
+*************************************************************************/
+class FontIterator
+{
+    string getCurrentKey @ key() const;
+    Font* getCurrentValue @ value() const;
+
+    bool isAtEnd() const;
+    bool isAtStart() const;
+
+    FontIterator& __operator_increment @ next();
+    FontIterator& __operator_decrement @ previous();
+    bool operator== (const FontIterator& rhs) const;
+
+    void toStart();
+    void toEnd();
+
+    FontIterator(const FontIterator& org);
+};
+
+// lua iterator
+$[
+
+CEGUI.FontIterator.iterator = CEGUI.iterator_impl;
+
+$]
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Key.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Key.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Key.pkg	(revision 6952)
@@ -0,0 +1,175 @@
+/***********************************************************************
+	Key::Scan
+
+	This is'nt exactly how it's done in the C++ code, but it works
+	fine anyway :)
+***********************************************************************/
+namespace Key
+{
+
+enum Scan
+{
+	Escape          =0x01,
+	One             =0x02,
+	Two             =0x03,
+	Three           =0x04,
+	Four            =0x05,
+	Five            =0x06,
+	Six             =0x07,
+	Seven           =0x08,
+	Eight           =0x09,
+	Nine            =0x0A,
+	Zero            =0x0B,
+	Minus           =0x0C,    /* - on main keyboard */
+	Equals			=0x0D,
+	Backspace		=0x0E,    /* backspace */
+	Tab				=0x0F,
+	Q               =0x10,
+	W               =0x11,
+	E               =0x12,
+	R               =0x13,
+	T               =0x14,
+	Y               =0x15,
+	U               =0x16,
+	I               =0x17,
+	O               =0x18,
+	P               =0x19,
+	LeftBracket     =0x1A,
+	RightBracket    =0x1B,
+	Return			=0x1C,    /* Enter on main keyboard */
+	LeftControl		=0x1D,
+	A               =0x1E,
+	S               =0x1F,
+	D               =0x20,
+	F               =0x21,
+	G               =0x22,
+	H               =0x23,
+	J               =0x24,
+	K               =0x25,
+	L               =0x26,
+	Semicolon       =0x27,
+	Apostrophe		=0x28,
+	Grave           =0x29,    /* accent grave */
+	LeftShift       =0x2A,
+	Backslash       =0x2B,
+	Z               =0x2C,
+	X               =0x2D,
+	C               =0x2E,
+	V               =0x2F,
+	B               =0x30,
+	N               =0x31,
+	M               =0x32,
+	Comma           =0x33,
+	Period          =0x34,    /* . on main keyboard */
+	Slash           =0x35,    /* '/' on main keyboard */
+	RightShift      =0x36,
+	Multiply        =0x37,    /* * on numeric keypad */
+	LeftAlt         =0x38,    /* left Alt */
+	Space           =0x39,
+	Capital         =0x3A,
+	F1              =0x3B,
+	F2              =0x3C,
+	F3              =0x3D,
+	F4              =0x3E,
+	F5              =0x3F,
+	F6              =0x40,
+	F7              =0x41,
+	F8              =0x42,
+	F9              =0x43,
+	F10             =0x44,
+	NumLock         =0x45,
+	ScrollLock      =0x46,    /* Scroll Lock */
+	Numpad7         =0x47,
+	Numpad8         =0x48,
+	Numpad9         =0x49,
+	Subtract        =0x4A,    /* - on numeric keypad */
+	Numpad4         =0x4B,
+	Numpad5         =0x4C,
+	Numpad6         =0x4D,
+	Add				=0x4E,    /* + on numeric keypad */
+	Numpad1         =0x4F,
+	Numpad2         =0x50,
+	Numpad3         =0x51,
+	Numpad0         =0x52,
+	Decimal			=0x53,    /* . on numeric keypad */
+	OEM_102         =0x56,    /* < > | on UK/Germany keyboards */
+	F11             =0x57,
+	F12             =0x58,
+	F13             =0x64,    /*                     (NEC PC98) */
+	F14             =0x65,    /*                     (NEC PC98) */
+	F15             =0x66,    /*                     (NEC PC98) */
+	Kana            =0x70,    /* (Japanese keyboard)            */
+	ABNT_C1         =0x73,    /* / ? on Portugese (Brazilian) keyboards */
+	Convert         =0x79,    /* (Japanese keyboard)            */
+	NoConvert       =0x7B,    /* (Japanese keyboard)            */
+	Yen             =0x7D,    /* (Japanese keyboard)            */
+	ABNT_C2         =0x7E,    /* Numpad . on Portugese (Brazilian) keyboards */
+	NumpadEquals    =0x8D,    /* = on numeric keypad (NEC PC98) */
+	PrevTrack       =0x90,    /* Previous Track (KC_CIRCUMFLEX on Japanese keyboard) */
+	At              =0x91,    /*                     (NEC PC98) */
+	Colon           =0x92,    /*                     (NEC PC98) */
+	Underline       =0x93,    /*                     (NEC PC98) */
+	Kanji           =0x94,    /* (Japanese keyboard)            */
+	Stop            =0x95,    /*                     (NEC PC98) */
+	AX              =0x96,    /*                     (Japan AX) */
+	Unlabeled       =0x97,    /*                        (J3100) */
+	NextTrack       =0x99,    /* Next Track */
+	NumpadEnter     =0x9C,    /* Enter on numeric keypad */
+	RightControl    =0x9D,
+	Mute            =0xA0,    /* Mute */
+	Calculator      =0xA1,    /* Calculator */
+	PlayPause       =0xA2,    /* Play / Pause */
+	MediaStop       =0xA4,    /* Media Stop */
+	VolumeDown      =0xAE,    /* Volume - */
+	VolumeUp        =0xB0,    /* Volume + */
+	WebHome         =0xB2,    /* Web home */
+	NumpadComma     =0xB3,    /* , on numeric keypad (NEC PC98) */
+	Divide          =0xB5,    /* / on numeric keypad */
+	SysRq           =0xB7,
+	RightAlt        =0xB8,    /* right Alt */
+	Pause           =0xC5,    /* Pause */
+	Home            =0xC7,    /* Home on arrow keypad */
+	ArrowUp         =0xC8,    /* UpArrow on arrow keypad */
+	PageUp          =0xC9,    /* PgUp on arrow keypad */
+	ArrowLeft       =0xCB,    /* LeftArrow on arrow keypad */
+	ArrowRight      =0xCD,    /* RightArrow on arrow keypad */
+	End             =0xCF,    /* End on arrow keypad */
+	ArrowDown       =0xD0,    /* DownArrow on arrow keypad */
+	PageDown		=0xD1,    /* PgDn on arrow keypad */
+	Insert          =0xD2,    /* Insert on arrow keypad */
+	Delete          =0xD3,    /* Delete on arrow keypad */
+	LeftWindows     =0xDB,    /* Left Windows key */
+	RightWindow     =0xDC,    /* Right Windows key */
+	AppMenu         =0xDD,    /* AppMenu key */
+	Power           =0xDE,    /* System Power */
+	Sleep           =0xDF,    /* System Sleep */
+	Wake			=0xE3,    /* System Wake */
+	WebSearch		=0xE5,    /* Web Search */
+	WebFavorites	=0xE6,    /* Web Favorites */
+	WebRefresh		=0xE7,    /* Web Refresh */
+	WebStop			=0xE8,    /* Web Stop */
+	WebForward		=0xE9,    /* Web Forward */
+	WebBack			=0xEA,    /* Web Back */
+	MyComputer		=0xEB,    /* My Computer */
+	Mail			=0xEC,    /* Mail */
+	MediaSelect		=0xED     /* Media Select */
+
+}; // Key::Scan
+
+} // Key
+
+
+
+/***********************************************************************
+	SystemKey
+***********************************************************************/
+enum SystemKey
+{
+	LeftMouse		= 0x01,			//!< The left mouse button.
+	RightMouse		= 0x02,			//!< The right mouse button.
+	Shift			= 0x04,			//!< Either shift key.
+	Control			= 0x08,			//!< Either control key.
+	MiddleMouse		= 0x10,			//!< The middle mouse button.
+	X1Mouse			= 0x20,			//!< The first 'extra' mouse button
+	X2Mouse			= 0x40			//!< The second 'extra' mouse button.
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Logger.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Logger.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Logger.pkg	(revision 6952)
@@ -0,0 +1,25 @@
+/***********************************************************************
+	LoggingLevel
+***********************************************************************/
+enum LoggingLevel
+{
+	Errors,
+	Standard,
+	Informative,
+	Insane
+};
+
+
+
+/***********************************************************************
+	Logger
+***********************************************************************/
+class Logger
+{
+	static Logger& getSingleton();
+
+	void setLoggingLevel(LoggingLevel level);
+	LoggingLevel getLoggingLevel() const;
+
+	void logEvent(string message, LoggingLevel level=Standard);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/MouseCursor.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/MouseCursor.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/MouseCursor.pkg	(revision 6952)
@@ -0,0 +1,40 @@
+/***********************************************************************
+	MouseCursorImage
+***********************************************************************/
+enum MouseCursorImage
+{
+	BlankMouseCursor	= 0,
+	DefaultMouseCursor	= -1
+};
+
+
+
+/***********************************************************************
+	MouseCursor
+***********************************************************************/
+class MouseCursor : public EventSet
+{
+	static MouseCursor& getSingleton();
+
+	void setImage(const Image* image);
+	void setImage(string imageset, string image);
+	const Image* getImage() const;
+
+	void setPosition(const Vector2& pos);
+	void offsetPosition(const Vector2& offset);
+	void setConstraintArea(const Rect* area);
+	Vector2 getPosition() const;
+	Rect getConstraintArea() const;
+	Vector2 getDisplayIndependantPosition() const;
+
+	void setUnifiedConstraintArea(const URect* area);
+	const URect& getUnifiedConstraintArea(void) const;
+
+	void hide();
+	void show();
+
+    void setVisible(bool visible);
+	bool isVisible() const;
+
+    tolua_outside EventIterator ceguiLua_getEventIterator @ getEventIterator() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/OutStream.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/OutStream.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/OutStream.pkg	(revision 6952)
@@ -0,0 +1,16 @@
+/***********************************************************************
+    OutStream
+***********************************************************************/
+
+class OutStream
+{
+};
+
+class FileStream : public OutStream
+{
+    FileStream();
+
+    bool is_open();
+    tolua_outside void CEGUI::ceguiLua_FileStream_open @ open(const char* filename);
+    void close();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/PropertyHelper.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/PropertyHelper.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/PropertyHelper.pkg	(revision 6952)
@@ -0,0 +1,33 @@
+/***********************************************************************
+	PropertyHelper
+***********************************************************************/
+class PropertyHelper
+{
+	static	float			stringToFloat(string str);
+	static	unsigned int	stringToUint(string str);
+	static	bool			stringToBool(string str);
+	static	Size			stringToSize(string str);
+	static	Vector2			stringToPoint(string str);
+	static	Rect			stringToRect(string str);
+	static	const Image*	stringToImage(string str);
+	static	colour			stringToColour(string str);
+	static	ColourRect		stringToColourRect(string str);
+
+	static	UDim			stringToUDim(string str);
+	static	UVector2		stringToUVector2(string str);
+	static	URect			stringToURect(string str);
+
+	static string	floatToString(float val);
+	static string	uintToString(unsigned int val);
+	static string	boolToString(bool val);
+	static string	sizeToString(const Size& val);
+	static string	pointToString(const Vector2& val);
+	static string	rectToString(const Rect& val);
+	static string	imageToString(const Image* val);
+	static string	colourToString(const colour& val);
+	static string	colourRectToString(const ColourRect& val);
+
+	static string	udimToString(const UDim& val);
+	static string	uvector2ToString(const UVector2& val);
+	static string	urectToString(const URect& val);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Renderer.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Renderer.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Renderer.pkg	(revision 6952)
@@ -0,0 +1,34 @@
+/***********************************************************************
+	Renderer
+***********************************************************************/
+class Renderer : public EventSet
+{
+	//void doRender();
+	//void clearRenderList();
+
+	//void resetZValue();
+	//void advanceZValue();
+	float getCurrentZ() const;
+	float getZLayer(unsigned int layer) const;
+
+	//void setQueueingEnabled(bool setting);
+	bool isQueueingEnabled() const;
+
+	Texture* createTexture();
+	Texture* createTexture(float size);
+	Texture* createTexture(string filename, string resourcegroup);
+
+	void destroyTexture(Texture* tex);
+	void destroyAllTextures();
+
+	float getWidth() const;
+	float getHeight() const;
+	Size getSize() const;
+	Rect getRect() const;
+
+	unsigned int getMaxTextureSize() const;
+	unsigned int getHorzScreenDPI() const;
+	unsigned int getVertScreenDPI() const;
+
+    tolua_outside EventIterator ceguiLua_getEventIterator @ getEventIterator() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Scheme.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Scheme.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Scheme.pkg	(revision 6952)
@@ -0,0 +1,13 @@
+/***********************************************************************
+	Scheme
+***********************************************************************/
+class Scheme
+{
+	void loadResources();
+	void unloadResources();
+	bool resourcesLoaded() const;
+	string getName() const;
+
+    static void setDefaultResourceGroup(string resourceGroup);
+    static string getDefaultResourceGroup();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/SchemeManager.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/SchemeManager.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/SchemeManager.pkg	(revision 6952)
@@ -0,0 +1,15 @@
+/***********************************************************************
+	SchemeManager
+***********************************************************************/
+class SchemeManager
+{
+	static SchemeManager& getSingleton();
+
+	Scheme* loadScheme(string filename, string resourcegroup="");
+	void unloadScheme(string name);
+	bool isSchemePresent(string name) const;
+	Scheme* getScheme(string name) const;
+	void unloadAllSchemes();
+
+    SchemeIterator getIterator() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/System.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/System.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/System.pkg	(revision 6952)
@@ -0,0 +1,64 @@
+/***********************************************************************
+	System
+***********************************************************************/
+class System : public EventSet
+{
+	static System& getSingleton();
+
+	Renderer* getRenderer() const;
+
+	void setDefaultFont(string name);
+	void setDefaultFont(Font* font);
+    Font* getDefaultFont() const;
+
+	void signalRedraw();
+	bool isRedrawRequested() const;
+	void renderGUI();
+
+	Window* setGUISheet(Window* sheet);
+	Window* getGUISheet() const;
+
+	void setSingleClickTimeout(double timeout);
+	void setMultiClickTimeout(double timeout);
+	void setMultiClickToleranceAreaSize(const Size& sz);
+	double getSingleClickTimeout() const;
+	double getMultiClickTimeout() const;
+	const Size& getMultiClickToleranceAreaSize() const;
+
+	void setDefaultMouseCursor(MouseCursorImage image);
+	void setDefaultMouseCursor(const Image* image);
+	void setDefaultMouseCursor(string imageset_name, string image_name);
+	const Image* getDefaultMouseCursor() const;
+
+	Window* getWindowContainingMouse() const;
+
+	void executeScriptFile(string filename) const;
+	int executeScriptGlobal(string global_name) const;
+	void executeScriptString(string lua_string) const;
+
+	float getMouseMoveScaling() const;
+	void setMouseMoveScaling(float scaling);
+
+	void notifyWindowDestroyed(const Window* window);
+
+    // commented because we can't do 'bitwise and' in Lua
+	//unsigned int getSystemKeys() const;
+	tolua_outside bool ceguiLua_System_isSystemKeyDown @ isSystemKeyDown(SystemKey k) const;
+
+	void setDefaultTooltip(Tooltip* tooltip);
+	void setDefaultTooltip(string tooltipType);
+	Tooltip* getDefaultTooltip(void) const;
+
+	bool injectMouseMove(float dx, float dy);
+	bool injectMouseLeaves();
+	bool injectMouseButtonDown(MouseButton btn);
+	bool injectMouseButtonUp(MouseButton btn);
+	bool injectKeyDown(unsigned int keycode);
+	bool injectKeyUp(unsigned int keycode);
+	bool injectChar(unsigned long code_point);
+	bool injectMouseWheelChange(float delta);
+	bool injectMousePosition(float x, float y);
+	bool injectTimePulse(float timeElapsed);
+
+    tolua_outside EventIterator ceguiLua_getEventIterator @ getEventIterator() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Texture.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Texture.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Texture.pkg	(revision 6952)
@@ -0,0 +1,13 @@
+/***********************************************************************
+	Texture
+***********************************************************************/
+class Texture
+{
+	unsigned short getWidth() const;
+	unsigned short getHeight() const;
+	void loadFromFile(string filename, string resourcegroup="");
+
+	// no memory loading
+
+	Renderer* getRenderer() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/UnifiedCoordSystem.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/UnifiedCoordSystem.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/UnifiedCoordSystem.pkg	(revision 6952)
@@ -0,0 +1,73 @@
+/***********************************************************************
+	UDim
+***********************************************************************/
+class UDim
+{
+	float d_scale @ scale;
+	float d_offset @ offset;
+
+	float asAbsolute(float base) const;
+	float asRelative(float base) const;
+
+	UDim operator+ (const UDim& other) const;
+	UDim operator- (const UDim& other) const;
+	UDim operator/ (const UDim& other) const;
+	UDim operator* (const UDim& other) const;
+
+	bool operator== (const UDim& other) const;
+
+	UDim();
+	UDim(float scale, float offset);
+};
+
+
+/***********************************************************************
+	UVector2
+***********************************************************************/
+class UVector2
+{
+	UDim d_x @ x;
+	UDim d_y @ y;
+
+	Vector2 asAbsolute(const Size& base) const;
+	Vector2 asRelative(const Size& base) const;
+
+	UVector2 operator+ (const UVector2& other) const;
+	UVector2 operator- (const UVector2& other) const;
+	UVector2 operator/ (const UVector2& other) const;
+	UVector2 operator* (const UVector2& other) const;
+
+	bool operator== (const UVector2& other) const;
+
+	UVector2();
+	UVector2(UDim& scale, UDim& offset);
+};
+
+
+/***********************************************************************
+	URect
+***********************************************************************/
+class URect
+{
+	UVector2 d_min @ min;
+	UVector2 d_max @ max;
+
+	Rect asAbsolute(const Size& base) const;
+	Rect asRelative(const Size& base) const;
+
+	const UVector2& getPosition() const;
+	UVector2 getSize() const;
+	UDim getWidth() const;
+	UDim getHeight() const;
+
+	void setPosition(const UVector2& pos);
+	void setSize(const UVector2& sz);
+	void setWidth(const UDim& w);
+	void setHeight(const UDim& h);
+
+	void offset(const UVector2& sz);
+
+	URect();
+	URect(const UVector2& min, const UVector2& max);
+	URect(const UDim& left, const UDim& top, const UDim& right, const UDim& bottom);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Window.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Window.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/Window.pkg	(revision 6952)
@@ -0,0 +1,247 @@
+/****************************************
+	Vertical alignment modes
+*****************************************/
+enum VerticalAlignment
+{
+	VA_TOP,
+	VA_CENTRE,
+	VA_BOTTOM
+};
+
+
+/****************************************
+	Horizontal alignment modes
+*****************************************/
+enum HorizontalAlignment
+{
+	HA_LEFT,
+	HA_CENTRE,
+	HA_RIGHT
+};
+
+
+/****************************************
+	Window
+*****************************************/
+class Window //: public EventSet
+{
+	string getType() const;
+	string getName() const;
+
+	bool isDestroyedByParent() const;
+	bool isAlwaysOnTop() const;
+	bool isDisabled(bool localOnly=false) const;
+	bool isVisible(bool localOnly=false) const;
+	bool isActive() const;
+	bool isClippedByParent() const;
+
+	void setDestroyedByParent(bool setting);
+	void setAlwaysOnTop(bool setting);
+	void setEnabled(bool setting);
+	void enable();
+	void disable();
+	void setVisible(bool setting);
+	void show();
+	void hide();
+	void activate();
+	void deactivate();
+
+	void setClippedByParent(bool setting);
+
+	unsigned int getID() const;
+	void setID(unsigned int ID);
+
+	unsigned int getChildCount() const;
+
+	bool isChild(unsigned int ID) const;
+	bool isChild(string name) const;
+	bool isChild(const Window* window) const;
+	bool isChildRecursive(unsigned int ID) const;
+
+	void addChildWindow(string name);
+	void addChildWindow(Window* window);
+
+	void removeChildWindow(unsigned int ID);
+	void removeChildWindow(string name);
+	void removeChildWindow(Window* window);
+
+	tolua_throws|CEGUI::UnknownObjectException,nil| Window* getChild(unsigned int ID) const;
+	tolua_throws|CEGUI::UnknownObjectException,nil| Window* getChild(string name) const;
+	Window* getChildAtIdx(unsigned int ID) const;
+	Window* getActiveChild() const;
+	Window* getChildAtPosition(const Vector2& pos) const;
+    Window* getTargetChildAtPosition(const Vector2& pos) const;
+    Window* getChildRecursive(unsigned int ID) const;
+
+	Window* getParent() const;
+
+	bool isAncestor(unsigned int ID) const;
+	bool isAncestor(string name) const;
+	bool isAncestor(const Window* window) const;
+
+	void setFont(string name);
+	void setFont(Font* font);
+	Font* getFont() const;
+
+	void setText(string text);
+	string getText() const;
+
+	bool inheritsAlpha() const;
+	float getAlpha() const;
+	float getEffectiveAlpha() const;
+	void setAlpha(float a);
+	void setInheritsAlpha(bool setting);
+
+	void requestRedraw() const;
+
+	bool isZOrderingEnabled() const;
+	void setZOrderingEnabled(bool setting);
+
+	Rect getPixelRect() const;
+	Rect getInnerRect() const;
+	Rect getUnclippedPixelRect() const;
+	Rect getUnclippedInnerRect() const;
+
+    Size getParentPixelSize(void) const;
+    float getParentPixelWidth(void) const;
+    float getParentPixelHeight(void) const;
+
+	static Window* getCaptureWindow();
+	void setRestoreCapture(bool setting);
+	bool restoresOldCapture() const;
+
+	bool distributesCapturedInputs() const;
+	void setDistributesCapturedInputs(bool setting);
+
+	bool captureInput();
+	void releaseInput();
+
+	bool isCapturedByThis() const;
+	bool isCapturedByAncestor() const;
+	bool isCapturedByChild() const;
+
+	bool isHit(const Vector2& pos) const;
+
+	bool isRiseOnClickEnabled() const;
+	void setRiseOnClickEnabled(bool setting);
+
+	const Image* getMouseCursor() const;
+	void setMouseCursor(MouseCursorImage cursor);
+	void setMouseCursor(const Image* image);
+	void setMouseCursor(string imageset, string image);
+
+	void moveToFront();
+	void moveToBack();
+
+	bool wantsMultiClickEvents() const;
+	bool isMouseAutoRepeatEnabled() const;
+	float getAutoRepeatDelay() const;
+	float getAutoRepeatRate() const;
+	void setWantsMultiClickEvents(bool setting);
+	void setMouseAutoRepeatEnabled(bool setting);
+	void setAutoRepeatDelay(float delay);
+	void setAutoRepeatRate(float rate);
+
+	//void destroy();
+
+	bool isUsingDefaultTooltip() const;
+	Tooltip* getTooltip() const;
+	string getTooltipType() const;
+	string getTooltipText() const;
+	bool inheritsTooltipText() const;
+
+	void setTooltip(Tooltip* tooltip);
+	void setTooltipType(string tooltipType);
+	void setTooltipText(string tip);
+	void setInheritsTooltipText(bool setting);
+
+	bool testClassName(string class_name) const;
+
+	void notifyDragDropItemEnters(DragContainer* item);
+	void notifyDragDropItemLeaves(DragContainer* item);
+	void notifyDragDropItemDropped(DragContainer* item);
+
+	VerticalAlignment getVerticalAlignment() const;
+	HorizontalAlignment getHorizontalAlignment() const;
+
+    // these actually have a const, but tolua++ chokes on that
+    void setVerticalAlignment(VerticalAlignment alignment);
+    void setHorizontalAlignment(HorizontalAlignment alignment);
+
+	string getLookNFeel() const;
+    tolua_throws|CEGUI::Exception,error| void setLookNFeel(string lnf);
+
+    tolua_throws|CEGUI::Exception,error| void setWindowRenderer(string name);
+    string getWindowRendererName() const;
+
+	//RenderCache& getRenderCache()
+
+	bool getModalState() const;
+	void setModalState(bool state);
+
+    tolua_throws|CEGUI::UnknownObjectException,nil| string getUserString(string name) const;
+    bool isUserStringDefined(string name) const;
+    void setUserString(string name, string value);
+
+    void beginInitialisation();
+    void endInitialisation();
+
+	// unified stuff
+	void setArea(const UDim& xpos, const UDim& ypos, const UDim& width, const UDim& height);
+	void setArea(const UVector2& pos, const UVector2& size);
+	void setArea(const URect& area);
+	void setPosition(const UVector2& pos);
+	void setXPosition(const UDim& x);
+	void setYPosition(const UDim& y);
+	void setSize(const UVector2& size);
+	void setWidth(const UDim& width);
+	void setHeight(const UDim& height);
+	void setMaxSize(const UVector2& size);
+	void setMinSize(const UVector2& size);
+
+	const URect& getArea() const;
+	const UVector2& getPosition() const;
+	const UDim& getXPosition() const;
+	const UDim& getYPosition() const;
+	UVector2 getSize() const;
+	UDim getWidth() const;
+	UDim getHeight() const;
+	const UVector2& getMaxSize() const;
+	const UVector2& getMinSize() const;
+
+    // event pass through
+    bool isMousePassThroughEnabled() const;
+    void setMousePassThroughEnabled(bool setting);
+    
+    tolua_throws|CEGUI::Exception,error| void rename(string new_name);
+
+	//////////////////////////////////////////////
+	// PropertySet
+	void setProperty(string name, string value);
+	string getProperty(string name) const;
+	string getPropertyDefault(string name) const;
+	string getPropertyHelp(string name) const;
+
+	bool isPropertyPresent(string name) const;
+	bool isPropertyDefault(string name) const;
+
+    tolua_outside PropertyIterator ceguiLua_getPropertyIterator @ getPropertyIterator() const;
+
+	//////////////////////////////////////////////
+	// EventSet
+	void addEvent(string name);
+	void removeEvent(string name);
+	void removeAllEvents();
+	bool isEventPresent(string name);
+
+	tolua_throws|CEGUI::UnknownObjectException,error| tolua_outside EventConnection LuaFunctorSubscribeEvent @ subscribeEvent(string name, lua_Object funcIndex, lua_Object selfIndex=LUA_NOREF, lua_State*);
+
+	tolua_throws|CEGUI::UnknownObjectException,error| EventConnection subscribeScriptedEvent @ subscribeEvent(string name, string callback_name);
+	
+	void fireEvent(string name, EventArgs& args, string eventnamespace="");
+
+	bool isMuted() const;
+	void setMutedState(bool setting);
+
+    tolua_outside EventIterator ceguiLua_getEventIterator @ getEventIterator() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/WindowFactoryManager.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/WindowFactoryManager.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/WindowFactoryManager.pkg	(revision 6952)
@@ -0,0 +1,34 @@
+/***********************************************************************
+	WindowFactoryManager
+***********************************************************************/
+class FalagardWindowMapping
+{
+    string d_windowType @ windowType;
+    string d_lookName @ lookName;
+    string d_baseType @ baseType;
+    string d_rendererType @ rendererType;
+};
+
+class WindowFactory
+{
+    string getTypeName() const;
+};
+
+class WindowFactoryManager
+{
+    static WindowFactoryManager& getSingleton();
+
+    bool isFactoryPresent(string name) const;
+    void addWindowTypeAlias(string aliasName, string targetType);
+    void removeWindowTypeAlias(string aliasName, string targetType);
+    void addFalagardWindowMapping(string newType, string targetType, string lookName, string renderer);
+    void removeFalagardWindowMapping(string type);
+    bool isFalagardMappedType(string type) const;
+    string getMappedLookForType(string type) const;
+    string getMappedRendererForType(string type) const;
+    String getDereferencedAliasType(string type) const;
+    const FalagardWindowMapping& getFalagardMappingForType(string type) const;
+
+    WindowFactoryIterator getIterator() const;
+    FalagardMappingIterator getFalagardMappingIterator() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/WindowManager.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/WindowManager.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/WindowManager.pkg	(revision 6952)
@@ -0,0 +1,31 @@
+/***********************************************************************
+	WindowManager
+***********************************************************************/
+class WindowManager
+{
+	static WindowManager& getSingleton();
+
+	tolua_throws|CEGUI::AlreadyExistsException,nil| Window* createWindow(string type, string name="");
+	tolua_throws|CEGUI::Exception,error|std::exception,error|any,error| Window* loadWindowLayout(string filename, string name_prefix="", string resourcegroup="");
+
+    void writeWindowLayoutToStream(string window, OutStream& out, bool writeParent=false) const;
+    void writeWindowLayoutToStream(const Window& window, OutStream& out, bool writeParent=false) const;
+
+	void destroyWindow(string name);
+	void destroyWindow(Window* window);
+	void destroyAllWindows();
+
+	tolua_throws|CEGUI::UnknownObjectException,nil| Window* getWindow(string name) const;
+	bool isWindowPresent(string name) const;
+
+	bool isDeadPoolEmpty() const;
+	void cleanDeadPool();
+
+    void renameWindow(Window* window, string  new_name);
+    void renameWindow(string window, string new_name);
+
+    WindowIterator getIterator() const;
+
+    static void setDefaultResourceGroup(string resourceGroup);
+    static string& getDefaultResourceGroup();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ButtonBase.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ButtonBase.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ButtonBase.pkg	(revision 6952)
@@ -0,0 +1,8 @@
+/***********************************************************************
+	ButtonBase
+***********************************************************************/
+class ButtonBase : public Window
+{
+	bool isHovering() const;
+	bool isPushed() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Checkbox.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Checkbox.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Checkbox.pkg	(revision 6952)
@@ -0,0 +1,8 @@
+/***********************************************************************
+	Checkbox
+***********************************************************************/
+class Checkbox : public ButtonBase
+{
+	bool isSelected() const;
+	void setSelected(bool select);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ComboDropList.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ComboDropList.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ComboDropList.pkg	(revision 6952)
@@ -0,0 +1,10 @@
+/***********************************************************************
+	ComboDropList
+***********************************************************************/
+class ComboDropList : public Listbox
+{
+	void	setArmed(bool setting);
+	bool	isArmed(void) const;
+	void	setAutoArmEnabled(bool setting);
+	bool	isAutoArmEnabled(void) const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Combobox.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Combobox.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Combobox.pkg	(revision 6952)
@@ -0,0 +1,59 @@
+/***********************************************************************
+	Combobox
+***********************************************************************/
+class Combobox : public Window
+{
+	bool getSingleClickEnabled() const;
+	bool isDropDownListVisible() const;
+
+    Editbox* getEditbox() const;
+    PushButton* getPushButton() const;
+    ComboDropList* getDropList() const;
+
+	bool hasInputFocus() const;
+	bool isReadOnly() const;
+	bool isTextValid() const;
+	string getValidationString() const;
+
+	unsigned long getCaratIndex() const;
+	unsigned long getSelectionStartIndex() const;
+	unsigned long getSelectionEndIndex() const;
+	unsigned long getSelectionLength() const;
+	unsigned long getMaxTextLength() const;
+
+	void activateEditbox();
+
+	unsigned long getItemCount() const;
+	ListboxItem* getSelectedItem() const;
+	ListboxItem* getListboxItemFromIndex(unsigned long index) const;
+	unsigned long getItemIndex(const ListboxItem* item) const;
+	bool isItemSelected(unsigned long index) const;
+	ListboxItem* findItemWithText(string text, const ListboxItem* start_item);
+	bool isListboxItemInList(const ListboxItem* item) const;
+
+	void resetList();
+	void addItem(ListboxItem* item);
+	void insertItem(ListboxItem* item, const ListboxItem* position);
+	void removeItem(const ListboxItem* item);
+	void clearAllSelections();
+	void setSortingEnabled(bool setting);
+	void setShowVertScrollbar(bool setting);
+	void setShowHorzScrollbar(bool setting);
+	void setItemSelectState(ListboxItem* item, bool state);
+	void setItemSelectState(unsigned long item_index, bool state);
+	void handleUpdatedListItemData();
+
+	bool isSortEnabled() const;
+	bool isVertScrollbarAlwaysShown() const;
+	bool isHorzScrollbarAlwaysShown() const;
+
+	void showDropList();
+	void hideDropList();
+	void setSingleClickEnabled(bool setting);
+
+	void setReadOnly(bool setting);
+	void setValidationString(string validation_string);
+	void setCaratIndex(unsigned long carat_pos);
+	void setSelection(unsigned long start_pos, unsigned long end_pos);
+	void setMaxTextLength(unsigned long max_len);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/DragContainer.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/DragContainer.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/DragContainer.pkg	(revision 6952)
@@ -0,0 +1,23 @@
+/***********************************************************************
+	DragContainer
+***********************************************************************/
+class DragContainer : public Window
+{
+	bool isDraggingEnabled() const;
+	void setDraggingEnabled(bool setting);
+
+	bool isBeingDragged() const;
+
+	float getPixelDragThreshold() const;
+	void setPixelDragThreshold(float pixels);
+
+	float getDragAlpha() const;
+	void setDragAlpha(float alpha);
+
+	const Image* getDragCursorImage() const;
+	void setDragCursorImage(MouseCursorImage image);
+	void setDragCursorImage(string imageset, string image);
+	void setDragCursorImage(const Image* image);
+
+	Window* getCurrentDropTarget() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Editbox.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Editbox.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Editbox.pkg	(revision 6952)
@@ -0,0 +1,27 @@
+/***********************************************************************
+	Editbox
+***********************************************************************/
+class Editbox : public Window
+{
+	bool hasInputFocus() const;
+	bool isReadOnly() const;
+	bool isTextMasked() const;
+	bool isTextValid() const;
+
+	string getValidationString() const;
+
+	unsigned long getCaratIndex() const;
+	unsigned long getSelectionStartIndex() const;
+	unsigned long getSelectionEndIndex() const;
+	unsigned long getSelectionLength() const;
+	unsigned long getMaskCodePoint() const;
+	unsigned long getMaxTextLength() const;
+
+	void setReadOnly(bool setting);
+	void setTextMasked(bool setting);
+	void setValidationString(string validation_string);
+	void setCaratIndex(unsigned long carat_pos);
+	void setSelection(unsigned long start_pos, unsigned long end_pos);
+	void setMaskCodePoint(unsigned long code_point);
+	void setMaxTextLength(unsigned long max_len);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/FrameWindow.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/FrameWindow.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/FrameWindow.pkg	(revision 6952)
@@ -0,0 +1,27 @@
+/***********************************************************************
+	FrameWindow
+***********************************************************************/
+class FrameWindow : public Window
+{
+	bool isSizingEnabled() const;
+	bool isFrameEnabled() const;
+	bool isTitleBarEnabled() const;
+	bool isCloseButtonEnabled() const;
+	bool isRollupEnabled() const;
+	bool isRolledup() const;
+	bool isDragMovingEnabled() const;
+
+	void setSizingEnabled(bool enabled);
+	void setFrameEnabled(bool enabled);
+	void setTitleBarEnabled(bool enabled);
+	void setCloseButtonEnabled(bool enabled);
+	void setRollupEnabled(bool enabled);
+	void setDragMovingEnabled(bool enabled);
+
+	float getSizingBorderThickness() const;
+	void setSizingBorderThickness(float pixels);
+
+	void toggleRollup();
+
+	void offsetPixelPosition(const Vector2& offset);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/GUISheet.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/GUISheet.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/GUISheet.pkg	(revision 6952)
@@ -0,0 +1,6 @@
+/***********************************************************************
+	GUISheet
+***********************************************************************/
+class GUISheet : public Window
+{
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ItemEntry.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ItemEntry.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ItemEntry.pkg	(revision 6952)
@@ -0,0 +1,14 @@
+/***********************************************************************
+	ItemEntry
+***********************************************************************/
+class ItemEntry : public Window
+{
+	Size getItemPixelSize();
+	ItemListBase* getOwnerList() const;
+	bool isSelected() const;
+	bool isSelectable() const;
+	void setSelected(bool setting);
+	void select();
+	void deselect();
+	void setSelectable(bool setting);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ItemListBase.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ItemListBase.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ItemListBase.pkg	(revision 6952)
@@ -0,0 +1,34 @@
+/***********************************************************************
+	ItemListBase
+***********************************************************************/
+class ItemListBase : public Window
+{
+    enum SortMode
+    {
+        Ascending,
+        Descending,
+        UserSort
+    };
+
+	unsigned int getItemCount() const;
+	ItemEntry* getItemFromIndex(unsigned int index) const;
+	unsigned int getItemIndex(const ItemEntry* item) const;
+	ItemEntry* findItemWithText(string text, const ItemEntry* start_item);
+	bool isItemInList(const ItemEntry* item) const;
+	bool isAutoResizeEnabled() const;
+	bool isSortEnabled() const;
+	SortMode getSortMode() const;
+	Rect getItemRenderArea() const;
+    Window* getContentPane() const;
+
+	void resetList();
+	void addItem(ItemEntry* item);
+	void insertItem(ItemEntry* item, const ItemEntry* position);
+	void removeItem(ItemEntry* item);
+	void handleUpdatedItemData();
+	void setAutoResizeEnabled(bool setting);
+	void sizeToContent();
+    void setSortEnabled(bool setting);
+    void setSortMode(SortMode mode);
+    void sortList();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ItemListbox.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ItemListbox.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ItemListbox.pkg	(revision 6952)
@@ -0,0 +1,17 @@
+/***********************************************************************
+	ItemListbox
+***********************************************************************/
+class ItemListbox : public ScrolledItemListBase
+{
+    unsigned long getSelectedCount() const;
+    ItemEntry* getLastSelectedItem() const;
+    ItemEntry* getFirstSelectedItem(unsigned long start_index=0) const;
+    ItemEntry* getNextSelectedItem() const;
+    ItemEntry* getNextSelectedItemAfter(const ItemEntry* start_item) const;
+    bool isMultiSelectEnabled() const;
+    bool isItemSelected(unsigned long index) const;
+    void setMultiSelectEnabled(bool state);
+    void clearAllSelections();
+    void selectRange(unsigned long a, unsigned long z);
+    void selectAllItems();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ListHeader.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ListHeader.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ListHeader.pkg	(revision 6952)
@@ -0,0 +1,55 @@
+/***********************************************************************
+	ListHeader
+***********************************************************************/
+class ListHeader : public Window
+{
+	unsigned int getColumnCount() const;
+
+	ListHeaderSegment& getSegmentFromColumn(unsigned int column) const;
+	ListHeaderSegment& getSegmentFromID(unsigned int id) const;
+	ListHeaderSegment& getSortSegment() const;
+
+	unsigned int getColumnFromSegment(const ListHeaderSegment& segment) const;
+	unsigned int getColumnFromID(unsigned int id) const;
+	unsigned int getSortColumn() const;
+	unsigned int getColumnWithText(string text) const;
+
+	float getPixelOffsetToSegment(const ListHeaderSegment& segment) const;
+	float getPixelOffsetToColumn(unsigned int column) const;
+	float getTotalSegmentsPixelExtent() const;
+	UDim  getColumnWidth(unsigned int column) const;
+
+	ListHeaderSegment::SortDirection getSortDirection() const;
+
+	bool isSortingEnabled() const;
+	bool isColumnSizingEnabled() const;
+	bool isColumnDraggingEnabled() const;
+
+	float getSegmentOffset() const;
+
+
+	void setSortingEnabled(bool setting);
+	void setSortDirection(ListHeaderSegment::SortDirection direction);
+	void setSortSegment(const ListHeaderSegment& segment);
+	void setSortColumn(unsigned int column);
+	void setSortColumnFromID(unsigned int id);
+
+	void setColumnSizingEnabled(bool setting);
+	void setColumnDraggingEnabled(bool setting);
+	void addColumn(string text, unsigned int id, const UDim& width);
+
+	void insertColumn(string text, unsigned int id, const UDim& width, unsigned int position);
+	void insertColumn(string text, unsigned int id, const UDim& width, const ListHeaderSegment& position);
+	void removeColumn(unsigned int column);
+	void removeSegment(const ListHeaderSegment& segment);
+
+	void moveColumn(unsigned int column, unsigned int position);
+	void moveColumn(unsigned int column, const ListHeaderSegment& position);
+
+	void moveSegment(const ListHeaderSegment& segment, unsigned int position);
+	void moveSegment(const ListHeaderSegment& segment, const ListHeaderSegment& position);
+
+	void setSegmentOffset(float offset);
+
+	void setColumnWidth(unsigned int column, const UDim& width);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ListHeaderSegment.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ListHeaderSegment.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ListHeaderSegment.pkg	(revision 6952)
@@ -0,0 +1,23 @@
+/***********************************************************************
+	ListHeaderSegment
+***********************************************************************/
+class ListHeaderSegment : public Window
+{
+	enum SortDirection
+	{
+		None,
+		Ascending,
+		Descending
+	};
+
+	bool isSizingEnabled() const;
+	SortDirection getSortDirection() const;
+	bool isDragMovingEnabled() const;
+	const Vector2& getDragMoveOffset() const;
+	bool isClickable() const;
+
+	void setSizingEnabled(bool setting);
+	void setSortDirection(SortDirection sort_dir);
+	void setDragMovingEnabled(bool setting);
+	void setClickable(bool setting);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Listbox.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Listbox.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Listbox.pkg	(revision 6952)
@@ -0,0 +1,40 @@
+/***********************************************************************
+	Listbox
+***********************************************************************/
+class Listbox : public Window
+{
+	unsigned long getItemCount() const;
+	unsigned long getSelectedCount() const;
+	ListboxItem* getFirstSelectedItem() const;
+	ListboxItem* getNextSelected(const ListboxItem* start_item) const;
+	ListboxItem* getListboxItemFromIndex(unsigned long index) const;
+	unsigned long getItemIndex(const ListboxItem* item) const;
+	ListboxItem* findItemWithText(string text, const ListboxItem* start_item);
+	bool isSortEnabled() const;
+	bool isMultiselectEnabled() const;
+	bool isItemSelected(unsigned long index) const;
+	bool isListboxItemInList(const ListboxItem* item) const;
+	bool isVertScrollbarAlwaysShown() const;
+	bool isHorzScrollbarAlwaysShown() const;
+
+	void resetList(void);
+	void addItem(ListboxItem* item);
+	void insertItem(ListboxItem* item, const ListboxItem* position);
+	void removeItem(const ListboxItem* item);
+	void clearAllSelections(void);
+	void setSortingEnabled(bool setting);
+	void setMultiselectEnabled(bool setting);
+	void setShowVertScrollbar(bool setting);
+	void setShowHorzScrollbar(bool setting);
+	void setItemSelectState(ListboxItem* item, bool state);
+	void setItemSelectState(unsigned long item_index, bool state);
+	void handleUpdatedItemData(void);
+	void ensureItemIsVisible(unsigned long item_index);
+	void ensureItemIsVisible(const ListboxItem* item);
+	
+	Rect getListRenderArea() const;
+	Scrollbar* getVertScrollbar() const;
+	Scrollbar* getHorzScrollbar() const;
+	float getWidestItemWidth() const;
+	float getTotalItemsHeight() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ListboxItem.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ListboxItem.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ListboxItem.pkg	(revision 6952)
@@ -0,0 +1,33 @@
+/***********************************************************************
+	ListboxItem
+***********************************************************************/
+class ListboxItem
+{
+	string getText() const;
+	unsigned int getID() const;
+	void* getUserData() const;
+	bool isSelected() const;
+	bool isDisabled() const;
+	bool isAutoDeleted() const;
+	const Window* getOwnerWindow();
+	ColourRect getSelectionColours() const;
+	const Image* getSelectionBrushImage() const;
+
+	void setText(string text);
+	void setID(unsigned int item_id);
+	void setUserData(void* item_data);
+	void setSelected(bool setting);
+	void setDisabled(bool setting);
+	void setAutoDeleted(bool setting);
+	void setOwnerWindow(const Window* owner);
+	void setSelectionColours(const ColourRect& cols);
+	void setSelectionColours(colour top_left_colour, colour top_right_colour, colour bottom_left_colour, colour bottom_right_colour);
+	void setSelectionColours(colour col);
+	void setSelectionBrushImage(const Image* image);
+	void setSelectionBrushImage(string imageset, string image);
+
+	Size getPixelSize() const;
+
+	//void draw(const Vector3& position, float alpha, const Rect& clipper) const;
+	// operators missing
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ListboxTextItem.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ListboxTextItem.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ListboxTextItem.pkg	(revision 6952)
@@ -0,0 +1,21 @@
+/***********************************************************************
+	ListboxTextItem
+
+	The constructor is not exportet, instead a helper function is
+	available (CEGUI.createListboxTextItem).
+
+	I decided to do it like this to avoid any possible memory issues
+	with allocating from Lua.
+***********************************************************************/
+class ListboxTextItem : public ListboxItem
+{
+	Font* getFont() const;
+	ColourRect getTextColours() const;
+
+	void setFont(string font_name);
+	void setFont(Font* font);
+
+	void setTextColours(colour top_left_colour, colour top_right_colour, colour bottom_left_colour, colour bottom_right_colour);
+	void setTextColours(const ColourRect& cols);
+	void setTextColours(colour col);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/MenuBase.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/MenuBase.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/MenuBase.pkg	(revision 6952)
@@ -0,0 +1,13 @@
+/***********************************************************************
+	MenuBase
+***********************************************************************/
+class MenuBase : public ItemListBase
+{
+	float getItemSpacing() const;
+	bool isMultiplePopupsAllowed() const;
+	MenuItem* getPopupMenuItem() const;
+
+	void setItemSpacing(float spacing);
+	void changePopupMenuItem(MenuItem* item);
+	void setAllowMultiplePopups(bool setting);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/MenuItem.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/MenuItem.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/MenuItem.pkg	(revision 6952)
@@ -0,0 +1,14 @@
+/***********************************************************************
+	Menubar
+***********************************************************************/
+class MenuItem : public ItemEntry
+{
+	bool isHovering() const;
+	bool isPushed() const;
+	PopupMenu* getPopupMenu() const;
+
+	void setPopupMenu(PopupMenu* popup);
+	void openPopupMenu();
+	void closePopupMenu(bool notify=true);
+	bool togglePopupMenu();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Menubar.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Menubar.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Menubar.pkg	(revision 6952)
@@ -0,0 +1,6 @@
+/***********************************************************************
+	Menubar
+***********************************************************************/
+class Menubar : public MenuBase
+{
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/MultiColumnList.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/MultiColumnList.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/MultiColumnList.pkg	(revision 6952)
@@ -0,0 +1,138 @@
+/***********************************************************************
+	MultiColumnList
+***********************************************************************/
+struct MCLGridRef
+{
+	unsigned int row;
+	unsigned int column;
+
+	//bool operator< (const MCLGridRef& rhs) const;
+	//bool operator>= (const MCLGridRef& rhs) const;
+	bool operator== (const MCLGridRef& rhs) const;
+
+	MCLGridRef(unsigned int r, unsigned int c);
+};
+
+
+/***********************************************************************
+	MultiColumnList
+***********************************************************************/
+class MultiColumnList : public Window
+{
+	enum SelectionMode
+	{
+		RowSingle,
+		RowMultiple,
+		CellSingle,
+		CellMultiple,
+		NominatedColumnSingle,
+		NominatedColumnMultiple,
+		ColumnSingle,
+		ColumnMultiple,
+		NominatedRowSingle,
+		NominatedRowMultiple
+	};
+
+	bool isUserSortControlEnabled() const;
+	bool isUserColumnSizingEnabled() const;
+	bool isUserColumnDraggingEnabled() const;
+
+	unsigned int getColumnCount() const;
+	unsigned int getRowCount() const;
+	unsigned int getSortColumn() const;
+	unsigned int getColumnWithID(unsigned int col_id) const;
+	unsigned int getColumnWithHeaderText(string text) const;
+
+	UDim getTotalColumnHeadersWidth() const;
+	UDim getColumnHeaderWidth(unsigned int col_idx) const;
+
+	ListHeaderSegment::SortDirection getSortDirection() const;
+	ListHeaderSegment& getHeaderSegmentForColumn(unsigned int col_idx) const;
+
+	unsigned int getItemRowIndex(const ListboxItem* item) const;
+	unsigned int getItemColumnIndex(const ListboxItem* item) const;
+
+	MCLGridRef getItemGridReference(const ListboxItem* item) const;
+	ListboxItem* getItemAtGridReference(const MCLGridRef& grid_ref) const;
+
+	bool isListboxItemInColumn(const ListboxItem* item, unsigned int col_idx) const;
+	bool isListboxItemInRow(const ListboxItem* item, unsigned int row_idx) const;
+	bool isListboxItemInList(const ListboxItem* item) const;
+
+	ListboxItem* findColumnItemWithText(string text, unsigned int col_idx, const ListboxItem* start_item) const;
+	ListboxItem* findRowItemWithText(string text, unsigned int row_idx, const ListboxItem* start_item) const;
+	ListboxItem* findListItemWithText(string text, const ListboxItem* start_item) const;
+	ListboxItem* getFirstSelectedItem() const;
+	ListboxItem* getNextSelected(const ListboxItem* start_item) const;
+
+	unsigned int getSelectedCount() const;
+	bool isItemSelected(const MCLGridRef& grid_ref) const;
+
+	unsigned int getNominatedSelectionColumnID() const;
+	unsigned int getNominatedSelectionColumn() const;
+	unsigned int getNominatedSelectionRow() const;
+
+	SelectionMode getSelectionMode() const;
+
+	bool isVertScrollbarAlwaysShown() const;
+	bool isHorzScrollbarAlwaysShown() const;
+
+	unsigned int getColumnID(unsigned int col_idx) const;
+	unsigned int getRowID(unsigned int row_idx) const;
+    unsigned int getRowWithID(unsigned int row_id) const;
+
+    Rect getListRenderArea() const;
+
+    Scrollbar* getVertScrollbar() const;
+    Scrollbar* getHorzScrollbar() const;
+    ListHeader* getListHeader() const;
+
+    float getTotalRowsHeight() const;
+    float getWidestColumnItemWidth(unsigned int col_idx) const;
+    float getHighestRowItemHeight(unsigned int row_idx) const;
+
+	void resetList();
+
+	void addColumn(string text, unsigned int col_id, const UDim& width);
+	void insertColumn(string text, unsigned int col_id, const UDim& width, unsigned int position);
+	void removeColumn(unsigned int col_idx);
+	void removeColumnWithID(unsigned int col_id);
+	void moveColumn(unsigned int col_idx, unsigned int position);
+	void moveColumnWithID(unsigned int col_id, unsigned int position);
+
+	unsigned int addRow();
+	unsigned int addRow(ListboxItem* item, unsigned int col_id);
+	unsigned int insertRow(unsigned int row_idx);
+	unsigned int insertRow(ListboxItem* item, unsigned int col_id, unsigned int row_idx);
+	void removeRow(unsigned int row_idx);
+
+	void setItem(ListboxItem* item, const MCLGridRef& position);
+	void setItem(ListboxItem* item, unsigned int col_id, unsigned int row_idx);
+
+	void setSelectionMode(MultiColumnList::SelectionMode sel_mode);
+	void setNominatedSelectionColumnID(unsigned int col_id);
+	void setNominatedSelectionColumn(unsigned int col_idx);
+	void setNominatedSelectionRow(unsigned int row_idx);
+
+	void setSortDirection(ListHeaderSegment::SortDirection direction);
+	void setSortColumn(unsigned int col_idx);
+	void setSortColumnByID(unsigned int col_id);
+
+	void setShowVertScrollbar(bool setting);
+	void setShowHorzScrollbar(bool setting);
+
+	void clearAllSelections();
+
+	void setItemSelectState(ListboxItem* item, bool state);
+	void setItemSelectState(const MCLGridRef& grid_ref, bool state);
+
+	void handleUpdatedItemData();
+
+	void setColumnHeaderWidth(unsigned int col_idx, const UDim& width);
+	void setUserSortControlEnabled(bool setting);
+	void setUserColumnSizingEnabled(bool setting);
+	void setUserColumnDraggingEnabled(bool setting);
+	void autoSizeColumnHeader(unsigned int col_idx);
+	
+	void setRowID(unsigned int row_idx, unsigned int row_id);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/MultiLineEditbox.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/MultiLineEditbox.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/MultiLineEditbox.pkg	(revision 6952)
@@ -0,0 +1,29 @@
+/***********************************************************************
+	MultiLineEditbox
+***********************************************************************/
+class MultiLineEditbox : public Window
+{
+	bool hasInputFocus() const;
+	bool isReadOnly() const;
+	unsigned long getCaratIndex() const;
+	unsigned long getSelectionStartIndex() const;
+	unsigned long getSelectionEndIndex() const;
+	unsigned long getSelectionLength() const;
+	unsigned long getMaxTextLength() const;
+	bool isWordWrapped() const;
+
+    Scrollbar* getVertScrollbar() const;
+    Scrollbar* getHorzScrollbar() const;
+    Rect getTextRenderArea() const;
+    unsigned long getLineNumberFromIndex(unsigned long index) const;
+
+	void setReadOnly(bool setting);
+	void setCaratIndex(unsigned long carat_pos);
+	void setSelection(unsigned long start_pos, unsigned long end_pos);
+	void setMaxTextLength(unsigned long max_len);
+	void ensureCaratIsVisible();
+	void setWordWrapping(bool setting);
+
+    void setSelectionBrushImage(const Image* image);
+    const Image* getSelectionBrushImage() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/PopupMenu.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/PopupMenu.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/PopupMenu.pkg	(revision 6952)
@@ -0,0 +1,13 @@
+/***********************************************************************
+	PopupMenu
+***********************************************************************/
+class PopupMenu : public MenuBase
+{
+	float getFadeInTime() const;
+	float getFadeOutTime() const;
+
+	void setFadeInTime(float fadetime);
+	void setFadeOutTime(float fadetime);
+	void openPopupMenu();
+	void closePopupMenu();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ProgressBar.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ProgressBar.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ProgressBar.pkg	(revision 6952)
@@ -0,0 +1,13 @@
+/***********************************************************************
+	ProgressBar
+***********************************************************************/
+class ProgressBar : public Window
+{
+	float getProgress() const;
+	float getStep() const;
+
+	void setProgress(float progress);
+	void setStepSize(float step);
+	void step();
+	void adjustProgress(float delta);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/PushButton.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/PushButton.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/PushButton.pkg	(revision 6952)
@@ -0,0 +1,6 @@
+/***********************************************************************
+	PushButton
+***********************************************************************/
+class PushButton : public ButtonBase
+{
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/RadioButton.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/RadioButton.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/RadioButton.pkg	(revision 6952)
@@ -0,0 +1,13 @@
+/***********************************************************************
+	RadioButton
+***********************************************************************/
+class RadioButton : public ButtonBase
+{
+	bool isSelected() const;
+	void setSelected(bool select);
+
+	unsigned long getGroupID() const;
+	void setGroupID(unsigned long group);
+
+	RadioButton* getSelectedButtonInGroup() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ScrollablePane.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ScrollablePane.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ScrollablePane.pkg	(revision 6952)
@@ -0,0 +1,41 @@
+/***********************************************************************
+	ScrollablePane
+***********************************************************************/
+class ScrollablePane : public Window
+{
+	const ScrolledContainer* getContentPane() const;
+
+	bool	isVertScrollbarAlwaysShown() const;
+	void	setShowVertScrollbar(bool setting);
+
+	bool	isHorzScrollbarAlwaysShown() const;
+	void	setShowHorzScrollbar(bool setting);
+
+	bool isContentPaneAutoSized() const;
+	void setContentPaneAutoSized(bool setting);
+
+	const Rect& getContentPaneArea() const;
+	void setContentPaneArea(const Rect& area);
+
+	float getHorizontalStepSize() const;
+	void setHorizontalStepSize(float step);
+
+	float getHorizontalOverlapSize() const;
+	void setHorizontalOverlapSize(float overlap);
+
+	float getHorizontalScrollPosition() const;
+	void setHorizontalScrollPosition(float position);
+
+	float getVerticalStepSize() const;
+	void setVerticalStepSize(float step);
+
+	float getVerticalOverlapSize() const;
+	void setVerticalOverlapSize(float overlap);
+
+	float getVerticalScrollPosition() const;
+	void setVerticalScrollPosition(float position);
+
+    Rect getViewableArea() const;
+    Scrollbar* getVertScrollbar() const;
+    Scrollbar* getHorzScrollbar() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Scrollbar.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Scrollbar.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Scrollbar.pkg	(revision 6952)
@@ -0,0 +1,17 @@
+/***********************************************************************
+	Scrollbar
+***********************************************************************/
+class Scrollbar : public Window
+{
+	float getDocumentSize() const;
+	float getPageSize() const;
+	float getStepSize() const;
+	float getOverlapSize() const;
+	float getScrollPosition() const;
+
+	void setDocumentSize(float document_size);
+	void setPageSize(float page_size);
+	void setStepSize(float step_size);
+	void setOverlapSize(float overlap_size);
+	void setScrollPosition(float position);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ScrolledContainer.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ScrolledContainer.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ScrolledContainer.pkg	(revision 6952)
@@ -0,0 +1,13 @@
+/***********************************************************************
+	ScrolledContainer
+***********************************************************************/
+class ScrolledContainer : public Window
+{
+	bool isContentPaneAutoSized() const;
+	void setContentPaneAutoSized(bool setting);
+
+	const Rect& getContentArea() const;
+	void setContentArea(const Rect& area);
+
+	Rect getChildExtentsArea() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ScrolledItemListBase.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ScrolledItemListBase.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/ScrolledItemListBase.pkg	(revision 6952)
@@ -0,0 +1,12 @@
+/***********************************************************************
+	ScrolledItemListBase
+***********************************************************************/
+class ScrolledItemListBase : public ItemListBase
+{
+	bool isVertScrollbarAlwaysShown() const;
+	bool isHorzScrollbarAlwaysShown() const;
+    Scrollbar* getVertScrollbar() const;
+    Scrollbar* getHorzScrollbar() const;
+    void setShowVertScrollbar(bool mode);
+    void setShowHorzScrollbar(bool mode);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Slider.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Slider.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Slider.pkg	(revision 6952)
@@ -0,0 +1,13 @@
+/***********************************************************************
+	Slider
+***********************************************************************/
+class Slider : public Window
+{
+	float getCurrentValue() const;
+	float getMaxValue() const;
+	float getClickStep() const;
+
+	void setMaxValue(float maxVal);
+	void setCurrentValue(float value);
+	void setClickStep(float step);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Spinner.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Spinner.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Spinner.pkg	(revision 6952)
@@ -0,0 +1,25 @@
+/***********************************************************************
+	Spinner
+***********************************************************************/
+class Spinner : public Window
+{
+	enum TextInputMode
+	{
+		FloatingPoint,
+		Integer,
+		Hexadecimal,
+		Octal
+	};
+
+	float getCurrentValue() const;
+	float getStepSize() const;
+	float getMaximumValue() const;
+	float getMinimumValue() const;
+	TextInputMode getTextInputMode() const;
+
+	void setCurrentValue(float value);
+	void setStepSize(float step);
+	void setMaximumValue(float maxValue);
+	void setMinimumValue(float minVaue);
+	void setTextInputMode(TextInputMode mode);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/TabButton.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/TabButton.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/TabButton.pkg	(revision 6952)
@@ -0,0 +1,11 @@
+/***********************************************************************
+	TabButton
+***********************************************************************/
+class TabButton : public ButtonBase
+{
+	bool isSelected() const;
+	void setSelected(bool select);
+
+	void setTargetWindow(Window* wnd);
+	Window* getTargetWindow();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/TabControl.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/TabControl.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/TabControl.pkg	(revision 6952)
@@ -0,0 +1,29 @@
+/***********************************************************************
+	TabControl
+***********************************************************************/
+class TabControl : public Window
+{
+	unsigned int getTabCount() const;
+
+	void setSelectedTab(string name);
+	void setSelectedTab(unsigned int ID);
+	void setSelectedTabAtIndex(unsigned int index);
+
+	Window* getTabContentsAtIndex(unsigned int index) const;
+	Window* getTabContents(string name) const;
+	Window* getTabContents(unsigned int ID) const;
+
+	bool isTabContentsSelected(Window* wnd) const;
+	unsigned int getSelectedTabIndex() const;
+
+	const UDim& getTabHeight() const;
+	const UDim& getTabTextPadding() const;
+
+	void setTabHeight(const UDim& height);
+	void setTabTextPadding(const UDim& pad);
+
+	void addTab(Window* wnd);
+
+	void removeTab(unsigned int ID);
+	void removeTab(string name);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Thumb.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Thumb.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Thumb.pkg	(revision 6952)
@@ -0,0 +1,22 @@
+/***********************************************************************
+	Thumb
+***********************************************************************/
+class Thumb : public PushButton
+{
+	bool isHotTracked() const;
+	bool isVertFree() const;
+	bool isHorzFree() const;
+
+	void setHotTracked(bool setting);
+	void setVertFree(bool setting);
+	void setHorzFree(bool setting);
+
+
+	// we have a helper function that converts the std::pair to two return values tolua++ style
+	tolua_outside void ceguiLua_Thumb_getVertRange @ getVertRange(float* min=0, float* max=0);
+	tolua_outside void ceguiLua_Thumb_getHorzRange @ getHorzRange(float* min=0, float* max=0);
+
+
+	void setVertRange(float min, float max);
+	void setHorzRange(float min, float max);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Titlebar.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Titlebar.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Titlebar.pkg	(revision 6952)
@@ -0,0 +1,8 @@
+/***********************************************************************
+	Titlebar
+***********************************************************************/
+class Titlebar : public Window
+{
+	bool isDraggingEnabled() const;
+	void setDraggingEnabled(bool setting);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Tooltip.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Tooltip.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/elements/Tooltip.pkg	(revision 6952)
@@ -0,0 +1,14 @@
+/***********************************************************************
+	Tooltip
+***********************************************************************/
+class Tooltip : public Window
+{
+	void setTargetWindow(Window* wnd);
+	void resetTimer();
+	float getHoverTime() const;
+	void setDisplayTime(float seconds);
+	float getFadeTime() const;
+	void setHoverTime(float seconds);
+	float getDisplayTime() const;
+	void setFadeTime(float seconds);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/exceptions.lua
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/exceptions.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/exceptions.lua	(revision 6952)
@@ -0,0 +1,7 @@
+exceptionDefs["CEGUI::Exception"]           = {}
+exceptionDefs["CEGUI::Exception"]["var"]    = "&e"
+exceptionDefs["CEGUI::Exception"]["c_str"]  = "e.getMessage().c_str()"
+
+exceptionDefs["CEGUI::AlreadyExistsException"]  = exceptionDefs["CEGUI::Exception"]
+exceptionDefs["CEGUI::InvalidRequestException"] = exceptionDefs["CEGUI::Exception"]
+exceptionDefs["CEGUI::UnknownObjectException"]  = exceptionDefs["CEGUI::Exception"]
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/Dimension.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/Dimension.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/Dimension.pkg	(revision 6952)
@@ -0,0 +1,102 @@
+/******************************************************************************
+  BaseDim  
+******************************************************************************/
+class BaseDim
+{
+  tolua_throws|CEGUI::InvalidRequestException,error| float getValue(const Window& wnd) const;
+  tolua_throws|CEGUI::InvalidRequestException,error| float getValue(const Window& wnd, const Rect& container) const;
+  BaseDim* clone() const;
+  DimensionOperator getDimensionOperator() const;
+  void setDimensionOperator(DimensionOperator op);
+  const BaseDim* getOperand() const;
+  void setOperand(const BaseDim& operand);
+  //void writeXMLToStream(OutStream& out_stream) const;
+};
+
+/******************************************************************************
+  AbsoluteDim 
+******************************************************************************/
+class AbsoluteDim : public BaseDim
+{
+  void setValue(float val);
+  AbsoluteDim(float val);
+};
+
+/******************************************************************************
+  ImageDim
+******************************************************************************/
+class ImageDim : public BaseDim 
+{
+  void setSourceImage(string imageset, string image);
+  void setSourceDimension(DimensionType dim);
+  ImageDim(string imageset, string image, DimensionType dim);
+};
+
+/******************************************************************************
+  WidgetDim
+******************************************************************************/
+class WidgetDim : public BaseDim
+{
+  void setWidgetName(string name);
+  void setSourceDimension(DimensionType dim); 
+  WidgetDim(string name, DimensionType dim);
+};
+
+/******************************************************************************
+  UnifiedDim
+******************************************************************************/
+class UnifiedDim : public BaseDim 
+{
+  UnifiedDim(const UDim& value, DimensionType dim);
+};
+
+/******************************************************************************
+  FontDim
+******************************************************************************/
+class FontDim : public BaseDim
+{
+  FontDim(string name, string font, string text, FontMetricType metric, float padding = 0);
+};
+
+/******************************************************************************
+  PropertyDim
+******************************************************************************/
+class PropertyDim : public BaseDim
+{
+  PropertyDim(string name, string property, DimensionType type);
+};
+
+/******************************************************************************
+  Dimension
+******************************************************************************/
+class Dimension
+{
+  const BaseDim& getBaseDimension() const;
+  void setBaseDimension(const BaseDim& dim);
+  DimensionType getDimensionType() const;
+  void setDimensionType(DimensionType type);
+
+  //Dimension& operator=(const Dimension& other);
+  //void writeXMLToStream(OutStream& out_stream) const;
+  Dimension(const BaseDim& dim, DimensionType type);
+  Dimension(const Dimension& other);
+  Dimension();
+};
+
+/******************************************************************************
+  ComponentArea 
+******************************************************************************/
+class ComponentArea
+{
+  Rect getPixelRect(const Window& wnd) const;
+  Rect getPixelRect(const Window& wnd, const Rect& container) const;
+  //void writeXMLToStream(OutStream& out_stream) const;
+  bool isAreaFetchedFromProperty() const;
+  string getAreaPropertySource() const;
+  void setAreaPropertySource(string property);
+  Dimension d_left;
+  Dimension d_top;
+  Dimension d_right_or_width;
+  Dimension d_bottom_or_height;
+  ComponentArea();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/Enums.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/Enums.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/Enums.pkg	(revision 6952)
@@ -0,0 +1,108 @@
+/******************************************************************************
+  DimensionType
+*******************************************************************************/
+enum DimensionType
+{
+  DT_LEFT_EDGE,
+  DT_X_POSITION,
+  DT_TOP_EDGE,
+  DT_Y_POSITION,
+  DT_RIGHT_EDGE,
+  DT_BOTTOM_EDGE,
+  DT_WIDTH,
+  DT_HEIGHT,
+  DT_X_OFFSET, 
+  DT_Y_OFFSET,
+  DT_INVALID 
+};
+
+
+/******************************************************************************
+  VerticalFormatting  
+*******************************************************************************/
+enum VerticalFormatting
+{
+  VF_TOP_ALIGNED,
+  VF_CENTRE_ALIGNED,
+  VF_BOTTOM_ALIGNED, 
+  VF_STRETCHED,  
+  VF_TILED 
+};
+
+
+/******************************************************************************
+  HorizontalFormatting  
+*******************************************************************************/
+enum HorizontalFormatting
+{
+  HF_LEFT_ALIGNED,
+  HF_CENTRE_ALIGNED,
+  HF_RIGHT_ALIGNED,
+  HF_STRETCHED,
+  HF_TILED
+};
+
+/******************************************************************************
+  VerticalTextFormatting  
+*******************************************************************************/
+enum VerticalTextFormatting
+{
+  VTF_TOP_ALIGNED,
+  VTF_CENTRE_ALIGNED,
+  VTF_BOTTOM_ALIGNED 
+};
+
+/******************************************************************************
+  HorinzontalTextFormatting  
+*******************************************************************************/
+enum HorizontalTextFormatting
+{
+  HTF_LEFT_ALIGNED,
+  HTF_RIGHT_ALIGNED,
+  HTF_CENTRE_ALIGNED,
+  HTF_JUSTIFIED, 
+  HTF_WORDWRAP_LEFT_ALIGNED,
+  HTF_WORDWRAP_RIGHT_ALIGNED,
+  HTF_WORDWRAP_CENTRE_ALIGNED,
+  HTF_WORDWRAP_JUSTIFIED 
+};
+
+/******************************************************************************
+  FontMetricType   
+*******************************************************************************/
+enum FontMetricType
+{
+  FMT_LINE_SPACING,
+  FMT_BASELINE,
+  FMT_HORZ_EXTENT
+};
+
+/******************************************************************************
+  DimensionOperator 
+*******************************************************************************/
+enum DimensionOperator
+{
+  DOP_NOOP,
+  DOP_ADD,
+  DOP_SUBTRACT,
+  DOP_MULTIPLY,
+  DOP_DIVIDE
+};
+
+/******************************************************************************
+  FrameImageComponent
+*******************************************************************************/
+enum FrameImageComponent
+{
+  FIC_BACKGROUND,
+  FIC_TOP_LEFT_CORNER,
+  FIC_TOP_RIGHT_CORNER,
+  FIC_BOTTOM_LEFT_CORNER,
+  FIC_BOTTOM_RIGHT_CORNER,
+  FIC_LEFT_EDGE,
+  FIC_RIGHT_EDGE,
+  FIC_TOP_EDGE,
+  FIC_BOTTOM_EDGE,
+  FIC_FRAME_IMAGE_COUNT 
+};
+
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/FalagardComponentBase.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/FalagardComponentBase.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/FalagardComponentBase.pkg	(revision 6952)
@@ -0,0 +1,17 @@
+/******************************************************************************
+  FalagardComponentBase
+******************************************************************************/
+
+class FalagardComponentBase
+{
+  void render(Window& srcWindow, float base_z, const ColourRect* modColours = 0, const Rect* clipper = 0, bool clipToDisplay = false) const;
+  void render(Window& srcWindow, const Rect& baseRect, float base_z, const ColourRect* modColours = 0, const Rect* clipper = 0, bool clipToDisplay = false) const;
+  const ComponentArea& getComponentArea() const;
+  void setComponentArea(const ComponentArea& area);
+  const ColourRect& getColours() const;
+  void setColours(const ColourRect& cols);
+  void setColoursPropertySource(string property);
+  void setColoursPropertyIsColourRect(bool setting = true);
+  void setVertFormattingPropertySource(string property);
+  void setHorzFormattingPropertySource(string property);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/FrameComponent.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/FrameComponent.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/FrameComponent.pkg	(revision 6952)
@@ -0,0 +1,17 @@
+/******************************************************************************
+  FrameComponent
+******************************************************************************/
+
+class FrameComponent : public FalagardComponentBase
+{
+
+  VerticalFormatting getBackgroundVerticalFormatting() const;
+  void setBackgroundVerticalFormatting(VerticalFormatting fmt);
+  HorizontalFormatting getBackgroundHorizontalFormatting() const;
+  void setBackgroundHorizontalFormatting(HorizontalFormatting fmt);
+  const Image* getImage(FrameImageComponent part) const;
+  void setImage(FrameImageComponent part, const Image* image);
+  void setImage(FrameImageComponent part, string imageset, string image);
+  //void writeXMLToStream(OutStream& out_stream) const;
+  FrameComponent();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/ImageryComponent.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/ImageryComponent.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/ImageryComponent.pkg	(revision 6952)
@@ -0,0 +1,19 @@
+/******************************************************************************
+  ImageryComponent
+******************************************************************************/
+
+class ImageryComponent : public FalagardComponentBase 
+{
+  const Image* getImage() const;
+  void setImage(const Image* image);
+  void setImage(string imageset, string image);
+  VerticalFormatting getVerticalFormatting() const;
+  void setVerticalFormatting(VerticalFormatting fmt);
+  HorizontalFormatting getHorizontalFormatting() const;
+  void setHorizontalFormatting(HorizontalFormatting fmt);
+  //void writeXMLToStream(OutStream& out_stream) const;
+  bool isImageFetchedFromProperty() const;
+  string getImagePropertySource() const;
+  void setImagePropertySource(string property);
+  ImageryComponent();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/ImagerySection.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/ImagerySection.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/ImagerySection.pkg	(revision 6952)
@@ -0,0 +1,28 @@
+/******************************************************************************
+  ImagerySection
+******************************************************************************/
+
+class ImagerySection
+{
+  void render(Window& srcWindow, float base_z, const ColourRect* modColours = 0, const Rect* clipper = 0, bool clipToDisplay = false) const;
+
+  void render(Window& srcWindow, const Rect& baseRect, float base_z, const ColourRect* modColours = 0, const Rect* clipper = 0, bool clipToDisplay = false) const;
+  void addImageryComponent(const ImageryComponent& img);
+  void clearImageryComponents();
+  void addTextComponent(const TextComponent& text);
+  void clearTextComponents();
+  void clearFrameComponents();
+  void addFrameComponent(const FrameComponent& frame);
+  const ColourRect& getMasterColours() const;
+  void setMasterColours(const ColourRect& cols);
+  string getName() const;
+  void setMasterColoursPropertySource(string property);
+  void setMasterColoursPropertyIsColourRect(bool setting = true);
+  Rect getBoundingRect(const Window& wnd) const;
+  Rect getBoundingRect(const Window& wnd, const Rect& rect) const;
+  //void writeXMLToStream(OutStream& out_stream) const;
+
+  ImagerySection();
+  ImagerySection(string name);
+};
+
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/LayerSpecification.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/LayerSpecification.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/LayerSpecification.pkg	(revision 6952)
@@ -0,0 +1,16 @@
+/******************************************************************************
+  LayerSpecification
+******************************************************************************/
+
+class LayerSpecification
+{
+  void render(Window& srcWindow, float base_z, const ColourRect* modcols = 0, const Rect* clipper = 0, bool clipToDisplay = false) const;
+  void render(Window& srcWindow, const Rect& baseRect, float base_z, const ColourRect* modcols = 0, const Rect* clipper = 0, bool clipToDisplay = false) const;
+  void addSectionSpecification(const SectionSpecification& section);
+  void clearSectionSpecifications();
+  unsigned int getLayerPriority() const;
+  bool operator<(const LayerSpecification& other) const;
+  //void writeXMLToStream(OutStream& out_stream) const;
+  LayerSpecification(unsigned int priority);
+};
+
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/NamedArea.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/NamedArea.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/NamedArea.pkg	(revision 6952)
@@ -0,0 +1,14 @@
+/***********************************************************************
+  NamedArea
+***********************************************************************/
+class NamedArea
+{
+  string getName() const;
+  const ComponentArea& getArea() const;
+  void setArea(ComponentArea area);
+  //void writeXMLToStream(OutStream& out_stream) const;
+
+  NamedArea();
+  NamedArea(string name);
+};
+
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/PropertyDefinition.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/PropertyDefinition.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/PropertyDefinition.pkg	(revision 6952)
@@ -0,0 +1,13 @@
+/******************************************************************************
+  PropertyDefinition
+******************************************************************************/
+
+class PropertyDefinition : public PropertyDefinitionBase
+{
+  //string get(const PropertyReceiver* receiver) const;
+  //void set(PropertyReceiver* receiver, string value);
+  string get(const Window* receiver) const;
+  void set(Window* receiver, string value);
+
+  PropertyDefinition(string name, string initialValue, bool redrawOnWrite, bool layoutOnWrite);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/PropertyDefinitionBase.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/PropertyDefinitionBase.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/PropertyDefinitionBase.pkg	(revision 6952)
@@ -0,0 +1,10 @@
+/******************************************************************************
+  PropertyDefinitionBase 
+*******************************************************************************/
+
+class PropertyDefinitionBase : public Property 
+{
+  //void set(PropertyReceiver* receiver, string value);
+  void set(Window* receiver, string value);
+  //virtual void writeXMLToStream(OutStream& out_stream) const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/PropertyInitialiser.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/PropertyInitialiser.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/PropertyInitialiser.pkg	(revision 6952)
@@ -0,0 +1,14 @@
+/******************************************************************************
+  PropertyInitialiser
+******************************************************************************/
+
+class PropertyInitialiser
+{
+  //void apply(PropertySet& target) const;
+  void apply(Window& target) const;
+
+  string getTargetPropertyName() const;
+  string getInitialiserValue() const;
+  //void writeXMLToStream(OutStream& out_stream) const;
+  PropertyInitialiser(string property, string value);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/PropertyLinkDefinition.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/PropertyLinkDefinition.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/PropertyLinkDefinition.pkg	(revision 6952)
@@ -0,0 +1,12 @@
+/******************************************************************************
+  PropertyLinkDefinition
+******************************************************************************/
+
+class PropertyLinkDefinition : public PropertyDefinitionBase
+{
+  //string get(const PropertyReceiver* receiver) const;
+  //void set(PropertyReceiver* receiver, string value);
+  string get(const Window* receiver) const;
+  void set(Window* receiver, string value);
+  PropertyLinkDefinition(string propertyName, string widgetNameSuffix, string targetProperty, string initialValue, bool redrawOnWrite, bool layoutOnWrite);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/SectionSpecification.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/SectionSpecification.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/SectionSpecification.pkg	(revision 6952)
@@ -0,0 +1,23 @@
+/******************************************************************************
+  SectionSpecification
+******************************************************************************/
+
+class SectionSpecification
+{
+  void render(Window& srcWindow, float base_z, const ColourRect* modcols = 0, const Rect* clipper = 0, bool clipToDisplay = false) const;
+  void render(Window& srcWindow, const Rect& baseRect, float base_z, const ColourRect* modcols = 0, const Rect* clipper = 0, bool clipToDisplay = false) const;
+
+  string getOwnerWidgetLookFeel() const;
+  string getSectionName() const;
+  const ColourRect& getOverrideColours() const;
+  void setOverrideColours(const ColourRect& cols);
+  bool isUsingOverrideColours() const;
+  void setUsingOverrideColours(bool setting = true);
+  void setOverrideColoursPropertySource(string property);
+  void setOverrideColoursPropertyIsColourRect(bool setting = true);  
+  void setRenderControlPropertySource(string property);
+  // void writeXMLToStream(OutStream& out_stream) const;
+  SectionSpecification(string owner, string sectionName, const string controlPropertySource);
+  SectionSpecification(string owner, string sectionName, string controlPropertySource, const ColourRect& cols);
+  
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/StateImagery.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/StateImagery.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/StateImagery.pkg	(revision 6952)
@@ -0,0 +1,19 @@
+/******************************************************************************
+  StateImagery
+******************************************************************************/
+
+class StateImagery
+{
+  void render(Window& srcWindow, const ColourRect* modcols = 0, const Rect* clipper = 0) const;
+  void render(Window& srcWindow, const Rect& baseRect, const ColourRect* modcols = 0, const Rect* clipper = 0) const;
+
+  void addLayer(const LayerSpecification& layer);
+  void clearLayers();
+  string getName() const;
+  bool isClippedToDisplay() const;
+  void setClippedToDisplay(bool setting);
+  //void writeXMLToStream(OutStream& out_stream) const;
+  StateImagery(string name);
+  StateImagery();
+};
+
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/TextComponent.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/TextComponent.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/TextComponent.pkg	(revision 6952)
@@ -0,0 +1,22 @@
+/*********************************************************************
+ TextComponent
+**********************************************************************/
+class TextComponent : public FalagardComponentBase 
+{
+    string getText() const;
+    void setText(string text);
+    string getFont() const;
+    void setFont(string font);
+    VerticalTextFormatting getVerticalFormatting() const;
+    void setVerticalFormatting(VerticalTextFormatting fmt);
+    HorizontalTextFormatting getHorizontalFormatting() const;
+    void setHorizontalFormatting(HorizontalTextFormatting fmt);
+    //void writeXMLToStream(OutStream& out_stream) const;
+    bool isTextFetchedFromProperty() const;
+    string getTextPropertySource() const;
+    void setTextPropertySource(string property);
+    bool isFontFetchedFromProperty() const;
+    string getFontPropertySource() const;
+    void setFontPropertySource(string property);
+    TextComponent();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/WidgetComponent.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/WidgetComponent.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/WidgetComponent.pkg	(revision 6952)
@@ -0,0 +1,33 @@
+/******************************************************************************
+  WidgetComponent
+******************************************************************************/
+
+class WidgetComponent
+{
+  void create(Window& parent) const;
+  const ComponentArea& getComponentArea() const;
+  void setComponentArea(const ComponentArea& area);
+  string getBaseWidgetType() const;
+  void setBaseWidgetType(string type);
+  string getWidgetLookName() const;
+  void setWidgetLookName(string look);
+  string getWidgetNameSuffix() const;
+  void setWidgetNameSuffix(string suffix);
+  string getWindowRendererType() const;
+  void setWindowRendererType(string type);
+  VerticalAlignment getVerticalWidgetAlignment() const;
+  void setVerticalWidgetAlignment(VerticalAlignment alignment);
+  HorizontalAlignment getHorizontalWidgetAlignment() const;
+  void setHorizontalWidgetAlignment(HorizontalAlignment alignment);
+  void addPropertyInitialiser(const PropertyInitialiser& initialiser);
+  void clearPropertyInitialisers();
+  void layout(const Window& owner) const;
+
+  //void writeXMLToStream(OutStream& out_stream) const;
+
+  const PropertyInitialiser* findPropertyInitialiser(string propertyName) const;
+
+  WidgetComponent();
+  WidgetComponent(string type, string look, string suffix, string renderer);
+};
+
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/WidgetLookFeel.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/WidgetLookFeel.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/WidgetLookFeel.pkg	(revision 6952)
@@ -0,0 +1,37 @@
+/**************************************************************************************
+    WidgetLookFeel
+**************************************************************************************/
+
+class WidgetLookFeel
+{
+    StateImagery& getStateImagery(string state) const;
+    ImagerySection& getImagerySection(string section) const;
+    string getName() const;
+    void addImagerySection(const ImagerySection& section);
+    void addWidgetComponent(const WidgetComponent& widget);
+    void addStateSpecification(const StateImagery& state);
+    void addPropertyInitialiser(const PropertyInitialiser& initialiser);
+    void clearImagerySections();
+    void clearWidgetComponents();
+    void clearStateSpecifications();
+    void clearPropertyInitialisers();
+    void initialiseWidget(Window& widget) const;
+    bool isStateImageryPresent(string state) const;
+    void addNamedArea(const NamedArea& area);
+    void clearNamedAreas();
+    const NamedArea& getNamedArea(string name) const;
+    bool isNamedAreaDefined(string name) const;
+    void layoutChildWidgets(const Window& owner) const;
+    void addPropertyDefinition(const PropertyDefinition& propdef);
+    void addPropertyLinkDefinition(const PropertyLinkDefinition& propdef);
+    void clearPropertyDefinitions();
+    void clearPropertyLinkDefinitions();
+    //void writeXMLToStream(XMLSerializer& out_stream) const;
+    void renameChildren(const Window& widget, string newBaseName) const;
+
+    const PropertyInitialiser* findPropertyInitialiser(string propertyName) const;
+    const WidgetComponent* findWidgetComponent(string nameSuffix) const;
+
+    WidgetLookFeel(string name);
+    WidgetLookFeel();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/WidgetLookManager.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/WidgetLookManager.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.5.0/package/falagard/WidgetLookManager.pkg	(revision 6952)
@@ -0,0 +1,22 @@
+/***********************************************************************
+  WidgetLookManager
+***********************************************************************/
+
+class WidgetLookManager
+{
+  static WidgetLookManager& getSingleton(void);
+
+  void parseLookNFeelSpecification(string filename, string resourceGroup = "");
+  bool isWidgetLookAvailable(string widget) const;
+  const WidgetLookFeel& getWidgetLook(string widget) const;
+  void eraseWidgetLook(string widget);
+  void addWidgetLook(WidgetLookFeel& look);
+
+  void writeWidgetLookToStream(string name, OutStream& out_stream) const;
+  void writeWidgetLookSeriesToStream(string prefix, OutStream& out_stream) const;
+
+  WidgetLookManager();
+
+  static void setDefaultResourceGroup(string resourceGroup);
+  static string getDefaultResourceGroup();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,12 @@
+SET(_package_files
+  CEGUI.pkg
+  Logger.pkg
+  ScriptWindowHelper.pkg
+  WindowManager.pkg
+  elements/GroupBox.pkg
+  elements/MultiLineEditbox.pkg
+  elements/Tree.pkg
+  elements/TreeItem.pkg
+
+  PARENT_SCOPE
+)
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/CEGUILua.cpp
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/CEGUILua.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/CEGUILua.cpp	(revision 6952)
@@ -0,0 +1,336 @@
+/***********************************************************************
+	filename: CEGUILua.cpp
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+
+	purpose:  Implementation for LuaScriptModule class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUI.h"
+#include "CEGUIPropertyHelper.h"
+#include "CEGUILua.h"
+#include "CEGUILuaFunctor.h"
+#include <vector>
+
+// include Lua libs and tolua++
+extern "C" {
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+}
+
+#include "tolua/tolua++.h"
+
+// prototype for bindings initialisation function
+int tolua_CEGUI_open(lua_State* tolua_S);
+
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*************************************************************************
+	Constructor (creates Lua state)
+*************************************************************************/
+LuaScriptModule::LuaScriptModule()
+{
+    #if LUA_VERSION_NUM >= 501
+        static const luaL_Reg lualibs[] = {
+            {"", luaopen_base},
+            {LUA_LOADLIBNAME, luaopen_package},
+            {LUA_TABLIBNAME, luaopen_table},
+            {LUA_IOLIBNAME, luaopen_io},
+            {LUA_OSLIBNAME, luaopen_os},
+            {LUA_STRLIBNAME, luaopen_string},
+            {LUA_MATHLIBNAME, luaopen_math},
+        #if defined(DEBUG) || defined (_DEBUG)
+                {LUA_DBLIBNAME, luaopen_debug},
+        #endif
+            {0, 0}
+        };
+    #endif /* LUA_VERSION_NUM >= 501 */
+
+    // create a lua state
+    d_ownsState = true;
+    d_state = lua_open();
+
+    // init all standard libraries
+    #if LUA_VERSION_NUM >= 501
+            const luaL_Reg *lib = lualibs;
+            for (; lib->func; lib++)
+            {
+                lua_pushcfunction(d_state, lib->func);
+                lua_pushstring(d_state, lib->name);
+                lua_call(d_state, 1, 0);
+            }
+    #else /* LUA_VERSION_NUM >= 501 */
+        luaopen_base(d_state);
+        luaopen_io(d_state);
+        luaopen_string(d_state);
+        luaopen_table(d_state);
+        luaopen_math(d_state);
+        #if defined(DEBUG) || defined (_DEBUG)
+            luaopen_debug(d_state);
+        #endif
+    #endif /* LUA_VERSION_NUM >= 501 */
+
+    setModuleIdentifierString();
+}
+
+
+/*************************************************************************
+	Constructor (uses given Lua state)
+*************************************************************************/
+LuaScriptModule::LuaScriptModule(lua_State* state)
+{
+	// just use the given state
+	d_ownsState = false;
+	d_state = state;
+
+	setModuleIdentifierString();
+}
+
+
+/*************************************************************************
+	Destructor
+*************************************************************************/
+LuaScriptModule::~LuaScriptModule()
+{
+	if ( d_ownsState && d_state )
+	{
+		lua_close( d_state );
+	}
+}
+
+
+/*************************************************************************
+	Execute script file
+*************************************************************************/
+void LuaScriptModule::executeScriptFile(const String& filename, const String& resourceGroup)
+{
+	// load file
+	RawDataContainer raw;
+	System::getSingleton().getResourceProvider()->loadRawDataContainer(filename,
+        raw, resourceGroup.empty() ? d_defaultResourceGroup : resourceGroup);
+
+	// load code into lua
+	int top = lua_gettop(d_state);
+	int loaderr = luaL_loadbuffer(d_state, (char*)raw.getDataPtr(), raw.getSize(), filename.c_str());
+	System::getSingleton().getResourceProvider()->unloadRawDataContainer( raw );
+	if (loaderr)
+	{
+	    String errMsg = lua_tostring(d_state,-1);
+		lua_settop(d_state,top);
+		throw ScriptException("Unable to execute Lua script file: '"+filename+"'\n\n"+errMsg+"\n");
+	}
+
+    // call it
+	if (lua_pcall(d_state,0,0,0))
+	{
+	    String errMsg = lua_tostring(d_state,-1);
+		lua_settop(d_state,top);
+		throw ScriptException("Unable to execute Lua script file: '"+filename+"'\n\n"+errMsg+"\n");
+	}
+
+	lua_settop(d_state,top); // just in case :P
+}
+
+
+/*************************************************************************
+	Execute global script function
+*************************************************************************/
+int	LuaScriptModule::executeScriptGlobal(const String& function_name)
+{
+    int top = lua_gettop(d_state);
+
+    // get the function from lua
+    lua_getglobal(d_state, function_name.c_str());
+
+    // is it a function
+    if (!lua_isfunction(d_state,-1))
+    {
+        lua_settop(d_state,top);
+        throw ScriptException("Unable to get Lua global: '"+function_name+"' as name not represent a global Lua function" );
+    }
+
+    // call it
+    int error = lua_pcall(d_state,0,1,0);
+
+    // handle errors
+    if (error)
+    {
+        String errMsg = lua_tostring(d_state,-1);
+        lua_pop(d_state,1);
+        throw ScriptException("Unable to evaluate Lua global: '"+function_name+"\n\n"+errMsg+"\n");
+    }
+
+    // get return value
+    if (!lua_isnumber(d_state,-1))
+    {
+        // log that return value is invalid. return -1 and move on.
+        lua_settop(d_state,top);
+        ScriptException("Unable to get Lua global : '"+function_name+"' return value as it's not a number" );
+        return -1;
+    }
+
+    int ret = (int)lua_tonumber(d_state,-1);
+    lua_pop(d_state,1);
+
+    // return it
+    return ret;
+}
+
+
+/*************************************************************************
+	Execute scripted event handler
+*************************************************************************/
+bool LuaScriptModule::executeScriptedEventHandler(const String& handler_name, const EventArgs& e)
+{
+
+	LuaFunctor::pushNamedFunction(d_state, handler_name);
+
+	ScriptWindowHelper* helper = 0;
+	//If this is an event that was triggered by a window then make a "this" pointer to the window for the script.
+	if(e.d_hasWindow)
+	{
+		WindowEventArgs& we = (WindowEventArgs&)e;
+		helper = new ScriptWindowHelper(we.window);
+		lua_pushlightuserdata(d_state,(void*)helper);
+		lua_setglobal(d_state,"this");
+	} // if(e.d_hasWindow)
+
+    // push EventArgs as the first parameter
+    tolua_pushusertype(d_state,(void*)&e,"const CEGUI::EventArgs");
+
+    // call it
+    int error = lua_pcall(d_state,1,0,0);
+
+    // handle errors
+    if (error)
+    {
+        String errStr(lua_tostring(d_state,-1));
+        lua_pop(d_state,1);
+		//cleanup the helper object if any
+		if(helper)
+		{
+			delete helper;
+			helper = 0;
+		}
+        throw ScriptException("Unable to evaluate the Lua event handler: '"+handler_name+"'\n\n"+errStr+"\n");
+    } // if (error)
+
+	if(helper)
+	{
+		delete helper;
+		helper = 0;
+	}
+
+    return true;
+}
+
+
+/*************************************************************************
+	Execute script code string
+*************************************************************************/
+void LuaScriptModule::executeString(const String& str)
+{
+    int top = lua_gettop(d_state);
+
+    // load code into lua and call it
+    int error =	luaL_loadbuffer(d_state, str.c_str(), str.length(), str.c_str()) || lua_pcall(d_state,0,0,0);
+
+    // handle errors
+    if (error)
+    {
+        String errMsg = lua_tostring(d_state,-1);
+        lua_settop(d_state,top);
+        throw ScriptException("Unable to execute Lua script string: '"+str+"'\n\n"+errMsg+"\n");
+    }
+}
+
+
+/*************************************************************************
+	Create Lua bindings
+*************************************************************************/
+void LuaScriptModule::createBindings(void)
+{
+	CEGUI::Logger::getSingleton().logEvent( "---- Creating Lua bindings ----" );
+	// init CEGUI module
+	tolua_CEGUI_open(d_state);
+}
+
+
+/*************************************************************************
+	Destroy Lua bindings
+*************************************************************************/
+void LuaScriptModule::destroyBindings(void)
+{
+	CEGUI::Logger::getSingleton().logEvent( "---- Destroying Lua bindings ----" );
+	// is this ok ?
+	lua_pushnil(d_state);
+	lua_setglobal(d_state,"CEGUI");
+}
+
+
+/*************************************************************************
+	Set the ID string for the module
+*************************************************************************/
+void LuaScriptModule::setModuleIdentifierString()
+{
+    // set ID string
+    d_identifierString = "CEGUI::LuaScriptModule - Official Lua based scripting module for CEGUI";
+	d_language = "Lua";
+}
+
+
+/*************************************************************************
+	Subscribe to a scripted event handler
+*************************************************************************/
+Event::Connection LuaScriptModule::subscribeEvent(EventSet* target, const String& event_name, const String& subscriber_name)
+{
+    // do the real subscription
+    LuaFunctor functor(d_state,subscriber_name,LUA_NOREF);
+    Event::Connection con = target->subscribeEvent(event_name, Event::Subscriber(functor));
+    // make sure we don't release the reference we just made when this call returns
+    functor.index = LUA_NOREF;
+
+    // return the event connection
+    return con;
+}
+
+
+/*************************************************************************
+	Subscribe to a scripted event handler
+*************************************************************************/
+Event::Connection LuaScriptModule::subscribeEvent(EventSet* target, const String& event_name, Event::Group group, const String& subscriber_name)
+{
+    // do the real subscription
+    LuaFunctor functor(d_state,subscriber_name,LUA_NOREF);
+    Event::Connection con = target->subscribeEvent(event_name, group, Event::Subscriber(functor));
+
+    // return the event connection
+    return con;
+}
+
+} // namespace CEGUI
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/CEGUILua.h
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/CEGUILua.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/CEGUILua.h	(revision 6952)
@@ -0,0 +1,253 @@
+/***********************************************************************
+	filename: CEGUILua.h
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+	
+	purpose:  Defines interface for LuaScriptModule class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#ifndef _CEGUILua_h_
+#define _CEGUILua_h_
+
+
+/*************************************************************************
+	Import / Export control macros
+*************************************************************************/
+#if (defined( __WIN32__ ) || defined( _WIN32 )) && !defined(CEGUI_STATIC)
+#   ifdef CEGUILUA_EXPORTS
+#       define CEGUILUA_API __declspec(dllexport)
+#   else
+#       if defined( __MINGW32__ )
+#           define CEGUILUA_API
+#       else
+#           define CEGUILUA_API __declspec(dllimport)
+#       endif
+#   endif
+#else
+#   define CEGUILUA_API
+#endif
+
+
+#include "CEGUIScriptModule.h"
+
+struct lua_State;
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*!
+\brief
+	Interface for the LuaScriptModule class
+*/
+class CEGUILUA_API LuaScriptModule : public CEGUI::ScriptModule
+{
+public:
+	/*************************************************************************
+		Construction and Destruction
+	*************************************************************************/
+	/*!
+	\brief
+		Constructor for LuaScriptModule class which create a lua_State
+	*/
+	LuaScriptModule();
+
+
+	/*!
+	\brief
+		Constructor for LuaScriptModule class which takes a lua_State
+
+	\param state
+		Pointer to the lua_State that the script module should attach to.
+	*/
+	LuaScriptModule(lua_State* state);
+
+
+	/*!
+	\brief
+		Destructor for LuaScriptModule class.
+	*/
+	~LuaScriptModule();
+
+
+	/*************************************************************************
+		Script Execution Functions
+	*************************************************************************/
+	/*!
+	\brief
+		Execute a script file.
+
+	\param filename
+		String object holding the filename of the script file that is to be executed
+		
+	\param resourceGroup
+		Resource group idendifier to be passed to the ResourceProvider when loading the script file.
+	*/
+	void executeScriptFile(const String& filename, const String& resourceGroup);
+
+
+	/*!
+	\brief
+		Execute a scripted global function.  The function should not take any parameters and should return an integer.
+
+	\param function_name
+		String object holding the name of the function, in the global script environment, that
+		is to be executed.
+
+	\return
+		The integer value returned from the script function.
+	*/
+	int executeScriptGlobal(const String& function_name);
+
+
+    /*!
+    \brief
+        Execute a scripted global 'event handler' function by looking it up by name.
+
+    \param handler_name
+        String object holding the name of the scripted handler function.
+        If this string contains dots '.' it will be parsed as tables containing a function field.
+        For example: 'mytable.subtable.func'
+
+    \param e
+        EventArgs based object that should be passed, by any appropriate means, to the scripted function.
+
+    \return
+        - true if the event was handled.
+        - false if the event was not handled.
+    */
+    bool executeScriptedEventHandler(const String& handler_name, const EventArgs& e);
+
+
+    /*!
+    \brief
+        Execute script code contained in the given CEGUI::String object.
+
+    \param str
+        String object holding the valid script code that should be executed.
+
+    \return
+        Nothing.
+    */
+    void executeString(const String& str);
+
+    /*************************************************************************
+        Event subscription
+    *************************************************************************/
+    /*!
+    \brief
+            Subscribes the named Event to a scripted funtion
+
+    \param target
+            The target EventSet for the subscription.
+
+    \param name
+            String object containing the name of the Event to subscribe to.
+
+    \param subscriber_name
+            String object containing the name of the script funtion that is to be subscribed to the Event.
+
+    \return
+            Connection object that can be used to check the status of the Event connection and to disconnect (unsubscribe) from the Event.
+
+    \exception UnknownObjectException	Thrown if an Event named \a name is not in the EventSet
+    */
+    Event::Connection	subscribeEvent(EventSet* target, const String& name, const String& subscriber_name);
+
+    /*!
+    \brief
+            Subscribes the specified group of the named Event to a scripted funtion.
+
+    \param target
+            The target EventSet for the subscription.
+
+    \param name
+            String object containing the name of the Event to subscribe to.
+
+    \param group
+            Group which is to be subscribed to.  Subscription groups are called in ascending order.
+
+    \param subscriber_name
+            String object containing the name of the script funtion that is to be subscribed to the Event.
+
+    \return
+            Connection object that can be used to check the status of the Event connection and to disconnect (unsubscribe) from the Event.
+
+    \exception UnknownObjectException	Thrown if an Event named \a name is not in the EventSet
+    */
+    Event::Connection	subscribeEvent(EventSet* target, const String& name, Event::Group group, const String& subscriber_name);
+
+    /*************************************************************************
+        Bindings creation / destruction
+    *************************************************************************/
+    /*!
+    \brief
+        Method called during system initialisation, prior to running any scripts via the ScriptModule, to enable the ScriptModule
+        to perform any operations required to complete initialisation or binding of the script language to the gui system objects.
+
+    \return
+        Nothing.
+    */
+    void createBindings(void);
+
+
+    /*!
+    \brief
+        Method called during system destruction, after all scripts have been run via the ScriptModule, to enable the ScriptModule
+        to perform any operations required to cleanup bindings of the script language to the gui system objects, as set-up in the
+        earlier createBindings call.
+
+    \return
+        Nothing.
+    */
+    void destroyBindings(void);
+
+    /*************************************************************************
+        Accessor type functions
+    *************************************************************************/
+    /*!
+    \brief
+        Method used to get a pointer to the lua_State that the script module is attached to.
+
+    \return
+        A pointer to the lua_State that the script module is attached to.
+    */
+    lua_State* getLuaState(void) const {return d_state;}
+
+private:
+    /*************************************************************************
+        Implementation Functions
+    *************************************************************************/
+    void setModuleIdentifierString();
+
+    /*************************************************************************
+        Implementation Data
+    *************************************************************************/
+    bool d_ownsState;      //!< true when the attached lua_State was created by this script module
+    lua_State* d_state;    //!< The lua_State that this script module uses.
+};
+
+} // namespace CEGUI
+
+#endif // end of guard _CEGUILua_h_
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/CEGUILuaFunctor.cpp
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/CEGUILuaFunctor.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/CEGUILuaFunctor.cpp	(revision 6952)
@@ -0,0 +1,280 @@
+/***********************************************************************
+    filename: CEGUILuaFunctor.cpp
+    created:  Thu Jan 26 2006
+    author:   Tomas Lindquist Olsen <tomas@famolsen.dk>
+
+    purpose:  Implementation for LuaFunctor class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUILuaFunctor.h"
+#include "CEGUILogger.h"
+#include "CEGUIExceptions.h"
+#include "CEGUIPropertyHelper.h"
+
+// include Lua libs and tolua++
+extern "C" {
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+}
+
+#include "tolua/tolua++.h"
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*************************************************************************
+    Constructor
+*************************************************************************/
+LuaFunctor::LuaFunctor(lua_State* state, int func, int selfIndex) :
+    L(state),
+    index(func),
+    self(selfIndex),
+    needs_lookup(false)
+{
+}
+
+/*************************************************************************
+    Constructor
+*************************************************************************/
+LuaFunctor::LuaFunctor(lua_State* state, const String& func, int selfIndex) :
+    L(state),
+    index(LUA_NOREF),
+    self(selfIndex),
+    needs_lookup(true),
+    function_name(func)
+{
+}
+
+/*************************************************************************
+    Constructor
+*************************************************************************/
+LuaFunctor::LuaFunctor(const LuaFunctor& cp) :
+    L(cp.L),
+    index(cp.index),
+    self(cp.self),
+    needs_lookup(cp.needs_lookup),
+    function_name(cp.function_name)
+{
+}
+
+/*************************************************************************
+    Destructor
+*************************************************************************/
+LuaFunctor::~LuaFunctor()
+{
+    if (self!=LUA_NOREF)
+    {
+        luaL_unref(L, LUA_REGISTRYINDEX, self);
+    }
+    if (index!=LUA_NOREF)
+    {
+        luaL_unref(L, LUA_REGISTRYINDEX, index);
+    }
+}
+
+/*************************************************************************
+    Call operator
+*************************************************************************/
+bool LuaFunctor::operator()(const EventArgs& args) const
+{
+    // is this a late binding?
+    if (needs_lookup)
+    {
+        pushNamedFunction(L, function_name);
+        // reference function
+        index = luaL_ref(L, LUA_REGISTRYINDEX);
+        needs_lookup = false;
+        CEGUI_LOGINSANE("Late binding of callback '"+function_name+"' performed");
+        function_name.clear();
+    } // if (needs_lookup)
+
+	ScriptWindowHelper* helper = 0;
+	//Set a global for this window
+	if(args.d_hasWindow)
+	{
+		WindowEventArgs& we = (WindowEventArgs&)args;
+		helper = new ScriptWindowHelper(we.window);
+		tolua_pushusertype(L,(void*)helper,"CEGUI::ScriptWindowHelper");
+		lua_setglobal(L,"this");
+	}
+
+    // retrieve function
+    lua_rawgeti(L, LUA_REGISTRYINDEX, index);
+
+    // possibly self as well?
+    int nargs = 1;
+    if (self != LUA_NOREF)
+    {
+        lua_rawgeti(L, LUA_REGISTRYINDEX, self);
+        ++nargs;
+    }
+
+    // push EventArgs  parameter
+    tolua_pushusertype(L, (void*)&args, "const CEGUI::EventArgs");
+
+    // call it
+    int error = lua_pcall(L, nargs, 0, 0);
+
+    // handle errors
+    if (error)
+    {
+        String errStr(lua_tostring(L, -1));
+        lua_pop(L, 1);
+		if(helper)
+		{
+			delete helper;
+			helper = 0;
+		}
+        throw ScriptException("Unable to call Lua event handler:\n\n"+errStr+"\n");
+    } // if (error)
+
+	if(helper)
+	{
+		delete helper;
+		helper = 0;
+	}
+
+    return true;
+}
+
+/*************************************************************************
+    do event subscription by reference instead of by name
+*************************************************************************/
+Event::Connection LuaFunctor::SubscribeEvent(EventSet* self, const String& event_name, int funcIndex, int selfIndex, lua_State* L)
+{
+    // should we pass a self to the callback?
+    int thisIndex = LUA_NOREF;
+    if (selfIndex != LUA_NOREF)
+    {
+        // reference self
+        thisIndex = luaL_ref(L, LUA_REGISTRYINDEX);
+    }
+
+    // do the real subscription
+    int type = lua_type(L,-1);
+    Event::Connection con;
+    if (type == LUA_TFUNCTION)
+    {
+        // reference function
+        int index = luaL_ref(L, LUA_REGISTRYINDEX);
+        LuaFunctor functor(L,index,thisIndex);
+        con = self->subscribeEvent(String(event_name), Event::Subscriber(functor));
+        // make sure we don't release the reference(s) we just made when this call returns
+        functor.index = LUA_NOREF;
+        functor.self = LUA_NOREF;
+    }
+    else if (type == LUA_TSTRING)
+    {
+        const char* str = lua_tostring(L, -1);
+        LuaFunctor functor(L,String(str),thisIndex);
+        con = self->subscribeEvent(String(event_name), Event::Subscriber(functor));
+        // make sure we don't release the reference we just (maybe) made when this call returns
+        functor.self = LUA_NOREF;
+    }
+    else
+    {
+        luaL_error(L,"bad function passed to subscribe function. must be a real function, or a string for late binding");
+    }
+
+    // return the event connection
+    return con;
+}
+
+/*************************************************************************
+    Pushes a named function on the stack
+*************************************************************************/
+void LuaFunctor::pushNamedFunction(lua_State* L, const String& handler_name)
+{
+    int top = lua_gettop(L);
+
+    // do we have any dots in the handler name? if so we grab the function as a table field
+    String::size_type i = handler_name.find_first_of((utf32)'.');
+    if (i!=String::npos)
+    {
+        // split the rest of the string up in parts seperated by '.'
+        // TODO: count the dots and size the vector accordingly from the beginning.
+        std::vector<String> parts;
+        String::size_type start = 0;
+        do
+        {
+            parts.push_back(handler_name.substr(start,i-start));
+            start = i+1;
+            i = handler_name.find_first_of((utf32)'.',start);
+        } while(i!=String::npos);
+
+        // add last part
+        parts.push_back(handler_name.substr(start));
+
+        // first part is the global
+        lua_getglobal(L, parts[0].c_str());
+        if (!lua_istable(L,-1))
+        {
+            lua_settop(L,top);
+            throw ScriptException("Unable to get the Lua event handler: '"+handler_name+"' as first part is not a table");
+        }
+
+        // if there is more than two parts, we have more tables to go through
+        std::vector<String>::size_type visz = parts.size();
+        if (visz-- > 2) // avoid subtracting one later on
+        {
+            // go through all the remaining parts to (hopefully) have a valid Lua function in the end
+            std::vector<String>::size_type vi = 1;
+            while (vi<visz)
+            {
+                // push key, and get the next table
+                lua_pushstring(L,parts[vi].c_str());
+                lua_gettable(L,-2);
+                if (!lua_istable(L,-1))
+                {
+                    lua_settop(L,top);
+                    throw ScriptException("Unable to get the Lua event handler: '"+handler_name+"' as part #"+PropertyHelper::uintToString(uint(vi+1))+" ("+parts[vi]+") is not a table");
+                }
+                // get rid of the last table and move on
+                lua_remove(L,-2);
+                vi++;
+            }
+        }
+
+        // now we are ready to get the function to call ... phew :)
+        lua_pushstring(L,parts[visz].c_str());
+        lua_gettable(L,-2);
+        lua_remove(L,-2); // get rid of the table
+    }
+    // just a regular global function
+    else
+    {
+        lua_getglobal(L, handler_name.c_str());
+    }
+
+    // is it a function
+    if (!lua_isfunction(L,-1))
+    {
+        lua_settop(L,top);
+        throw ScriptException("The Lua event handler: '"+handler_name+"' does not represent a Lua function");
+    }
+}
+
+} // namespace CEGUI
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/CEGUILuaFunctor.h
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/CEGUILuaFunctor.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/CEGUILuaFunctor.h	(revision 6952)
@@ -0,0 +1,86 @@
+/***********************************************************************
+    filename: CEGUILuaFunctor.h
+    created:  Thu Jan 26 2006
+    author:   Tomas Lindquist Olsen <tomas@famolsen.dk>
+
+    purpose:  Defines interface for LuaFunctor class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#ifndef _CEGUILuaFunctor_h_
+#define _CEGUILuaFunctor_h_
+
+#include "CEGUIEventSet.h"
+#include "CEGUIScriptWindowHelper.h"
+
+struct lua_State;
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+// forward declaration
+class LuaScriptModule;
+
+/*!
+\brief
+    Functor class used for subscribing Lua functions to CEGUI events
+*/
+class LuaFunctor
+{
+public:
+    LuaFunctor(lua_State* state, int func, int selfIndex);
+    LuaFunctor(lua_State* state, const String& func, int selfIndex);
+    LuaFunctor(const LuaFunctor& cp);
+    ~LuaFunctor();
+
+    bool operator()(const EventArgs& args) const;
+
+    /*!
+    \brief
+        function used to subscribe any Lua function as event handler.
+        References using the Lua registry.
+        To be called from Lua only.
+    */
+    static Event::Connection SubscribeEvent(EventSet* self, const String& eventName, int funcIndex, int selfIndex, lua_State* L);
+
+    /*!
+    \brief
+        Pushes the Lua function named \param name on top of the Lua stack.
+        The name may contain '.' (dots) character for (nested) table values.
+    */
+    static void pushNamedFunction(lua_State* L, const String& name);
+
+private:
+    lua_State* L;
+    mutable int index;
+    int self;
+    mutable bool needs_lookup;
+    mutable String function_name;
+
+    friend class LuaScriptModule;
+};
+
+} // namespace CEGUI
+
+#endif // end of guard _CEGUILuaFunctor_h_
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/changes_orxonox.diff
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/changes_orxonox.diff	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/changes_orxonox.diff	(revision 6952)
@@ -0,0 +1,92 @@
+--- CEGUILua.cpp	Sun Jan 25 18:30:39 2009
++++ CEGUILua.cpp	Thu Jan 29 10:25:05 2009
+@@ -27,10 +27,6 @@
+  *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+  *   OTHER DEALINGS IN THE SOFTWARE.
+  ***************************************************************************/
+-#ifdef HAVE_CONFIG_H
+-#   include "config.h"
+-#endif
+-
+ #include "CEGUI.h"
+ #include "CEGUIPropertyHelper.h"
+ #include "CEGUILua.h"
+@@ -44,7 +40,7 @@
+ #include "lauxlib.h"
+ }
+ 
+-#include "tolua++.h"
++#include "tolua/tolua++.h"
+ 
+ // prototype for bindings initialisation function
+ int tolua_CEGUI_open(lua_State* tolua_S);
+@@ -59,7 +55,7 @@
+ *************************************************************************/
+ LuaScriptModule::LuaScriptModule()
+ {
+-    #if CEGUI_LUA_VER >= 51
++    #if LUA_VERSION_NUM >= 501
+         static const luaL_Reg lualibs[] = {
+             {"", luaopen_base},
+             {LUA_LOADLIBNAME, luaopen_package},
+@@ -73,14 +69,14 @@
+         #endif
+             {0, 0}
+         };
+-    #endif /* CEGUI_LUA_VER >= 51 */
++    #endif /* LUA_VERSION_NUM >= 501 */
+ 
+     // create a lua state
+     d_ownsState = true;
+     d_state = lua_open();
+ 
+     // init all standard libraries
+-    #if CEGUI_LUA_VER >= 51
++    #if LUA_VERSION_NUM >= 501
+             const luaL_Reg *lib = lualibs;
+             for (; lib->func; lib++)
+             {
+@@ -88,7 +84,7 @@
+                 lua_pushstring(d_state, lib->name);
+                 lua_call(d_state, 1, 0);
+             }
+-    #else /* CEGUI_LUA_VER >= 51 */
++    #else /* LUA_VERSION_NUM >= 501 */
+         luaopen_base(d_state);
+         luaopen_io(d_state);
+         luaopen_string(d_state);
+@@ -97,7 +93,7 @@
+         #if defined(DEBUG) || defined (_DEBUG)
+             luaopen_debug(d_state);
+         #endif
+-    #endif /* CEGUI_LUA_VER >= 51 */
++    #endif /* LUA_VERSION_NUM >= 501 */
+ 
+     setModuleIdentifierString();
+ }
+--- CEGUILua.h	Wed Jul  9 18:24:49 2008
++++ CEGUILua.h	Thu Jan 29 10:17:07 2009
+@@ -38,7 +38,11 @@
+ #   ifdef CEGUILUA_EXPORTS
+ #       define CEGUILUA_API __declspec(dllexport)
+ #   else
+-#       define CEGUILUA_API __declspec(dllimport)
++#       if defined( __MINGW32__ )
++#           define CEGUILUA_API
++#       else
++#           define CEGUILUA_API __declspec(dllimport)
++#       endif
+ #   endif
+ #else
+ #   define CEGUILUA_API
+--- CEGUILuaFunctor.cpp	Wed Jul  9 18:25:02 2008
++++ CEGUILuaFunctor.cpp	Thu Jan 29 10:26:58 2009
+@@ -39,7 +39,7 @@
+ #include "lauxlib.h"
+ }
+ 
+-#include "tolua++.h"
++#include "tolua/tolua++.h"
+ 
+ // Start of CEGUI namespace section
+ namespace CEGUI
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/required.cpp
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/required.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/required.cpp	(revision 6952)
@@ -0,0 +1,88 @@
+/***********************************************************************
+	filename: required.cpp
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+	
+	purpose:  Implementation of helper functions
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUI.h"
+#include "required.h"
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*************************************************************************
+	Functions for getting Thumb range pairs as two return values
+*************************************************************************/
+
+// returns horizontal range as two values for lua
+void ceguiLua_Thumb_getHorzRange(Thumb* wnd, float* min, float* max)
+{
+	std::pair<float,float> range_pair = wnd->getHorzRange();
+	*min = range_pair.first;
+	*max = range_pair.second;
+}
+
+
+// returns vertical range as two values for lua
+void ceguiLua_Thumb_getVertRange(Thumb* wnd, float* min, float* max)
+{
+	std::pair<float,float> range_pair = wnd->getVertRange();
+	*min = range_pair.first;
+	*max = range_pair.second;
+}
+
+
+/*************************************************************************
+	Functions for creating list box items
+*************************************************************************/
+
+// allocates and returns a new ListboxTextItem
+ListboxTextItem* ceguiLua_createListboxTextItem(const String& text, uint item_id, void* item_data, bool disabled, bool auto_delete)
+{
+	return new ListboxTextItem(text,item_id,item_data,disabled,auto_delete);
+}
+
+
+/************************************************************************
+    OutStream
+*************************************************************************/
+void ceguiLua_FileStream_open(FileStream* os, const char* filename)
+{
+    os->open(filename, std::ios::binary);
+}
+
+
+/************************************************************************
+    CEGUI::System::getSystemKeys alternative
+*************************************************************************/
+bool ceguiLua_System_isSystemKeyDown(const System* sys, SystemKey k)
+{
+    return (k & sys->getSystemKeys()) != 0;
+}
+
+
+} // namespace CEGUI
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/required.h
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/required.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/ceguilua/required.h	(revision 6952)
@@ -0,0 +1,113 @@
+/***********************************************************************
+	filename: required.h
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+
+	purpose:  Header that includes the necessary stuff needed for the Lua bindings
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUI.h"
+#include "CEGUILua.h"
+#include "CEGUILuaFunctor.h"
+#include <fstream>
+
+#define __operator_increment    operator++
+#define __operator_decrement    operator--
+#define __operator_dereference  operator*
+
+#define LuaFunctorSubscribeEvent CEGUI::LuaFunctor::SubscribeEvent
+
+//This is used to keep compilers happy
+#define CEGUIDeadException(e) &
+
+#if defined(_MSC_VER) && !defined(snprintf)
+#   define snprintf   _snprintf
+#endif
+
+typedef CEGUI::String string;
+
+namespace CEGUI
+{
+
+typedef Event::Connection EventConnection;
+
+/*************************************************************************
+	Functions for getting Thumb range pairs as two return values
+*************************************************************************/
+void ceguiLua_Thumb_getHorzRange(Thumb* wnd, float* min, float* max);
+void ceguiLua_Thumb_getVertRange(Thumb* wnd, float* min, float* max);
+
+
+/*************************************************************************
+	Functions for creating list box items
+*************************************************************************/
+ListboxTextItem* ceguiLua_createListboxTextItem(const String& text, uint item_id, void* item_data, bool disabled, bool auto_delete);
+
+
+/************************************************************************
+    Stuff needed to make the iterators work
+*************************************************************************/
+typedef PropertySet::Iterator PropertyIterator;
+typedef EventSet::Iterator EventIterator;
+typedef WindowManager::WindowIterator WindowIterator;
+typedef WindowFactoryManager::WindowFactoryIterator WindowFactoryIterator;
+typedef WindowFactoryManager::FalagardMappingIterator FalagardMappingIterator;
+typedef WindowFactoryManager::FalagardWindowMapping FalagardWindowMapping;
+typedef ImagesetManager::ImagesetIterator ImagesetIterator;
+typedef Imageset::ImageIterator ImageIterator;
+typedef SchemeManager::SchemeIterator SchemeIterator;
+typedef FontManager::FontIterator FontIterator;
+
+template <typename T>
+inline PropertyIterator ceguiLua_getPropertyIterator(const T* self)
+{
+    return static_cast<const PropertySet*>(self)->getIterator();
+}
+
+template <typename T>
+inline EventIterator ceguiLua_getEventIterator(const T* self)
+{
+    return static_cast<const EventSet*>(self)->getIterator();
+}
+
+
+/************************************************************************
+    OutStream
+*************************************************************************/
+typedef std::ofstream FileStream;
+void ceguiLua_FileStream_open(FileStream*, const char* filename);
+
+
+/************************************************************************
+    CEGUI::System::getSystemKeys alternative
+*************************************************************************/
+bool ceguiLua_System_isSystemKeyDown(const System* sys, SystemKey k);
+
+}
+
+// the binding file generates alot of
+// warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
+#if defined(_MSC_VER)
+#   pragma warning(disable : 4800)
+#endif
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/CEGUI.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/CEGUI.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/CEGUI.pkg	(revision 6952)
@@ -0,0 +1,121 @@
+// include the header that makes these files generate valid code
+$#include "ceguilua/required.h"
+$#include "CEGUIPropertyHelper.h"
+
+// start the CEGUI namespace and include everything inside that
+namespace CEGUI
+{
+
+$pfile "Basic.pkg"
+$pfile "UnifiedCoordSystem.pkg"
+$pfile "Logger.pkg"
+
+$pfile "Font.pkg"
+$pfile "FontManager.pkg"
+
+$pfile "Image.pkg"
+$pfile "Texture.pkg"
+$pfile "Imageset.pkg"
+$pfile "ImagesetManager.pkg"
+
+$pfile "Iterators.pkg"
+
+$pfile "Key.pkg"
+$pfile "InputEvent.pkg"
+$pfile "EventSet.pkg"
+
+$pfile "MouseCursor.pkg"
+$pfile "Window.pkg"
+$pfile "CoordConverter.pkg"
+$pfile "Renderer.pkg"
+$pfile "ScriptWindowHelper.pkg"
+$pfile "System.pkg"
+
+$pfile "WindowManager.pkg"
+$pfile "WindowFactoryManager.pkg"
+
+$pfile "Scheme.pkg"
+$pfile "SchemeManager.pkg"
+
+$pfile "PropertyHelper.pkg"
+
+// elements
+$pfile "elements/GUISheet.pkg"
+$pfile "elements/Tree.pkg"
+
+$pfile "elements/ButtonBase.pkg"
+$pfile "elements/Checkbox.pkg"
+$pfile "elements/PushButton.pkg"
+$pfile "elements/Thumb.pkg"
+$pfile "elements/RadioButton.pkg"
+
+$pfile "elements/TabButton.pkg"
+$pfile "elements/TabControl.pkg"
+
+$pfile "elements/Titlebar.pkg"
+$pfile "elements/TreeItem.pkg"
+$pfile "elements/FrameWindow.pkg"
+
+$pfile "elements/Tooltip.pkg"
+
+$pfile "elements/DragContainer.pkg"
+
+$pfile "elements/Scrollbar.pkg"
+$pfile "elements/ScrolledContainer.pkg"
+$pfile "elements/ScrollablePane.pkg"
+
+$pfile "elements/Slider.pkg"
+
+$pfile "elements/Spinner.pkg"
+
+$pfile "elements/ProgressBar.pkg"
+
+$pfile "elements/Editbox.pkg"
+$pfile "elements/MultiLineEditbox.pkg"
+
+$pfile "elements/ListboxItem.pkg"
+$pfile "elements/ListboxTextItem.pkg"
+
+$pfile "elements/Combobox.pkg"
+$pfile "elements/Listbox.pkg"
+$pfile "elements/ComboDropList.pkg"
+
+$pfile "elements/ListHeaderSegment.pkg"
+$pfile "elements/ListHeader.pkg"
+$pfile "elements/MultiColumnList.pkg"
+
+$pfile "elements/ItemEntry.pkg"
+$pfile "elements/ItemListBase.pkg"
+$pfile "elements/MenuBase.pkg"
+$pfile "elements/Menubar.pkg"
+$pfile "elements/PopupMenu.pkg"
+$pfile "elements/MenuItem.pkg"
+$pfile "elements/ScrolledItemListBase.pkg"
+$pfile "elements/ItemListbox.pkg"
+
+$pfile "elements/GroupBox.pkg"
+
+$pfile "falagard/Enums.pkg"
+$pfile "falagard/Dimension.pkg"
+$pfile "falagard/NamedArea.pkg"
+$pfile "falagard/PropertyDefinitionBase.pkg"
+$pfile "falagard/PropertyDefinition.pkg"
+$pfile "falagard/PropertyInitialiser.pkg"
+$pfile "falagard/PropertyLinkDefinition.pkg"
+$pfile "falagard/FalagardComponentBase.pkg"
+$pfile "falagard/FrameComponent.pkg"
+$pfile "falagard/ImageryComponent.pkg"
+$pfile "falagard/TextComponent.pkg"
+$pfile "falagard/ImagerySection.pkg"
+$pfile "falagard/SectionSpecification.pkg"
+$pfile "falagard/LayerSpecification.pkg"
+$pfile "falagard/StateImagery.pkg"
+$pfile "falagard/WidgetComponent.pkg"
+$pfile "falagard/WidgetLookFeel.pkg"
+$pfile "falagard/WidgetLookManager.pkg"
+
+$pfile "HelperFunctions.pkg"
+
+$pfile "OutStream.pkg"
+
+}
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/Logger.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/Logger.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/Logger.pkg	(revision 6952)
@@ -0,0 +1,26 @@
+/***********************************************************************
+	LoggingLevel
+***********************************************************************/
+enum LoggingLevel
+{
+	Errors,
+	Warnings,
+	Standard,
+	Informative,
+	Insane
+};
+
+
+
+/***********************************************************************
+	Logger
+***********************************************************************/
+class Logger
+{
+	static Logger& getSingleton();
+
+	void setLoggingLevel(LoggingLevel level);
+	LoggingLevel getLoggingLevel() const;
+
+	void logEvent(string message, LoggingLevel level=Standard);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/ScriptWindowHelper.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/ScriptWindowHelper.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/ScriptWindowHelper.pkg	(revision 6952)
@@ -0,0 +1,8 @@
+/***********************************************************************
+	ScriptWindowHelper
+***********************************************************************/
+class ScriptWindowHelper
+{
+	Window* getWindow(string name);
+	Window* getWindow();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/WindowManager.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/WindowManager.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/WindowManager.pkg	(revision 6952)
@@ -0,0 +1,32 @@
+/***********************************************************************
+	WindowManager
+***********************************************************************/
+class WindowManager
+{
+	static WindowManager& getSingleton();
+
+	tolua_throws|CEGUI::AlreadyExistsException,nil| Window* createWindow(string type, string name="");
+	tolua_throws|CEGUI::Exception,error|std::exception,error|any,error| Window* loadWindowLayout(string filename, string name_prefix="", string resourcegroup="");
+	tolua_throws|CEGUI::Exception,error|std::exception,error|any,error| Window* loadWindowLayout(string filename, bool generateRandomPrefix);
+
+    void writeWindowLayoutToStream(string window, OutStream& out, bool writeParent=false) const;
+    void writeWindowLayoutToStream(const Window& window, OutStream& out, bool writeParent=false) const;
+
+	void destroyWindow(string name);
+	void destroyWindow(Window* window);
+	void destroyAllWindows();
+
+	tolua_throws|CEGUI::UnknownObjectException,nil| Window* getWindow(string name) const;
+	bool isWindowPresent(string name) const;
+
+	bool isDeadPoolEmpty() const;
+	void cleanDeadPool();
+
+    void renameWindow(Window* window, string  new_name);
+    void renameWindow(string window, string new_name);
+
+    WindowIterator getIterator() const;
+
+    static void setDefaultResourceGroup(string resourceGroup);
+    static string& getDefaultResourceGroup();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/elements/GroupBox.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/elements/GroupBox.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/elements/GroupBox.pkg	(revision 6952)
@@ -0,0 +1,7 @@
+/***********************************************************************
+	GroupBox
+***********************************************************************/
+class GroupBox : public Window
+{
+	bool drawAroundWidget(string name);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/elements/MultiLineEditbox.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/elements/MultiLineEditbox.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/elements/MultiLineEditbox.pkg	(revision 6952)
@@ -0,0 +1,31 @@
+/***********************************************************************
+	MultiLineEditbox
+***********************************************************************/
+class MultiLineEditbox : public Window
+{
+	bool hasInputFocus() const;
+	bool isReadOnly() const;
+	unsigned long getCaratIndex() const;
+	unsigned long getSelectionStartIndex() const;
+	unsigned long getSelectionEndIndex() const;
+	unsigned long getSelectionLength() const;
+	unsigned long getMaxTextLength() const;
+	bool isWordWrapped() const;
+
+    Scrollbar* getVertScrollbar() const;
+    bool isVertScrollbarAlwaysShown() const;
+    Scrollbar* getHorzScrollbar() const;
+    Rect getTextRenderArea() const;
+    unsigned long getLineNumberFromIndex(unsigned long index) const;
+
+	void setReadOnly(bool setting);
+	void setCaratIndex(unsigned long carat_pos);
+	void setSelection(unsigned long start_pos, unsigned long end_pos);
+	void setMaxTextLength(unsigned long max_len);
+	void ensureCaratIsVisible();
+	void setWordWrapping(bool setting);
+    void setShowVertScrollbar(bool setting);
+
+    void setSelectionBrushImage(const Image* image);
+    const Image* getSelectionBrushImage() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/elements/Tree.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/elements/Tree.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/elements/Tree.pkg	(revision 6952)
@@ -0,0 +1,33 @@
+/***********************************************************************
+	Tree
+***********************************************************************/
+class Tree : public Window
+{
+	size_t	getItemCount(void) const;
+	size_t	getSelectedCount(void) const;
+	
+	TreeItem*	getFirstSelectedItem(void) const;
+	TreeItem*	getLastSelectedItem(void) const;
+	
+	bool	isSortEnabled(void) const;
+	bool	isMultiselectEnabled(void) const;
+	bool	isItemTooltipsEnabled(void) const;
+	
+	tolua_throws|CEGUI::Exception,error|std::exception,error|any,error| TreeItem*	findFirstItemWithText(string text);
+	tolua_throws|CEGUI::Exception,error|std::exception,error|any,error| TreeItem*	findNextItemWithText(string text, const TreeItem* start_item);
+	tolua_throws|CEGUI::Exception,error|std::exception,error|any,error| TreeItem*	findFirstItemWithID(unsigned int searchID);
+	tolua_throws|CEGUI::Exception,error|std::exception,error|any,error| TreeItem*	findNextItemWithID(unsigned int searchID, const TreeItem* start_item);
+	
+	bool	isTreeItemInList(const TreeItem* item) const;
+	void	resetList(void);
+	void	addItem(TreeItem* item);
+	
+	tolua_throws|CEGUI::Exception,error|std::exception,error|any,error| void	insertItem(TreeItem* item, const TreeItem* position);
+	void	removeItem(const TreeItem* item);
+	void	clearAllSelections(void);
+	void	setSortingEnabled(bool setting);
+	void	setMultiselectEnabled(bool setting);
+	void	setItemSelectState(TreeItem* item, bool state);
+	tolua_throws|CEGUI::Exception,error|std::exception,error|any,error| void	setItemSelectState(size_t item_index, bool state);
+	tolua_throws|CEGUI::Exception,error|std::exception,error|any,error| void	ensureItemIsVisible(const TreeItem* item);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/elements/TreeItem.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/elements/TreeItem.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.0/package/elements/TreeItem.pkg	(revision 6952)
@@ -0,0 +1,33 @@
+/***********************************************************************
+	TreeItem
+***********************************************************************/
+class TreeItem
+{
+	ColourRect  getTextColours(void) const;
+	void  setTextColours(ColourRect& cols);
+	void  setTextColours(colour top_left_colour, colour top_right_colour, colour bottom_left_colour, colour bottom_right_colour);
+	void  setTextColours(colour col);
+	string getText(void) const;
+	string getTooltipText(void) const;
+	unsigned int  getID(void) const;
+	void* getUserData(void) const;
+	bool  isSelected(void) const;
+	bool  isDisabled(void) const;
+	bool  isAutoDeleted(void) const;
+	Window*  getOwnerWindow(void);
+	ColourRect  getSelectionColours(void) const;
+	void  setText(string text);
+	void  setTooltipText(string text);
+	void  setUserData(void* item_data);
+	void  setSelected(bool setting);
+	void  setDisabled(bool setting);
+	void  setAutoDeleted(bool setting);
+	void  setSelectionColours(ColourRect& cols);
+	void  setSelectionColours(colour top_left_colour, colour top_right_colour, colour bottom_left_colour, colour bottom_right_colour);
+	void  setSelectionColours(colour col);
+	bool  getIsOpen();
+	void toggleIsOpen();
+	size_t getItemCount();
+	void addItem(TreeItem* item);
+	void setIcon(Image& icon);		
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,5 @@
+SET(_package_files
+  Window.pkg
+
+  PARENT_SCOPE
+)
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/CEGUILua.cpp
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/CEGUILua.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/CEGUILua.cpp	(revision 6952)
@@ -0,0 +1,337 @@
+/***********************************************************************
+	filename: CEGUILua.cpp
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+
+	purpose:  Implementation for LuaScriptModule class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUI.h"
+#include "CEGUIConfig.h"
+#include "CEGUIPropertyHelper.h"
+#include "CEGUILua.h"
+#include "CEGUILuaFunctor.h"
+#include <vector>
+
+// include Lua libs and tolua++
+extern "C" {
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+}
+
+#include "tolua/tolua++.h"
+
+// prototype for bindings initialisation function
+int tolua_CEGUI_open(lua_State* tolua_S);
+
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*************************************************************************
+	Constructor (creates Lua state)
+*************************************************************************/
+LuaScriptModule::LuaScriptModule()
+{
+    #if LUA_VERSION_NUM >= 501
+        static const luaL_Reg lualibs[] = {
+            {"", luaopen_base},
+            {LUA_LOADLIBNAME, luaopen_package},
+            {LUA_TABLIBNAME, luaopen_table},
+            {LUA_IOLIBNAME, luaopen_io},
+            {LUA_OSLIBNAME, luaopen_os},
+            {LUA_STRLIBNAME, luaopen_string},
+            {LUA_MATHLIBNAME, luaopen_math},
+        #if defined(DEBUG) || defined (_DEBUG)
+                {LUA_DBLIBNAME, luaopen_debug},
+        #endif
+            {0, 0}
+        };
+    #endif /* LUA_VERSION_NUM >= 501 */
+
+    // create a lua state
+    d_ownsState = true;
+    d_state = lua_open();
+
+    // init all standard libraries
+    #if LUA_VERSION_NUM >= 501
+            const luaL_Reg *lib = lualibs;
+            for (; lib->func; lib++)
+            {
+                lua_pushcfunction(d_state, lib->func);
+                lua_pushstring(d_state, lib->name);
+                lua_call(d_state, 1, 0);
+            }
+    #else /* LUA_VERSION_NUM >= 501 */
+        luaopen_base(d_state);
+        luaopen_io(d_state);
+        luaopen_string(d_state);
+        luaopen_table(d_state);
+        luaopen_math(d_state);
+        #if defined(DEBUG) || defined (_DEBUG)
+            luaopen_debug(d_state);
+        #endif
+    #endif /* LUA_VERSION_NUM >= 501 */
+
+    setModuleIdentifierString();
+}
+
+
+/*************************************************************************
+	Constructor (uses given Lua state)
+*************************************************************************/
+LuaScriptModule::LuaScriptModule(lua_State* state)
+{
+	// just use the given state
+	d_ownsState = false;
+	d_state = state;
+
+	setModuleIdentifierString();
+}
+
+
+/*************************************************************************
+	Destructor
+*************************************************************************/
+LuaScriptModule::~LuaScriptModule()
+{
+	if ( d_ownsState && d_state )
+	{
+		lua_close( d_state );
+	}
+}
+
+
+/*************************************************************************
+	Execute script file
+*************************************************************************/
+void LuaScriptModule::executeScriptFile(const String& filename, const String& resourceGroup)
+{
+	// load file
+	RawDataContainer raw;
+	System::getSingleton().getResourceProvider()->loadRawDataContainer(filename,
+        raw, resourceGroup.empty() ? d_defaultResourceGroup : resourceGroup);
+
+	// load code into lua
+	int top = lua_gettop(d_state);
+	int loaderr = luaL_loadbuffer(d_state, (char*)raw.getDataPtr(), raw.getSize(), filename.c_str());
+	System::getSingleton().getResourceProvider()->unloadRawDataContainer( raw );
+	if (loaderr)
+	{
+	    String errMsg = lua_tostring(d_state,-1);
+		lua_settop(d_state,top);
+		throw ScriptException("Unable to execute Lua script file: '"+filename+"'\n\n"+errMsg+"\n");
+	}
+
+    // call it
+	if (lua_pcall(d_state,0,0,0))
+	{
+	    String errMsg = lua_tostring(d_state,-1);
+		lua_settop(d_state,top);
+		throw ScriptException("Unable to execute Lua script file: '"+filename+"'\n\n"+errMsg+"\n");
+	}
+
+	lua_settop(d_state,top); // just in case :P
+}
+
+
+/*************************************************************************
+	Execute global script function
+*************************************************************************/
+int	LuaScriptModule::executeScriptGlobal(const String& function_name)
+{
+    int top = lua_gettop(d_state);
+
+    // get the function from lua
+    lua_getglobal(d_state, function_name.c_str());
+
+    // is it a function
+    if (!lua_isfunction(d_state,-1))
+    {
+        lua_settop(d_state,top);
+        throw ScriptException("Unable to get Lua global: '"+function_name+"' as name not represent a global Lua function" );
+    }
+
+    // call it
+    int error = lua_pcall(d_state,0,1,0);
+
+    // handle errors
+    if (error)
+    {
+        String errMsg = lua_tostring(d_state,-1);
+        lua_pop(d_state,1);
+        throw ScriptException("Unable to evaluate Lua global: '"+function_name+"\n\n"+errMsg+"\n");
+    }
+
+    // get return value
+    if (!lua_isnumber(d_state,-1))
+    {
+        // log that return value is invalid. return -1 and move on.
+        lua_settop(d_state,top);
+        ScriptException("Unable to get Lua global : '"+function_name+"' return value as it's not a number" );
+        return -1;
+    }
+
+    int ret = (int)lua_tonumber(d_state,-1);
+    lua_pop(d_state,1);
+
+    // return it
+    return ret;
+}
+
+
+/*************************************************************************
+	Execute scripted event handler
+*************************************************************************/
+bool LuaScriptModule::executeScriptedEventHandler(const String& handler_name, const EventArgs& e)
+{
+
+	LuaFunctor::pushNamedFunction(d_state, handler_name);
+
+	ScriptWindowHelper* helper = 0;
+	//If this is an event that was triggered by a window then make a "this" pointer to the window for the script.
+	if(e.d_hasWindow)
+	{
+		WindowEventArgs& we = (WindowEventArgs&)e;
+		helper = new ScriptWindowHelper(we.window);
+		lua_pushlightuserdata(d_state,(void*)helper);
+		lua_setglobal(d_state,"this");
+	} // if(e.d_hasWindow)
+
+    // push EventArgs as the first parameter
+    tolua_pushusertype(d_state,(void*)&e,"const CEGUI::EventArgs");
+
+    // call it
+    int error = lua_pcall(d_state,1,0,0);
+
+    // handle errors
+    if (error)
+    {
+        String errStr(lua_tostring(d_state,-1));
+        lua_pop(d_state,1);
+		//cleanup the helper object if any
+		if(helper)
+		{
+			delete helper;
+			helper = 0;
+		}
+        throw ScriptException("Unable to evaluate the Lua event handler: '"+handler_name+"'\n\n"+errStr+"\n");
+    } // if (error)
+
+	if(helper)
+	{
+		delete helper;
+		helper = 0;
+	}
+
+    return true;
+}
+
+
+/*************************************************************************
+	Execute script code string
+*************************************************************************/
+void LuaScriptModule::executeString(const String& str)
+{
+    int top = lua_gettop(d_state);
+
+    // load code into lua and call it
+    int error =	luaL_loadbuffer(d_state, str.c_str(), str.length(), str.c_str()) || lua_pcall(d_state,0,0,0);
+
+    // handle errors
+    if (error)
+    {
+        String errMsg = lua_tostring(d_state,-1);
+        lua_settop(d_state,top);
+        throw ScriptException("Unable to execute Lua script string: '"+str+"'\n\n"+errMsg+"\n");
+    }
+}
+
+
+/*************************************************************************
+	Create Lua bindings
+*************************************************************************/
+void LuaScriptModule::createBindings(void)
+{
+	CEGUI::Logger::getSingleton().logEvent( "---- Creating Lua bindings ----" );
+	// init CEGUI module
+	tolua_CEGUI_open(d_state);
+}
+
+
+/*************************************************************************
+	Destroy Lua bindings
+*************************************************************************/
+void LuaScriptModule::destroyBindings(void)
+{
+	CEGUI::Logger::getSingleton().logEvent( "---- Destroying Lua bindings ----" );
+	// is this ok ?
+	lua_pushnil(d_state);
+	lua_setglobal(d_state,"CEGUI");
+}
+
+
+/*************************************************************************
+	Set the ID string for the module
+*************************************************************************/
+void LuaScriptModule::setModuleIdentifierString()
+{
+    // set ID string
+    d_identifierString = "CEGUI::LuaScriptModule - Official Lua based scripting module for CEGUI";
+	d_language = "Lua";
+}
+
+
+/*************************************************************************
+	Subscribe to a scripted event handler
+*************************************************************************/
+Event::Connection LuaScriptModule::subscribeEvent(EventSet* target, const String& event_name, const String& subscriber_name)
+{
+    // do the real subscription
+    LuaFunctor functor(d_state,subscriber_name,LUA_NOREF);
+    Event::Connection con = target->subscribeEvent(event_name, Event::Subscriber(functor));
+    // make sure we don't release the reference we just made when this call returns
+    functor.index = LUA_NOREF;
+
+    // return the event connection
+    return con;
+}
+
+
+/*************************************************************************
+	Subscribe to a scripted event handler
+*************************************************************************/
+Event::Connection LuaScriptModule::subscribeEvent(EventSet* target, const String& event_name, Event::Group group, const String& subscriber_name)
+{
+    // do the real subscription
+    LuaFunctor functor(d_state,subscriber_name,LUA_NOREF);
+    Event::Connection con = target->subscribeEvent(event_name, group, Event::Subscriber(functor));
+
+    // return the event connection
+    return con;
+}
+
+} // namespace CEGUI
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/CEGUILua.h
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/CEGUILua.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/CEGUILua.h	(revision 6952)
@@ -0,0 +1,253 @@
+/***********************************************************************
+	filename: CEGUILua.h
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+	
+	purpose:  Defines interface for LuaScriptModule class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#ifndef _CEGUILua_h_
+#define _CEGUILua_h_
+
+
+/*************************************************************************
+	Import / Export control macros
+*************************************************************************/
+#if (defined( __WIN32__ ) || defined( _WIN32 )) && !defined(CEGUI_STATIC)
+#   ifdef CEGUILUA_EXPORTS
+#       define CEGUILUA_API __declspec(dllexport)
+#   else
+#       if defined( __MINGW32__ )
+#           define CEGUILUA_API
+#       else
+#           define CEGUILUA_API __declspec(dllimport)
+#       endif
+#   endif
+#else
+#   define CEGUILUA_API
+#endif
+
+
+#include "CEGUIScriptModule.h"
+
+struct lua_State;
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*!
+\brief
+	Interface for the LuaScriptModule class
+*/
+class CEGUILUA_API LuaScriptModule : public CEGUI::ScriptModule
+{
+public:
+	/*************************************************************************
+		Construction and Destruction
+	*************************************************************************/
+	/*!
+	\brief
+		Constructor for LuaScriptModule class which create a lua_State
+	*/
+	LuaScriptModule();
+
+
+	/*!
+	\brief
+		Constructor for LuaScriptModule class which takes a lua_State
+
+	\param state
+		Pointer to the lua_State that the script module should attach to.
+	*/
+	LuaScriptModule(lua_State* state);
+
+
+	/*!
+	\brief
+		Destructor for LuaScriptModule class.
+	*/
+	~LuaScriptModule();
+
+
+	/*************************************************************************
+		Script Execution Functions
+	*************************************************************************/
+	/*!
+	\brief
+		Execute a script file.
+
+	\param filename
+		String object holding the filename of the script file that is to be executed
+		
+	\param resourceGroup
+		Resource group idendifier to be passed to the ResourceProvider when loading the script file.
+	*/
+	void executeScriptFile(const String& filename, const String& resourceGroup);
+
+
+	/*!
+	\brief
+		Execute a scripted global function.  The function should not take any parameters and should return an integer.
+
+	\param function_name
+		String object holding the name of the function, in the global script environment, that
+		is to be executed.
+
+	\return
+		The integer value returned from the script function.
+	*/
+	int executeScriptGlobal(const String& function_name);
+
+
+    /*!
+    \brief
+        Execute a scripted global 'event handler' function by looking it up by name.
+
+    \param handler_name
+        String object holding the name of the scripted handler function.
+        If this string contains dots '.' it will be parsed as tables containing a function field.
+        For example: 'mytable.subtable.func'
+
+    \param e
+        EventArgs based object that should be passed, by any appropriate means, to the scripted function.
+
+    \return
+        - true if the event was handled.
+        - false if the event was not handled.
+    */
+    bool executeScriptedEventHandler(const String& handler_name, const EventArgs& e);
+
+
+    /*!
+    \brief
+        Execute script code contained in the given CEGUI::String object.
+
+    \param str
+        String object holding the valid script code that should be executed.
+
+    \return
+        Nothing.
+    */
+    void executeString(const String& str);
+
+    /*************************************************************************
+        Event subscription
+    *************************************************************************/
+    /*!
+    \brief
+            Subscribes the named Event to a scripted funtion
+
+    \param target
+            The target EventSet for the subscription.
+
+    \param name
+            String object containing the name of the Event to subscribe to.
+
+    \param subscriber_name
+            String object containing the name of the script funtion that is to be subscribed to the Event.
+
+    \return
+            Connection object that can be used to check the status of the Event connection and to disconnect (unsubscribe) from the Event.
+
+    \exception UnknownObjectException	Thrown if an Event named \a name is not in the EventSet
+    */
+    Event::Connection	subscribeEvent(EventSet* target, const String& name, const String& subscriber_name);
+
+    /*!
+    \brief
+            Subscribes the specified group of the named Event to a scripted funtion.
+
+    \param target
+            The target EventSet for the subscription.
+
+    \param name
+            String object containing the name of the Event to subscribe to.
+
+    \param group
+            Group which is to be subscribed to.  Subscription groups are called in ascending order.
+
+    \param subscriber_name
+            String object containing the name of the script funtion that is to be subscribed to the Event.
+
+    \return
+            Connection object that can be used to check the status of the Event connection and to disconnect (unsubscribe) from the Event.
+
+    \exception UnknownObjectException	Thrown if an Event named \a name is not in the EventSet
+    */
+    Event::Connection	subscribeEvent(EventSet* target, const String& name, Event::Group group, const String& subscriber_name);
+
+    /*************************************************************************
+        Bindings creation / destruction
+    *************************************************************************/
+    /*!
+    \brief
+        Method called during system initialisation, prior to running any scripts via the ScriptModule, to enable the ScriptModule
+        to perform any operations required to complete initialisation or binding of the script language to the gui system objects.
+
+    \return
+        Nothing.
+    */
+    void createBindings(void);
+
+
+    /*!
+    \brief
+        Method called during system destruction, after all scripts have been run via the ScriptModule, to enable the ScriptModule
+        to perform any operations required to cleanup bindings of the script language to the gui system objects, as set-up in the
+        earlier createBindings call.
+
+    \return
+        Nothing.
+    */
+    void destroyBindings(void);
+
+    /*************************************************************************
+        Accessor type functions
+    *************************************************************************/
+    /*!
+    \brief
+        Method used to get a pointer to the lua_State that the script module is attached to.
+
+    \return
+        A pointer to the lua_State that the script module is attached to.
+    */
+    lua_State* getLuaState(void) const {return d_state;}
+
+private:
+    /*************************************************************************
+        Implementation Functions
+    *************************************************************************/
+    void setModuleIdentifierString();
+
+    /*************************************************************************
+        Implementation Data
+    *************************************************************************/
+    bool d_ownsState;      //!< true when the attached lua_State was created by this script module
+    lua_State* d_state;    //!< The lua_State that this script module uses.
+};
+
+} // namespace CEGUI
+
+#endif // end of guard _CEGUILua_h_
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/CEGUILuaFunctor.cpp
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/CEGUILuaFunctor.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/CEGUILuaFunctor.cpp	(revision 6952)
@@ -0,0 +1,280 @@
+/***********************************************************************
+    filename: CEGUILuaFunctor.cpp
+    created:  Thu Jan 26 2006
+    author:   Tomas Lindquist Olsen <tomas@famolsen.dk>
+
+    purpose:  Implementation for LuaFunctor class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUILuaFunctor.h"
+#include "CEGUILogger.h"
+#include "CEGUIExceptions.h"
+#include "CEGUIPropertyHelper.h"
+
+// include Lua libs and tolua++
+extern "C" {
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+}
+
+#include "tolua/tolua++.h"
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*************************************************************************
+    Constructor
+*************************************************************************/
+LuaFunctor::LuaFunctor(lua_State* state, int func, int selfIndex) :
+    L(state),
+    index(func),
+    self(selfIndex),
+    needs_lookup(false)
+{
+}
+
+/*************************************************************************
+    Constructor
+*************************************************************************/
+LuaFunctor::LuaFunctor(lua_State* state, const String& func, int selfIndex) :
+    L(state),
+    index(LUA_NOREF),
+    self(selfIndex),
+    needs_lookup(true),
+    function_name(func)
+{
+}
+
+/*************************************************************************
+    Constructor
+*************************************************************************/
+LuaFunctor::LuaFunctor(const LuaFunctor& cp) :
+    L(cp.L),
+    index(cp.index),
+    self(cp.self),
+    needs_lookup(cp.needs_lookup),
+    function_name(cp.function_name)
+{
+}
+
+/*************************************************************************
+    Destructor
+*************************************************************************/
+LuaFunctor::~LuaFunctor()
+{
+    if (self!=LUA_NOREF)
+    {
+        luaL_unref(L, LUA_REGISTRYINDEX, self);
+    }
+    if (index!=LUA_NOREF)
+    {
+        luaL_unref(L, LUA_REGISTRYINDEX, index);
+    }
+}
+
+/*************************************************************************
+    Call operator
+*************************************************************************/
+bool LuaFunctor::operator()(const EventArgs& args) const
+{
+    // is this a late binding?
+    if (needs_lookup)
+    {
+        pushNamedFunction(L, function_name);
+        // reference function
+        index = luaL_ref(L, LUA_REGISTRYINDEX);
+        needs_lookup = false;
+        CEGUI_LOGINSANE("Late binding of callback '"+function_name+"' performed");
+        function_name.clear();
+    } // if (needs_lookup)
+
+	ScriptWindowHelper* helper = 0;
+	//Set a global for this window
+	if(args.d_hasWindow)
+	{
+		WindowEventArgs& we = (WindowEventArgs&)args;
+		helper = new ScriptWindowHelper(we.window);
+		tolua_pushusertype(L,(void*)helper,"CEGUI::ScriptWindowHelper");
+		lua_setglobal(L,"this");
+	}
+
+    // retrieve function
+    lua_rawgeti(L, LUA_REGISTRYINDEX, index);
+
+    // possibly self as well?
+    int nargs = 1;
+    if (self != LUA_NOREF)
+    {
+        lua_rawgeti(L, LUA_REGISTRYINDEX, self);
+        ++nargs;
+    }
+
+    // push EventArgs  parameter
+    tolua_pushusertype(L, (void*)&args, "const CEGUI::EventArgs");
+
+    // call it
+    int error = lua_pcall(L, nargs, 0, 0);
+
+    // handle errors
+    if (error)
+    {
+        String errStr(lua_tostring(L, -1));
+        lua_pop(L, 1);
+		if(helper)
+		{
+			delete helper;
+			helper = 0;
+		}
+        throw ScriptException("Unable to call Lua event handler:\n\n"+errStr+"\n");
+    } // if (error)
+
+	if(helper)
+	{
+		delete helper;
+		helper = 0;
+	}
+
+    return true;
+}
+
+/*************************************************************************
+    do event subscription by reference instead of by name
+*************************************************************************/
+Event::Connection LuaFunctor::SubscribeEvent(EventSet* self, const String& event_name, int funcIndex, int selfIndex, lua_State* L)
+{
+    // should we pass a self to the callback?
+    int thisIndex = LUA_NOREF;
+    if (selfIndex != LUA_NOREF)
+    {
+        // reference self
+        thisIndex = luaL_ref(L, LUA_REGISTRYINDEX);
+    }
+
+    // do the real subscription
+    int type = lua_type(L,-1);
+    Event::Connection con;
+    if (type == LUA_TFUNCTION)
+    {
+        // reference function
+        int index = luaL_ref(L, LUA_REGISTRYINDEX);
+        LuaFunctor functor(L,index,thisIndex);
+        con = self->subscribeEvent(String(event_name), Event::Subscriber(functor));
+        // make sure we don't release the reference(s) we just made when this call returns
+        functor.index = LUA_NOREF;
+        functor.self = LUA_NOREF;
+    }
+    else if (type == LUA_TSTRING)
+    {
+        const char* str = lua_tostring(L, -1);
+        LuaFunctor functor(L,String(str),thisIndex);
+        con = self->subscribeEvent(String(event_name), Event::Subscriber(functor));
+        // make sure we don't release the reference we just (maybe) made when this call returns
+        functor.self = LUA_NOREF;
+    }
+    else
+    {
+        luaL_error(L,"bad function passed to subscribe function. must be a real function, or a string for late binding");
+    }
+
+    // return the event connection
+    return con;
+}
+
+/*************************************************************************
+    Pushes a named function on the stack
+*************************************************************************/
+void LuaFunctor::pushNamedFunction(lua_State* L, const String& handler_name)
+{
+    int top = lua_gettop(L);
+
+    // do we have any dots in the handler name? if so we grab the function as a table field
+    String::size_type i = handler_name.find_first_of((utf32)'.');
+    if (i!=String::npos)
+    {
+        // split the rest of the string up in parts seperated by '.'
+        // TODO: count the dots and size the vector accordingly from the beginning.
+        std::vector<String> parts;
+        String::size_type start = 0;
+        do
+        {
+            parts.push_back(handler_name.substr(start,i-start));
+            start = i+1;
+            i = handler_name.find_first_of((utf32)'.',start);
+        } while(i!=String::npos);
+
+        // add last part
+        parts.push_back(handler_name.substr(start));
+
+        // first part is the global
+        lua_getglobal(L, parts[0].c_str());
+        if (!lua_istable(L,-1))
+        {
+            lua_settop(L,top);
+            throw ScriptException("Unable to get the Lua event handler: '"+handler_name+"' as first part is not a table");
+        }
+
+        // if there is more than two parts, we have more tables to go through
+        std::vector<String>::size_type visz = parts.size();
+        if (visz-- > 2) // avoid subtracting one later on
+        {
+            // go through all the remaining parts to (hopefully) have a valid Lua function in the end
+            std::vector<String>::size_type vi = 1;
+            while (vi<visz)
+            {
+                // push key, and get the next table
+                lua_pushstring(L,parts[vi].c_str());
+                lua_gettable(L,-2);
+                if (!lua_istable(L,-1))
+                {
+                    lua_settop(L,top);
+                    throw ScriptException("Unable to get the Lua event handler: '"+handler_name+"' as part #"+PropertyHelper::uintToString(uint(vi+1))+" ("+parts[vi]+") is not a table");
+                }
+                // get rid of the last table and move on
+                lua_remove(L,-2);
+                vi++;
+            }
+        }
+
+        // now we are ready to get the function to call ... phew :)
+        lua_pushstring(L,parts[visz].c_str());
+        lua_gettable(L,-2);
+        lua_remove(L,-2); // get rid of the table
+    }
+    // just a regular global function
+    else
+    {
+        lua_getglobal(L, handler_name.c_str());
+    }
+
+    // is it a function
+    if (!lua_isfunction(L,-1))
+    {
+        lua_settop(L,top);
+        throw ScriptException("The Lua event handler: '"+handler_name+"' does not represent a Lua function");
+    }
+}
+
+} // namespace CEGUI
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/CEGUILuaFunctor.h
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/CEGUILuaFunctor.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/CEGUILuaFunctor.h	(revision 6952)
@@ -0,0 +1,86 @@
+/***********************************************************************
+    filename: CEGUILuaFunctor.h
+    created:  Thu Jan 26 2006
+    author:   Tomas Lindquist Olsen <tomas@famolsen.dk>
+
+    purpose:  Defines interface for LuaFunctor class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#ifndef _CEGUILuaFunctor_h_
+#define _CEGUILuaFunctor_h_
+
+#include "CEGUIEventSet.h"
+#include "CEGUIScriptWindowHelper.h"
+
+struct lua_State;
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+// forward declaration
+class LuaScriptModule;
+
+/*!
+\brief
+    Functor class used for subscribing Lua functions to CEGUI events
+*/
+class LuaFunctor
+{
+public:
+    LuaFunctor(lua_State* state, int func, int selfIndex);
+    LuaFunctor(lua_State* state, const String& func, int selfIndex);
+    LuaFunctor(const LuaFunctor& cp);
+    ~LuaFunctor();
+
+    bool operator()(const EventArgs& args) const;
+
+    /*!
+    \brief
+        function used to subscribe any Lua function as event handler.
+        References using the Lua registry.
+        To be called from Lua only.
+    */
+    static Event::Connection SubscribeEvent(EventSet* self, const String& eventName, int funcIndex, int selfIndex, lua_State* L);
+
+    /*!
+    \brief
+        Pushes the Lua function named \param name on top of the Lua stack.
+        The name may contain '.' (dots) character for (nested) table values.
+    */
+    static void pushNamedFunction(lua_State* L, const String& name);
+
+private:
+    lua_State* L;
+    mutable int index;
+    int self;
+    mutable bool needs_lookup;
+    mutable String function_name;
+
+    friend class LuaScriptModule;
+};
+
+} // namespace CEGUI
+
+#endif // end of guard _CEGUILuaFunctor_h_
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/changes_orxonox.diff
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/changes_orxonox.diff	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/changes_orxonox.diff	(revision 6952)
@@ -0,0 +1,92 @@
+--- CEGUILua.h	Mi Jul  9 18:24:49 2008
++++ CEGUILua.h	Do Jan 29 10:18:14 2009
+@@ -38,7 +38,11 @@
+ #   ifdef CEGUILUA_EXPORTS
+ #       define CEGUILUA_API __declspec(dllexport)
+ #   else
+-#       define CEGUILUA_API __declspec(dllimport)
++#       if defined( __MINGW32__ )
++#           define CEGUILUA_API
++#       else
++#           define CEGUILUA_API __declspec(dllimport)
++#       endif
+ #   endif
+ #else
+ #   define CEGUILUA_API
+--- CEGUILuaFunctor.cpp	Mi Jul  9 18:25:01 2008
++++ CEGUILuaFunctor.cpp	Do Jan 29 10:26:27 2009
+@@ -39,7 +39,7 @@
+ #include "lauxlib.h"
+ }
+ 
+-#include "tolua++.h"
++#include "tolua/tolua++.h"
+ 
+ // Start of CEGUI namespace section
+ namespace CEGUI
+--- CEGUILua.cpp	Mi Jul  9 18:25:01 2008
++++ CEGUILua.cpp	Do Jan 29 10:24:53 2009
+@@ -27,10 +27,6 @@
+  *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+  *   OTHER DEALINGS IN THE SOFTWARE.
+  ***************************************************************************/
+-#ifdef HAVE_CONFIG_H
+-#   include "config.h"
+-#endif
+-
+ #include "CEGUI.h"
+ #include "CEGUIConfig.h"
+ #include "CEGUIPropertyHelper.h"
+@@ -45,7 +41,7 @@
+ #include "lauxlib.h"
+ }
+ 
+-#include "tolua++.h"
++#include "tolua/tolua++.h"
+ 
+ // prototype for bindings initialisation function
+ int tolua_CEGUI_open(lua_State* tolua_S);
+@@ -60,7 +56,7 @@
+ *************************************************************************/
+ LuaScriptModule::LuaScriptModule()
+ {
+-    #if CEGUI_LUA_VER >= 51
++    #if LUA_VERSION_NUM >= 501
+         static const luaL_Reg lualibs[] = {
+             {"", luaopen_base},
+             {LUA_LOADLIBNAME, luaopen_package},
+@@ -74,14 +70,14 @@
+         #endif
+             {0, 0}
+         };
+-    #endif /* CEGUI_LUA_VER >= 51 */
++    #endif /* LUA_VERSION_NUM >= 501 */
+ 
+     // create a lua state
+     d_ownsState = true;
+     d_state = lua_open();
+ 
+     // init all standard libraries
+-    #if CEGUI_LUA_VER >= 51
++    #if LUA_VERSION_NUM >= 501
+             const luaL_Reg *lib = lualibs;
+             for (; lib->func; lib++)
+             {
+@@ -89,7 +85,7 @@
+                 lua_pushstring(d_state, lib->name);
+                 lua_call(d_state, 1, 0);
+             }
+-    #else /* CEGUI_LUA_VER >= 51 */
++    #else /* LUA_VERSION_NUM >= 501 */
+         luaopen_base(d_state);
+         luaopen_io(d_state);
+         luaopen_string(d_state);
+@@ -98,7 +94,7 @@
+         #if defined(DEBUG) || defined (_DEBUG)
+             luaopen_debug(d_state);
+         #endif
+-    #endif /* CEGUI_LUA_VER >= 51 */
++    #endif /* LUA_VERSION_NUM >= 501 */
+ 
+     setModuleIdentifierString();
+ }
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/required.cpp
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/required.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/required.cpp	(revision 6952)
@@ -0,0 +1,88 @@
+/***********************************************************************
+	filename: required.cpp
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+	
+	purpose:  Implementation of helper functions
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUI.h"
+#include "required.h"
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*************************************************************************
+	Functions for getting Thumb range pairs as two return values
+*************************************************************************/
+
+// returns horizontal range as two values for lua
+void ceguiLua_Thumb_getHorzRange(Thumb* wnd, float* min, float* max)
+{
+	std::pair<float,float> range_pair = wnd->getHorzRange();
+	*min = range_pair.first;
+	*max = range_pair.second;
+}
+
+
+// returns vertical range as two values for lua
+void ceguiLua_Thumb_getVertRange(Thumb* wnd, float* min, float* max)
+{
+	std::pair<float,float> range_pair = wnd->getVertRange();
+	*min = range_pair.first;
+	*max = range_pair.second;
+}
+
+
+/*************************************************************************
+	Functions for creating list box items
+*************************************************************************/
+
+// allocates and returns a new ListboxTextItem
+ListboxTextItem* ceguiLua_createListboxTextItem(const String& text, uint item_id, void* item_data, bool disabled, bool auto_delete)
+{
+	return new ListboxTextItem(text,item_id,item_data,disabled,auto_delete);
+}
+
+
+/************************************************************************
+    OutStream
+*************************************************************************/
+void ceguiLua_FileStream_open(FileStream* os, const char* filename)
+{
+    os->open(filename, std::ios::binary);
+}
+
+
+/************************************************************************
+    CEGUI::System::getSystemKeys alternative
+*************************************************************************/
+bool ceguiLua_System_isSystemKeyDown(const System* sys, SystemKey k)
+{
+    return (k & sys->getSystemKeys()) != 0;
+}
+
+
+} // namespace CEGUI
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/required.h
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/required.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/ceguilua/required.h	(revision 6952)
@@ -0,0 +1,113 @@
+/***********************************************************************
+	filename: required.h
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+
+	purpose:  Header that includes the necessary stuff needed for the Lua bindings
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUI.h"
+#include "CEGUILua.h"
+#include "CEGUILuaFunctor.h"
+#include <fstream>
+
+#define __operator_increment    operator++
+#define __operator_decrement    operator--
+#define __operator_dereference  operator*
+
+#define LuaFunctorSubscribeEvent CEGUI::LuaFunctor::SubscribeEvent
+
+//This is used to keep compilers happy
+#define CEGUIDeadException(e) &
+
+#if defined(_MSC_VER) && !defined(snprintf)
+#   define snprintf   _snprintf
+#endif
+
+typedef CEGUI::String string;
+
+namespace CEGUI
+{
+
+typedef Event::Connection EventConnection;
+
+/*************************************************************************
+	Functions for getting Thumb range pairs as two return values
+*************************************************************************/
+void ceguiLua_Thumb_getHorzRange(Thumb* wnd, float* min, float* max);
+void ceguiLua_Thumb_getVertRange(Thumb* wnd, float* min, float* max);
+
+
+/*************************************************************************
+	Functions for creating list box items
+*************************************************************************/
+ListboxTextItem* ceguiLua_createListboxTextItem(const String& text, uint item_id, void* item_data, bool disabled, bool auto_delete);
+
+
+/************************************************************************
+    Stuff needed to make the iterators work
+*************************************************************************/
+typedef PropertySet::Iterator PropertyIterator;
+typedef EventSet::Iterator EventIterator;
+typedef WindowManager::WindowIterator WindowIterator;
+typedef WindowFactoryManager::WindowFactoryIterator WindowFactoryIterator;
+typedef WindowFactoryManager::FalagardMappingIterator FalagardMappingIterator;
+typedef WindowFactoryManager::FalagardWindowMapping FalagardWindowMapping;
+typedef ImagesetManager::ImagesetIterator ImagesetIterator;
+typedef Imageset::ImageIterator ImageIterator;
+typedef SchemeManager::SchemeIterator SchemeIterator;
+typedef FontManager::FontIterator FontIterator;
+
+template <typename T>
+inline PropertyIterator ceguiLua_getPropertyIterator(const T* self)
+{
+    return static_cast<const PropertySet*>(self)->getIterator();
+}
+
+template <typename T>
+inline EventIterator ceguiLua_getEventIterator(const T* self)
+{
+    return static_cast<const EventSet*>(self)->getIterator();
+}
+
+
+/************************************************************************
+    OutStream
+*************************************************************************/
+typedef std::ofstream FileStream;
+void ceguiLua_FileStream_open(FileStream*, const char* filename);
+
+
+/************************************************************************
+    CEGUI::System::getSystemKeys alternative
+*************************************************************************/
+bool ceguiLua_System_isSystemKeyDown(const System* sys, SystemKey k);
+
+}
+
+// the binding file generates alot of
+// warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
+#if defined(_MSC_VER)
+#   pragma warning(disable : 4800)
+#endif
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/package/Window.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/package/Window.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.1/package/Window.pkg	(revision 6952)
@@ -0,0 +1,249 @@
+/****************************************
+	Vertical alignment modes
+*****************************************/
+enum VerticalAlignment
+{
+	VA_TOP,
+	VA_CENTRE,
+	VA_BOTTOM
+};
+
+
+/****************************************
+	Horizontal alignment modes
+*****************************************/
+enum HorizontalAlignment
+{
+	HA_LEFT,
+	HA_CENTRE,
+	HA_RIGHT
+};
+
+
+/****************************************
+	Window
+*****************************************/
+class Window //: public EventSet
+{
+	string getType() const;
+	string getName() const;
+
+	bool isDestroyedByParent() const;
+	bool isAlwaysOnTop() const;
+	bool isDisabled(bool localOnly=false) const;
+	bool isVisible(bool localOnly=false) const;
+	bool isActive() const;
+	bool isClippedByParent() const;
+
+	void setDestroyedByParent(bool setting);
+	void setAlwaysOnTop(bool setting);
+	void setEnabled(bool setting);
+	void enable();
+	void disable();
+	void setVisible(bool setting);
+	void show();
+	void hide();
+	void activate();
+	void deactivate();
+
+	void setClippedByParent(bool setting);
+
+	unsigned int getID() const;
+	void setID(unsigned int ID);
+
+	unsigned int getChildCount() const;
+
+	bool isChild(unsigned int ID) const;
+	bool isChild(string name) const;
+	bool isChild(const Window* window) const;
+	bool isChildRecursive(unsigned int ID) const;
+
+	void addChildWindow(string name);
+	void addChildWindow(Window* window);
+
+	void removeChildWindow(unsigned int ID);
+	void removeChildWindow(string name);
+	void removeChildWindow(Window* window);
+
+	tolua_throws|CEGUI::UnknownObjectException,nil| Window* getChild(unsigned int ID) const;
+	tolua_throws|CEGUI::UnknownObjectException,nil| Window* getChild(string name) const;
+	Window* getChildAtIdx(unsigned int ID) const;
+	Window* getActiveChild() const;
+	Window* getChildAtPosition(const Vector2& pos) const;
+    Window* getTargetChildAtPosition(const Vector2& pos) const;
+    Window* getChildRecursive(unsigned int ID) const;
+
+	Window* getParent() const;
+
+	bool isAncestor(unsigned int ID) const;
+	bool isAncestor(string name) const;
+	bool isAncestor(const Window* window) const;
+
+	void setFont(string name);
+	void setFont(Font* font);
+	Font* getFont() const;
+
+	void setText(string text);
+    void insertText(string text, unsigned long position);
+    void appendText(string text);
+	string getText() const;
+
+	bool inheritsAlpha() const;
+	float getAlpha() const;
+	float getEffectiveAlpha() const;
+	void setAlpha(float a);
+	void setInheritsAlpha(bool setting);
+
+	void requestRedraw() const;
+
+	bool isZOrderingEnabled() const;
+	void setZOrderingEnabled(bool setting);
+
+	Rect getPixelRect() const;
+	Rect getInnerRect() const;
+	Rect getUnclippedPixelRect() const;
+	Rect getUnclippedInnerRect() const;
+
+    Size getParentPixelSize(void) const;
+    float getParentPixelWidth(void) const;
+    float getParentPixelHeight(void) const;
+
+	static Window* getCaptureWindow();
+	void setRestoreCapture(bool setting);
+	bool restoresOldCapture() const;
+
+	bool distributesCapturedInputs() const;
+	void setDistributesCapturedInputs(bool setting);
+
+	bool captureInput();
+	void releaseInput();
+
+	bool isCapturedByThis() const;
+	bool isCapturedByAncestor() const;
+	bool isCapturedByChild() const;
+
+	bool isHit(const Vector2& pos) const;
+
+	bool isRiseOnClickEnabled() const;
+	void setRiseOnClickEnabled(bool setting);
+
+	const Image* getMouseCursor() const;
+	void setMouseCursor(MouseCursorImage cursor);
+	void setMouseCursor(const Image* image);
+	void setMouseCursor(string imageset, string image);
+
+	void moveToFront();
+	void moveToBack();
+
+	bool wantsMultiClickEvents() const;
+	bool isMouseAutoRepeatEnabled() const;
+	float getAutoRepeatDelay() const;
+	float getAutoRepeatRate() const;
+	void setWantsMultiClickEvents(bool setting);
+	void setMouseAutoRepeatEnabled(bool setting);
+	void setAutoRepeatDelay(float delay);
+	void setAutoRepeatRate(float rate);
+
+	//void destroy();
+
+	bool isUsingDefaultTooltip() const;
+	Tooltip* getTooltip() const;
+	string getTooltipType() const;
+	string getTooltipText() const;
+	bool inheritsTooltipText() const;
+
+	void setTooltip(Tooltip* tooltip);
+	void setTooltipType(string tooltipType);
+	void setTooltipText(string tip);
+	void setInheritsTooltipText(bool setting);
+
+	bool testClassName(string class_name) const;
+
+	void notifyDragDropItemEnters(DragContainer* item);
+	void notifyDragDropItemLeaves(DragContainer* item);
+	void notifyDragDropItemDropped(DragContainer* item);
+
+	VerticalAlignment getVerticalAlignment() const;
+	HorizontalAlignment getHorizontalAlignment() const;
+
+    // these actually have a const, but tolua++ chokes on that
+    void setVerticalAlignment(VerticalAlignment alignment);
+    void setHorizontalAlignment(HorizontalAlignment alignment);
+
+	string getLookNFeel() const;
+    tolua_throws|CEGUI::Exception,error| void setLookNFeel(string lnf);
+
+    tolua_throws|CEGUI::Exception,error| void setWindowRenderer(string name);
+    string getWindowRendererName() const;
+
+	//RenderCache& getRenderCache()
+
+	bool getModalState() const;
+	void setModalState(bool state);
+
+    tolua_throws|CEGUI::UnknownObjectException,nil| string getUserString(string name) const;
+    bool isUserStringDefined(string name) const;
+    void setUserString(string name, string value);
+
+    void beginInitialisation();
+    void endInitialisation();
+
+	// unified stuff
+	void setArea(const UDim& xpos, const UDim& ypos, const UDim& width, const UDim& height);
+	void setArea(const UVector2& pos, const UVector2& size);
+	void setArea(const URect& area);
+	void setPosition(const UVector2& pos);
+	void setXPosition(const UDim& x);
+	void setYPosition(const UDim& y);
+	void setSize(const UVector2& size);
+	void setWidth(const UDim& width);
+	void setHeight(const UDim& height);
+	void setMaxSize(const UVector2& size);
+	void setMinSize(const UVector2& size);
+
+	const URect& getArea() const;
+	const UVector2& getPosition() const;
+	const UDim& getXPosition() const;
+	const UDim& getYPosition() const;
+	UVector2 getSize() const;
+	UDim getWidth() const;
+	UDim getHeight() const;
+	const UVector2& getMaxSize() const;
+	const UVector2& getMinSize() const;
+
+    // event pass through
+    bool isMousePassThroughEnabled() const;
+    void setMousePassThroughEnabled(bool setting);
+    
+    tolua_throws|CEGUI::Exception,error| void rename(string new_name);
+
+	//////////////////////////////////////////////
+	// PropertySet
+	void setProperty(string name, string value);
+	string getProperty(string name) const;
+	string getPropertyDefault(string name) const;
+	string getPropertyHelp(string name) const;
+
+	bool isPropertyPresent(string name) const;
+	bool isPropertyDefault(string name) const;
+
+    tolua_outside PropertyIterator ceguiLua_getPropertyIterator @ getPropertyIterator() const;
+
+	//////////////////////////////////////////////
+	// EventSet
+	void addEvent(string name);
+	void removeEvent(string name);
+	void removeAllEvents();
+	bool isEventPresent(string name);
+
+	tolua_throws|CEGUI::UnknownObjectException,error| tolua_outside EventConnection LuaFunctorSubscribeEvent @ subscribeEvent(string name, lua_Object funcIndex, lua_Object selfIndex=LUA_NOREF, lua_State*);
+
+	tolua_throws|CEGUI::UnknownObjectException,error| EventConnection subscribeScriptedEvent @ subscribeEvent(string name, string callback_name);
+	
+	void fireEvent(string name, EventArgs& args, string eventnamespace="");
+
+	bool isMuted() const;
+	void setMutedState(bool setting);
+
+    tolua_outside EventIterator ceguiLua_getEventIterator @ getEventIterator() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,9 @@
+SET(_package_files
+  EventSet.pkg
+  HelperFunctions.pkg
+  InputEvent.pkg
+  Window.pkg
+  WindowManager.pkg
+
+  PARENT_SCOPE
+)
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/CEGUILua.cpp
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/CEGUILua.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/CEGUILua.cpp	(revision 6952)
@@ -0,0 +1,712 @@
+/***********************************************************************
+	filename: CEGUILua.cpp
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+
+	purpose:  Implementation for LuaScriptModule class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2008 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUI.h"
+#include "CEGUIConfig.h"
+#include "CEGUIPropertyHelper.h"
+#include "CEGUILua.h"
+#include "CEGUILuaFunctor.h"
+#include <vector>
+
+// include Lua libs and tolua++
+extern "C" {
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+}
+
+#include "tolua/tolua++.h"
+
+// prototype for bindings initialisation function
+int tolua_CEGUI_open(lua_State* tolua_S);
+
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*************************************************************************
+	Constructor (creates Lua state)
+*************************************************************************/
+LuaScriptModule::LuaScriptModule() :
+    d_errFuncIndex(LUA_NOREF),
+    d_activeErrFuncIndex(LUA_NOREF)
+{
+    #if LUA_VERSION_NUM >= 501
+        static const luaL_Reg lualibs[] = {
+            {"", luaopen_base},
+            {LUA_LOADLIBNAME, luaopen_package},
+            {LUA_TABLIBNAME, luaopen_table},
+            {LUA_IOLIBNAME, luaopen_io},
+            {LUA_OSLIBNAME, luaopen_os},
+            {LUA_STRLIBNAME, luaopen_string},
+            {LUA_MATHLIBNAME, luaopen_math},
+        #if defined(DEBUG) || defined (_DEBUG)
+                {LUA_DBLIBNAME, luaopen_debug},
+        #endif
+            {0, 0}
+        };
+    #endif /* LUA_VERSION_NUM >= 501 */
+
+    // create a lua state
+    d_ownsState = true;
+    d_state = lua_open();
+
+    // init all standard libraries
+    #if LUA_VERSION_NUM >= 501
+            const luaL_Reg *lib = lualibs;
+            for (; lib->func; lib++)
+            {
+                lua_pushcfunction(d_state, lib->func);
+                lua_pushstring(d_state, lib->name);
+                lua_call(d_state, 1, 0);
+            }
+    #else /* LUA_VERSION_NUM >= 501 */
+        luaopen_base(d_state);
+        luaopen_io(d_state);
+        luaopen_string(d_state);
+        luaopen_table(d_state);
+        luaopen_math(d_state);
+        #if defined(DEBUG) || defined (_DEBUG)
+            luaopen_debug(d_state);
+        #endif
+    #endif /* LUA_VERSION_NUM >= 501 */
+
+    setModuleIdentifierString();
+}
+
+
+/*************************************************************************
+	Constructor (uses given Lua state)
+*************************************************************************/
+LuaScriptModule::LuaScriptModule(lua_State* state) :
+    d_errFuncIndex(LUA_NOREF),
+    d_activeErrFuncIndex(LUA_NOREF)
+{
+	// just use the given state
+	d_ownsState = false;
+	d_state = state;
+
+	setModuleIdentifierString();
+}
+
+
+/*************************************************************************
+	Destructor
+*************************************************************************/
+LuaScriptModule::~LuaScriptModule()
+{
+    if (d_state)
+    {
+        unrefErrorFunc();
+
+        if (d_ownsState)
+            lua_close( d_state );
+    }
+}
+
+
+/*************************************************************************
+	Execute script file
+*************************************************************************/
+void LuaScriptModule::executeScriptFile(const String& filename,
+    const String& resourceGroup)
+{
+    int top = lua_gettop(d_state);
+
+    executeScriptFile_impl(filename, resourceGroup,
+                           initErrorHandlerFunc(),
+                           top);
+
+    cleanupErrorHandlerFunc();
+}
+
+
+/*************************************************************************
+	Execute global script function
+*************************************************************************/
+int	LuaScriptModule::executeScriptGlobal(const String& function_name)
+{
+    int top = lua_gettop(d_state);
+    int r = executeScriptGlobal_impl(function_name, initErrorHandlerFunc(), top);
+    cleanupErrorHandlerFunc();
+
+    return r;
+}
+
+
+/*************************************************************************
+	Execute scripted event handler
+*************************************************************************/
+bool LuaScriptModule::executeScriptedEventHandler(const String& handler_name,
+    const EventArgs& e)
+{
+    int top = lua_gettop(d_state);
+    bool r = executeScriptedEventHandler_impl(handler_name, e,
+                                              initErrorHandlerFunc(), top);
+    cleanupErrorHandlerFunc();
+
+    return r;
+}
+
+
+/*************************************************************************
+	Execute script code string
+*************************************************************************/
+void LuaScriptModule::executeString(const String& str)
+{
+    int top = lua_gettop(d_state);
+
+    executeString_impl(str, initErrorHandlerFunc(), top);
+    cleanupErrorHandlerFunc();
+}
+
+
+/*************************************************************************
+	Create Lua bindings
+*************************************************************************/
+void LuaScriptModule::createBindings(void)
+{
+	CEGUI::Logger::getSingleton().logEvent( "---- Creating Lua bindings ----" );
+	// init CEGUI module
+	tolua_CEGUI_open(d_state);
+}
+
+
+/*************************************************************************
+	Destroy Lua bindings
+*************************************************************************/
+void LuaScriptModule::destroyBindings(void)
+{
+	CEGUI::Logger::getSingleton().logEvent( "---- Destroying Lua bindings ----" );
+	// is this ok ?
+	lua_pushnil(d_state);
+	lua_setglobal(d_state,"CEGUI");
+}
+
+
+/*************************************************************************
+	Set the ID string for the module
+*************************************************************************/
+void LuaScriptModule::setModuleIdentifierString()
+{
+    // set ID string
+    d_identifierString = "CEGUI::LuaScriptModule - Official Lua based scripting module for CEGUI";
+	d_language = "Lua";
+}
+
+
+/*************************************************************************
+	Subscribe to a scripted event handler
+*************************************************************************/
+Event::Connection LuaScriptModule::subscribeEvent(EventSet* target,
+    const String& event_name, const String& subscriber_name)
+{
+    const String& err_str = getActivePCallErrorHandlerString();
+    const int err_ref     = getActivePCallErrorHandlerReference();
+
+    // do the real subscription
+    LuaFunctor functor((err_ref == LUA_NOREF) ?
+                LuaFunctor(d_state, subscriber_name, LUA_NOREF, err_str) :
+                LuaFunctor(d_state, subscriber_name, LUA_NOREF, err_ref));
+    Event::Connection con =
+        target->subscribeEvent(event_name, Event::Subscriber(functor));
+
+    // make sure we don't release the reference we just made when 'functor' is
+    // destroyed as it goes out of scope.
+    functor.index = LUA_NOREF;
+    functor.d_errFuncIndex = LUA_NOREF;
+
+    // return the event connection
+    return con;
+}
+
+
+/*************************************************************************
+	Subscribe to a scripted event handler
+*************************************************************************/
+Event::Connection LuaScriptModule::subscribeEvent(EventSet* target,
+    const String& event_name, Event::Group group, const String& subscriber_name)
+{
+    const String& err_str = getActivePCallErrorHandlerString();
+    const int err_ref     = getActivePCallErrorHandlerReference();
+
+    // do the real subscription
+    LuaFunctor functor((err_ref == LUA_NOREF) ?
+                LuaFunctor(d_state, subscriber_name, LUA_NOREF, err_str) :
+                LuaFunctor(d_state, subscriber_name, LUA_NOREF, err_ref));
+    Event::Connection con =
+        target->subscribeEvent(event_name, group, Event::Subscriber(functor));
+
+    // make sure we don't release the reference we just made when 'functor' is
+    // destroyed as it goes out of scope.
+    functor.index = LUA_NOREF;
+    functor.d_errFuncIndex = LUA_NOREF;
+
+    // return the event connection
+    return con;
+}
+
+//----------------------------------------------------------------------------//
+void LuaScriptModule::setDefaultPCallErrorHandler(
+    const String& error_handler_function)
+{
+    unrefErrorFunc();
+
+    d_errFuncName = error_handler_function;
+    d_errFuncIndex = LUA_NOREF;
+}
+
+//----------------------------------------------------------------------------//
+void LuaScriptModule::setDefaultPCallErrorHandler(int function_reference)
+{
+    unrefErrorFunc();
+
+    d_errFuncIndex = function_reference;
+    d_errFuncName.clear();
+}
+
+//----------------------------------------------------------------------------//
+const String& LuaScriptModule::getActivePCallErrorHandlerString() const
+{
+    if ((d_activeErrFuncIndex == LUA_NOREF) && d_activeErrFuncName.empty())
+        return d_errFuncName;
+    else
+        return d_activeErrFuncName;
+}
+
+//----------------------------------------------------------------------------//
+int LuaScriptModule::getActivePCallErrorHandlerReference() const
+{
+    if ((d_activeErrFuncIndex == LUA_NOREF) && d_activeErrFuncName.empty())
+        return d_errFuncIndex;
+    else
+        return d_activeErrFuncIndex;
+}
+
+//----------------------------------------------------------------------------//
+int LuaScriptModule::initErrorHandlerFunc()
+{
+    d_activeErrFuncName = d_errFuncName;
+
+    // should we create a registry reference for named function
+    if ((d_errFuncIndex == LUA_NOREF) && !d_errFuncName.empty())
+    {
+        int top = lua_gettop(d_state);
+
+        LuaFunctor::pushNamedFunction(d_state, d_errFuncName);
+        // reference function
+        d_errFuncIndex = luaL_ref(d_state, LUA_REGISTRYINDEX);
+
+        lua_settop(d_state, top);
+    }
+
+    // init handler via function index in registry
+    return initErrorHandlerFunc(d_errFuncIndex);
+}
+
+//----------------------------------------------------------------------------//
+int LuaScriptModule::initErrorHandlerFunc(const String func_name)
+{
+    d_activeErrFuncName = func_name;
+
+    // string has some text in it?
+    if (!func_name.empty())
+    {
+        LuaFunctor::pushNamedFunction(d_state, func_name);
+        return lua_gettop(d_state);
+    }
+
+    // use no error handler function.
+    return 0;
+}
+
+//----------------------------------------------------------------------------//
+int LuaScriptModule::initErrorHandlerFunc(int func)
+{
+    d_activeErrFuncIndex = func;
+
+    // check if we have a valid registry index for the error handler function
+    if (func != LUA_NOREF)
+    {
+        lua_rawgeti(d_state, LUA_REGISTRYINDEX, func);
+        return lua_gettop(d_state);
+    }
+
+    // use no error handler function.
+    return 0;
+}
+
+//----------------------------------------------------------------------------//
+void LuaScriptModule::cleanupErrorHandlerFunc()
+{
+    d_activeErrFuncIndex = LUA_NOREF;
+    d_activeErrFuncName.clear();
+}
+
+//----------------------------------------------------------------------------//
+void LuaScriptModule::unrefErrorFunc()
+{
+    if ((d_errFuncIndex != LUA_NOREF) && !d_errFuncName.empty())
+    {
+        luaL_unref(d_state, LUA_REGISTRYINDEX, d_errFuncIndex);
+        d_errFuncIndex = LUA_NOREF;
+    }
+}
+
+//----------------------------------------------------------------------------//
+void LuaScriptModule::executeScriptFile(const String& filename,
+    const String& resourceGroup, const String& error_handler)
+{
+    int top = lua_gettop(d_state);
+
+    executeScriptFile_impl(filename, resourceGroup,
+                           initErrorHandlerFunc(error_handler),
+                           top);
+    cleanupErrorHandlerFunc();
+}
+
+//----------------------------------------------------------------------------//
+void LuaScriptModule::executeScriptFile(const String& filename,
+    const String& resourceGroup, const int error_handler)
+{
+    int top = lua_gettop(d_state);
+
+    executeScriptFile_impl(filename, resourceGroup,
+                           initErrorHandlerFunc(error_handler),
+                           top);
+    cleanupErrorHandlerFunc();
+}
+
+//----------------------------------------------------------------------------//
+int LuaScriptModule::executeScriptGlobal(const String& function_name,
+    const String& error_handler)
+{
+    int top = lua_gettop(d_state);
+    int r = executeScriptGlobal_impl(function_name,
+                                     initErrorHandlerFunc(error_handler),
+                                     top);
+    cleanupErrorHandlerFunc();
+
+    return r;
+}
+
+//----------------------------------------------------------------------------//
+int LuaScriptModule::executeScriptGlobal(const String& function_name,
+    const int error_handler)
+{
+    int top = lua_gettop(d_state);
+    int r = executeScriptGlobal_impl(function_name,
+                                     initErrorHandlerFunc(error_handler),
+                                     top);
+    cleanupErrorHandlerFunc();
+
+    return r;
+}
+
+//----------------------------------------------------------------------------//
+bool LuaScriptModule::executeScriptedEventHandler(const String& handler_name,
+    const EventArgs& e, const String& error_handler)
+{
+    int top = lua_gettop(d_state);
+
+    bool r =executeScriptedEventHandler_impl(handler_name, e,
+                                             initErrorHandlerFunc(error_handler),
+                                             top);
+    cleanupErrorHandlerFunc();
+
+    return r;
+}
+
+//----------------------------------------------------------------------------//
+bool LuaScriptModule::executeScriptedEventHandler(const String& handler_name,
+    const EventArgs& e, const int error_handler)
+{
+    int top = lua_gettop(d_state);
+    bool r = executeScriptedEventHandler_impl(handler_name, e,
+                                              initErrorHandlerFunc(error_handler),
+                                              top);
+    cleanupErrorHandlerFunc();
+
+    return r;
+}
+
+//----------------------------------------------------------------------------//
+void LuaScriptModule::executeString(const String& str,
+    const String& error_handler)
+{
+    int top = lua_gettop(d_state);
+
+    executeString_impl(str, initErrorHandlerFunc(error_handler), top);
+    cleanupErrorHandlerFunc();
+}
+
+//----------------------------------------------------------------------------//
+void LuaScriptModule::executeString(const String& str, const int error_handler)
+{
+    int top = lua_gettop(d_state);
+
+    executeString_impl(str, initErrorHandlerFunc(error_handler), top);
+    cleanupErrorHandlerFunc();
+}
+
+//----------------------------------------------------------------------------//
+Event::Connection LuaScriptModule::subscribeEvent(EventSet* target,
+    const String& event_name, const String& subscriber_name,
+    const String& error_handler)
+{
+    // do the real subscription
+    LuaFunctor functor(d_state, subscriber_name, LUA_NOREF, error_handler);
+    Event::Connection con =
+        target->subscribeEvent(event_name, Event::Subscriber(functor));
+
+    // make sure we don't release the references we just made when 'functor' is
+    // destroyed as it goes out of scope.
+    functor.index = LUA_NOREF;
+    functor.d_errFuncIndex = LUA_NOREF;
+
+    // return the event connection
+    return con;
+}
+
+//----------------------------------------------------------------------------//
+Event::Connection LuaScriptModule::subscribeEvent(EventSet* target,
+    const String& event_name, const String& subscriber_name,
+    const int error_handler)
+{
+    // do the real subscription
+    LuaFunctor functor(d_state, subscriber_name, LUA_NOREF, error_handler);
+    Event::Connection con =
+        target->subscribeEvent(event_name, Event::Subscriber(functor));
+
+    // make sure we don't release the references we just made when 'functor' is
+    // destroyed as it goes out of scope.
+    functor.index = LUA_NOREF;
+    functor.d_errFuncIndex = LUA_NOREF;
+
+    // return the event connection
+    return con;
+}
+
+
+//----------------------------------------------------------------------------//
+Event::Connection LuaScriptModule::subscribeEvent(EventSet* target,
+    const String& event_name, Event::Group group, const String& subscriber_name,
+    const String& error_handler)
+{
+    // do the real subscription
+    LuaFunctor functor(d_state, subscriber_name, LUA_NOREF, error_handler);
+    Event::Connection con =
+        target->subscribeEvent(event_name, group, Event::Subscriber(functor));
+
+    // make sure we don't release the references we just made when 'functor' is
+    // destroyed as it goes out of scope.
+    functor.index = LUA_NOREF;
+    functor.d_errFuncIndex = LUA_NOREF;
+
+    // return the event connection
+    return con;
+}
+
+//----------------------------------------------------------------------------//
+Event::Connection LuaScriptModule::subscribeEvent(EventSet* target,
+    const String& event_name, Event::Group group, const String& subscriber_name,
+    const int error_handler)
+{
+    // do the real subscription
+    LuaFunctor functor(d_state, subscriber_name, LUA_NOREF, error_handler);
+    Event::Connection con =
+        target->subscribeEvent(event_name, group, Event::Subscriber(functor));
+
+    // make sure we don't release the references we just made when 'functor' is
+    // destroyed as it goes out of scope.
+    functor.index = LUA_NOREF;
+    functor.d_errFuncIndex = LUA_NOREF;
+
+    // return the event connection
+    return con;
+}
+
+//----------------------------------------------------------------------------//
+void LuaScriptModule::executeScriptFile_impl(const String& filename,
+    const String& resourceGroup, const int err_idx, const int top)
+{
+    // load file
+    RawDataContainer raw;
+    System::getSingleton().getResourceProvider()->loadRawDataContainer(filename,
+        raw, resourceGroup.empty() ? d_defaultResourceGroup : resourceGroup);
+
+    // load code into lua
+    int loaderr = luaL_loadbuffer(d_state,
+                                  reinterpret_cast<char*>(raw.getDataPtr()),
+                                  raw.getSize(), filename.c_str());
+
+    System::getSingleton().getResourceProvider()->unloadRawDataContainer( raw );
+
+    if (loaderr)
+    {
+        String errMsg = lua_tostring(d_state,-1);
+        lua_settop(d_state,top);
+        throw ScriptException("Unable to execute Lua script file: '" +
+                              filename + "'\n\n" + errMsg + "\n");
+    }
+
+    // call it
+    if (lua_pcall(d_state, 0, 0, err_idx))
+    {
+        String errMsg = lua_tostring(d_state,-1);
+        lua_settop(d_state,top);
+        throw ScriptException("Unable to execute Lua script file: '" +
+                              filename + "'\n\n" + errMsg + "\n");
+    }
+
+    lua_settop(d_state,top); // just in case :P
+}
+
+//----------------------------------------------------------------------------//
+int LuaScriptModule::executeScriptGlobal_impl(const String& function_name,
+    const int err_idx, const int top)
+{
+    // get the function from lua
+    lua_getglobal(d_state, function_name.c_str());
+
+    // is it a function
+    if (!lua_isfunction(d_state,-1))
+    {
+        lua_settop(d_state,top);
+        throw ScriptException("Unable to get Lua global: '" + function_name +
+                              "' as name not represent a global Lua function" );
+    }
+
+    // call it
+    int error = lua_pcall(d_state, 0, 1, err_idx);
+
+    // handle errors
+    if (error)
+    {
+        String errMsg = lua_tostring(d_state,-1);
+        lua_settop(d_state,top);
+        throw ScriptException("Unable to evaluate Lua global: '" + 
+                              function_name + "\n\n" + errMsg + "\n");
+    }
+
+    // get return value
+    if (!lua_isnumber(d_state,-1))
+    {
+        // log that return value is invalid. return -1 and move on.
+        lua_settop(d_state,top);
+        ScriptException("Unable to get Lua global : '" + function_name +
+                        "' return value as it's not a number");
+        return -1;
+    }
+
+    int ret = static_cast<int>(lua_tonumber(d_state,-1));
+    lua_settop(d_state,top);
+
+    // return it
+    return ret;
+}
+
+//----------------------------------------------------------------------------//
+bool LuaScriptModule::executeScriptedEventHandler_impl(
+    const String& handler_name, const EventArgs& e, const int err_idx,
+    const int top)
+{
+    LuaFunctor::pushNamedFunction(d_state, handler_name);
+
+    ScriptWindowHelper* helper = 0;
+    // If this is an event that was triggered by a window then make a "this"
+    // pointer to the window for the script.
+    if(e.d_hasWindow)
+    {
+        WindowEventArgs& we = (WindowEventArgs&)e;
+        helper = new ScriptWindowHelper(we.window);
+        lua_pushlightuserdata(d_state,(void*)helper);
+        lua_setglobal(d_state,"this");
+    }
+
+    // push EventArgs as the first parameter
+    tolua_pushusertype(d_state, (void*)&e, "const CEGUI::EventArgs");
+
+    // call it
+    int error = lua_pcall(d_state, 1, 1, err_idx);
+
+    // handle errors
+    if (error)
+    {
+        String errStr(lua_tostring(d_state,-1));
+        lua_settop(d_state,top);
+        //cleanup the helper object if any
+        if(helper)
+        {
+            delete helper;
+            helper = 0;
+        }
+
+        throw ScriptException("Unable to evaluate the Lua event handler: '" +
+                              handler_name + "'\n\n" + errStr + "\n");
+    }
+
+    // retrieve result
+    bool ret = lua_isboolean(d_state, -1) ? lua_toboolean(d_state, -1 ) : true;
+    lua_settop(d_state,top);
+
+    if(helper)
+    {
+        delete helper;
+        helper = 0;
+    }
+
+    return ret;
+}
+
+//----------------------------------------------------------------------------//
+void LuaScriptModule::executeString_impl(const String& str, const int err_idx,
+    const int top)
+{
+    // load code into lua and call it
+    int error = luaL_loadbuffer(d_state, str.c_str(), str.length(), str.c_str()) ||
+                lua_pcall(d_state, 0, 0, err_idx);
+
+    // handle errors
+    if (error)
+    {
+        String errMsg = lua_tostring(d_state,-1);
+        lua_settop(d_state,top);
+        throw ScriptException("Unable to execute Lua script string: '" +
+                              str + "'\n\n" + errMsg + "\n");
+    }
+
+    lua_settop(d_state,top);
+}
+
+//----------------------------------------------------------------------------//
+
+
+} // namespace CEGUI
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/CEGUILua.h
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/CEGUILua.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/CEGUILua.h	(revision 6952)
@@ -0,0 +1,674 @@
+/***********************************************************************
+	filename: CEGUILua.h
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+	
+	purpose:  Defines interface for LuaScriptModule class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2008 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#ifndef _CEGUILua_h_
+#define _CEGUILua_h_
+
+
+/*************************************************************************
+	Import / Export control macros
+*************************************************************************/
+#if (defined( __WIN32__ ) || defined( _WIN32 )) && !defined(CEGUI_STATIC)
+#   ifdef CEGUILUA_EXPORTS
+#       define CEGUILUA_API __declspec(dllexport)
+#   else
+#       if defined( __MINGW32__ )
+#           define CEGUILUA_API
+#       else
+#           define CEGUILUA_API __declspec(dllimport)
+#       endif
+#   endif
+#else
+#   define CEGUILUA_API
+#endif
+
+
+#include "CEGUIScriptModule.h"
+
+struct lua_State;
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*!
+\brief
+	Interface for the LuaScriptModule class
+*/
+class CEGUILUA_API LuaScriptModule : public CEGUI::ScriptModule
+{
+public:
+	/*************************************************************************
+		Construction and Destruction
+	*************************************************************************/
+	/*!
+	\brief
+		Constructor for LuaScriptModule class which create a lua_State
+	*/
+	LuaScriptModule();
+
+
+	/*!
+	\brief
+		Constructor for LuaScriptModule class which takes a lua_State
+
+	\param state
+		Pointer to the lua_State that the script module should attach to.
+	*/
+	LuaScriptModule(lua_State* state);
+
+
+	/*!
+	\brief
+		Destructor for LuaScriptModule class.
+	*/
+	~LuaScriptModule();
+
+
+	/*************************************************************************
+		Script Execution Functions
+	*************************************************************************/
+    /*!
+    \brief
+        Execute a script file.
+
+    \param filename
+        String object holding the filename of the script file that is to be
+        executed.
+
+    \param resourceGroup
+        Resource group idendifier to be passed to the ResourceProvider when
+        loading the script file.
+    */
+    void executeScriptFile(const String& filename, const String& resourceGroup);
+
+    /*!
+    \brief
+        Execute a script file.
+
+    \param filename
+        String object holding the filename of the script file that is to be
+        executed.
+
+    \param resourceGroup
+        Resource group idendifier to be passed to the ResourceProvider when
+        loading the script file.
+
+    \param error_handler
+        String containing the name of the script fuction that will be called
+        if an error occurs while executing the handler function.  NB: This is
+        the function passed as the error handler to lua_pcall.
+    */
+    void executeScriptFile(const String& filename,
+                           const String& resourceGroup,
+                           const String& error_handler);
+
+    /*!
+    \brief
+        Execute a script file.
+
+    \param filename
+        String object holding the filename of the script file that is to be
+        executed.
+
+    \param resourceGroup
+        Resource group idendifier to be passed to the ResourceProvider when
+        loading the script file.
+
+    \param error_handler
+        integer value describing a lua registry reference to the function that
+        will be called if an error occurs while executing the handler function.
+        NB: This is the function passed as the error handler to lua_pcall.
+    */
+    void executeScriptFile(const String& filename,
+                           const String& resourceGroup,
+                           const int error_handler);
+
+    /*!
+    \brief
+        Execute a scripted global function.  The function should not take any
+        parameters and should return an integer.
+
+    \param function_name
+        String object holding the name of the function, in the global script
+        environment, that is to be executed.
+
+    \return
+        The integer value returned from the script function.
+    */
+    int executeScriptGlobal(const String& function_name);
+
+    /*!
+    \brief
+        Execute a scripted global function.  The function should not take any
+        parameters and should return an integer.
+
+    \param function_name
+        String object holding the name of the function, in the global script
+        environment, that is to be executed.
+
+    \param error_handler
+        String containing the name of the script fuction that will be called
+        if an error occurs while executing the handler function.  NB: This is
+        the function passed as the error handler to lua_pcall.
+
+    \return
+        The integer value returned from the script function.
+    */
+    int executeScriptGlobal(const String& function_name,
+                            const String& error_handler);
+
+    /*!
+    \brief
+        Execute a scripted global function.  The function should not take any
+        parameters and should return an integer.
+
+    \param function_name
+        String object holding the name of the function, in the global script
+        environment, that is to be executed.
+
+    \param error_handler
+        integer value describing a lua registry reference to the function that
+        will be called if an error occurs while executing the handler function.
+        NB: This is the function passed as the error handler to lua_pcall.
+
+    \return
+        The integer value returned from the script function.
+    */
+    int executeScriptGlobal(const String& function_name,
+                            const int error_handler);
+
+
+    /*!
+    \brief
+        Execute a scripted global 'event handler' function by looking it up by
+        name.
+
+    \param handler_name
+        String object holding the name of the scripted handler function.
+        If this string contains dots '.' it will be parsed as tables containing
+        a function field.  For example: 'mytable.subtable.func'
+
+    \param e
+        EventArgs based object that should be passed, by any appropriate means,
+        to the scripted function.
+
+    \return
+        - true if the event was handled.
+        - false if the event was not handled.
+    */
+    bool executeScriptedEventHandler(const String& handler_name,
+                                     const EventArgs& e);
+
+    /*!
+    \brief
+        Execute a scripted global 'event handler' function by looking it up by
+        name.
+
+    \param handler_name
+        String object holding the name of the scripted handler function.
+        If this string contains dots '.' it will be parsed as tables containing
+        a function field.  For example: 'mytable.subtable.func'
+
+    \param e
+        EventArgs based object that should be passed, by any appropriate means,
+        to the scripted function.
+
+    \param error_handler
+        String containing the name of the script fuction that will be called
+        if an error occurs while executing the handler function.  NB: This is
+        the function passed as the error handler to lua_pcall.
+
+    \return
+        - true if the event was handled.
+        - false if the event was not handled.
+    */
+    bool executeScriptedEventHandler(const String& handler_name,
+                                     const EventArgs& e,
+                                     const String& error_handler);
+
+    /*!
+    \brief
+        Execute a scripted global 'event handler' function by looking it up by
+        name.
+
+    \param handler_name
+        String object holding the name of the scripted handler function.
+        If this string contains dots '.' it will be parsed as tables containing
+        a function field.  For example: 'mytable.subtable.func'
+
+    \param e
+        EventArgs based object that should be passed, by any appropriate means,
+        to the scripted function.
+
+    \param error_handler
+        integer value describing a lua registry reference to the function that
+        will be called if an error occurs while executing the handler function.
+        NB: This is the function passed as the error handler to lua_pcall.
+
+    \return
+        - true if the event was handled.
+        - false if the event was not handled.
+    */
+    bool executeScriptedEventHandler(const String& handler_name,
+                                     const EventArgs& e,
+                                     const int error_handler);
+
+    /*!
+    \brief
+        Execute script code contained in the given CEGUI::String object.
+
+    \param str
+        String object holding the valid script code that should be executed.
+
+    \return
+        Nothing.
+    */
+    void executeString(const String& str);
+
+    /*!
+    \brief
+        Execute script code contained in the given CEGUI::String object.
+
+    \param str
+        String object holding the valid script code that should be executed.
+
+    \param error_handler
+        String containing the name of the script fuction that will be called
+        if an error occurs while executing the handler function.  NB: This is
+        the function passed as the error handler to lua_pcall.
+
+    \return
+        Nothing.
+    */
+    void executeString(const String& str, const String& error_handler);
+
+    /*!
+    \brief
+        Execute script code contained in the given CEGUI::String object.
+
+    \param str
+        String object holding the valid script code that should be executed.
+
+    \param error_handler
+        integer value describing a lua registry reference to the function that
+        will be called if an error occurs while executing the handler function.
+        NB: This is the function passed as the error handler to lua_pcall.
+
+    \return
+        Nothing.
+    */
+    void executeString(const String& str, const int error_handler);
+
+    /*************************************************************************
+        Event subscription
+    *************************************************************************/
+    /*!
+    \brief
+        Subscribes the named Event to a scripted funtion
+
+    \param target
+        The target EventSet for the subscription.
+
+    \param name
+        String object containing the name of the Event to subscribe to.
+
+    \param subscriber_name
+        String object containing the name of the script funtion that is to be
+        subscribed to the Event.
+
+    \return
+        Connection object that can be used to check the status of the Event
+        connection and to disconnect (unsubscribe) from the Event.
+    */
+    Event::Connection subscribeEvent(EventSet* target, const String& name,
+                                     const String& subscriber_name);
+
+    /*!
+    \brief
+        Subscribes the named Event to a scripted funtion
+
+    \param target
+        The target EventSet for the subscription.
+
+    \param name
+        String object containing the name of the Event to subscribe to.
+
+    \param subscriber_name
+        String object containing the name of the script funtion that is to be
+        subscribed to the Event.
+
+    \param error_handler
+        String containing the name of the script fuction that will be called
+        if an error occurs while executing the handler function.  NB: This is
+        the function passed as the error handler to lua_pcall.
+
+    \return
+        Connection object that can be used to check the status of the Event
+        connection and to disconnect (unsubscribe) from the Event.
+    */
+    Event::Connection subscribeEvent(EventSet* target, const String& name,
+                                     const String& subscriber_name,
+                                     const String& error_handler);
+
+    /*!
+    \brief
+        Subscribes the named Event to a scripted funtion
+
+    \param target
+        The target EventSet for the subscription.
+
+    \param name
+        String object containing the name of the Event to subscribe to.
+
+    \param subscriber_name
+        String object containing the name of the script funtion that is to be
+        subscribed to the Event.
+
+    \param error_handler
+        integer value describing a lua registry reference to the function that
+        will be called if an error occurs while executing the handler function.
+        NB: This is the function passed as the error handler to lua_pcall.
+
+    \return
+        Connection object that can be used to check the status of the Event
+        connection and to disconnect (unsubscribe) from the Event.
+    */
+    Event::Connection subscribeEvent(EventSet* target, const String& name,
+                                     const String& subscriber_name,
+                                     const int error_handler);
+
+    /*!
+    \brief
+        Subscribes the specified group of the named Event to a scripted funtion.
+
+    \param target
+        The target EventSet for the subscription.
+
+    \param name
+        String object containing the name of the Event to subscribe to.
+
+    \param group
+        Group which is to be subscribed to.  Subscription groups are called in
+        ascending order.
+
+    \param subscriber_name
+        String object containing the name of the script funtion that is to be
+        subscribed to the Event.
+
+    \return
+        Connection object that can be used to check the status of the Event
+        connection and to disconnect (unsubscribe) from the Event.
+    */
+    Event::Connection	subscribeEvent(EventSet* target, const String& name,
+                                       Event::Group group,
+                                       const String& subscriber_name);
+
+    /*!
+    \brief
+        Subscribes the specified group of the named Event to a scripted funtion.
+
+    \param target
+        The target EventSet for the subscription.
+
+    \param name
+        String object containing the name of the Event to subscribe to.
+
+    \param group
+        Group which is to be subscribed to.  Subscription groups are called in
+        ascending order.
+
+    \param subscriber_name
+        String object containing the name of the script funtion that is to be
+        subscribed to the Event.
+
+    \param error_handler
+        String containing the name of the script fuction that will be called
+        if an error occurs while executing the handler function.  NB: This is
+        the function passed as the error handler to lua_pcall.
+
+    \return
+        Connection object that can be used to check the status of the Event
+        connection and to disconnect (unsubscribe) from the Event.
+    */
+    Event::Connection subscribeEvent(EventSet* target, const String& name,
+                                     Event::Group group,
+                                     const String& subscriber_name,
+                                     const String& error_handler);
+
+    /*!
+    \brief
+        Subscribes the specified group of the named Event to a scripted funtion.
+
+    \param target
+        The target EventSet for the subscription.
+
+    \param name
+        String object containing the name of the Event to subscribe to.
+
+    \param group
+        Group which is to be subscribed to.  Subscription groups are called in
+        ascending order.
+
+    \param subscriber_name
+        String object containing the name of the script funtion that is to be
+        subscribed to the Event.
+
+    \param error_handler
+        integer value describing a lua registry reference to the function that
+        will be called if an error occurs while executing the handler function.
+        NB: This is the function passed as the error handler to lua_pcall.
+
+    \return
+        Connection object that can be used to check the status of the Event
+        connection and to disconnect (unsubscribe) from the Event.
+    */
+    Event::Connection subscribeEvent(EventSet* target, const String& name,
+                                     Event::Group group,
+                                     const String& subscriber_name,
+                                     const int error_handler);
+
+    /*************************************************************************
+        Bindings creation / destruction
+    *************************************************************************/
+    /*!
+    \brief
+        Method called during system initialisation, prior to running any scripts
+        via the ScriptModule, to enable the ScriptModule to perform any
+        operations required to complete initialisation or binding of the script
+        language to the gui system objects.
+
+    \return
+        Nothing.
+    */
+    void createBindings(void);
+
+    /*!
+    \brief
+        Method called during system destruction, after all scripts have been run
+        via the ScriptModule, to enable the ScriptModule to perform any
+        operations required to cleanup bindings of the script language to the
+        gui system objects, as set-up in the earlier createBindings call.
+
+    \return
+        Nothing.
+    */
+    void destroyBindings(void);
+
+    /*************************************************************************
+        Accessor type functions
+    *************************************************************************/
+    /*!
+    \brief
+        Method used to get a pointer to the lua_State that the script module is
+        attached to.
+
+    \return
+        A pointer to the lua_State that the script module is attached to.
+    */
+    lua_State* getLuaState(void) const {return d_state;}
+
+    /*************************************************************************
+        Lua error handler related functions
+    *************************************************************************/
+    /*!
+    \brief
+        Set the name of the lua function that will be passed as the error
+        handler in calls to lua_pcall, unless an alternative is specified
+        in some other function call.
+
+    \param error_handler_function
+        Name of the lua function to be called.  This is looked up / bound on
+        first usage.
+    */
+    void setDefaultPCallErrorHandler(const String& error_handler_function);
+
+    /*!
+    \brief
+        Set the function that will be passed as the error handler in calls to
+        lua_pcall, unless an alternative is specified in some other function
+        call.
+
+    \param function_reference
+        Lua function registry index of the function to be called.
+    */
+    void setDefaultPCallErrorHandler(int function_reference);
+
+    /*!
+    \brief
+        Return the function name string of the active error handler function.
+
+        The 'active' error handler for the LuaScriptModule is either the
+        default as specified by calling setDefaultPCallErrorHandler, or
+        whatever might have been set up by a call to the internal
+        initErrorHandlerFunc function.
+
+    \note
+        This function is really intended for use internally by other parts of
+        the lua scripting support.  Although it could be useful elsewhere for
+        advanced uses, so long as you're careful!
+    */
+    const String& getActivePCallErrorHandlerString() const;
+
+    /*!
+    \brief
+        return the lua registry index of the active error handler function.
+
+        The 'active' error handler for the LuaScriptModule is either the
+        default as specified by calling setDefaultPCallErrorHandler, or
+        whatever might have been set up by a call to the internal
+        initErrorHandlerFunc function.
+        \par This may return a value previously set by the user, or the value as
+        bound internally by the script module for an error handler specified by
+        function name.
+
+    \note
+        This function is really intended for use internally by other parts of
+        the lua scripting support.  Although it could be useful elsewhere for
+        advanced uses, so long as you're careful!
+
+    \warning
+        You should never call luaL_unref on the value returned by this function
+        unless you created tge reference in the first place, and even then only
+        after having called setDefaultPCallErrorHandler passing LUA_NOREF.
+    */
+    int getActivePCallErrorHandlerReference() const;
+
+private:
+    /*************************************************************************
+        Implementation Functions
+    *************************************************************************/
+    void setModuleIdentifierString();
+    /** Init the error handler function.  Return the lua stack index that
+     *  should be passed to lua_pcall.  NB: This should be called prior to
+     *  pushing any function parameters onto the lua stack.
+     */
+    int initErrorHandlerFunc();
+    /** Init the error handler function.  Return the lua stack index that
+     *  should be passed to lua_pcall.  NB: This should be called prior to
+     *  pushing any function parameters onto the lua stack.
+     */
+    int initErrorHandlerFunc(const String func_name);
+    /** Init the error handler function.  Return the lua stack index that
+     *  should be passed to lua_pcall.  NB: This should be called prior to
+     *  pushing any function parameters onto the lua stack.
+     */
+    int initErrorHandlerFunc(int func);
+
+    /** do any needed cleanup after having called initErrorHandlerFunc and
+     * (possible) executed a script.
+     *
+     * NB: This probably does less than you think ;)
+     */
+    void cleanupErrorHandlerFunc();
+
+    //! release any reference we might have made to an error handling function.
+    void unrefErrorFunc();
+
+    //! Implementation function that executes a scipt file.
+    void executeScriptFile_impl(const String& filename,
+                                const String& resourceGroup,
+                                const int err_idx, const int top);
+
+    //! Implementation function that executes a global script function.
+    int executeScriptGlobal_impl(const String& function_name,
+                                 const int err_idx, const int top);
+
+    //! Implementation function that executes a scripted event handler.
+    bool executeScriptedEventHandler_impl(const String& handler_name,
+                                          const EventArgs& e,
+                                          const int err_idx, const int top);
+
+    //! Implementation function that executes script contained in a String.
+    void executeString_impl(const String& str, const int err_idx, const int top);
+
+    /*************************************************************************
+        Implementation Data
+    *************************************************************************/
+    //! true when the attached lua_State was created by this script module
+    bool d_ownsState;
+    //! The lua_State that this script module uses.
+    lua_State* d_state;
+    //! Default error handler function to pass to lua_pcall.
+    String d_errFuncName;
+    //! Default registry index of the function to pass to lua_pcall.
+    int d_errFuncIndex;
+    /** Error handler function that is currently in use (as setup via a call
+        to initErrorHandlerFunc)
+    */
+    String d_activeErrFuncName;
+    /** Registry index of the function that is currently in use (as setup via a
+        call to initErrorHandlerFunc)
+    */
+    int d_activeErrFuncIndex;
+};
+
+} // namespace CEGUI
+
+#endif // end of guard _CEGUILua_h_
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/CEGUILuaFunctor.cpp
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/CEGUILuaFunctor.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/CEGUILuaFunctor.cpp	(revision 6952)
@@ -0,0 +1,430 @@
+/***********************************************************************
+    filename: CEGUILuaFunctor.cpp
+    created:  Thu Jan 26 2006
+    author:   Tomas Lindquist Olsen <tomas@famolsen.dk>
+
+    purpose:  Implementation for LuaFunctor class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2008 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUILuaFunctor.h"
+#include "CEGUILogger.h"
+#include "CEGUIExceptions.h"
+#include "CEGUIPropertyHelper.h"
+#include "CEGUILua.h"
+
+// include Lua libs and tolua++
+extern "C" {
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+}
+
+#include "tolua/tolua++.h"
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*************************************************************************
+    Constructor
+*************************************************************************/
+LuaFunctor::LuaFunctor(lua_State* state, int func, int selfIndex) :
+    L(state),
+    index(func),
+    self(selfIndex),
+    needs_lookup(false),
+    d_ourErrFuncIndex(false)
+{
+    // TODO: This would perhaps be better done another way, to avoid the
+    // TODO: interdependence.
+    LuaScriptModule* sm =
+        static_cast<LuaScriptModule*>(System::getSingleton().getScriptingModule());
+
+    if (sm)
+    {
+        d_errFuncName  = sm->getActivePCallErrorHandlerString();
+        d_errFuncIndex = sm->getActivePCallErrorHandlerReference();
+    }
+}
+
+/*************************************************************************
+    Constructor
+*************************************************************************/
+LuaFunctor::LuaFunctor(lua_State* state, const String& func, int selfIndex) :
+    L(state),
+    index(LUA_NOREF),
+    self(selfIndex),
+    needs_lookup(true),
+    function_name(func),
+    d_ourErrFuncIndex(false)
+{
+    // TODO: This would perhaps be better done another way, to avoid the
+    // TODO: interdependence.
+    LuaScriptModule* sm =
+        static_cast<LuaScriptModule*>(System::getSingleton().getScriptingModule());
+
+    if (sm)
+    {
+        d_errFuncName  = sm->getActivePCallErrorHandlerString();
+        d_errFuncIndex = sm->getActivePCallErrorHandlerReference();
+    }
+}
+
+/*************************************************************************
+    Constructor
+*************************************************************************/
+LuaFunctor::LuaFunctor(const LuaFunctor& cp) :
+    L(cp.L),
+    index(cp.index),
+    self(cp.self),
+    needs_lookup(cp.needs_lookup),
+    function_name(cp.function_name),
+    d_errFuncName(cp.d_errFuncName),
+    d_errFuncIndex(cp.d_errFuncIndex),
+    d_ourErrFuncIndex(cp.d_ourErrFuncIndex)
+{
+}
+
+/*************************************************************************
+    Destructor
+*************************************************************************/
+LuaFunctor::~LuaFunctor()
+{
+    if (self != LUA_NOREF)
+        luaL_unref(L, LUA_REGISTRYINDEX, self);
+
+    if (index != LUA_NOREF)
+        luaL_unref(L, LUA_REGISTRYINDEX, index);
+
+    if (d_ourErrFuncIndex &&
+        (d_errFuncIndex != LUA_NOREF) &&
+        !d_errFuncName.empty())
+            luaL_unref(L, LUA_REGISTRYINDEX, d_errFuncIndex);
+}
+
+/*************************************************************************
+    Call operator
+*************************************************************************/
+bool LuaFunctor::operator()(const EventArgs& args) const
+{
+    // named error handler needs binding?
+    if ((d_errFuncIndex == LUA_NOREF) && !d_errFuncName.empty())
+    {
+        pushNamedFunction(L, d_errFuncName);
+        d_errFuncIndex = luaL_ref(L, LUA_REGISTRYINDEX);
+        d_ourErrFuncIndex = true;
+    }
+
+    // is this a late binding?
+    if (needs_lookup)
+    {
+        pushNamedFunction(L, function_name);
+        // reference function
+        index = luaL_ref(L, LUA_REGISTRYINDEX);
+        needs_lookup = false;
+        CEGUI_LOGINSANE("Late binding of callback '"+function_name+"' performed");
+        function_name.clear();
+    } // if (needs_lookup)
+
+    // put error handler on stack if we're using such a thing
+    int err_idx = 0;
+    if (d_errFuncIndex != LUA_NOREF)
+    {
+        lua_rawgeti(L, LUA_REGISTRYINDEX, d_errFuncIndex);
+        err_idx = lua_gettop(L);
+    }
+
+	ScriptWindowHelper* helper = 0;
+	//Set a global for this window
+	if(args.d_hasWindow)
+	{
+		WindowEventArgs& we = (WindowEventArgs&)args;
+		helper = new ScriptWindowHelper(we.window);
+		tolua_pushusertype(L,(void*)helper,"CEGUI::ScriptWindowHelper");
+		lua_setglobal(L,"this");
+	}
+
+    // retrieve function
+    lua_rawgeti(L, LUA_REGISTRYINDEX, index);
+
+    // possibly self as well?
+    int nargs = 1;
+    if (self != LUA_NOREF)
+    {
+        lua_rawgeti(L, LUA_REGISTRYINDEX, self);
+        ++nargs;
+    }
+
+    // push EventArgs  parameter
+    tolua_pushusertype(L, (void*)&args, "const CEGUI::EventArgs");
+
+    // call it
+    int error = lua_pcall(L, nargs, 1, err_idx);
+
+    // handle errors
+    if (error)
+    {
+        String errStr(lua_tostring(L, -1));
+        lua_pop(L, 1);
+		if(helper)
+		{
+			delete helper;
+			helper = 0;
+		}
+        throw ScriptException("Unable to call Lua event handler:\n\n"+errStr+"\n");
+    } // if (error)
+
+    // retrieve result
+    bool ret = lua_isboolean(L, -1) ? lua_toboolean(L, -1 ) : true;
+    lua_pop(L, 1);
+
+    // remove error handler from stack
+    if (err_idx != 0)
+        lua_remove(L, err_idx);
+
+	if(helper)
+	{
+		delete helper;
+		helper = 0;
+	}
+
+    return ret;
+}
+
+/*************************************************************************
+    Pushes a named function on the stack
+*************************************************************************/
+void LuaFunctor::pushNamedFunction(lua_State* L, const String& handler_name)
+{
+    int top = lua_gettop(L);
+
+    // do we have any dots in the handler name? if so we grab the function as a table field
+    String::size_type i = handler_name.find_first_of((utf32)'.');
+    if (i!=String::npos)
+    {
+        // split the rest of the string up in parts seperated by '.'
+        // TODO: count the dots and size the vector accordingly from the beginning.
+        std::vector<String> parts;
+        String::size_type start = 0;
+        do
+        {
+            parts.push_back(handler_name.substr(start,i-start));
+            start = i+1;
+            i = handler_name.find_first_of((utf32)'.',start);
+        } while(i!=String::npos);
+
+        // add last part
+        parts.push_back(handler_name.substr(start));
+
+        // first part is the global
+        lua_getglobal(L, parts[0].c_str());
+        if (!lua_istable(L,-1))
+        {
+            lua_settop(L,top);
+            throw ScriptException("Unable to get the Lua event handler: '"+handler_name+"' as first part is not a table");
+        }
+
+        // if there is more than two parts, we have more tables to go through
+        std::vector<String>::size_type visz = parts.size();
+        if (visz-- > 2) // avoid subtracting one later on
+        {
+            // go through all the remaining parts to (hopefully) have a valid Lua function in the end
+            std::vector<String>::size_type vi = 1;
+            while (vi<visz)
+            {
+                // push key, and get the next table
+                lua_pushstring(L,parts[vi].c_str());
+                lua_gettable(L,-2);
+                if (!lua_istable(L,-1))
+                {
+                    lua_settop(L,top);
+                    throw ScriptException("Unable to get the Lua event handler: '"+handler_name+"' as part #"+PropertyHelper::uintToString(uint(vi+1))+" ("+parts[vi]+") is not a table");
+                }
+                // get rid of the last table and move on
+                lua_remove(L,-2);
+                vi++;
+            }
+        }
+
+        // now we are ready to get the function to call ... phew :)
+        lua_pushstring(L,parts[visz].c_str());
+        lua_gettable(L,-2);
+        lua_remove(L,-2); // get rid of the table
+    }
+    // just a regular global function
+    else
+    {
+        lua_getglobal(L, handler_name.c_str());
+    }
+
+    // is it a function
+    if (!lua_isfunction(L,-1))
+    {
+        lua_settop(L,top);
+        throw ScriptException("The Lua event handler: '"+handler_name+"' does not represent a Lua function");
+    }
+}
+
+//----------------------------------------------------------------------------//
+LuaFunctor::LuaFunctor(lua_State* state, const int func, const int selfIndex,
+    const String& error_handler) :
+    // State initialisation
+    L(state),
+    index(func),
+    self(selfIndex),
+    needs_lookup(false),
+    d_errFuncName(error_handler),
+    d_errFuncIndex(LUA_NOREF),
+    d_ourErrFuncIndex(false)
+{
+}
+
+//----------------------------------------------------------------------------//
+LuaFunctor::LuaFunctor(lua_State* state, const String& func, const int selfIndex,
+    const String& error_handler) :
+    // State initialisation
+    L(state),
+    index(LUA_NOREF),
+    self(selfIndex),
+    needs_lookup(true),
+    function_name(func),
+    d_errFuncName(error_handler),
+    d_errFuncIndex(LUA_NOREF),
+    d_ourErrFuncIndex(false)
+{
+}
+
+//----------------------------------------------------------------------------//
+LuaFunctor::LuaFunctor(lua_State* state, const int func, const int selfIndex,
+    const int error_handler) :
+    // State initialisation
+    L(state),
+    index(func),
+    self(selfIndex),
+    needs_lookup(false),
+    d_errFuncIndex(error_handler),
+    d_ourErrFuncIndex(false)
+{
+}
+
+//----------------------------------------------------------------------------//
+LuaFunctor::LuaFunctor(lua_State* state, const String& func, const int selfIndex,
+    const int error_handler) :
+    // State initialisation
+    L(state),
+    index(LUA_NOREF),
+    self(selfIndex),
+    needs_lookup(true),
+    function_name(func),
+    d_errFuncIndex(error_handler),
+    d_ourErrFuncIndex(false)
+{
+}
+
+//----------------------------------------------------------------------------//
+Event::Connection LuaFunctor::SubscribeEvent(EventSet* self,
+    const String& event_name, const int funcIndex, const int selfIndex,
+    const int error_handler, lua_State* L)
+{
+    // deal with error handler function
+    int err_idx = LUA_NOREF;
+    String err_str;
+    if (error_handler != LUA_NOREF)
+    {
+        int err_handler_type = lua_type(L,-1);
+        switch (err_handler_type)
+        {
+        case LUA_TFUNCTION:
+            // reference function
+            err_idx = luaL_ref(L, LUA_REGISTRYINDEX);
+            break;
+        case LUA_TSTRING:
+            err_str = lua_tostring(L, -1);
+            lua_pop(L, 1);
+            break;
+        default:
+            luaL_error(L, "bad error handler function passed to subscribe "
+                          "function. must be a real function, or a string for "
+                          "late binding");
+            break;
+        }
+
+    }
+
+    // should we pass a self to the callback?
+    int thisIndex = LUA_NOREF;
+    if (selfIndex != LUA_NOREF)
+    {
+        // reference self
+        thisIndex = luaL_ref(L, LUA_REGISTRYINDEX);
+    }
+
+    // do the real subscription
+    int type = lua_type(L,-1);
+    Event::Connection con;
+    if (type == LUA_TFUNCTION)
+    {
+        // reference function
+        int index = luaL_ref(L, LUA_REGISTRYINDEX);
+
+        LuaFunctor functor((err_idx != LUA_NOREF) ?
+                        LuaFunctor(L, index, thisIndex, err_idx) :
+                        (!err_str.empty()) ?
+                            LuaFunctor(L, index, thisIndex, err_str) :
+                            LuaFunctor(L, index, thisIndex));
+        con = self->subscribeEvent(String(event_name), Event::Subscriber(functor));
+        // make sure we don't release the reference(s) we just made when the
+        // 'functor' object is destroyed (goes out of scope)
+        functor.index = LUA_NOREF;
+        functor.self = LUA_NOREF;
+        functor.d_errFuncIndex = LUA_NOREF;
+    }
+    else if (type == LUA_TSTRING)
+    {
+        const char* str = lua_tostring(L, -1);
+        LuaFunctor functor((err_idx != LUA_NOREF) ?
+                        LuaFunctor(L, String(str), thisIndex, err_idx) :
+                        (!err_str.empty()) ?
+                            LuaFunctor(L, String(str), thisIndex, err_str) :
+                            LuaFunctor(L, String(str), thisIndex));
+
+        con = self->subscribeEvent(String(event_name), Event::Subscriber(functor));
+        // make sure we don't release the reference(s) we just made when the
+        // 'functor' object is destroyed (goes out of scope)
+        functor.self = LUA_NOREF;
+        functor.d_errFuncIndex = LUA_NOREF;
+    }
+    else
+    {
+        luaL_error(L, "bad function passed to subscribe function. must be a "
+                      "real function, or a string for late binding");
+    }
+
+    // return the event connection
+    return con;
+}
+
+//----------------------------------------------------------------------------//
+
+} // namespace CEGUI
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/CEGUILuaFunctor.h
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/CEGUILuaFunctor.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/CEGUILuaFunctor.h	(revision 6952)
@@ -0,0 +1,108 @@
+/***********************************************************************
+    filename: CEGUILuaFunctor.h
+    created:  Thu Jan 26 2006
+    author:   Tomas Lindquist Olsen <tomas@famolsen.dk>
+
+    purpose:  Defines interface for LuaFunctor class
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2008 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#ifndef _CEGUILuaFunctor_h_
+#define _CEGUILuaFunctor_h_
+
+#include "CEGUIEventSet.h"
+#include "CEGUIScriptWindowHelper.h"
+
+struct lua_State;
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+// forward declaration
+class LuaScriptModule;
+
+/*!
+\brief
+    Functor class used for subscribing Lua functions to CEGUI events
+*/
+class LuaFunctor
+{
+public:
+    LuaFunctor(lua_State* state, int func, int selfIndex);
+    LuaFunctor(lua_State* state, const String& func, int selfIndex);
+
+    LuaFunctor(lua_State* state, const int func, const int selfIndex,
+               const String& error_handler);
+    LuaFunctor(lua_State* state, const String& func, const int selfIndex,
+               const String& error_handler);
+    LuaFunctor(lua_State* state, const int func, const int selfIndex,
+               const int error_handler);
+    LuaFunctor(lua_State* state, const String& func, const int selfIndex,
+               const int error_handler);
+
+    LuaFunctor(const LuaFunctor& cp);
+    ~LuaFunctor();
+
+    bool operator()(const EventArgs& args) const;
+
+    /*!
+    \brief
+        function used to subscribe any Lua function as event handler.
+        References using the Lua registry.
+        To be called from Lua only.
+    */
+    static Event::Connection SubscribeEvent(EventSet* self,
+                                            const String& eventName,
+                                            const int funcIndex,
+                                            const int selfIndex,
+                                            const int error_handler,
+                                            lua_State* L);
+
+    /*!
+    \brief
+        Pushes the Lua function named \param name on top of the Lua stack.
+        The name may contain '.' (dots) character for (nested) table values.
+    */
+    static void pushNamedFunction(lua_State* L, const String& name);
+
+private:
+    lua_State* L;
+    mutable int index;
+    int self;
+    mutable bool needs_lookup;
+    mutable String function_name;
+
+    //! Error handler function to pass to lua_pcall.
+    mutable String d_errFuncName;
+    //! registry index of the function to pass to lua_pcall.
+    mutable int d_errFuncIndex;
+    //! signfies whether we made the reference index at d_errFuncIndex.
+    mutable bool d_ourErrFuncIndex;
+
+    friend class LuaScriptModule;
+};
+
+} // namespace CEGUI
+
+#endif // end of guard _CEGUILuaFunctor_h_
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/changes_orxonox.diff
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/changes_orxonox.diff	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/changes_orxonox.diff	(revision 6952)
@@ -0,0 +1,118 @@
+--- CEGUILua.cpp	Sun Jan 25 18:32:57 2009
++++ CEGUILua.cpp	Thu Jan 29 10:24:44 2009
+@@ -27,10 +27,6 @@
+  *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+  *   OTHER DEALINGS IN THE SOFTWARE.
+  ***************************************************************************/
+-#ifdef HAVE_CONFIG_H
+-#   include "config.h"
+-#endif
+-
+ #include "CEGUI.h"
+ #include "CEGUIConfig.h"
+ #include "CEGUIPropertyHelper.h"
+@@ -45,7 +41,7 @@
+ #include "lauxlib.h"
+ }
+ 
+-#include "tolua++.h"
++#include "tolua/tolua++.h"
+ 
+ // prototype for bindings initialisation function
+ int tolua_CEGUI_open(lua_State* tolua_S);
+@@ -59,9 +55,10 @@
+ 	Constructor (creates Lua state)
+ *************************************************************************/
+ LuaScriptModule::LuaScriptModule() :
+-    d_errFuncIndex(LUA_NOREF)
++    d_errFuncIndex(LUA_NOREF),
++    d_activeErrFuncIndex(LUA_NOREF)
+ {
+-    #if CEGUI_LUA_VER >= 51
++    #if LUA_VERSION_NUM >= 501
+         static const luaL_Reg lualibs[] = {
+             {"", luaopen_base},
+             {LUA_LOADLIBNAME, luaopen_package},
+@@ -75,14 +72,14 @@
+         #endif
+             {0, 0}
+         };
+-    #endif /* CEGUI_LUA_VER >= 51 */
++    #endif /* LUA_VERSION_NUM >= 501 */
+ 
+     // create a lua state
+     d_ownsState = true;
+     d_state = lua_open();
+ 
+     // init all standard libraries
+-    #if CEGUI_LUA_VER >= 51
++    #if LUA_VERSION_NUM >= 501
+             const luaL_Reg *lib = lualibs;
+             for (; lib->func; lib++)
+             {
+@@ -90,7 +87,7 @@
+                 lua_pushstring(d_state, lib->name);
+                 lua_call(d_state, 1, 0);
+             }
+-    #else /* CEGUI_LUA_VER >= 51 */
++    #else /* LUA_VERSION_NUM >= 501 */
+         luaopen_base(d_state);
+         luaopen_io(d_state);
+         luaopen_string(d_state);
+@@ -99,7 +96,7 @@
+         #if defined(DEBUG) || defined (_DEBUG)
+             luaopen_debug(d_state);
+         #endif
+-    #endif /* CEGUI_LUA_VER >= 51 */
++    #endif /* LUA_VERSION_NUM >= 501 */
+ 
+     setModuleIdentifierString();
+ }
+@@ -108,7 +105,9 @@
+ /*************************************************************************
+ 	Constructor (uses given Lua state)
+ *************************************************************************/
+-LuaScriptModule::LuaScriptModule(lua_State* state)
++LuaScriptModule::LuaScriptModule(lua_State* state) :
++    d_errFuncIndex(LUA_NOREF),
++    d_activeErrFuncIndex(LUA_NOREF)
+ {
+ 	// just use the given state
+ 	d_ownsState = false;
+--- CEGUILua.h	Sun Jan 25 18:32:57 2009
++++ CEGUILua.h	Thu Jan 29 10:17:42 2009
+@@ -38,7 +38,11 @@
+ #   ifdef CEGUILUA_EXPORTS
+ #       define CEGUILUA_API __declspec(dllexport)
+ #   else
+-#       define CEGUILUA_API __declspec(dllimport)
++#       if defined( __MINGW32__ )
++#           define CEGUILUA_API
++#       else
++#           define CEGUILUA_API __declspec(dllimport)
++#       endif
+ #   endif
+ #else
+ #   define CEGUILUA_API
+--- CEGUILuaFunctor.cpp	Sun Jan 25 18:32:57 2009
++++ CEGUILuaFunctor.cpp	Thu Jan 29 10:25:48 2009
+@@ -40,7 +40,7 @@
+ #include "lauxlib.h"
+ }
+ 
+-#include "tolua++.h"
++#include "tolua/tolua++.h"
+ 
+ // Start of CEGUI namespace section
+ namespace CEGUI
+@@ -199,6 +199,10 @@
+     bool ret = lua_isboolean(L, -1) ? lua_toboolean(L, -1 ) : true;
+     lua_pop(L, 1);
+ 
++    // remove error handler from stack
++    if (err_idx != 0)
++        lua_remove(L, err_idx);
++
+ 	if(helper)
+ 	{
+ 		delete helper;
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/required.cpp
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/required.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/required.cpp	(revision 6952)
@@ -0,0 +1,108 @@
+/***********************************************************************
+	filename: required.cpp
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+
+	purpose:  Implementation of helper functions
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUI.h"
+#include "required.h"
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+
+/*************************************************************************
+	Functions for getting Thumb range pairs as two return values
+*************************************************************************/
+
+// returns horizontal range as two values for lua
+void ceguiLua_Thumb_getHorzRange(Thumb* wnd, float* min, float* max)
+{
+	std::pair<float,float> range_pair = wnd->getHorzRange();
+	*min = range_pair.first;
+	*max = range_pair.second;
+}
+
+
+// returns vertical range as two values for lua
+void ceguiLua_Thumb_getVertRange(Thumb* wnd, float* min, float* max)
+{
+	std::pair<float,float> range_pair = wnd->getVertRange();
+	*min = range_pair.first;
+	*max = range_pair.second;
+}
+
+
+/*************************************************************************
+	Functions for creating list box items
+*************************************************************************/
+
+// allocates and returns a new ListboxTextItem
+ListboxTextItem* ceguiLua_createListboxTextItem(const String& text, uint item_id, void* item_data, bool disabled, bool auto_delete)
+{
+	return new ListboxTextItem(text,item_id,item_data,disabled,auto_delete);
+}
+
+
+/************************************************************************
+    OutStream
+*************************************************************************/
+void ceguiLua_FileStream_open(FileStream* os, const char* filename)
+{
+    os->open(filename, std::ios::binary);
+}
+
+
+/************************************************************************
+    CEGUI::System::getSystemKeys alternative
+*************************************************************************/
+bool ceguiLua_System_isSystemKeyDown(const System* sys, SystemKey k)
+{
+    return (k & sys->getSystemKeys()) != 0;
+}
+
+/************************************************************************
+    EventConnection helper class implementation
+*************************************************************************/
+EventConnection::EventConnection(RefCounted<BoundSlot> slot) :
+    d_slot(slot)
+{}
+
+//----------------------------------------------------------------------------//
+bool EventConnection::connected() const
+{
+    return d_slot->connected();
+}
+
+//----------------------------------------------------------------------------//
+void EventConnection::disconnect()
+{
+    d_slot->disconnect();
+}
+
+//----------------------------------------------------------------------------//
+
+} // namespace CEGUI
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/required.h
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/required.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/ceguilua/required.h	(revision 6952)
@@ -0,0 +1,125 @@
+/***********************************************************************
+	filename: required.h
+	created:  16/3/2005
+	author:   Tomas Lindquist Olsen
+
+	purpose:  Header that includes the necessary stuff needed for the Lua bindings
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGUI.h"
+#include "CEGUILua.h"
+#include "CEGUILuaFunctor.h"
+#include <fstream>
+
+#define __operator_increment    operator++
+#define __operator_decrement    operator--
+#define __operator_dereference  operator*
+
+#define LuaFunctorSubscribeEvent CEGUI::LuaFunctor::SubscribeEvent
+
+//This is used to keep compilers happy
+#define CEGUIDeadException(e) &
+
+#if defined(_MSC_VER) && !defined(snprintf)
+#   define snprintf   _snprintf
+#endif
+
+typedef CEGUI::String string;
+
+namespace CEGUI
+{
+
+/*************************************************************************
+    Helper class to enable us to represent an Event::Connection object
+    (which is actually a RefCounted<BoundSlot> object)
+*************************************************************************/
+class EventConnection
+{
+    RefCounted<BoundSlot> d_slot;
+
+public:
+    EventConnection(RefCounted<BoundSlot> slot);
+    bool connected() const;
+    void disconnect();
+};
+
+/*************************************************************************
+	Functions for getting Thumb range pairs as two return values
+*************************************************************************/
+void ceguiLua_Thumb_getHorzRange(Thumb* wnd, float* min, float* max);
+void ceguiLua_Thumb_getVertRange(Thumb* wnd, float* min, float* max);
+
+
+/*************************************************************************
+	Functions for creating list box items
+*************************************************************************/
+ListboxTextItem* ceguiLua_createListboxTextItem(const String& text, uint item_id, void* item_data, bool disabled, bool auto_delete);
+
+
+/************************************************************************
+    Stuff needed to make the iterators work
+*************************************************************************/
+typedef PropertySet::Iterator PropertyIterator;
+typedef EventSet::Iterator EventIterator;
+typedef WindowManager::WindowIterator WindowIterator;
+typedef WindowFactoryManager::WindowFactoryIterator WindowFactoryIterator;
+typedef WindowFactoryManager::FalagardMappingIterator FalagardMappingIterator;
+typedef WindowFactoryManager::FalagardWindowMapping FalagardWindowMapping;
+typedef ImagesetManager::ImagesetIterator ImagesetIterator;
+typedef Imageset::ImageIterator ImageIterator;
+typedef SchemeManager::SchemeIterator SchemeIterator;
+typedef FontManager::FontIterator FontIterator;
+
+template <typename T>
+inline PropertyIterator ceguiLua_getPropertyIterator(const T* self)
+{
+    return static_cast<const PropertySet*>(self)->getIterator();
+}
+
+template <typename T>
+inline EventIterator ceguiLua_getEventIterator(const T* self)
+{
+    return static_cast<const EventSet*>(self)->getIterator();
+}
+
+
+/************************************************************************
+    OutStream
+*************************************************************************/
+typedef std::ofstream FileStream;
+void ceguiLua_FileStream_open(FileStream*, const char* filename);
+
+
+/************************************************************************
+    CEGUI::System::getSystemKeys alternative
+*************************************************************************/
+bool ceguiLua_System_isSystemKeyDown(const System* sys, SystemKey k);
+
+}
+
+// the binding file generates alot of
+// warning C4800: 'int' : forcing value to bool 'true' or 'false' (performance warning)
+#if defined(_MSC_VER)
+#   pragma warning(disable : 4800)
+#endif
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/EventSet.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/EventSet.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/EventSet.pkg	(revision 6952)
@@ -0,0 +1,46 @@
+/************************************************************************
+    Event
+*************************************************************************/
+class Event
+{
+    string getName() const;
+};
+
+class EventConnection
+{
+    bool connected() const;
+    void disconnect();
+};
+
+
+/***********************************************************************
+	EventSet
+***********************************************************************/
+class EventSet
+{
+	void addEvent(string name);
+	void removeEvent(string name);
+	void removeAllEvents();
+	bool isEventPresent(string name);
+
+    tolua_throws|CEGUI::UnknownObjectException,error| tolua_outside EventConnection LuaFunctorSubscribeEvent @ subscribeEvent(string name, lua_Object funcIndex, lua_Object selfIndex=LUA_NOREF, lua_Object error_handler = LUA_NOREF, lua_State*);
+
+	tolua_throws|CEGUI::UnknownObjectException,error| EventConnection subscribeScriptedEvent @ subscribeEvent(string name, string callback_name);
+
+	void fireEvent(string name, EventArgs& args, string eventnamespace="");
+
+	bool isMuted() const;
+	void setMutedState(bool setting);
+
+    tolua_outside EventIterator ceguiLua_getEventIterator @ getEventIterator() const;
+};
+
+
+
+/***********************************************************************
+	GlobalEventSet
+***********************************************************************/
+class GlobalEventSet : public EventSet
+{
+	static GlobalEventSet& getSingleton();
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/HelperFunctions.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/HelperFunctions.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/HelperFunctions.pkg	(revision 6952)
@@ -0,0 +1,240 @@
+/****************************************************
+	EventArgs casting helper functions.
+	These are not part of the core CEGUI API, merely here for
+	convenience
+*****************************************************/
+$[
+
+function CEGUI.toMouseCursorEventArgs(e)
+    return tolua.cast(e,"const CEGUI::MouseCursorEventArgs")
+end
+
+function CEGUI.toWindowEventArgs(e)
+    return tolua.cast(e,"const CEGUI::WindowEventArgs")
+end
+
+function CEGUI.toActivationEventArgs(e)
+    return tolua.cast(e,"const CEGUI::ActivationEventArgs")
+end
+
+function CEGUI.toHeaderSequenceEventArgs(e)
+    return tolua.cast(e,"const CEGUI::HeaderSequenceEventArgs")
+end
+
+function CEGUI.toMouseEventArgs(e)
+    return tolua.cast(e,"const CEGUI::MouseEventArgs")
+end
+
+function CEGUI.toKeyEventArgs(e)
+    return tolua.cast(e,"const CEGUI::KeyEventArgs")
+end
+
+function CEGUI.toDragDropEventArgs(e)
+    return tolua.cast(e,"const CEGUI::DragDropEventArgs")
+end
+
+function CEGUI.toTreeEventArgs(e)
+    return tolua.cast(e,"const CEGUI::TreeEventArgs")
+end
+
+CEGUI.EventArgs.toMouseCursorEventArgs      = CEGUI.toMouseCursorEventArgs
+CEGUI.EventArgs.toWindowEventArgs           = CEGUI.toWindowEventArgs
+CEGUI.EventArgs.toActivationEventArgs       = CEGUI.toActivationEventArgs
+CEGUI.EventArgs.toHeaderSequenceEventArgs   = CEGUI.toHeaderSequenceEventArgs
+CEGUI.EventArgs.toMouseEventArgs            = CEGUI.toMouseEventArgs
+CEGUI.EventArgs.toKeyEventArgs              = CEGUI.toKeyEventArgs
+CEGUI.EventArgs.toDragDropEventArgs         = CEGUI.toDragDropEventArgs
+CEGUI.EventArgs.toTreeEventArgs             = CEGUI.toTreeEventArgs
+
+$]
+
+
+/****************************************************
+	Functions for easy casting CEGUI::Window class
+	to the widget classes derived from it.
+	
+	all widget types gets these and they are made available as:
+	CEGUI.toButtonBase and CEGUI.Window:toButtonBase
+	etc...
+*****************************************************/
+$[
+
+function CEGUI.toButtonBase(w)
+    return tolua.cast(w,"CEGUI::ButtonBase")
+end
+
+function CEGUI.toCheckbox(w)
+    return tolua.cast(w,"CEGUI::Checkbox")
+end
+
+function CEGUI.toCombobox(w)
+    return tolua.cast(w,"CEGUI::Combobox")
+end
+
+function CEGUI.toComboDropList(w)
+    return tolua.cast(w,"CEGUI::ComboDropList")
+end
+
+function CEGUI.toDragContainer(w)
+    return tolua.cast(w,"CEGUI::DragContainer")
+end
+
+function CEGUI.toEditbox(w)
+    return tolua.cast(w,"CEGUI::Editbox")
+end
+
+function CEGUI.toFrameWindow(w)
+    return tolua.cast(w,"CEGUI::FrameWindow")
+end
+
+function CEGUI.toGUISheet(w)
+    return tolua.cast(w,"CEGUI::GUISheet")
+end
+
+function CEGUI.toItemEntry(w)
+    return tolua.cast(w,"CEGUI::ItemEntry")
+end
+
+function CEGUI.toItemListBase(w)
+    return tolua.cast(w,"CEGUI::ItemListBase")
+end
+
+function CEGUI.toItemListbox(w)
+    return tolua.cast(w,"CEGUI::ItemListbox")
+end
+
+function CEGUI.toListbox(w)
+    return tolua.cast(w,"CEGUI::Listbox")
+end
+
+function CEGUI.toListHeader(w)
+    return tolua.cast(w,"CEGUI::ListHeader")
+end
+
+function CEGUI.toListHeaderSegment(w)
+    return tolua.cast(w,"CEGUI::ListHeaderSegment")
+end
+
+function CEGUI.toMenubar(w)
+    return tolua.cast(w,"CEGUI::Menubar")
+end
+
+function CEGUI.toMenuBase(w)
+    return tolua.cast(w,"CEGUI::MenuBase")
+end
+
+function CEGUI.toMenuItem(w)
+    return tolua.cast(w,"CEGUI::MenuItem")
+end
+
+function CEGUI.toMultiColumnList(w)
+    return tolua.cast(w,"CEGUI::MultiColumnList")
+end
+
+function CEGUI.toMultiLineEditbox(w)
+    return tolua.cast(w,"CEGUI::MultiLineEditbox")
+end
+
+function CEGUI.toPopupMenu(w)
+    return tolua.cast(w,"CEGUI::PopupMenu")
+end
+
+function CEGUI.toProgressBar(w)
+    return tolua.cast(w,"CEGUI::ProgressBar")
+end
+
+function CEGUI.toPushButton(w)
+    return tolua.cast(w,"CEGUI::PushButton")
+end
+
+function CEGUI.toRadioButton(w)
+    return tolua.cast(w,"CEGUI::RadioButton")
+end
+
+function CEGUI.toScrollablePane(w)
+    return tolua.cast(w,"CEGUI::ScrollablePane")
+end
+
+function CEGUI.toScrollbar(w)
+    return tolua.cast(w,"CEGUI::Scrollbar")
+end
+
+function CEGUI.toScrolledContainer(w)
+    return tolua.cast(w,"CEGUI::ScrolledContainer")
+end
+
+function CEGUI.toScrolledItemListBase(w)
+    return tolua.cast(w,"CEGUI::ScrolledItemListBase")
+end
+
+function CEGUI.toSlider(w)
+    return tolua.cast(w,"CEGUI::Slider")
+end
+
+function CEGUI.toSpinner(w)
+    return tolua.cast(w,"CEGUI::Spinner")
+end
+
+function CEGUI.toTabButton(w)
+    return tolua.cast(w,"CEGUI::TabButton")
+end
+
+function CEGUI.toTabControl(w)
+    return tolua.cast(w,"CEGUI::TabControl")
+end
+
+function CEGUI.toTabPane(w)
+    return tolua.cast(w,"CEGUI::TabPane")
+end
+
+function CEGUI.toThumb(w)
+    return tolua.cast(w,"CEGUI::Thumb")
+end
+
+function CEGUI.toTooltip(w)
+    return tolua.cast(w,"CEGUI::Tooltip")
+end
+
+CEGUI.Window.toButtonBase = CEGUI.toButtonBase
+CEGUI.Window.toCheckbox = CEGUI.toCheckbox
+CEGUI.Window.toCombobox = CEGUI.toCombobox
+CEGUI.Window.toComboDropList = CEGUI.toComboDropList
+CEGUI.Window.toDragContainer = CEGUI.toDragContainer
+CEGUI.Window.toEditbox = CEGUI.toEditbox
+CEGUI.Window.toFrameWindow = CEGUI.toFrameWindow
+CEGUI.Window.toGUISheet = CEGUI.toGUISheet
+CEGUI.Window.toItemEntry = CEGUI.toItemEntry
+CEGUI.Window.toItemListBase = CEGUI.toItemListBase
+CEGUI.Window.toItemListbox = CEGUI.toItemListBase
+CEGUI.Window.toListbox = CEGUI.toListbox
+CEGUI.Window.toListHeader = CEGUI.toListHeader
+CEGUI.Window.toListHeaderSegment = CEGUI.toListHeaderSegment
+CEGUI.Window.toMenubar = CEGUI.toMenubar
+CEGUI.Window.toMenuBase = CEGUI.toMenuBase
+CEGUI.Window.toMenuItem = CEGUI.toMenuItem
+CEGUI.Window.toMultiColumnList = CEGUI.toMultiColumnList
+CEGUI.Window.toMultiLineEditbox = CEGUI.toMultiLineEditbox
+CEGUI.Window.toPopupMenu = CEGUI.toPopupMenu
+CEGUI.Window.toProgressBar = CEGUI.toProgressBar
+CEGUI.Window.toPushButton = CEGUI.toPushButton
+CEGUI.Window.toRadioButton = CEGUI.toRadioButton
+CEGUI.Window.toScrollablePane = CEGUI.toScrollablePane
+CEGUI.Window.toScrollbar = CEGUI.toScrollbar
+CEGUI.Window.toScrolledContainer = CEGUI.toScrolledContainer
+CEGUI.Window.toScrolledItemListBase = CEGUI.toScrolledItemListBase
+CEGUI.Window.toSlider = CEGUI.toSlider
+CEGUI.Window.toSpinner = CEGUI.toSpinner
+CEGUI.Window.toTabButton = CEGUI.toTabButton
+CEGUI.Window.toTabControl = CEGUI.toTabControl
+CEGUI.Window.toTabPane = CEGUI.toTabPane
+CEGUI.Window.toThumb = CEGUI.toThumb
+CEGUI.Window.toTooltip = CEGUI.toTooltip
+
+$]
+
+
+/****************************************************
+	Helper to create a ListboxTextItem.
+	Mimics the constructor
+*****************************************************/
+ListboxTextItem* ceguiLua_createListboxTextItem @ createListboxTextItem(string text, unsigned int item_id=0, void* item_data=0, bool disabled=false, bool auto_delete=true);
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/InputEvent.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/InputEvent.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/InputEvent.pkg	(revision 6952)
@@ -0,0 +1,129 @@
+/***********************************************************************
+	EventArgs
+***********************************************************************/
+class EventArgs
+{
+	bool handled;
+
+	EventArgs();
+};
+
+
+
+/***********************************************************************
+	MouseCursorEventArgs
+***********************************************************************/
+class MouseCursorEventArgs : public EventArgs
+{
+	MouseCursor* mouseCursor;
+	const Image* image;
+
+	MouseCursorEventArgs(MouseCursor* cursor);
+};
+
+
+
+/***********************************************************************
+	WindowEventArgs
+***********************************************************************/
+class WindowEventArgs : public EventArgs
+{
+	Window* window;
+
+	WindowEventArgs(Window* wnd);
+};
+
+
+
+/***********************************************************************
+	ActivationEventArgs
+***********************************************************************/
+class ActivationEventArgs : public WindowEventArgs
+{
+	Window* otherWindow;
+
+	ActivationEventArgs(Window* wnd);
+};
+
+
+
+/***********************************************************************
+	HeaderSequenceEventArgs
+***********************************************************************/
+class HeaderSequenceEventArgs : public WindowEventArgs
+{
+	// remove 'd_' member variable prefix
+	unsigned int d_oldIdx @ oldIdx;
+	unsigned int d_newIdx @ newIdx;
+
+	HeaderSequenceEventArgs(Window* wnd, unsigned int old_index, unsigned int new_index);
+};
+
+
+
+/***********************************************************************
+	MouseButton
+***********************************************************************/
+enum MouseButton
+{
+	LeftButton,
+	RightButton,
+	MiddleButton,
+	X1Button,
+	X2Button,
+	MouseButtonCount,
+	NoButton
+};
+
+
+
+/***********************************************************************
+	MouseEventArgs
+***********************************************************************/
+class MouseEventArgs : public WindowEventArgs
+{
+	Vector2 position;
+	Vector2 moveDelta;
+	MouseButton button;
+	unsigned int sysKeys;
+	float wheelChange;
+
+	MouseEventArgs(Window* wnd);
+};
+
+
+
+/***********************************************************************
+	KeyEventArgs
+***********************************************************************/
+class KeyEventArgs : public WindowEventArgs
+{
+	unsigned long codepoint;
+	Key::Scan scancode;
+	unsigned int sysKeys;
+
+	KeyEventArgs(Window* wnd);
+};
+
+
+
+/************************************************************************
+    DragDropEventArgs
+*************************************************************************/
+class DragDropEventArgs : public WindowEventArgs
+{
+    DragContainer* dragDropItem;
+
+    DragDropEventArgs(Window* wnd);
+};
+
+
+/***********************************************************************
+   TreeEventArgs
+***********************************************************************/
+class TreeEventArgs : public WindowEventArgs
+{
+   TreeItem *treeItem;
+
+   TreeEventArgs(Window* wnd);
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/Window.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/Window.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/Window.pkg	(revision 6952)
@@ -0,0 +1,250 @@
+/****************************************
+	Vertical alignment modes
+*****************************************/
+enum VerticalAlignment
+{
+	VA_TOP,
+	VA_CENTRE,
+	VA_BOTTOM
+};
+
+
+/****************************************
+	Horizontal alignment modes
+*****************************************/
+enum HorizontalAlignment
+{
+	HA_LEFT,
+	HA_CENTRE,
+	HA_RIGHT
+};
+
+
+/****************************************
+	Window
+*****************************************/
+class Window //: public EventSet
+{
+	string getType() const;
+	string getName() const;
+
+	bool isDestroyedByParent() const;
+	bool isAlwaysOnTop() const;
+	bool isDisabled(bool localOnly=false) const;
+	bool isVisible(bool localOnly=false) const;
+	bool isActive() const;
+	bool isClippedByParent() const;
+
+	void setDestroyedByParent(bool setting);
+	void setAlwaysOnTop(bool setting);
+	void setEnabled(bool setting);
+	void enable();
+	void disable();
+	void setVisible(bool setting);
+	void show();
+	void hide();
+	void activate();
+	void deactivate();
+
+	void setClippedByParent(bool setting);
+
+	unsigned int getID() const;
+	void setID(unsigned int ID);
+
+	unsigned int getChildCount() const;
+
+	bool isChild(unsigned int ID) const;
+	bool isChild(string name) const;
+	bool isChild(const Window* window) const;
+	bool isChildRecursive(unsigned int ID) const;
+
+	void addChildWindow(string name);
+	void addChildWindow(Window* window);
+
+	void removeChildWindow(unsigned int ID);
+	void removeChildWindow(string name);
+	void removeChildWindow(Window* window);
+
+	tolua_throws|CEGUI::UnknownObjectException,nil| Window* getChild(unsigned int ID) const;
+	tolua_throws|CEGUI::UnknownObjectException,nil| Window* getChild(string name) const;
+    Window* getChildRecursive(unsigned int ID) const;
+    Window* getChildRecursive(string name) const;
+	Window* getChildAtIdx(unsigned int ID) const;
+	Window* getActiveChild() const;
+	Window* getChildAtPosition(const Vector2& pos) const;
+    Window* getTargetChildAtPosition(const Vector2& pos) const;
+
+	Window* getParent() const;
+
+	bool isAncestor(unsigned int ID) const;
+	bool isAncestor(string name) const;
+	bool isAncestor(const Window* window) const;
+
+	void setFont(string name);
+	void setFont(Font* font);
+	Font* getFont() const;
+
+	void setText(string text);
+    void insertText(string text, unsigned long position);
+    void appendText(string text);
+	string getText() const;
+
+	bool inheritsAlpha() const;
+	float getAlpha() const;
+	float getEffectiveAlpha() const;
+	void setAlpha(float a);
+	void setInheritsAlpha(bool setting);
+
+	void requestRedraw() const;
+
+	bool isZOrderingEnabled() const;
+	void setZOrderingEnabled(bool setting);
+
+	Rect getPixelRect() const;
+	Rect getInnerRect() const;
+	Rect getUnclippedPixelRect() const;
+	Rect getUnclippedInnerRect() const;
+
+    Size getParentPixelSize(void) const;
+    float getParentPixelWidth(void) const;
+    float getParentPixelHeight(void) const;
+
+	static Window* getCaptureWindow();
+	void setRestoreCapture(bool setting);
+	bool restoresOldCapture() const;
+
+	bool distributesCapturedInputs() const;
+	void setDistributesCapturedInputs(bool setting);
+
+	bool captureInput();
+	void releaseInput();
+
+	bool isCapturedByThis() const;
+	bool isCapturedByAncestor() const;
+	bool isCapturedByChild() const;
+
+	bool isHit(const Vector2& pos) const;
+
+	bool isRiseOnClickEnabled() const;
+	void setRiseOnClickEnabled(bool setting);
+
+	const Image* getMouseCursor() const;
+	void setMouseCursor(MouseCursorImage cursor);
+	void setMouseCursor(const Image* image);
+	void setMouseCursor(string imageset, string image);
+
+	void moveToFront();
+	void moveToBack();
+
+	bool wantsMultiClickEvents() const;
+	bool isMouseAutoRepeatEnabled() const;
+	float getAutoRepeatDelay() const;
+	float getAutoRepeatRate() const;
+	void setWantsMultiClickEvents(bool setting);
+	void setMouseAutoRepeatEnabled(bool setting);
+	void setAutoRepeatDelay(float delay);
+	void setAutoRepeatRate(float rate);
+
+	//void destroy();
+
+	bool isUsingDefaultTooltip() const;
+	Tooltip* getTooltip() const;
+	string getTooltipType() const;
+	string getTooltipText() const;
+	bool inheritsTooltipText() const;
+
+	void setTooltip(Tooltip* tooltip);
+	void setTooltipType(string tooltipType);
+	void setTooltipText(string tip);
+	void setInheritsTooltipText(bool setting);
+
+	bool testClassName(string class_name) const;
+
+	void notifyDragDropItemEnters(DragContainer* item);
+	void notifyDragDropItemLeaves(DragContainer* item);
+	void notifyDragDropItemDropped(DragContainer* item);
+
+	VerticalAlignment getVerticalAlignment() const;
+	HorizontalAlignment getHorizontalAlignment() const;
+
+    // these actually have a const, but tolua++ chokes on that
+    void setVerticalAlignment(VerticalAlignment alignment);
+    void setHorizontalAlignment(HorizontalAlignment alignment);
+
+	string getLookNFeel() const;
+    tolua_throws|CEGUI::Exception,error| void setLookNFeel(string lnf);
+
+    tolua_throws|CEGUI::Exception,error| void setWindowRenderer(string name);
+    string getWindowRendererName() const;
+
+	//RenderCache& getRenderCache()
+
+	bool getModalState() const;
+	void setModalState(bool state);
+
+    tolua_throws|CEGUI::UnknownObjectException,nil| string getUserString(string name) const;
+    bool isUserStringDefined(string name) const;
+    void setUserString(string name, string value);
+
+    void beginInitialisation();
+    void endInitialisation();
+
+	// unified stuff
+	void setArea(const UDim& xpos, const UDim& ypos, const UDim& width, const UDim& height);
+	void setArea(const UVector2& pos, const UVector2& size);
+	void setArea(const URect& area);
+	void setPosition(const UVector2& pos);
+	void setXPosition(const UDim& x);
+	void setYPosition(const UDim& y);
+	void setSize(const UVector2& size);
+	void setWidth(const UDim& width);
+	void setHeight(const UDim& height);
+	void setMaxSize(const UVector2& size);
+	void setMinSize(const UVector2& size);
+
+	const URect& getArea() const;
+	const UVector2& getPosition() const;
+	const UDim& getXPosition() const;
+	const UDim& getYPosition() const;
+	UVector2 getSize() const;
+	UDim getWidth() const;
+	UDim getHeight() const;
+	const UVector2& getMaxSize() const;
+	const UVector2& getMinSize() const;
+
+    // event pass through
+    bool isMousePassThroughEnabled() const;
+    void setMousePassThroughEnabled(bool setting);
+    
+    tolua_throws|CEGUI::Exception,error| void rename(string new_name);
+
+	//////////////////////////////////////////////
+	// PropertySet
+	void setProperty(string name, string value);
+	string getProperty(string name) const;
+	string getPropertyDefault(string name) const;
+	string getPropertyHelp(string name) const;
+
+	bool isPropertyPresent(string name) const;
+	bool isPropertyDefault(string name) const;
+
+    tolua_outside PropertyIterator ceguiLua_getPropertyIterator @ getPropertyIterator() const;
+
+	//////////////////////////////////////////////
+	// EventSet
+	void addEvent(string name);
+	void removeEvent(string name);
+	void removeAllEvents();
+	bool isEventPresent(string name);
+
+    tolua_throws|CEGUI::UnknownObjectException,error| tolua_outside EventConnection LuaFunctorSubscribeEvent @ subscribeEvent(string name, lua_Object funcIndex, lua_Object selfIndex=LUA_NOREF, lua_Object error_handler = LUA_NOREF, lua_State*);
+
+	tolua_throws|CEGUI::UnknownObjectException,error| EventConnection subscribeScriptedEvent @ subscribeEvent(string name, string callback_name);
+	
+	void fireEvent(string name, EventArgs& args, string eventnamespace="");
+
+	bool isMuted() const;
+	void setMutedState(bool setting);
+
+    tolua_outside EventIterator ceguiLua_getEventIterator @ getEventIterator() const;
+};
Index: /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/WindowManager.pkg
===================================================================
--- /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/WindowManager.pkg	(revision 6952)
+++ /code/branches/rocket2/src/external/ceguilua/ceguilua-0.6.2/package/WindowManager.pkg	(revision 6952)
@@ -0,0 +1,36 @@
+/***********************************************************************
+	WindowManager
+***********************************************************************/
+class WindowManager
+{
+	static WindowManager& getSingleton();
+
+	tolua_throws|CEGUI::AlreadyExistsException,nil|CEGUI::InvalidRequestException,nil| Window* createWindow(string type, string name="");
+	tolua_throws|CEGUI::Exception,error|std::exception,error|any,error| Window* loadWindowLayout(string filename, string name_prefix="", string resourcegroup="");
+	tolua_throws|CEGUI::Exception,error|std::exception,error|any,error| Window* loadWindowLayout(string filename, bool generateRandomPrefix);
+
+    void writeWindowLayoutToStream(string window, OutStream& out, bool writeParent=false) const;
+    void writeWindowLayoutToStream(const Window& window, OutStream& out, bool writeParent=false) const;
+
+	void destroyWindow(string name);
+	void destroyWindow(Window* window);
+	void destroyAllWindows();
+
+	tolua_throws|CEGUI::UnknownObjectException,nil| Window* getWindow(string name) const;
+	bool isWindowPresent(string name) const;
+
+	bool isDeadPoolEmpty() const;
+	void cleanDeadPool();
+
+    void renameWindow(Window* window, string  new_name);
+    void renameWindow(string window, string new_name);
+
+    WindowIterator getIterator() const;
+
+    static void setDefaultResourceGroup(string resourceGroup);
+    static string& getDefaultResourceGroup();
+
+    void lock();
+    void unlock();
+    bool isLocked() const;
+};
Index: /code/branches/rocket2/src/external/cpptcl/CHANGES
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/CHANGES	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/CHANGES	(revision 6952)
@@ -0,0 +1,46 @@
+This file contains the history of changes in the C++/Tcl library.
+
+---
+The version 1.1.3 differs from 1.1.2 in the following ways:
+
+- A bug in the initialization of interpreter object was fixed.
+
+---
+The version 1.1.2 differs from 1.1.1 in the following ways:
+
+- Copyright was updated to cover 2006.
+
+- Information was added to docs about the usage of the Boost library.
+
+- Few bug fixes were applied to allow empty parameter lists with variadic
+  functions.
+
+---
+The version 1.1.1 differs from 1.1.0 in the following ways:
+
+- Explicit instantiations of some templates were moved to proper namespace.
+
+
+---
+The version 1.1.0 differs from 1.0.0 in the following ways:
+
+- CHANGES file was added.
+
+- LICENSE file was added with clear description of the license terms.
+
+- Copyright was updated to cover 2005.
+
+- Small patch was added to make the code compile on g++ 3.2.
+
+- New assign method was added that accepts Tcl_Obj.
+
+- Overload of interpreter::eval was added that accepts istream& parameter.
+  This allows to evaluate the contents of arbitrary stream
+  (for example, a file).
+
+- Support for package definitions was added.
+
+- Support for const class member functions was added.
+
+- Support for variadic free functions, constructors and class methods
+  was added.
Index: /code/branches/rocket2/src/external/cpptcl/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,43 @@
+ #
+ #             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.
+ #
+
+SET(CPPTCL_FILES
+  cpptcl.h
+  cpptcl.cc
+
+  details/callbacks.h
+  details/callbacks_v.h
+  details/constructors.h
+  details/conversions.h
+  details/dispatchers.h
+  details/metahelpers.h
+  details/methods.h
+  details/methods_v.h
+)
+
+ORXONOX_ADD_LIBRARY(cpptcl_orxonox
+  ORXONOX_EXTERNAL
+  NO_DLL_INTERFACE
+  VERSION
+    1.1.3
+  LINK_LIBRARIES
+    ${TCL_LIBRARY}
+  SOURCE_FILES
+    ${CPPTCL_FILES}
+)
Index: /code/branches/rocket2/src/external/cpptcl/CREDITS
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/CREDITS	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/CREDITS	(revision 6952)
@@ -0,0 +1,11 @@
+I would like to thank you very much for your contributions:
+
+---
+Alexey Pakhunov provided patches with various bugfixes and enhancements.
+His patches were used in the 1.1.2 release.
+
+---
+Christoph Pesch provided a small patch for the g++ 3.2 compiler.
+
+After the 1.1.0 release, Christoph provided also a patch for newer g++ 3.4.3.
+(included in 1.1.1)
Index: /code/branches/rocket2/src/external/cpptcl/LICENSE
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/LICENSE	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/LICENSE	(revision 6952)
@@ -0,0 +1,39 @@
+Each source file contains the following notice:
+
+//
+// Copyright (C) 2004-2006, Maciej Sobczak
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+
+The above is the shortest license I have found.
+I have copied this wording from one of the source files of the Boost library.
+
+Just to explain the above terms:
+
+1. The library is free (like in "freedom").
+
+2. You can use it for any purpose you wish. You can even sell it.
+
+3. You can modify the source files. If you do this, please feel free to add
+   your own copyright notices wherever you want, if you want.
+   You may also add more restrictive license terms.
+   You only have to keep the above notice unchanged in all source files.
+
+4. You can combine this library or its modified version with other software.
+   The license claims nothing that would affect the resulting work.
+   See point 3. if you need to make any modifications.
+
+5. You can compile this library or its modified version to the binary form.
+   The license does not affect the compiled result in any way.
+   In particular, you do not need to (but you still can) display the above
+   copyright notice to the final user, and you do not need to (but you still
+   can) inform the final user that your product was prepared with the help
+   of this library.
+
+6. Do not sue me for my (and your) mistakes and errors.
+
+As you see, this license is very permissive.
Index: /code/branches/rocket2/src/external/cpptcl/README
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/README	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/README	(revision 6952)
@@ -0,0 +1,32 @@
+C++/Tcl - a C++ library for interoperability between C++ and Tcl.
+
+Copyright (C) 2004-2006, Maciej Sobczak
+
+---
+
+You should see the following directories here:
+
+- doc      - contains a short documentation for the library
+- examples - some simple examples to show C++/Tcl basics
+- test     - tests used for development - use them for regression testing
+             if you want to modify the library
+- details  - some additional code used by the library (not for client use)
+
+In addition, the following files may be of interest to you:
+
+- README   - this file
+- LICENSE  - explanation of the license terms
+- CHANGES  - the history of changes
+
+
+The C++/Tcl itself consists of these files:
+- cpptcl.h   - to be included in your own files
+- cpptcl.cc  - to be compiled and linked with your code
+
+
+In order to compile the tests and the examples you may need to change the
+compiler options to fit your particular environment (different paths to the
+Tcl headers and libs, another compiler, etc.)
+
+
+Anyway - have fun! :-)
Index: /code/branches/rocket2/src/external/cpptcl/changes_orxonox.diff
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/changes_orxonox.diff	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/changes_orxonox.diff	(revision 6952)
@@ -0,0 +1,29 @@
+--- cpptcl.cc	So Feb  8 23:14:34 2009
++++ cpptcl.cc	So Feb  8 23:13:07 2009
+@@ -320,7 +320,7 @@
+ 
+           post_process_policies(interp, pol, objv, false);
+      }
+-     catch (exception const &e)
++     catch (std::exception const &e)
+      {
+           Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE);
+           return TCL_ERROR;
+@@ -363,7 +363,7 @@
+ 
+           post_process_policies(interp, pol, objv, true);
+      }
+-     catch (exception const &e)
++     catch (std::exception const &e)
+      {
+           Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE);
+           return TCL_ERROR;
+@@ -430,7 +430,7 @@
+                Tcl_GetString(Tcl_GetObjResult(interp)),
+                object_handler, static_cast<ClientData>(chb), 0);
+      }
+-     catch (exception const &e)
++     catch (std::exception const &e)
+      {
+           Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE);
+           return TCL_ERROR;
Index: /code/branches/rocket2/src/external/cpptcl/cpptcl.cc
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/cpptcl.cc	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/cpptcl.cc	(revision 6952)
@@ -0,0 +1,1083 @@
+//
+// Copyright (C) 2004-2006, Maciej Sobczak
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+
+#include "cpptcl.h"
+#include <map>
+#include <sstream>
+#include <iterator>
+
+
+using namespace Tcl;
+using namespace Tcl::details;
+using namespace std;
+using namespace boost;
+
+
+result::result(Tcl_Interp *interp) : interp_(interp) {}
+
+result::operator bool() const
+{
+     Tcl_Obj *obj = Tcl_GetObjResult(interp_);
+     
+     int val, cc;
+     cc = Tcl_GetBooleanFromObj(interp_, obj, &val);
+     if (cc != TCL_OK)
+     {
+          throw tcl_error(interp_);
+     }
+     
+     return static_cast<bool>(val);
+}
+
+result::operator double() const
+{
+     Tcl_Obj *obj = Tcl_GetObjResult(interp_);
+     
+     double val;
+     int cc = Tcl_GetDoubleFromObj(interp_, obj, &val);
+     if (cc != TCL_OK)
+     {
+          throw tcl_error(interp_);
+     }
+     
+     return val;
+}
+
+result::operator int() const
+{
+     Tcl_Obj *obj = Tcl_GetObjResult(interp_);
+     
+     int val, cc;
+     cc = Tcl_GetIntFromObj(interp_, obj, &val);
+     if (cc != TCL_OK)
+     {
+          throw tcl_error(interp_);
+     }
+     
+     return val;
+}
+
+result::operator long() const
+{
+     Tcl_Obj *obj = Tcl_GetObjResult(interp_);
+     
+     long val;
+     int cc;
+     cc = Tcl_GetLongFromObj(interp_, obj, &val);
+     if (cc != TCL_OK)
+     {
+          throw tcl_error(interp_);
+     }
+     
+     return val;
+}
+
+result::operator string() const
+{
+     Tcl_Obj *obj = Tcl_GetObjResult(interp_);
+     return Tcl_GetString(obj);
+}
+
+result::operator object() const
+{
+     return object(Tcl_GetObjResult(interp_));
+}
+
+
+void details::set_result(Tcl_Interp *interp, bool b)
+{
+     Tcl_SetObjResult(interp, Tcl_NewBooleanObj(b));
+}
+
+void details::set_result(Tcl_Interp *interp, int i)
+{
+     Tcl_SetObjResult(interp, Tcl_NewIntObj(i));
+}
+
+void details::set_result(Tcl_Interp *interp, long i)
+{
+     Tcl_SetObjResult(interp, Tcl_NewLongObj(i));
+}
+
+void details::set_result(Tcl_Interp *interp, double d)
+{
+     Tcl_SetObjResult(interp, Tcl_NewDoubleObj(d));
+}
+
+void details::set_result(Tcl_Interp *interp, string const &s)
+{
+     Tcl_SetObjResult(interp,
+          Tcl_NewStringObj(s.data(), static_cast<int>(s.size())));
+}
+
+void details::set_result(Tcl_Interp *interp, void *p)
+{
+     ostringstream ss;
+     ss << 'p' << p;
+     string s(ss.str());
+
+     Tcl_SetObjResult(interp,
+          Tcl_NewStringObj(s.data(), static_cast<int>(s.size())));
+}
+
+void details::set_result(Tcl_Interp *interp, object const &o)
+{
+     Tcl_SetObjResult(interp, o.get_object());
+}
+
+
+void details::check_params_no(int objc, int required)
+{
+     if (objc < required)
+     {
+          throw tcl_error("Too few arguments.");
+     }
+}
+
+object details::get_var_params(Tcl_Interp *interp,
+     int objc, Tcl_Obj * CONST objv[],
+     int from, policies const &pol)
+{
+     object o;
+     if (pol.variadic_)
+     {
+          check_params_no(objc, from);
+          o.assign(objv + from, objv + objc);
+     }
+     else
+     {
+          check_params_no(objc, from + 1);
+          o.assign(objv[from]);
+     }
+
+     o.set_interp(interp);
+
+     return o;
+}
+
+
+namespace // anonymous
+{
+
+// map of polymorphic callbacks
+typedef map<string, shared_ptr<callback_base> > callback_interp_map;
+typedef map<Tcl_Interp *, callback_interp_map> callback_map;
+
+callback_map callbacks;
+callback_map constructors;
+
+// map of call policies
+typedef map<string, policies> policies_interp_map;
+typedef map<Tcl_Interp *, policies_interp_map> policies_map;
+
+policies_map call_policies;
+
+// map of object handlers
+typedef map<string, shared_ptr<class_handler_base> > class_interp_map;
+typedef map<Tcl_Interp *, class_interp_map> class_handlers_map;
+
+class_handlers_map class_handlers;
+
+
+// helper for finding call policies - returns true when found
+bool find_policies(Tcl_Interp *interp, string const &cmdName,
+     policies_interp_map::iterator &piti)
+{
+     policies_map::iterator pit = call_policies.find(interp);
+     if (pit == call_policies.end())
+     {
+          return false;
+     }
+     
+     piti = pit->second.find(cmdName);
+     return piti != pit->second.end();
+}
+
+extern "C"
+int object_handler(ClientData cd, Tcl_Interp *interp,
+     int objc, Tcl_Obj * CONST objv[]);
+
+// helper function for post-processing call policies
+// for both free functions (isMethod == false)
+// and class methods (isMethod == true)
+void post_process_policies(Tcl_Interp *interp, policies &pol,
+     Tcl_Obj * CONST objv[], bool isMethod)
+{
+     // check if it is a factory
+     if (!pol.factory_.empty())
+     {
+          class_handlers_map::iterator it = class_handlers.find(interp);
+          if (it == class_handlers.end())
+          {
+               throw tcl_error(
+                    "Factory was registered for unknown class.");
+          }
+
+          class_interp_map::iterator oit = it->second.find(pol.factory_);
+          if (oit == it->second.end())
+          {
+               throw tcl_error(
+                    "Factory was registered for unknown class.");
+          }
+
+          class_handler_base *chb = oit->second.get();
+
+          // register a new command for the object returned
+          // by this factory function
+          // if everything went OK, the result is the address of the
+          // new object in the 'pXXX' form
+          // - the new command will be created with this name
+
+          Tcl_CreateObjCommand(interp,
+               Tcl_GetString(Tcl_GetObjResult(interp)),
+               object_handler, static_cast<ClientData>(chb), 0);
+     }
+
+     // process all declared sinks
+     // - unregister all object commands that envelopes the pointers
+     for (vector<int>::iterator s = pol.sinks_.begin();
+          s != pol.sinks_.end(); ++s)
+     {
+          if (isMethod == false)
+          {
+               // example: if there is a declared sink at parameter 3,
+               // and the Tcl command was:
+               // % fun par1 par2 PAR3 par4
+               // then the index 3 correctly points into the objv array
+
+               int index = *s;
+               Tcl_DeleteCommand(interp, Tcl_GetString(objv[index]));
+          }
+          else
+          {
+               // example: if there is a declared sink at parameter 3,
+               // and the Tcl command was:
+               // % $p method par1 par2 PAR3 par4
+               // then the index 3 needs to be incremented
+               // in order correctly point into the 4th index of objv array
+
+               int index = *s + 1;
+               Tcl_DeleteCommand(interp, Tcl_GetString(objv[index]));
+          }
+     }
+}
+
+// actual functions handling various callbacks
+
+// generic callback handler
+extern "C"
+int callback_handler(ClientData, Tcl_Interp *interp,
+     int objc, Tcl_Obj * CONST objv[])
+{
+     callback_map::iterator it = callbacks.find(interp);
+     if (it == callbacks.end())
+     {
+          Tcl_SetResult(interp,
+               "Trying to invoke non-existent callback (wrong interpreter?)",
+               TCL_STATIC);
+          return TCL_ERROR;
+     }
+     
+     string cmdName(Tcl_GetString(objv[0]));
+     callback_interp_map::iterator iti = it->second.find(cmdName);
+     if (iti == it->second.end())
+     {
+          Tcl_SetResult(interp,
+               "Trying to invoke non-existent callback (wrong cmd name?)",
+               TCL_STATIC);
+          return TCL_ERROR;
+     }
+     
+     policies_map::iterator pit = call_policies.find(interp);
+     if (pit == call_policies.end())
+     {
+          Tcl_SetResult(interp,
+               "Trying to invoke callback with no known policies",
+               TCL_STATIC);
+          return TCL_ERROR;
+     }
+     
+     policies_interp_map::iterator piti;
+     if (find_policies(interp, cmdName, piti) == false)
+     {
+          Tcl_SetResult(interp,
+               "Trying to invoke callback with no known policies",
+               TCL_STATIC);
+          return TCL_ERROR;
+     }
+
+     policies &pol = piti->second;
+     
+     try
+     {
+          iti->second->invoke(interp, objc, objv, pol);
+
+          post_process_policies(interp, pol, objv, false);
+     }
+     catch (std::exception const &e)
+     {
+          Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE);
+          return TCL_ERROR;
+     }
+     catch (...)
+     {
+          Tcl_SetResult(interp, "Unknown error.", TCL_STATIC);
+          return TCL_ERROR;
+     }
+     
+     return TCL_OK;
+}
+
+// generic "object" command handler
+extern "C"
+int object_handler(ClientData cd, Tcl_Interp *interp,
+     int objc, Tcl_Obj * CONST objv[])
+{
+     // here, client data points to the singleton object
+     // which is responsible for managing commands for
+     // objects of a given type
+
+     class_handler_base *chb = reinterpret_cast<class_handler_base*>(cd);
+
+     // the command name has the form 'pXXX' where XXX is the address
+     // of the "this" object
+
+     string const str(Tcl_GetString(objv[0]));
+     istringstream ss(str);
+     char dummy;
+     void *p;
+     ss >> dummy >> p;
+
+     try
+     {
+          string methodName(Tcl_GetString(objv[1]));
+          policies &pol = chb->get_policies(methodName);
+
+          chb->invoke(p, interp, objc, objv, pol);
+
+          post_process_policies(interp, pol, objv, true);
+     }
+     catch (std::exception const &e)
+     {
+          Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE);
+          return TCL_ERROR;
+     }
+     catch (...)
+     {
+          Tcl_SetResult(interp, "Unknown error.", TCL_STATIC);
+          return TCL_ERROR;
+     }
+
+     return TCL_OK;
+}
+
+// generic "constructor" command
+extern "C"
+int constructor_handler(ClientData cd, Tcl_Interp *interp,
+     int objc, Tcl_Obj * CONST objv[])
+{
+     // here, client data points to the singleton object
+     // which is responsible for managing commands for
+     // objects of a given type
+
+     class_handler_base *chb = reinterpret_cast<class_handler_base*>(cd);
+
+     callback_map::iterator it = constructors.find(interp);
+     if (it == constructors.end())
+     {
+          Tcl_SetResult(interp,
+               "Trying to invoke non-existent callback (wrong interpreter?)",
+               TCL_STATIC);
+          return TCL_ERROR;
+     }
+     
+     string className(Tcl_GetString(objv[0]));
+     callback_interp_map::iterator iti = it->second.find(className);
+     if (iti == it->second.end())
+     {
+          Tcl_SetResult(interp,
+               "Trying to invoke non-existent callback (wrong class name?)",
+               TCL_STATIC);
+          return TCL_ERROR;
+     }
+     
+     policies_interp_map::iterator piti;
+     if (find_policies(interp, className, piti) == false)
+     {
+          Tcl_SetResult(interp,
+               "Trying to invoke callback with no known policies",
+               TCL_STATIC);
+          return TCL_ERROR;
+     }
+
+     policies &pol = piti->second;
+
+     try
+     {
+          iti->second->invoke(interp, objc, objv, pol);
+
+          // if everything went OK, the result is the address of the
+          // new object in the 'pXXX' form
+          // - we can create a new command with this name
+
+          Tcl_CreateObjCommand(interp,
+               Tcl_GetString(Tcl_GetObjResult(interp)),
+               object_handler, static_cast<ClientData>(chb), 0);
+     }
+     catch (std::exception const &e)
+     {
+          Tcl_SetResult(interp, const_cast<char*>(e.what()), TCL_VOLATILE);
+          return TCL_ERROR;
+     }
+     catch (...)
+     {
+          Tcl_SetResult(interp, "Unknown error.", TCL_STATIC);
+          return TCL_ERROR;
+     }
+
+     return TCL_OK;
+}
+
+} // namespace anonymous
+
+Tcl::details::no_init_type Tcl::no_init;
+
+
+policies & policies::factory(string const &name)
+{
+     factory_ = name;
+     return *this;
+}
+
+policies & policies::sink(int index)
+{
+     sinks_.push_back(index);
+     return *this;
+}
+
+policies & policies::variadic()
+{
+     variadic_ = true;
+     return *this;
+}
+
+policies Tcl::factory(string const &name)
+{
+     return policies().factory(name);
+}
+
+policies Tcl::sink(int index)
+{
+     return policies().sink(index);
+}
+
+policies Tcl::variadic()
+{
+     return policies().variadic();
+}
+
+
+class_handler_base::class_handler_base()
+{
+     // default policies for the -delete command
+     policies_["-delete"] = policies();
+}
+
+void class_handler_base::register_method(string const &name,
+     shared_ptr<object_cmd_base> ocb, policies const &p)
+{
+     methods_[name] = ocb;
+     policies_[name] = p;
+}
+
+policies & class_handler_base::get_policies(string const &name)
+{
+     policies_map_type::iterator it = policies_.find(name);
+     if (it == policies_.end())
+     {
+          throw tcl_error("Trying to use non-existent policy: " + name);
+     }
+
+     return it->second;
+}
+
+
+object::object()
+     : interp_(0)
+{
+     obj_ = Tcl_NewObj();
+     Tcl_IncrRefCount(obj_);
+}
+
+object::object(bool b)
+     : interp_(0)
+{
+     obj_ = Tcl_NewBooleanObj(b);
+     Tcl_IncrRefCount(obj_);
+}
+
+object::object(char const *buf, size_t size)
+     : interp_(0)
+{
+     obj_ = Tcl_NewByteArrayObj(
+          reinterpret_cast<unsigned char const *>(buf),
+          static_cast<int>(size));
+     Tcl_IncrRefCount(obj_);
+}
+
+object::object(double d)
+     : interp_(0)
+{
+     obj_ = Tcl_NewDoubleObj(d);
+     Tcl_IncrRefCount(obj_);
+}
+
+object::object(int i)
+     : interp_(0)
+{
+     obj_ = Tcl_NewIntObj(i);
+     Tcl_IncrRefCount(obj_);
+}
+
+object::object(long l)
+     : interp_(0)
+{
+     obj_ = Tcl_NewLongObj(l);
+     Tcl_IncrRefCount(obj_);
+}
+
+object::object(char const *s)
+     : interp_(0)
+{
+     obj_ = Tcl_NewStringObj(s, -1);
+     Tcl_IncrRefCount(obj_);
+}
+
+object::object(string const &s)
+     : interp_(0)
+{
+     obj_ = Tcl_NewStringObj(s.data(), static_cast<int>(s.size()));
+     Tcl_IncrRefCount(obj_);
+}
+
+object::object(Tcl_Obj *o, bool shared)
+     : interp_(0)
+{
+     init(o, shared);
+}
+
+object::object(object const &other, bool shared)
+     : interp_(other.get_interp())
+{
+     init(other.obj_, shared);
+}
+
+void object::init(Tcl_Obj *o, bool shared)
+{
+     if (shared)
+     {
+          obj_ = o;
+     }
+     else
+     {
+          obj_ = Tcl_DuplicateObj(o);
+     }
+     Tcl_IncrRefCount(obj_);
+}
+
+object::~object()
+{
+     Tcl_DecrRefCount(obj_);
+}
+
+object & object::assign(bool b)
+{
+     Tcl_SetBooleanObj(obj_, b);
+     return *this;
+}
+
+object & object::resize(size_t size)
+{
+     Tcl_SetByteArrayLength(obj_, static_cast<int>(size));
+     return *this;
+}
+
+object & object::assign(char const *buf, size_t size)
+{
+     Tcl_SetByteArrayObj(obj_,
+          reinterpret_cast<unsigned char const *>(buf),
+          static_cast<int>(size));
+     return *this;
+}
+
+object & object::assign(double d)
+{
+     Tcl_SetDoubleObj(obj_, d);
+     return *this;
+}
+
+object & object::assign(int i)
+{
+     Tcl_SetIntObj(obj_, i);
+     return *this;
+}
+
+object & object::assign(long l)
+{
+     Tcl_SetLongObj(obj_, l);
+     return *this;
+}
+
+object & object::assign(char const *s)
+{
+     Tcl_SetStringObj(obj_, s, -1);
+     return *this;
+}
+
+object & object::assign(string const &s)
+{
+     Tcl_SetStringObj(obj_, s.data(), static_cast<int>(s.size()));
+     return *this;
+}
+
+object & object::assign(object const &other)
+{
+     object(other).swap(*this);
+     return *this;
+}
+
+object & object::assign(Tcl_Obj *o)
+{
+     object(o).swap(*this);
+     return *this;
+}
+
+object & object::swap(object &other)
+{
+     std::swap(obj_, other.obj_);
+     std::swap(interp_, other.interp_);
+     return *this;
+}
+
+template <>
+bool object::get<bool>(interpreter &i) const
+{
+     int retVal;
+     int res = Tcl_GetBooleanFromObj(i.get(), obj_, &retVal);
+     if (res != TCL_OK)
+     {
+          throw tcl_error(i.get());
+     }
+
+     return static_cast<bool>(retVal);
+}
+
+template <>
+vector<char> object::get<vector<char> >(interpreter &) const
+{
+     size_t size;
+     char const *buf = get(size);
+     return vector<char>(buf, buf + size);
+}
+
+template <>
+double object::get<double>(interpreter &i) const
+{
+     double retVal;
+     int res = Tcl_GetDoubleFromObj(i.get(), obj_, &retVal);
+     if (res != TCL_OK)
+     {
+          throw tcl_error(i.get());
+     }
+
+     return retVal;
+}
+
+template <>
+int object::get<int>(interpreter &i) const
+{
+     int retVal;
+
+     int res = Tcl_GetIntFromObj(i.get(), obj_, &retVal);
+     if (res != TCL_OK)
+     {
+          throw tcl_error(i.get());
+     }
+
+     return retVal;
+}
+
+template <>
+long object::get<long>(interpreter &i) const
+{
+     long retVal;
+     int res = Tcl_GetLongFromObj(i.get(), obj_, &retVal);
+     if (res != TCL_OK)
+     {
+          throw tcl_error(i.get());
+     }
+
+     return retVal;
+}
+
+template <>
+char const * object::get<char const *>(interpreter &) const
+{
+     return get();
+}
+
+template <>
+string object::get<string>(interpreter &) const
+{
+     int len;
+     char const *buf = Tcl_GetStringFromObj(obj_, &len);
+     return string(buf, buf + len);
+}
+
+char const * object::get() const
+{
+     return Tcl_GetString(obj_);
+}
+
+char const * object::get(size_t &size) const
+{
+     int len;
+     unsigned char *buf = Tcl_GetByteArrayFromObj(obj_, &len);
+     size = len;
+     return const_cast<char const *>(reinterpret_cast<char *>(buf));
+}
+
+size_t object::length(interpreter &i) const
+{
+     int len;
+     int res = Tcl_ListObjLength(i.get(), obj_, &len);
+
+     if (res != TCL_OK)
+     {
+          throw tcl_error(i.get());
+     }
+
+     return static_cast<size_t>(len);
+}
+
+object object::at(interpreter &i, size_t index) const
+{
+     Tcl_Obj *o;
+     int res = Tcl_ListObjIndex(i.get(), obj_, static_cast<int>(index), &o);
+     if (res != TCL_OK)
+     {
+          throw tcl_error(i.get());
+     }
+     if (o == NULL)
+     {
+          throw tcl_error("Index out of range.");
+     }
+
+     return object(o);
+}
+
+object & object::append(interpreter &i, object const &o)
+{
+     int res = Tcl_ListObjAppendElement(i.get(), obj_, o.obj_);
+     if (res != TCL_OK)
+     {
+          throw tcl_error(i.get());
+     }
+
+     return *this;
+}
+
+object & object::append_list(interpreter &i, object const &o)
+{
+     int res = Tcl_ListObjAppendList(i.get(), obj_, o.obj_);
+     if (res != TCL_OK)
+     {
+          throw tcl_error(i.get());
+     }
+
+     return *this;
+}
+
+object & object::replace(interpreter &i, size_t index, size_t count,
+     object const &o)
+{
+     int res = Tcl_ListObjReplace(i.get(), obj_,
+          static_cast<int>(index), static_cast<int>(count),
+          1, &(o.obj_));
+     if (res != TCL_OK)
+     {
+          throw tcl_error(i.get());
+     }
+
+     return *this;
+}
+
+object & object::replace_list(interpreter &i, size_t index, size_t count,
+     object const &o)
+{
+     int objc;
+     Tcl_Obj **objv;
+
+     int res = Tcl_ListObjGetElements(i.get(), o.obj_, &objc, &objv);
+     if (res != TCL_OK)
+     {
+          throw tcl_error(i.get());
+     }
+
+     res = Tcl_ListObjReplace(i.get(), obj_,
+          static_cast<int>(index), static_cast<int>(count),
+          objc, objv);
+     if (res != TCL_OK)
+     {
+          throw tcl_error(i.get());
+     }
+
+     return *this;
+}
+
+void object::set_interp(Tcl_Interp *interp)
+{
+     interp_ = interp;
+}
+
+Tcl_Interp * object::get_interp() const
+{
+     return interp_;
+}
+
+
+interpreter::interpreter()
+{
+     interp_ =  Tcl_CreateInterp();
+     owner_ = true;
+}
+
+interpreter::interpreter(Tcl_Interp *interp, bool owner)
+{
+     interp_ =  interp;
+     owner_ = owner;
+}
+
+interpreter::~interpreter()
+{
+     if (owner_)
+     {
+          // clear all callback info belonging to this interpreter
+          clear_definitions(interp_);
+
+          Tcl_DeleteInterp(interp_);
+     }
+}
+
+void interpreter::make_safe()
+{
+     int cc = Tcl_MakeSafe(interp_);
+     if (cc != TCL_OK)
+     {
+          throw tcl_error(interp_);
+     }
+}
+
+result interpreter::eval(string const &script)
+{
+     int cc = Tcl_Eval(interp_, script.c_str());
+     if (cc != TCL_OK)
+     {
+          throw tcl_error(interp_);
+     }
+ 
+     return result(interp_);
+}
+
+result interpreter::eval(istream &s)
+{
+     string str(
+          istreambuf_iterator<char>(s.rdbuf()),
+          istreambuf_iterator<char>()
+     );
+     return eval(str);
+}
+
+result interpreter::eval(object const &o)
+{
+     int cc = Tcl_EvalObjEx(interp_, o.get_object(), 0);
+     if (cc != TCL_OK)
+     {
+          throw tcl_error(interp_);
+     }
+ 
+     return result(interp_);
+}
+
+void interpreter::pkg_provide(string const &name, string const &version)
+{
+     int cc = Tcl_PkgProvide(interp_, name.c_str(), version.c_str());
+     if (cc != TCL_OK)
+     {
+          throw tcl_error(interp_);
+     }
+}
+
+void interpreter::create_alias(string const &cmd,
+     interpreter &targetInterp, string const &targetCmd)
+{
+     int cc = Tcl_CreateAlias(interp_, cmd.c_str(),
+          targetInterp.interp_, targetCmd.c_str(), 0, 0);
+     if (cc != TCL_OK)
+     {
+          throw tcl_error(interp_);
+     }
+}
+
+void interpreter::clear_definitions(Tcl_Interp *interp)
+{
+     // delete all callbacks that were registered for given interpreter
+
+     {
+          callback_map::iterator it = callbacks.find(interp);
+          if (it == callbacks.end())
+          {
+               // no callbacks defined for this interpreter
+               return;
+          }
+
+          callback_interp_map &imap = it->second;
+          for (callback_interp_map::iterator it2 = imap.begin();
+               it2 != imap.end(); ++it2)
+          {
+               Tcl_DeleteCommand(interp, it2->first.c_str());
+          }
+
+          callbacks.erase(interp);
+     }
+
+     // delete all constructors
+
+     {
+          callback_map::iterator it = constructors.find(interp);
+          if (it == constructors.end())
+          {
+               // no callbacks defined for this interpreter
+               return;
+          }
+
+          callback_interp_map &imap = it->second;
+          for (callback_interp_map::iterator it2 = imap.begin();
+               it2 != imap.end(); ++it2)
+          {
+               Tcl_DeleteCommand(interp, it2->first.c_str());
+          }
+
+          callbacks.erase(interp);
+     }
+
+     // delete all call policies
+
+     call_policies.erase(interp);
+
+     // delete all object handlers
+     // (we have to assume that all living objects were destroyed,
+     // otherwise Bad Things will happen)
+
+     class_handlers.erase(interp);
+}
+
+void interpreter::add_function(string const &name,
+     shared_ptr<callback_base> cb, policies const &p)
+{
+     Tcl_CreateObjCommand(interp_, name.c_str(),
+          callback_handler, 0, 0);
+     
+     callbacks[interp_][name] = cb;
+     call_policies[interp_][name] = p;
+}
+
+void interpreter::add_class(string const &name,
+     shared_ptr<class_handler_base> chb)
+{
+     class_handlers[interp_][name] = chb;
+}
+
+void interpreter::add_constructor(string const &name,
+     shared_ptr<class_handler_base> chb, shared_ptr<callback_base> cb,
+     policies const &p)
+{
+     Tcl_CreateObjCommand(interp_, name.c_str(),
+          constructor_handler, static_cast<ClientData>(chb.get()), 0);
+
+     constructors[interp_][name] = cb;
+     call_policies[interp_][name] = p;
+}
+
+
+int tcl_cast<int>::from(Tcl_Interp *interp, Tcl_Obj *obj)
+{
+     int res;
+     int cc = Tcl_GetIntFromObj(interp, obj, &res);
+     if (cc != TCL_OK)
+     {
+          throw tcl_error(interp);
+     }
+     
+     return res;
+}
+
+long tcl_cast<long>::from(Tcl_Interp *interp, Tcl_Obj *obj)
+{
+     long res;
+     int cc = Tcl_GetLongFromObj(interp, obj, &res);
+     if (cc != TCL_OK)
+     {
+          throw tcl_error(interp);
+     }
+     
+     return res;
+}
+
+bool tcl_cast<bool>::from(Tcl_Interp *interp, Tcl_Obj *obj)
+{
+     int res;
+     int cc = Tcl_GetBooleanFromObj(interp, obj, &res);
+     if (cc != TCL_OK)
+     {
+          throw tcl_error(interp);
+     }
+     
+     return res != 0;
+}
+
+double tcl_cast<double>::from(Tcl_Interp *interp, Tcl_Obj *obj)
+{
+     double res;
+     int cc = Tcl_GetDoubleFromObj(interp, obj, &res);
+     if (cc != TCL_OK)
+     {
+          throw tcl_error(interp);
+     }
+     
+     return res;
+}
+
+string tcl_cast<string>::from(Tcl_Interp *, Tcl_Obj *obj)
+{
+     return Tcl_GetString(obj);
+}
+
+char const * tcl_cast<char const *>::from(Tcl_Interp *, Tcl_Obj *obj)
+{
+     return Tcl_GetString(obj);
+}
+
+object tcl_cast<object>::from(Tcl_Interp *interp, Tcl_Obj *obj)
+{
+     object o(obj);
+     o.set_interp(interp);
+
+     return o;
+}
Index: /code/branches/rocket2/src/external/cpptcl/cpptcl.h
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/cpptcl.h	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/cpptcl.h	(revision 6952)
@@ -0,0 +1,870 @@
+//
+// Copyright (C) 2004-2006, Maciej Sobczak
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+
+#ifndef CPPTCL_INCLUDED
+#define CPPTCL_INCLUDED
+
+#include <tcl.h>
+#include <string>
+#include <stdexcept>
+#include <sstream>
+#include <map>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <boost/bind.hpp>
+
+
+namespace Tcl
+{
+
+// exception class used for reporting all Tcl errors
+
+class tcl_error : public std::runtime_error
+{
+public:
+     explicit tcl_error(std::string const &msg)
+          : std::runtime_error(msg) {}
+     explicit tcl_error(Tcl_Interp *interp)
+          : std::runtime_error(Tcl_GetString(Tcl_GetObjResult(interp))) {}
+};
+
+// call policies
+
+struct policies
+{
+     policies() : variadic_(false) {}
+
+     policies & factory(std::string const &name);
+
+     // note: this is additive
+     policies & sink(int index);
+
+     policies & variadic();
+
+     std::string factory_;
+     std::vector<int> sinks_;
+     bool variadic_;
+};
+
+// syntax short-cuts
+policies factory(std::string const &name);
+policies sink(int index);
+policies variadic();
+
+
+class interpreter;
+class object;
+
+namespace details
+{
+
+// wrapper for the evaluation result
+class result
+{
+public:
+     result(Tcl_Interp *interp);
+     
+     operator bool() const;
+     operator double() const;
+     operator int() const;
+     operator long() const;
+     operator std::string() const;
+     operator object() const;
+
+private:
+     Tcl_Interp *interp_;
+};
+
+// helper functions used to set the result value
+
+void set_result(Tcl_Interp *interp, bool b);
+void set_result(Tcl_Interp *interp, int i);
+void set_result(Tcl_Interp *interp, long i);
+void set_result(Tcl_Interp *interp, double d);
+void set_result(Tcl_Interp *interp, std::string const &s);
+void set_result(Tcl_Interp *interp, void *p);
+void set_result(Tcl_Interp *interp, object const &o);
+
+// helper functor for converting Tcl objects to the given type
+#include "details/conversions.h"
+
+// dispatchers able to capture (or ignore) the result
+#include "details/dispatchers.h"
+
+// helper for checking for required number of parameters
+// (throws tcl_error when not met)
+void check_params_no(int objc, int required);
+
+// helper for gathering optional params in variadic functions
+object get_var_params(Tcl_Interp *interp,
+     int objc, Tcl_Obj * CONST objv[],
+     int from, policies const &pol);
+
+// the callback_base is used to store callback handlers in a polynorphic map
+class callback_base
+{
+public:
+     virtual ~callback_base() {}
+
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &pol) = 0;
+};
+
+
+// base class for object command handlers
+// and for class handlers
+class object_cmd_base
+{
+public:
+     // destructor not needed, but exists to shut up the compiler warnings
+     virtual ~object_cmd_base() {}
+
+     virtual void invoke(void *p, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &pol) = 0;
+};
+
+// base class for all class handlers, still abstract
+class class_handler_base : public object_cmd_base
+{
+public:
+     typedef std::map<std::string, policies> policies_map_type;
+
+     class_handler_base();
+
+     void register_method(std::string const &name,
+          boost::shared_ptr<object_cmd_base> ocb, policies const &p);
+
+     policies & get_policies(std::string const &name);
+
+protected:
+     typedef std::map<
+          std::string,
+          boost::shared_ptr<object_cmd_base>
+          > method_map_type;
+
+     // a map of methods for the given class
+     method_map_type methods_;
+
+     policies_map_type policies_;
+};
+
+// class handler - responsible for executing class methods
+template <class C>
+class class_handler : public class_handler_base
+{
+public:
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &pol)
+     {
+          C * p = static_cast<C*>(pv);
+
+          if (objc < 2)
+          {
+               throw tcl_error("Too few arguments.");
+          }
+          
+          std::string methodName(Tcl_GetString(objv[1]));
+
+          if (methodName == "-delete")
+          {
+               Tcl_DeleteCommand(interp, Tcl_GetString(objv[0]));
+               delete p;
+               return;
+          }
+
+          // dispatch on the method name
+
+          method_map_type::iterator it = methods_.find(methodName);
+          if (it == methods_.end())
+          {
+               throw tcl_error("Method " + methodName + " not found.");
+          }
+
+          it->second->invoke(pv, interp, objc, objv, pol);
+     }
+};
+
+
+// factory functions for creating class objects
+#include "details/constructors.h"
+
+// actual callback envelopes
+#include "details/callbacks.h"
+
+// actual method envelopes
+#include "details/methods.h"
+
+// helper meta function for figuring appropriate constructor callback
+#include "details/metahelpers.h"
+
+
+// this class is used to provide the "def" interface for defining
+// class member functions
+
+template <class C>
+class class_definer
+{
+public:
+     class_definer(boost::shared_ptr<class_handler<C> > ch) : ch_(ch) {}
+
+     template <typename R>
+     class_definer & def(std::string const &name, R (C::*f)(),
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method0<C, R>(f)), p);
+          return *this;
+     }
+
+     template <typename R>
+     class_definer & def(std::string const &name, R (C::*f)() const,
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method0<C, R>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1>
+     class_definer & def(std::string const &name, R (C::*f)(T1),
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method1<C, R, T1>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1>
+     class_definer & def(std::string const &name, R (C::*f)(T1) const,
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method1<C, R, T1>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2>
+     class_definer & def(std::string const &name, R (C::*f)(T1, T2),
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method2<C, R, T1, T2>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2>
+     class_definer & def(std::string const &name, R (C::*f)(T1, T2) const,
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method2<C, R, T1, T2>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2, typename T3>
+     class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3),
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method3<C, R, T1, T2, T3>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2, typename T3>
+     class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3) const,
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method3<C, R, T1, T2, T3>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2, typename T3, typename T4>
+     class_definer & def(std::string const &name, R (C::*f)(T1, T2, T3, T4),
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method4<C, R, T1, T2, T3, T4>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2, typename T3, typename T4>
+     class_definer & def(std::string const &name,
+          R (C::*f)(T1, T2, T3, T4) const,
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method4<C, R, T1, T2, T3, T4>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2, typename T3, typename T4,
+          typename T5>
+     class_definer & def(std::string const &name,
+          R (C::*f)(T1, T2, T3, T4, T5), policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method5<C, R, T1, T2, T3, T4, T5>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2, typename T3, typename T4,
+          typename T5>
+     class_definer & def(std::string const &name,
+          R (C::*f)(T1, T2, T3, T4, T5) const, policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method5<C, R, T1, T2, T3, T4, T5>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6>
+     class_definer & def(std::string const &name,
+          R (C::*f)(T1, T2, T3, T4, T5, T6), policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method6<C, R, T1, T2, T3, T4, T5, T6>(f)),
+               p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6>
+     class_definer & def(std::string const &name,
+          R (C::*f)(T1, T2, T3, T4, T5, T6) const,
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method6<C, R, T1, T2, T3, T4, T5, T6>(f)),
+               p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7>
+     class_definer & def(std::string const &name,
+          R (C::*f)(T1, T2, T3, T4, T5, T6, T7),
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method7<C, R,
+                    T1, T2, T3, T4, T5, T6, T7>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7>
+     class_definer & def(std::string const &name,
+          R (C::*f)(T1, T2, T3, T4, T5, T6, T7) const,
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method7<C, R,
+                    T1, T2, T3, T4, T5, T6, T7>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7, typename T8>
+     class_definer & def(std::string const &name,
+          R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8),
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method8<C, R,
+                    T1, T2, T3, T4, T5, T6, T7, T8>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7, typename T8>
+     class_definer & def(std::string const &name,
+          R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8) const,
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method8<C, R,
+                    T1, T2, T3, T4, T5, T6, T7, T8>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7, typename T8, typename T9>
+     class_definer & def(std::string const &name,
+          R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9),
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method9<C, R,
+                    T1, T2, T3, T4, T5, T6, T7, T8, T9>(f)), p);
+          return *this;
+     }
+
+     template <typename R, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7, typename T8, typename T9>
+     class_definer & def(std::string const &name,
+          R (C::*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9) const,
+          policies const &p = policies())
+     {
+          ch_->register_method(name,
+               boost::shared_ptr<details::object_cmd_base>(
+                    new details::method9<C, R,
+                    T1, T2, T3, T4, T5, T6, T7, T8, T9>(f)), p);
+          return *this;
+     }
+
+private:
+     boost::shared_ptr<class_handler<C> > ch_;
+};
+
+} // namespace details
+
+
+// init type for defining class constructors
+template <typename T1 = void, typename T2 = void, typename T3 = void,
+          typename T4 = void, typename T5 = void, typename T6 = void,
+          typename T7 = void, typename T8 = void, typename T9 = void>
+class init {};
+
+// no_init type and object - to define classes without constructors
+namespace details
+{
+     struct no_init_type {};
+} // namespace details
+extern details::no_init_type no_init;
+
+
+// interpreter wrapper
+class interpreter
+{
+public:
+     interpreter();
+     interpreter(Tcl_Interp *, bool owner = true);
+     ~interpreter();
+     
+     void make_safe();
+     
+     Tcl_Interp * get() const { return interp_; }
+
+     // free function definitions     
+     
+     template <typename R>
+     void def(std::string const &name, R (*f)(),
+          policies const &p = policies())
+     {
+          add_function(name,
+               boost::shared_ptr<details::callback_base>(
+                    new details::callback0<R>(f)), p);
+     }
+
+     template <typename R, typename T1>
+     void def(std::string const &name, R (*f)(T1),
+          policies const &p = policies())
+     {
+          add_function(name,
+               boost::shared_ptr<details::callback_base>(
+                    new details::callback1<R, T1>(f)), p);
+     }
+
+     template <typename R, typename T1, typename T2>
+     void def(std::string const &name, R (*f)(T1, T2),
+          policies const &p = policies())
+     {
+          add_function(name,
+               boost::shared_ptr<details::callback_base>(
+                    new details::callback2<R, T1, T2>(f)), p);
+     }
+
+     template <typename R, typename T1, typename T2, typename T3>
+     void def(std::string const &name, R (*f)(T1, T2, T3),
+          policies const &p = policies())
+     {
+          add_function(name,
+               boost::shared_ptr<details::callback_base>(
+                    new details::callback3<R, T1, T2, T3>(f)), p);
+     }
+
+     template <typename R, typename T1, typename T2, typename T3, typename T4>
+     void def(std::string const &name, R (*f)(T1, T2, T3, T4),
+          policies const &p = policies())
+     {
+          add_function(name,
+               boost::shared_ptr<details::callback_base>(
+                    new details::callback4<R, T1, T2, T3, T4>(f)), p);
+     }
+
+     template <typename R, typename T1, typename T2, typename T3,
+          typename T4, typename T5>
+     void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5),
+          policies const &p = policies())
+     {
+          add_function(name,
+               boost::shared_ptr<details::callback_base>(
+                    new details::callback5<R, T1, T2, T3, T4, T5>(f)), p);
+     }
+
+     template <typename R, typename T1, typename T2, typename T3,
+          typename T4, typename T5, typename T6>
+     void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5, T6),
+          policies const &p = policies())
+     {
+          add_function(name,
+               boost::shared_ptr<details::callback_base>(
+                    new details::callback6<R, T1, T2, T3, T4, T5, T6>(f)), p);
+     }
+
+     template <typename R, typename T1, typename T2, typename T3,
+          typename T4, typename T5, typename T6, typename T7>
+     void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5, T6, T7),
+          policies const &p = policies())
+     {
+          add_function(name,
+               boost::shared_ptr<details::callback_base>(
+                    new details::callback7<R,
+                    T1, T2, T3, T4, T5, T6, T7>(f)), p);
+     }
+
+     template <typename R, typename T1, typename T2, typename T3,
+          typename T4, typename T5, typename T6, typename T7, typename T8>
+     void def(std::string const &name, R (*f)(T1, T2, T3, T4, T5, T6, T7, T8),
+          policies const &p = policies())
+     {
+          add_function(name,
+               boost::shared_ptr<details::callback_base>(
+                    new details::callback8<R,
+                    T1, T2, T3, T4, T5, T6, T7, T8>(f)), p);
+     }
+
+     template <typename R, typename T1, typename T2, typename T3,
+          typename T4, typename T5, typename T6, typename T7, typename T8,
+          typename T9>
+     void def(std::string const &name,
+          R (*f)(T1, T2, T3, T4, T5, T6, T7, T8, T9),
+          policies const &p = policies())
+     {
+          add_function(name,
+               boost::shared_ptr<details::callback_base>(
+                    new details::callback9<R,
+                    T1, T2, T3, T4, T5, T6, T7, T8, T9>(f)), p);
+     }
+
+
+     // class definitions
+
+     template <class C>
+     details::class_definer<C> class_(std::string const &name)
+     {
+          boost::shared_ptr<details::class_handler<C> > ch(
+               new details::class_handler<C>());
+
+          add_class(name, ch);
+
+          add_constructor(name, ch,
+               boost::shared_ptr<details::callback_base>(
+                    new details::callback0<C*>(&details::construct<
+                         C, void, void, void, void, void, void, void,
+                         void, void>::doit)));
+
+          return details::class_definer<C>(ch);
+     }
+
+     template <class C, typename T1, typename T2, typename T3, typename T4,
+               typename T5, typename T6, typename T7, typename T8,
+               typename T9>
+     details::class_definer<C> class_(std::string const &name,
+          init<T1, T2, T3, T4, T5, T6, T7, T8, T9> const &,
+          policies const &p = policies())
+     {
+          typedef typename details::get_callback_type_for_construct<
+               C, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
+               callback_type;
+
+          boost::shared_ptr<details::class_handler<C> > ch(
+               new details::class_handler<C>());
+
+          add_class(name, ch);
+
+          add_constructor(name, ch,
+               boost::shared_ptr<details::callback_base>(
+                    new callback_type(&details::construct<
+                         C, T1, T2, T3, T4, T5, T6, T7, T8, T9>::doit)), p);
+
+          return details::class_definer<C>(ch);
+     }
+
+     template <class C>
+     details::class_definer<C> class_(
+          std::string const &name, details::no_init_type const &)
+     {
+          boost::shared_ptr<details::class_handler<C> > ch(
+               new details::class_handler<C>());
+
+          add_class(name, ch);
+
+          return details::class_definer<C>(ch);
+     }
+
+     // free script evaluation     
+     details::result eval(std::string const &script);
+     details::result eval(std::istream &s);
+
+     details::result eval(object const &o);
+
+     // the InputIterator should give object& or Tcl_Obj* when dereferenced
+     template <class InputIterator>
+     details::result eval(InputIterator first, InputIterator last);
+
+     // create alias from the *this interpreter to the target interpreter
+     void create_alias(std::string const &cmd,
+          interpreter &targetInterp, std::string const &targetCmd);
+
+     // register a package info (useful when defining packages)
+     void pkg_provide(std::string const &name, std::string const &version);
+
+     // helper for cleaning up callbacks in non-managed interpreters
+     static void clear_definitions(Tcl_Interp *);
+
+private:
+
+     // copy not supported
+     interpreter(const interpreter &);
+     void operator=(const interpreter &);
+
+     void add_function(std::string const &name,
+          boost::shared_ptr<details::callback_base> cb,
+          policies const &p = policies());
+
+     void add_class(std::string const &name,
+          boost::shared_ptr<details::class_handler_base> chb);
+
+     void add_constructor(std::string const &name,
+          boost::shared_ptr<details::class_handler_base> chb,
+          boost::shared_ptr<details::callback_base> cb,
+          policies const &p = policies());
+
+     Tcl_Interp *interp_;
+     bool owner_;
+};
+
+
+// object wrapper
+class object
+{
+public:
+
+     // constructors
+
+     object();
+
+     explicit object(bool b);
+     object(char const *buf, size_t size); // byte array
+     explicit object(double b);
+     explicit object(int i);
+
+     // list creation
+     // the InputIterator should give object& or Tcl_Obj* when dereferenced
+     template <class InputIterator>
+     object(InputIterator first, InputIterator last)
+          : interp_(0)
+     {
+          std::vector<Tcl_Obj*> v;
+          fill_vector(v, first, last);
+          obj_ = Tcl_NewListObj(static_cast<int>(v.size()),
+               v.empty() ? NULL : &v[0]);
+          Tcl_IncrRefCount(obj_);
+     }
+
+     explicit object(long i);
+     explicit object(char const *s);        // string construction
+     explicit object(std::string const &s); // string construction
+
+     explicit object(Tcl_Obj *o, bool shared = false);
+
+     object(object const &other, bool shared = false);
+     ~object();
+
+     // assignment
+
+     object & assign(bool b);
+     object & resize(size_t size);                  // byte array resize
+     object & assign(char const *buf, size_t size); // byte array assignment
+     object & assign(double d);
+     object & assign(int i);
+
+     // list assignment
+     // the InputIterator should give Tcl_Obj* or object& when dereferenced
+     template <class InputIterator>
+     object & assign(InputIterator first, InputIterator last)
+     {
+          std::vector<Tcl_Obj*> v;
+          fill_vector(v, first, last);
+          Tcl_SetListObj(obj_, static_cast<int>(v.size()),
+               v.empty() ? NULL : &v[0]);
+          return *this;
+     }
+
+     object & assign(long l);
+     object & assign(char const *s);        // string assignment
+     object & assign(std::string const &s); // string assignment
+     object & assign(object const &o);
+     object & assign(Tcl_Obj *o);
+
+     object & operator=(bool b)               { return assign(b); }
+     object & operator=(double d)             { return assign(d); }
+     object & operator=(int i)                { return assign(i); }
+     object & operator=(long l)               { return assign(l); }
+     object & operator=(char const *s)        { return assign(s); }
+     object & operator=(std::string const &s) { return assign(s); }
+
+     object & operator=(object const &o)      { return assign(o); }
+     object & swap(object &other);
+
+     // (logically) non-modifying members
+
+     template <typename T>
+     T get(interpreter &i) const;
+
+     char const * get() const;             // string get
+     char const * get(size_t &size) const; // byte array get
+
+     size_t length(interpreter &i) const;  // returns list length
+     object at(interpreter &i, size_t index) const;
+
+     Tcl_Obj * get_object() const { return obj_; }
+
+     // modifying members
+
+     object & append(interpreter &i, object const &o);
+     object & append_list(interpreter &i, object const &o);
+
+     // list replace
+     // the InputIterator should give Tcl_Obj* or object& when dereferenced
+     template <class InputIterator>
+     object & replace(interpreter &i, size_t index, size_t count,
+          InputIterator first, InputIterator last)
+     {
+          std::vector<Tcl_Obj*> v;
+          fill_vector(v, first, last);
+          int res = Tcl_ListObjReplace(i.get(), obj_,
+               static_cast<int>(index), static_cast<int>(count),
+               static_cast<int>(v.size()), v.empty() ? NULL : &v[0]);
+          if (res != TCL_OK)
+          {
+               throw tcl_error(i.get());
+          }
+
+          return *this;
+     }
+
+     object & replace(interpreter &i, size_t index, size_t count,
+          object const &o);
+     object & replace_list(interpreter &i, size_t index, size_t count,
+          object const &o);
+
+     // helper functions for piggy-backing interpreter info
+     void set_interp(Tcl_Interp *interp);
+     Tcl_Interp * get_interp() const;
+
+     // helper function, also used from interpreter::eval
+     template <class InputIterator>
+     static void fill_vector(std::vector<Tcl_Obj*> &v,
+          InputIterator first, InputIterator last)
+     {
+          for (; first != last; ++first)
+          {
+               object o(*first, true);
+               v.push_back(o.obj_);
+          }
+     }
+
+private:
+
+     // helper function used from copy constructors
+     void init(Tcl_Obj *o, bool shared);
+
+     Tcl_Obj *obj_;
+     Tcl_Interp *interp_;
+};
+
+// available specializations for object::get
+template <> bool         object::get<bool>(interpreter &i) const;
+template <> double       object::get<double>(interpreter &i) const;
+template <> int          object::get<int>(interpreter &i) const;
+template <> long         object::get<long>(interpreter &i) const;
+template <> char const * object::get<char const *>(interpreter &i) const;
+template <> std::string  object::get<std::string>(interpreter &i) const;
+template <>
+std::vector<char> object::get<std::vector<char> >(interpreter &i) const;
+
+// the InputIterator should give object& or Tcl_Obj* when dereferenced
+template <class InputIterator>
+details::result interpreter::eval(InputIterator first, InputIterator last)
+{
+     std::vector<Tcl_Obj*> v;
+     object::fill_vector(v, first, last);
+     int cc = Tcl_EvalObjv(interp_,
+          static_cast<int>(v.size()), v.empty() ? NULL : &v[0], 0);
+     if (cc != TCL_OK)
+     {
+          throw tcl_error(interp_);
+     }
+ 
+     return details::result(interp_);
+}
+
+namespace details
+{
+
+// additional callback envelopes for variadic functions
+#include "details/callbacks_v.h"
+
+// additional method envelopes for variadic methods
+#include "details/methods_v.h"
+
+} // namespace details
+
+} // namespace Tcl
+
+
+// macro for defining loadable module entry point
+// - used for extending Tcl interpreter
+
+#define CPPTCL_MODULE(name, i) void name##_cpptcl_Init(Tcl::interpreter &i); \
+     extern "C" int name##_Init(Tcl_Interp *interp) \
+     { \
+          Tcl::interpreter i(interp, false); \
+          name##_cpptcl_Init(i); \
+          return TCL_OK; \
+     } \
+     void name##_cpptcl_Init(Tcl::interpreter &i)
+
+
+#endif // CPPTCL_INCLUDED
Index: /code/branches/rocket2/src/external/cpptcl/details/callbacks.h
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/details/callbacks.h	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/details/callbacks.h	(revision 6952)
@@ -0,0 +1,273 @@
+//
+// Copyright (C) 2004-2006, Maciej Sobczak
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+
+// Note: this file is not supposed to be a stand-alone header
+
+
+template <typename R>
+class callback0 : public callback_base
+{
+     typedef R (*functor_type)();
+     
+public:
+     callback0(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int, Tcl_Obj * CONST [],
+          policies const &)
+     {
+          dispatch<R>::do_dispatch(interp, f_);
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1>
+class callback1 : public callback_base
+{
+     typedef R (*functor_type)(T1);
+     
+public:
+     callback1(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &)
+     {
+          check_params_no(objc, 2);
+          
+          dispatch<R>::template do_dispatch<T1>(interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]));
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2>
+class callback2 : public callback_base
+{
+     typedef R (*functor_type)(T1, T2);
+     
+public:
+     callback2(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &)
+     {
+          check_params_no(objc, 3);
+          
+          dispatch<R>::template do_dispatch<T1, T2>(interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]));
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2, typename T3>
+class callback3 : public callback_base
+{
+     typedef R (*functor_type)(T1, T2, T3);
+     
+public:
+     callback3(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &)
+     {
+          check_params_no(objc, 4);
+          
+          dispatch<R>::template do_dispatch<T1, T2, T3>(interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]),
+               tcl_cast<T3>::from(interp, objv[3]));
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2, typename T3, typename T4>
+class callback4 : public callback_base
+{
+     typedef R (*functor_type)(T1, T2, T3, T4);
+     
+public:
+     callback4(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &)
+     {
+          check_params_no(objc, 5);
+          
+          dispatch<R>::template do_dispatch<T1, T2, T3, T4>(interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]),
+               tcl_cast<T3>::from(interp, objv[3]),
+               tcl_cast<T4>::from(interp, objv[4]));
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2, typename T3, typename T4,
+     typename T5>
+class callback5 : public callback_base
+{
+     typedef R (*functor_type)(T1, T2, T3, T4, T5);
+     
+public:
+     callback5(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &)
+     {
+          check_params_no(objc, 6);
+          
+          dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5>(interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]),
+               tcl_cast<T3>::from(interp, objv[3]),
+               tcl_cast<T4>::from(interp, objv[4]),
+               tcl_cast<T5>::from(interp, objv[5]));
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2, typename T3, typename T4,
+     typename T5, typename T6>
+class callback6 : public callback_base
+{
+     typedef R (*functor_type)(T1, T2, T3, T4, T5, T6);
+     
+public:
+     callback6(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &)
+     {
+          check_params_no(objc, 7);
+          
+          dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6>(
+               interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]),
+               tcl_cast<T3>::from(interp, objv[3]),
+               tcl_cast<T4>::from(interp, objv[4]),
+               tcl_cast<T5>::from(interp, objv[5]),
+               tcl_cast<T6>::from(interp, objv[6]));
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2, typename T3, typename T4,
+     typename T5, typename T6, typename T7>
+class callback7 : public callback_base
+{
+     typedef R (*functor_type)(T1, T2, T3, T4, T5, T6, T7);
+     
+public:
+     callback7(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &)
+     {
+          check_params_no(objc, 8);
+          
+          dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7>(
+               interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]),
+               tcl_cast<T3>::from(interp, objv[3]),
+               tcl_cast<T4>::from(interp, objv[4]),
+               tcl_cast<T5>::from(interp, objv[5]),
+               tcl_cast<T6>::from(interp, objv[6]),
+               tcl_cast<T7>::from(interp, objv[7]));
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2, typename T3, typename T4,
+     typename T5, typename T6, typename T7, typename T8>
+class callback8 : public callback_base
+{
+     typedef R (*functor_type)(T1, T2, T3, T4, T5, T6, T7, T8);
+     
+public:
+     callback8(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &)
+     {
+          check_params_no(objc, 9);
+          
+          dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7, T8>(
+               interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]),
+               tcl_cast<T3>::from(interp, objv[3]),
+               tcl_cast<T4>::from(interp, objv[4]),
+               tcl_cast<T5>::from(interp, objv[5]),
+               tcl_cast<T6>::from(interp, objv[6]),
+               tcl_cast<T7>::from(interp, objv[7]),
+               tcl_cast<T8>::from(interp, objv[8]));
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2, typename T3, typename T4,
+     typename T5, typename T6, typename T7, typename T8, typename T9>
+class callback9 : public callback_base
+{
+     typedef R (*functor_type)(T1, T2, T3, T4, T5, T6, T7, T8, T9);
+     
+public:
+     callback9(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &)
+     {
+          check_params_no(objc, 10);
+          
+          dispatch<R>::template do_dispatch<
+               T1, T2, T3, T4, T5, T6, T7, T8, T9>(interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]),
+               tcl_cast<T3>::from(interp, objv[3]),
+               tcl_cast<T4>::from(interp, objv[4]),
+               tcl_cast<T5>::from(interp, objv[5]),
+               tcl_cast<T6>::from(interp, objv[6]),
+               tcl_cast<T7>::from(interp, objv[7]),
+               tcl_cast<T8>::from(interp, objv[8]),
+               tcl_cast<T9>::from(interp, objv[9]));
+     }
+
+private:
+     functor_type f_;
+};
Index: /code/branches/rocket2/src/external/cpptcl/details/callbacks_v.h
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/details/callbacks_v.h	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/details/callbacks_v.h	(revision 6952)
@@ -0,0 +1,267 @@
+//
+// Copyright (C) 2004-2006, Maciej Sobczak
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+
+// Note: this file is not supposed to be a stand-alone header
+
+
+template <typename R>
+class callback1<R, object const &> : public callback_base
+{
+     typedef object const & T1;
+     typedef R (*functor_type)(T1);
+     enum { var_start = 1 };
+     
+public:
+     callback1(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &pol)
+     {
+          object t1 = get_var_params(interp, objc, objv, var_start, pol);
+          dispatch<R>::template do_dispatch<T1>(interp, f_,
+               t1);
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1>
+class callback2<R, T1, object const &> : public callback_base
+{
+     typedef object const & T2;
+     typedef R (*functor_type)(T1, T2);
+     enum { var_start = 2 };
+     
+public:
+     callback2(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &pol)
+     {
+          object t2 = get_var_params(interp, objc, objv, var_start, pol);
+          dispatch<R>::template do_dispatch<T1, T2>(interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               t2);
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2>
+class callback3<R, T1, T2, object const &> : public callback_base
+{
+     typedef object const & T3;
+     typedef R (*functor_type)(T1, T2, T3);
+     enum { var_start = 3 };
+     
+public:
+     callback3(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &pol)
+     {
+          object t3 = get_var_params(interp, objc, objv, var_start, pol);
+          dispatch<R>::template do_dispatch<T1, T2, T3>(interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]),
+               t3);
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2, typename T3>
+class callback4<R, T1, T2, T3, object const &> : public callback_base
+{
+     typedef object const & T4;
+     typedef R (*functor_type)(T1, T2, T3, T4);
+     enum { var_start = 4 };
+     
+public:
+     callback4(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &pol)
+     {
+          object t4 = get_var_params(interp, objc, objv, var_start, pol);
+          dispatch<R>::template do_dispatch<T1, T2, T3, T4>(interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]),
+               tcl_cast<T3>::from(interp, objv[3]),
+               t4);
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2, typename T3, typename T4>
+class callback5<R, T1, T2, T3, T4, object const &> : public callback_base
+{
+     typedef object const & T5;
+     typedef R (*functor_type)(T1, T2, T3, T4, T5);
+     enum { var_start = 5 };
+     
+public:
+     callback5(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &pol)
+     {
+          object t5 = get_var_params(interp, objc, objv, var_start, pol);
+          dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5>(
+               interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]),
+               tcl_cast<T3>::from(interp, objv[3]),
+               tcl_cast<T4>::from(interp, objv[4]),
+               t5);
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2, typename T3, typename T4,
+     typename T5>
+class callback6<R, T1, T2, T3, T4, T5, object const &> : public callback_base
+{
+     typedef object const & T6;
+     typedef R (*functor_type)(T1, T2, T3, T4, T5, T6);
+     enum { var_start = 6 };
+     
+public:
+     callback6(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &pol)
+     {
+          object t6 = get_var_params(interp, objc, objv, var_start, pol);
+          dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6>(
+               interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]),
+               tcl_cast<T3>::from(interp, objv[3]),
+               tcl_cast<T4>::from(interp, objv[4]),
+               tcl_cast<T5>::from(interp, objv[5]),
+               t6);
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2, typename T3, typename T4,
+     typename T5, typename T6>
+class callback7<R, T1, T2, T3, T4, T5, T6, object const &>
+     : public callback_base
+{
+     typedef object const & T7;
+     typedef R (*functor_type)(T1, T2, T3, T4, T5, T6, T7);
+     enum { var_start = 7 };
+     
+public:
+     callback7(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &pol)
+     {
+          object t7 = get_var_params(interp, objc, objv, var_start, pol);
+          dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7>(
+               interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]),
+               tcl_cast<T3>::from(interp, objv[3]),
+               tcl_cast<T4>::from(interp, objv[4]),
+               tcl_cast<T5>::from(interp, objv[5]),
+               tcl_cast<T6>::from(interp, objv[6]),
+               t7);
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2, typename T3, typename T4,
+     typename T5, typename T6, typename T7>
+class callback8<R, T1, T2, T3, T4, T5, T6, T7, object const &>
+     : public callback_base
+{
+     typedef object const & T8;
+     typedef R (*functor_type)(T1, T2, T3, T4, T5, T6, T7, T8);
+     enum { var_start = 8 };
+     
+public:
+     callback8(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &pol)
+     {
+          object t8 = get_var_params(interp, objc, objv, var_start, pol);
+          dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7, T8>(
+               interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]),
+               tcl_cast<T3>::from(interp, objv[3]),
+               tcl_cast<T4>::from(interp, objv[4]),
+               tcl_cast<T5>::from(interp, objv[5]),
+               tcl_cast<T6>::from(interp, objv[6]),
+               tcl_cast<T7>::from(interp, objv[7]),
+               t8);
+     }
+
+private:
+     functor_type f_;
+};
+
+template <typename R, typename T1, typename T2, typename T3, typename T4,
+     typename T5, typename T6, typename T7, typename T8>
+class callback9<R, T1, T2, T3, T4, T5, T6, T7, T8, object const &>
+     : public callback_base
+{
+     typedef object const & T9;
+     typedef R (*functor_type)(T1, T2, T3, T4, T5, T6, T7, T8, T9);
+     enum { var_start = 9 };
+     
+public:
+     callback9(functor_type f) : f_(f) {}
+     
+     virtual void invoke(Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[],
+          policies const &pol)
+     {
+          object t9 = get_var_params(interp, objc, objv, var_start, pol);
+          dispatch<R>::template do_dispatch<
+               T1, T2, T3, T4, T5, T6, T7, T8, T9>(
+               interp, f_,
+               tcl_cast<T1>::from(interp, objv[1]),
+               tcl_cast<T2>::from(interp, objv[2]),
+               tcl_cast<T3>::from(interp, objv[3]),
+               tcl_cast<T4>::from(interp, objv[4]),
+               tcl_cast<T5>::from(interp, objv[5]),
+               tcl_cast<T6>::from(interp, objv[6]),
+               tcl_cast<T7>::from(interp, objv[7]),
+               tcl_cast<T8>::from(interp, objv[8]),
+               t9);
+     }
+
+private:
+     functor_type f_;
+};
Index: /code/branches/rocket2/src/external/cpptcl/details/constructors.h
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/details/constructors.h	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/details/constructors.h	(revision 6952)
@@ -0,0 +1,88 @@
+//
+// Copyright (C) 2004-2006, Maciej Sobczak
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+
+// Note: this file is not supposed to be a stand-alone header
+
+
+template <class C, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7, typename T8, typename T9>
+struct construct
+{
+     static C * doit(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7,
+          T8 t8, T9 t9)
+     { return new C(t1, t2, t3, t4, t5, t6, t7, t8, t9); }
+};
+
+template <class C, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7, typename T8>
+struct construct<C, T1, T2, T3, T4, T5, T6, T7, T8, void>
+{
+     static C * doit(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
+     { return new C(t1, t2, t3, t4, t5, t6, t7, t8); }
+};
+
+template <class C, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7>
+struct construct<C, T1, T2, T3, T4, T5, T6, T7, void, void>
+{
+     static C * doit(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
+     { return new C(t1, t2, t3, t4, t5, t6, t7); }
+};
+
+template <class C, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6>
+struct construct<C, T1, T2, T3, T4, T5, T6, void, void, void>
+{
+     static C * doit(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
+     { return new C(t1, t2, t3, t4, t5, t6); }
+};
+
+template <class C, typename T1, typename T2, typename T3, typename T4,
+          typename T5>
+struct construct<C, T1, T2, T3, T4, T5, void, void, void, void>
+{
+     static C * doit(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
+     { return new C(t1, t2, t3, t4, t5); }
+};
+
+template <class C, typename T1, typename T2, typename T3, typename T4>
+struct construct<C, T1, T2, T3, T4, void, void, void, void, void>
+{
+     static C * doit(T1 t1, T2 t2, T3 t3, T4 t4)
+     { return new C(t1, t2, t3, t4); }
+};
+
+template <class C, typename T1, typename T2, typename T3>
+struct construct<C, T1, T2, T3, void, void, void, void, void, void>
+{
+     static C * doit(T1 t1, T2 t2, T3 t3)
+     { return new C(t1, t2, t3); }
+};
+
+template <class C, typename T1, typename T2>
+struct construct<C, T1, T2, void, void, void, void, void, void, void>
+{
+     static C * doit(T1 t1, T2 t2)
+     { return new C(t1, t2); }
+};
+
+template <class C, typename T1>
+struct construct<C, T1, void, void, void, void, void, void, void, void>
+{
+     static C * doit(T1 t1)
+     { return new C(t1); }
+};
+
+template <class C>
+struct construct<C, void, void, void, void, void,
+                 void, void, void, void>
+{
+     static C * doit()
+     { return new C(); }
+};
Index: /code/branches/rocket2/src/external/cpptcl/details/conversions.h
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/details/conversions.h	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/details/conversions.h	(revision 6952)
@@ -0,0 +1,101 @@
+//
+// Copyright (C) 2004-2006, Maciej Sobczak
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+
+// Note: this file is not supposed to be a stand-alone header
+
+
+// helper functor for converting Tcl objects to the given type
+// (it is a struct instead of function,
+// because I need to partially specialize it)
+
+template <typename T>
+struct tcl_cast;
+
+template <typename T>
+struct tcl_cast<T*>
+{
+     static T * from(Tcl_Interp *, Tcl_Obj *obj)
+     {
+          std::string s(Tcl_GetString(obj));
+          if (s.size() == 0)
+          {
+               throw tcl_error("Expected pointer value, got empty string.");
+          }
+
+          if (s[0] != 'p')
+          {
+               throw tcl_error("Expected pointer value.");
+          }
+
+          std::istringstream ss(s);
+          char dummy;
+          void *p;
+          ss >> dummy >> p;
+
+          return static_cast<T*>(p);
+     }
+};
+
+// the following partial specialization is to strip reference
+// (it returns a temporary object of the underlying type, which
+// can be bound to the const-ref parameter of the actual function)
+
+template <typename T>
+struct tcl_cast<T const &>
+{
+     static T from(Tcl_Interp *interp, Tcl_Obj *obj)
+     {
+          return tcl_cast<T>::from(interp, obj);
+     }
+};
+
+
+// the following specializations are implemented
+
+template <>
+struct tcl_cast<int>
+{
+     static int from(Tcl_Interp *, Tcl_Obj *);
+};
+
+template <>
+struct tcl_cast<long>
+{
+     static long from(Tcl_Interp *, Tcl_Obj *);
+};
+
+template <>
+struct tcl_cast<bool>
+{
+     static bool from(Tcl_Interp *, Tcl_Obj *);
+};
+
+template <>
+struct tcl_cast<double>
+{
+     static double from(Tcl_Interp *, Tcl_Obj *);
+};
+
+template <>
+struct tcl_cast<std::string>
+{
+     static std::string from(Tcl_Interp *, Tcl_Obj *);
+};
+
+template <>
+struct tcl_cast<char const *>
+{
+     static char const * from(Tcl_Interp *, Tcl_Obj *);
+};
+
+template <>
+struct tcl_cast<object>
+{
+     static object from(Tcl_Interp *, Tcl_Obj *);
+};
Index: /code/branches/rocket2/src/external/cpptcl/details/dispatchers.h
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/details/dispatchers.h	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/details/dispatchers.h	(revision 6952)
@@ -0,0 +1,181 @@
+//
+// Copyright (C) 2004-2006, Maciej Sobczak
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+
+// Note: this file is not supposed to be a stand-alone header
+
+
+// the dispatch class is used to execute the callback functor and to
+// capture its return value
+// further dispatch<void> specialization ignores the res
+
+template <typename R>
+struct dispatch
+{
+     template <class Functor>
+     static void do_dispatch(Tcl_Interp *interp, Functor f)
+     {
+          R res = f();
+          set_result(interp, res);
+     }
+
+     template <typename T1, class Functor>
+     static void do_dispatch(Tcl_Interp *interp, Functor f, T1 t1)
+     {
+          R res = f(t1);
+          set_result(interp, res);
+     }
+
+     template <typename T1, typename T2, class Functor>
+     static void do_dispatch(Tcl_Interp *interp, Functor f, T1 t1, T2 t2)
+     {
+          R res = f(t1, t2);
+          set_result(interp, res);
+     }
+
+     template <typename T1, typename T2, typename T3, class Functor>
+     static void do_dispatch(Tcl_Interp *interp, Functor f,
+          T1 t1, T2 t2, T3 t3)
+     {
+          R res = f(t1, t2, t3);
+          set_result(interp, res);
+     }
+
+     template <typename T1, typename T2, typename T3, typename T4,
+          class Functor>
+     static void do_dispatch(Tcl_Interp *interp, Functor f,
+          T1 t1, T2 t2, T3 t3, T4 t4)
+     {
+          R res = f(t1, t2, t3, t4);
+          set_result(interp, res);
+     }
+
+     template <typename T1, typename T2, typename T3, typename T4,
+          typename T5, class Functor>
+     static void do_dispatch(Tcl_Interp *interp, Functor f,
+          T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
+     {
+          R res = f(t1, t2, t3, t4, t5);
+          set_result(interp, res);
+     }
+
+     template <typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, class Functor>
+     static void do_dispatch(Tcl_Interp *interp, Functor f,
+          T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
+     {
+          R res = f(t1, t2, t3, t4, t5, t6);
+          set_result(interp, res);
+     }
+
+     template <typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7, class Functor>
+     static void do_dispatch(Tcl_Interp *interp, Functor f,
+          T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
+     {
+          R res = f(t1, t2, t3, t4, t5, t6, t7);
+          set_result(interp, res);
+     }
+
+     template <typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7, typename T8, class Functor>
+     static void do_dispatch(Tcl_Interp *interp, Functor f,
+          T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
+     {
+          R res = f(t1, t2, t3, t4, t5, t6, t7, t8);
+          set_result(interp, res);
+     }
+
+     template <typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7, typename T8, typename T9,
+          class Functor>
+     static void do_dispatch(Tcl_Interp *interp, Functor f,
+          T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9)
+     {
+          R res = f(t1, t2, t3, t4, t5, t6, t7, t8, t9);
+          set_result(interp, res);
+     }
+};
+
+template <>
+struct dispatch<void>
+{
+     template <class Functor>
+     static void do_dispatch(Tcl_Interp *, Functor f)
+     {
+          f();
+     }
+
+     template <typename T1, class Functor>
+     static void do_dispatch(Tcl_Interp *, Functor f, T1 t1)
+     {
+          f(t1);
+     }
+
+     template <typename T1, typename T2, class Functor>
+     static void do_dispatch(Tcl_Interp *, Functor f, T1 t1, T2 t2)
+     {
+          f(t1, t2);
+     }
+
+     template <typename T1, typename T2, typename T3, class Functor>
+     static void do_dispatch(Tcl_Interp *, Functor f,
+          T1 t1, T2 t2, T3 t3)
+     {
+          f(t1, t2, t3);
+     }
+
+     template <typename T1, typename T2, typename T3, typename T4,
+          class Functor>
+     static void do_dispatch(Tcl_Interp *, Functor f,
+          T1 t1, T2 t2, T3 t3, T4 t4)
+     {
+          f(t1, t2, t3, t4);
+     }
+
+     template <typename T1, typename T2, typename T3, typename T4,
+          typename T5, class Functor>
+     static void do_dispatch(Tcl_Interp *, Functor f,
+          T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
+     {
+          f(t1, t2, t3, t4, t5);
+     }
+
+     template <typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, class Functor>
+     static void do_dispatch(Tcl_Interp *, Functor f,
+          T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
+     {
+          f(t1, t2, t3, t4, t5, t6);
+     }
+
+     template <typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7, class Functor>
+     static void do_dispatch(Tcl_Interp *, Functor f,
+          T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
+     {
+          f(t1, t2, t3, t4, t5, t6, t7);
+     }
+
+     template <typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7, typename T8, class Functor>
+     static void do_dispatch(Tcl_Interp *, Functor f,
+          T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
+     {
+          f(t1, t2, t3, t4, t5, t6, t7, t8);
+     }
+
+     template <typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7, typename T8, typename T9,
+          class Functor>
+     static void do_dispatch(Tcl_Interp *, Functor f,
+          T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9)
+     {
+          f(t1, t2, t3, t4, t5, t6, t7, t8, t9);
+     }
+};
Index: /code/branches/rocket2/src/external/cpptcl/details/metahelpers.h
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/details/metahelpers.h	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/details/metahelpers.h	(revision 6952)
@@ -0,0 +1,86 @@
+//
+// Copyright (C) 2004-2006, Maciej Sobczak
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+
+// Note: this file is not supposed to be a stand-alone header
+
+
+template <class C, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7, typename T8,
+          typename T9>
+struct get_callback_type_for_construct
+{
+     typedef callback9<C*, T1, T2, T3, T4, T5, T6, T7, T8, T9> type;
+};
+
+template <class C, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7, typename T8>
+struct get_callback_type_for_construct<
+     C, T1, T2, T3, T4, T5, T6, T7, T8, void>
+{
+     typedef callback8<C*, T1, T2, T3, T4, T5, T6, T7, T8> type;
+};
+
+template <class C, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6, typename T7>
+struct get_callback_type_for_construct<
+     C, T1, T2, T3, T4, T5, T6, T7, void, void>
+{
+     typedef callback7<C*, T1, T2, T3, T4, T5, T6, T7> type;
+};
+
+template <class C, typename T1, typename T2, typename T3, typename T4,
+          typename T5, typename T6>
+struct get_callback_type_for_construct<
+     C, T1, T2, T3, T4, T5, T6, void, void, void>
+{
+     typedef callback6<C*, T1, T2, T3, T4, T5, T6> type;
+};
+
+template <class C, typename T1, typename T2, typename T3, typename T4,
+          typename T5>
+struct get_callback_type_for_construct<
+     C, T1, T2, T3, T4, T5, void, void, void, void>
+{
+     typedef callback5<C*, T1, T2, T3, T4, T5> type;
+};
+
+template <class C, typename T1, typename T2, typename T3, typename T4>
+struct get_callback_type_for_construct<
+     C, T1, T2, T3, T4, void, void, void, void, void>
+{
+     typedef callback4<C*, T1, T2, T3, T4> type;
+};
+
+template <class C, typename T1, typename T2, typename T3>
+struct get_callback_type_for_construct<
+     C, T1, T2, T3, void, void, void, void, void, void>
+{
+     typedef callback3<C*, T1, T2, T3> type;
+};
+
+template <class C, typename T1, typename T2>
+struct get_callback_type_for_construct<
+     C, T1, T2, void, void, void, void, void, void, void>
+{
+     typedef callback2<C*, T1, T2> type;
+};
+
+template <class C, typename T1>
+struct get_callback_type_for_construct<
+     C, T1, void, void, void, void, void, void, void, void>
+{
+     typedef callback1<C*, T1> type;
+};
+
+template <class C>
+struct get_callback_type_for_construct<
+     C, void, void, void, void, void, void, void, void, void>
+{
+     typedef callback0<C*> type;
+};
Index: /code/branches/rocket2/src/external/cpptcl/details/methods.h
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/details/methods.h	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/details/methods.h	(revision 6952)
@@ -0,0 +1,452 @@
+//
+// Copyright (C) 2004-2006, Maciej Sobczak
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+
+// Note: this file is not supposed to be a stand-alone header
+
+
+template <class C, typename R>
+class method0 : public object_cmd_base
+{
+     typedef R (C::*mem_type)();
+     typedef R (C::*cmem_type)() const;
+     
+public:
+     method0(mem_type f) : f_(f), cmem_(false) {}
+     method0(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int, Tcl_Obj * CONST [], policies const &)
+     {
+          C *p = static_cast<C*>(pv);
+          if (cmem_)
+          {
+               dispatch<R>::do_dispatch(interp, boost::bind(cf_, p));
+          }
+          else
+          {
+               dispatch<R>::do_dispatch(interp, boost::bind(f_, p));
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1>
+class method1 : public object_cmd_base
+{
+     typedef R (C::*mem_type)(T1);
+     typedef R (C::*cmem_type)(T1) const;
+     
+public:
+     method1(mem_type f) : f_(f), cmem_(false) {}
+     method1(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &)
+     {
+          check_params_no(objc, 3);
+          
+          C *p = static_cast<C*>(pv);
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<T1>(
+                    interp, boost::bind(cf_, p, _1),
+                    tcl_cast<T1>::from(interp, objv[2]));
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<T1>(
+                    interp, boost::bind(f_, p, _1),
+                    tcl_cast<T1>::from(interp, objv[2]));
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2>
+class method2 : public object_cmd_base
+{
+     typedef R (C::*mem_type)(T1, T2);
+     typedef R (C::*cmem_type)(T1, T2) const;
+     
+public:
+     method2(mem_type f) : f_(f), cmem_(false) {}
+     method2(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &)
+     {
+          check_params_no(objc, 4);
+          
+          C *p = static_cast<C*>(pv);
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<T1, T2>(
+                    interp, boost::bind(cf_, p, _1, _2),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]));
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<T1, T2>(
+                    interp, boost::bind(f_, p, _1, _2),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]));
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2, typename T3>
+class method3 : public object_cmd_base
+{
+     typedef R (C::*mem_type)(T1, T2, T3);
+     typedef R (C::*cmem_type)(T1, T2, T3) const;
+     
+public:
+     method3(mem_type f) : f_(f), cmem_(false) {}
+     method3(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &)
+     {
+          check_params_no(objc, 5);
+          
+          C *p = static_cast<C*>(pv);
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3>(
+                    interp, boost::bind(cf_, p, _1, _2, _3),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]));
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3>(
+                    interp, boost::bind(f_, p, _1, _2, _3),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]));
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2, typename T3,
+     typename T4>
+class method4 : public object_cmd_base
+{
+     typedef R (C::*mem_type)(T1, T2, T3, T4);
+     typedef R (C::*cmem_type)(T1, T2, T3, T4) const;
+     
+public:
+     method4(mem_type f) : f_(f), cmem_(false) {}
+     method4(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &)
+     {
+          check_params_no(objc, 6);
+          
+          C *p = static_cast<C*>(pv);
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4>(
+                    interp, boost::bind(cf_, p, _1, _2, _3, _4),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]));
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4>(
+                    interp, boost::bind(f_, p, _1, _2, _3, _4),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]));
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2, typename T3,
+     typename T4, typename T5>
+class method5 : public object_cmd_base
+{
+     typedef R (C::*mem_type)(T1, T2, T3, T4, T5);
+     typedef R (C::*cmem_type)(T1, T2, T3, T4, T5) const;
+     
+public:
+     method5(mem_type f) : f_(f), cmem_(false) {}
+     method5(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &)
+     {
+          check_params_no(objc, 7);
+          
+          C *p = static_cast<C*>(pv);
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5>(
+                    interp, boost::bind(cf_, p, _1, _2, _3, _4, _5),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]));
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5>(
+                    interp, boost::bind(f_, p, _1, _2, _3, _4, _5),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]));
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2, typename T3,
+     typename T4, typename T5, typename T6>
+class method6 : public object_cmd_base
+{
+     typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6);
+     typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6) const;
+     
+public:
+     method6(mem_type f) : f_(f), cmem_(false) {}
+     method6(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &)
+     {
+          check_params_no(objc, 8);
+          
+          C *p = static_cast<C*>(pv);
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6>(
+                    interp, boost::bind(cf_, p, _1, _2, _3, _4, _5, _6),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    tcl_cast<T6>::from(interp, objv[7]));
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6>(
+                    interp, boost::bind(f_, p, _1, _2, _3, _4, _5, _6),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    tcl_cast<T6>::from(interp, objv[7]));
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2, typename T3,
+     typename T4, typename T5, typename T6, typename T7>
+class method7 : public object_cmd_base
+{
+     typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6, T7);
+     typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6, T7) const;
+     
+public:
+     method7(mem_type f) : f_(f), cmem_(false) {}
+     method7(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &)
+     {
+          check_params_no(objc, 9);
+          
+          C *p = static_cast<C*>(pv);
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7>(
+                    interp, boost::bind(cf_, p, _1, _2, _3, _4, _5, _6, _7),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    tcl_cast<T6>::from(interp, objv[7]),
+                    tcl_cast<T7>::from(interp, objv[8]));
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7>(
+                    interp, boost::bind(f_, p, _1, _2, _3, _4, _5, _6, _7),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    tcl_cast<T6>::from(interp, objv[7]),
+                    tcl_cast<T7>::from(interp, objv[8]));
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2, typename T3,
+     typename T4, typename T5, typename T6, typename T7, typename T8>
+class method8 : public object_cmd_base
+{
+     typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6, T7, T8);
+     typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6, T7, T8) const;
+     
+public:
+     method8(mem_type f) : f_(f), cmem_(false) {}
+     method8(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &)
+     {
+          check_params_no(objc, 10);
+          
+          C *p = static_cast<C*>(pv);
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<
+                    T1, T2, T3, T4, T5, T6, T7, T8>(
+                    interp, boost::bind(cf_, p,
+                         _1, _2, _3, _4, _5, _6, _7, _8),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    tcl_cast<T6>::from(interp, objv[7]),
+                    tcl_cast<T7>::from(interp, objv[8]),
+                    tcl_cast<T8>::from(interp, objv[9]));
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<
+                    T1, T2, T3, T4, T5, T6, T7, T8>(
+                    interp, boost::bind(f_, p,
+                         _1, _2, _3, _4, _5, _6, _7, _8),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    tcl_cast<T6>::from(interp, objv[7]),
+                    tcl_cast<T7>::from(interp, objv[8]),
+                    tcl_cast<T8>::from(interp, objv[9]));
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2, typename T3,
+     typename T4, typename T5, typename T6, typename T7, typename T8,
+     typename T9>
+class method9 : public object_cmd_base
+{
+     typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6, T7, T8, T9);
+     typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6, T7, T8, T9) const;
+     
+public:
+     method9(mem_type f) : f_(f), cmem_(false) {}
+     method9(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &)
+     {
+          check_params_no(objc, 11);
+          
+          C *p = static_cast<C*>(pv);
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<
+                    T1, T2, T3, T4, T5, T6, T7, T8, T9>(
+                    interp, boost::bind(cf_, p,
+                         _1, _2, _3, _4, _5, _6, _7, _8, _9),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    tcl_cast<T6>::from(interp, objv[7]),
+                    tcl_cast<T7>::from(interp, objv[8]),
+                    tcl_cast<T8>::from(interp, objv[9]),
+                    tcl_cast<T9>::from(interp, objv[10]));
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<
+                    T1, T2, T3, T4, T5, T6, T7, T8, T9>(
+                    interp, boost::bind(f_, p,
+                         _1, _2, _3, _4, _5, _6, _7, _8, _9),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    tcl_cast<T6>::from(interp, objv[7]),
+                    tcl_cast<T7>::from(interp, objv[8]),
+                    tcl_cast<T8>::from(interp, objv[9]),
+                    tcl_cast<T9>::from(interp, objv[10]));
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
Index: /code/branches/rocket2/src/external/cpptcl/details/methods_v.h
===================================================================
--- /code/branches/rocket2/src/external/cpptcl/details/methods_v.h	(revision 6952)
+++ /code/branches/rocket2/src/external/cpptcl/details/methods_v.h	(revision 6952)
@@ -0,0 +1,451 @@
+//
+// Copyright (C) 2004-2006, Maciej Sobczak
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+
+// Note: this file is not supposed to be a stand-alone header
+
+
+template <class C, typename R>
+class method1<C, R, object const &> : public object_cmd_base
+{
+     typedef object const & T1;
+     typedef R (C::*mem_type)(T1);
+     typedef R (C::*cmem_type)(T1) const;
+     enum { var_start = 2 };
+     
+public:
+     method1(mem_type f) : f_(f), cmem_(false) {}
+     method1(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &pol)
+     {
+          C *p = static_cast<C*>(pv);
+
+          object t1 = get_var_params(interp, objc, objv, var_start, pol);
+
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<T1>(
+                    interp, boost::bind(cf_, p, _1),
+                    t1);
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<T1>(
+                    interp, boost::bind(f_, p, _1),
+                    t1);
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1>
+class method2<C, R, T1, object const &> : public object_cmd_base
+{
+     typedef object const & T2;
+     typedef R (C::*mem_type)(T1, T2);
+     typedef R (C::*cmem_type)(T1, T2) const;
+     enum { var_start = 3 };
+     
+public:
+     method2(mem_type f) : f_(f), cmem_(false) {}
+     method2(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &pol)
+     {
+          C *p = static_cast<C*>(pv);
+
+          object t2 = get_var_params(interp, objc, objv, var_start, pol);
+          
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<T1, T2>(
+                    interp, boost::bind(cf_, p, _1, _2),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    t2);
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<T1, T2>(
+                    interp, boost::bind(f_, p, _1, _2),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    t2);
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2>
+class method3<C, R, T1, T2, object const &> : public object_cmd_base
+{
+     typedef object const & T3;
+     typedef R (C::*mem_type)(T1, T2, T3);
+     typedef R (C::*cmem_type)(T1, T2, T3) const;
+     enum { var_start = 4 };
+     
+public:
+     method3(mem_type f) : f_(f), cmem_(false) {}
+     method3(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &pol)
+     {
+          C *p = static_cast<C*>(pv);
+
+          object t3 = get_var_params(interp, objc, objv, var_start, pol);
+          
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3>(
+                    interp, boost::bind(cf_, p, _1, _2, _3),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    t3);
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3>(
+                    interp, boost::bind(f_, p, _1, _2, _3),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    t3);
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2, typename T3>
+class method4<C, R, T1, T2, T3, object const &> : public object_cmd_base
+{
+     typedef object const & T4;
+     typedef R (C::*mem_type)(T1, T2, T3, T4);
+     typedef R (C::*cmem_type)(T1, T2, T3, T4) const;
+     enum { var_start = 5 };
+     
+public:
+     method4(mem_type f) : f_(f), cmem_(false) {}
+     method4(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &pol)
+     {
+          C *p = static_cast<C*>(pv);
+
+          object t4 = get_var_params(interp, objc, objv, var_start, pol);
+
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4>(
+                    interp, boost::bind(cf_, p, _1, _2, _3, _4),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    t4);
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4>(
+                    interp, boost::bind(f_, p, _1, _2, _3, _4),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    t4);
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2, typename T3,
+     typename T4>
+class method5<C, R, T1, T2, T3, T4, object const &> : public object_cmd_base
+{
+     typedef object const & T5;
+     typedef R (C::*mem_type)(T1, T2, T3, T4, T5);
+     typedef R (C::*cmem_type)(T1, T2, T3, T4, T5) const;
+     enum { var_start = 6 };
+     
+public:
+     method5(mem_type f) : f_(f), cmem_(false) {}
+     method5(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &pol)
+     {
+          C *p = static_cast<C*>(pv);
+
+          object t5 = get_var_params(interp, objc, objv, var_start, pol);
+
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5>(
+                    interp, boost::bind(cf_, p, _1, _2, _3, _4, _5),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    t5);
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5>(
+                    interp, boost::bind(f_, p, _1, _2, _3, _4, _5),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    t5);
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2, typename T3,
+     typename T4, typename T5>
+class method6<C, R, T1, T2, T3, T4, T5, object const &>
+     : public object_cmd_base
+{
+     typedef object const & T6;
+     typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6);
+     typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6) const;
+     enum { var_start = 7 };
+     
+public:
+     method6(mem_type f) : f_(f), cmem_(false) {}
+     method6(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &pol)
+     {
+          C *p = static_cast<C*>(pv);
+
+          object t6 = get_var_params(interp, objc, objv, var_start, pol);
+
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6>(
+                    interp, boost::bind(cf_, p, _1, _2, _3, _4, _5, _6),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    t6);
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6>(
+                    interp, boost::bind(f_, p, _1, _2, _3, _4, _5, _6),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    t6);
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2, typename T3,
+     typename T4, typename T5, typename T6>
+class method7<C, R, T1, T2, T3, T4, T5, T6, object const &>
+     : public object_cmd_base
+{
+     typedef object const & T7;
+     typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6, T7);
+     typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6, T7) const;
+     enum { var_start = 8 };
+     
+public:
+     method7(mem_type f) : f_(f), cmem_(false) {}
+     method7(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &pol)
+     {
+          C *p = static_cast<C*>(pv);
+
+          object t7 = get_var_params(interp, objc, objv, var_start, pol);
+
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7>(
+                    interp, boost::bind(cf_, p, _1, _2, _3, _4, _5, _6, _7),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    tcl_cast<T6>::from(interp, objv[7]),
+                    t7);
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<T1, T2, T3, T4, T5, T6, T7>(
+                    interp, boost::bind(f_, p, _1, _2, _3, _4, _5, _6, _7),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    tcl_cast<T6>::from(interp, objv[7]),
+                    t7);
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2, typename T3,
+     typename T4, typename T5, typename T6, typename T7>
+class method8<C, R, T1, T2, T3, T4, T5, T6, T7, object const &>
+     : public object_cmd_base
+{
+     typedef object const & T8;
+     typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6, T7, T8);
+     typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6, T7, T8) const;
+     enum { var_start = 9 };
+     
+public:
+     method8(mem_type f) : f_(f), cmem_(false) {}
+     method8(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &pol)
+     {
+          C *p = static_cast<C*>(pv);
+
+          object t8 = get_var_params(interp, objc, objv, var_start, pol);
+
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<
+                    T1, T2, T3, T4, T5, T6, T7, T8>(
+                    interp, boost::bind(cf_, p,
+                         _1, _2, _3, _4, _5, _6, _7, _8),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    tcl_cast<T6>::from(interp, objv[7]),
+                    tcl_cast<T7>::from(interp, objv[8]),
+                    t8);
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<
+                    T1, T2, T3, T4, T5, T6, T7, T8>(
+                    interp, boost::bind(f_, p,
+                         _1, _2, _3, _4, _5, _6, _7, _8),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    tcl_cast<T6>::from(interp, objv[7]),
+                    tcl_cast<T7>::from(interp, objv[8]),
+                    t8);
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
+
+template <class C, typename R, typename T1, typename T2, typename T3,
+     typename T4, typename T5, typename T6, typename T7, typename T8>
+class method9<C, R, T1, T2, T3, T4, T5, T6, T7, T8, object const &>
+     : public object_cmd_base
+{
+     typedef object const & T9;
+     typedef R (C::*mem_type)(T1, T2, T3, T4, T5, T6, T7, T8, T9);
+     typedef R (C::*cmem_type)(T1, T2, T3, T4, T5, T6, T7, T8, T9) const;
+     enum { var_start = 10 };
+     
+public:
+     method9(mem_type f) : f_(f), cmem_(false) {}
+     method9(cmem_type f) : cf_(f), cmem_(true) {}
+     
+     virtual void invoke(void *pv, Tcl_Interp *interp,
+          int objc, Tcl_Obj * CONST objv[], policies const &pol)
+     {
+          C *p = static_cast<C*>(pv);
+
+          object t9 = get_var_params(interp, objc, objv, var_start, pol);
+
+          if (cmem_)
+          {
+               dispatch<R>::template do_dispatch<
+                    T1, T2, T3, T4, T5, T6, T7, T8, T9>(
+                    interp, boost::bind(cf_, p,
+                         _1, _2, _3, _4, _5, _6, _7, _8, _9),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    tcl_cast<T6>::from(interp, objv[7]),
+                    tcl_cast<T7>::from(interp, objv[8]),
+                    tcl_cast<T8>::from(interp, objv[9]),
+                    t9);
+          }
+          else
+          {
+               dispatch<R>::template do_dispatch<
+                    T1, T2, T3, T4, T5, T6, T7, T8, T9>(
+                    interp, boost::bind(f_, p,
+                         _1, _2, _3, _4, _5, _6, _7, _8, _9),
+                    tcl_cast<T1>::from(interp, objv[2]),
+                    tcl_cast<T2>::from(interp, objv[3]),
+                    tcl_cast<T3>::from(interp, objv[4]),
+                    tcl_cast<T4>::from(interp, objv[5]),
+                    tcl_cast<T5>::from(interp, objv[6]),
+                    tcl_cast<T6>::from(interp, objv[7]),
+                    tcl_cast<T7>::from(interp, objv[8]),
+                    tcl_cast<T8>::from(interp, objv[9]),
+                    t9);
+          }
+     }
+
+private:
+     mem_type f_;
+     cmem_type cf_;
+     bool cmem_;
+};
Index: /code/branches/rocket2/src/external/ogreceguirenderer/AUTHORS
===================================================================
--- /code/branches/rocket2/src/external/ogreceguirenderer/AUTHORS	(revision 6952)
+++ /code/branches/rocket2/src/external/ogreceguirenderer/AUTHORS	(revision 6952)
@@ -0,0 +1,106 @@
+AUTHORS
+=======
+
+OGRE Team 
+---------
+Steve Streeting	(sinbad)              
+Thomas Muldowney (temas)
+James O'Sullivan (_mental_)
+Wladimir J. van der Laan (miathan6/wumpus)
+
+Feature Contributors
+--------------------
+The following list includes developers who have contributed features to OGRE:
+
+Contributor                             Subject Areas 
+-----------                             --------------------------------------
+Adrian Cearnau (cearny)               : Codecs, dynamic library loading
+Jon Anderson (janders)                : octree plugin
+Martin Persson                        : Nature plugin
+Jesse Rusak (jder) 	  				  : Mac OSX port
+Etienne Mallard (earthquakeproof)	  : 3D Studio Model Exporter
+Banania								  : ditto
+Paolo Gavocanov (cTh) 				  : Initial D3D9 port, Meshviewer, 
+                                        3D Studio Scene Exporter
+Ivica Aracic (macross/bytelord)       : Ogre4J, Maya exporter, .scene format
+Jeff Leigh							  : Sky enhancements, debug overlay
+Jose A Milan (jamilan/spoke)          : Paging landscape plugin
+Tuan Kuranes (kuranes)                : ditto
+Stephan Kaiser (psyclonist)           : OgreFsrad, OgreLMTS, .scene format
+Philippe Culet                        : Attaching objects to bones
+Jon L. Griffeth (silent3)             : GUI enhancements
+Dan Sonnemann (oberleutnantdan)       : Timers
+Amit Mathew                           : Profiler
+Dennis Verbeek                        : Lightwave exporter
+David Whittaker                       : Displacement mapping terrain
+Chris Groskopf (staringmonkey)        : OgreTok
+Jeff Doyle (nfz)                      : ATI_fragment_shader compiler, 
+                                        paging landscape
+Patrick Kooman                        : Overlay editor
+Doug Wolanick (icetec)                : DotSceneOctree exporter & plugin
+John Van Vliet (granite/fifty1)       : Maya exporter
+Marcin Zukowski (eru)                 : Demo_CubeMapping and Demo_Water
+Jens Hoffmann                         : Blender exporter
+Michael Reimpell                      : Blender exporter
+Sam le Pirate                         : BMP support
+Attila Tajti (attis)                  : Wings3D exporter
+? (Firestorm)                         : Particle scale and rotate affectors
+Lee Sandberg                          : Hardware occlusion query support
+Phillip Castaneda (pjcast)            : External texture sources / dynamic
+										textures
+Henry Goffin (qsilver)				  : Ultra-fast scaling code in 
+										OgreImageResampler.h
+Federico Di Gregorio (fog)			  : Debian packaging
+
+Others
+------
+The following people have been notable in their support of OGRE through the
+fixing of bugs, testing patches, and various other miscellaneous contributions:
+
+Timo Keller (norondion) 
+Kai-Peter Backman
+Daniel Wessl?n
+Benny Kramek (wolfman8k) 
+Riku Nurminen (rakkis)
+Christopher John Gilbert (thegilb)
+Martin Pollard (xmp)
+Nikita Mikros (santanopoulos)
+Chris Heald (antiarc)
+Michael Casaday
+Evgeni Popov
+Chris McGuirk (leedgitar)
+Te'ja (thiveertm)
+Keith Jackson
+G Nikolakis
+Genva
+Christian Lindequist Larsen (DWORD)
+Chris Heald (Antiarc)
+Green Eyed Monster (monster)
+
+
+
+
+If we've forgotten you in the above list, please contact us!
+
+See Readme.html in the Docs folder for more details, in particular information on the media supplied with the demos.
+
+-----
+
+Copyright 1999-2004 The OGRE Team.
+
+This file is part of OGRE (Object-Oriented Graphics Rendering Engine).
+
+OGRE is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+OGRE 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 Lesser General Public License
+along with OGRE; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
Index: /code/branches/rocket2/src/external/ogreceguirenderer/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/ogreceguirenderer/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/ogreceguirenderer/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,43 @@
+ #
+ #             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.
+ #
+
+SET_SOURCE_FILES(OCR_FILES
+  OgreCEGUIRenderer.h
+  OgreCEGUIResourceProvider.h
+  OgreCEGUITexture.h
+
+COMPILATION_BEGIN OgreCEGUIRendererCompilation.cpp
+  OgreCEGUIRenderer.cpp
+  OgreCEGUIResourceProvider.cpp
+  OgreCEGUITexture.cpp
+COMPILATION_END
+)
+
+ORXONOX_ADD_LIBRARY(ogreceguirenderer_orxonox
+  ORXONOX_EXTERNAL
+  LINK_LIBRARIES
+    ${OGRE_LIBRARY}
+    ${CEGUI_LIBRARY}
+  DEFINE_SYMBOL
+    "OGRE_GUIRENDERER_EXPORTS"
+  VERSION
+    1.4.9
+  SOURCE_FILES
+    ${OCR_FILES}
+)
Index: /code/branches/rocket2/src/external/ogreceguirenderer/COPYING
===================================================================
--- /code/branches/rocket2/src/external/ogreceguirenderer/COPYING	(revision 6952)
+++ /code/branches/rocket2/src/external/ogreceguirenderer/COPYING	(revision 6952)
@@ -0,0 +1,514 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+
Index: /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUIRenderer.cpp
===================================================================
--- /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUIRenderer.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUIRenderer.cpp	(revision 6952)
@@ -0,0 +1,793 @@
+/************************************************************************
+	filename: 	OgreCEGUIRenderer.cpp
+	created:	11/5/2004
+	author:		Paul D Turner
+	
+	purpose:	Implementation of Renderer class for Ogre engine
+*************************************************************************/
+/*************************************************************************
+    Crazy Eddie's GUI System (http://www.cegui.org.uk)
+    Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*************************************************************************/
+
+#include <CEGUIImagesetManager.h>
+#include <CEGUIImageset.h>
+#include <CEGUIImage.h>
+#include <CEGUIExceptions.h>
+#include <CEGUISystem.h>
+
+#include "OgreCEGUIRenderer.h"
+#include "OgreCEGUITexture.h"
+#include "OgreCEGUIResourceProvider.h"
+
+#include <OgreRenderSystem.h>
+#include <OgreRoot.h>
+#include <OgreHardwareBufferManager.h>
+#include <OgreRenderWindow.h>
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+/*************************************************************************
+	Constants definitions
+*************************************************************************/
+const size_t	OgreCEGUIRenderer::VERTEX_PER_QUAD			= 6;
+const size_t	OgreCEGUIRenderer::VERTEX_PER_TRIANGLE		= 3;
+const size_t	OgreCEGUIRenderer::VERTEXBUFFER_INITIAL_CAPACITY	= 256;
+const size_t    OgreCEGUIRenderer::UNDERUSED_FRAME_THRESHOLD = 50000; // halfs buffer every 8 minutes on 100fps
+
+/*************************************************************************
+	Utility function to create a render operation and vertex buffer to render quads
+*************************************************************************/
+static void createQuadRenderOp(Ogre::RenderOperation &d_render_op, 
+    Ogre::HardwareVertexBufferSharedPtr &d_buffer, size_t nquads)
+{
+    using namespace Ogre;
+    // Create and initialise the Ogre specific parts required for use in rendering later.
+	d_render_op.vertexData = new VertexData;
+	d_render_op.vertexData->vertexStart = 0;
+
+	// setup vertex declaration for the vertex format we use
+	VertexDeclaration* vd = d_render_op.vertexData->vertexDeclaration;
+	size_t vd_offset = 0;
+	vd->addElement(0, vd_offset, VET_FLOAT3, VES_POSITION);
+	vd_offset += VertexElement::getTypeSize(VET_FLOAT3);
+	vd->addElement(0, vd_offset, VET_COLOUR, VES_DIFFUSE);
+	vd_offset += VertexElement::getTypeSize(VET_COLOUR);
+	vd->addElement(0, vd_offset, VET_FLOAT2, VES_TEXTURE_COORDINATES);
+
+	// create hardware vertex buffer
+	d_buffer = HardwareBufferManager::getSingleton().createVertexBuffer(vd->getVertexSize(0), nquads,  
+        HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE, false);
+
+	// bind vertex buffer
+	d_render_op.vertexData->vertexBufferBinding->setBinding(0, d_buffer);
+
+	// complete render operation basic initialisation
+	d_render_op.operationType = RenderOperation::OT_TRIANGLE_LIST;
+	d_render_op.useIndexes = false;
+}
+
+static void destroyQuadRenderOp(Ogre::RenderOperation &d_render_op, 
+    Ogre::HardwareVertexBufferSharedPtr &d_buffer)
+{
+    delete d_render_op.vertexData;
+    d_render_op.vertexData = 0;
+    d_buffer.setNull();
+}
+
+/*************************************************************************
+	Constructor
+*************************************************************************/
+OgreCEGUIRenderer::OgreCEGUIRenderer(Ogre::RenderWindow* window, Ogre::uint8 queue_id, bool post_queue, uint max_quads)
+{
+	constructor_impl(window, queue_id, post_queue, max_quads);
+}
+
+
+/*************************************************************************
+	Constructor (specifying scene manager)
+*************************************************************************/
+OgreCEGUIRenderer::OgreCEGUIRenderer(Ogre::RenderWindow* window, Ogre::uint8 queue_id, bool post_queue, uint max_quads, Ogre::SceneManager* scene_manager)
+{
+	constructor_impl(window, queue_id, post_queue, max_quads);
+
+	// hook into ogre rendering system
+	setTargetSceneManager(scene_manager);
+}
+
+
+/*************************************************************************
+	Destructor
+*************************************************************************/
+OgreCEGUIRenderer::~OgreCEGUIRenderer(void)
+{
+	setTargetSceneManager(NULL);
+
+	if (d_ourlistener)
+	{
+		delete d_ourlistener;
+	}
+
+	// cleanup vertex data we allocated in constructor
+	destroyQuadRenderOp(d_render_op, d_buffer);
+    destroyQuadRenderOp(d_direct_render_op, d_direct_buffer);
+
+	destroyAllTextures();
+}
+
+
+/*************************************************************************
+	add's a quad to the list to be rendered
+*************************************************************************/
+void OgreCEGUIRenderer::addQuad(const Rect& dest_rect, float z, const Texture* tex, const Rect& texture_rect, const ColourRect& colours, QuadSplitMode quad_split_mode)
+{
+	// if not queueing, render directly (as in, right now!). This is used for the mouse cursor.
+	if (!d_queueing)
+	{
+		renderQuadDirect(dest_rect, z, tex, texture_rect, colours, quad_split_mode);
+	}
+	else
+	{
+		d_sorted = false;
+		QuadInfo quad;
+		
+		// set quad position, flipping y co-ordinates, and applying appropriate texel origin offset
+		quad.position.d_left	= dest_rect.d_left;
+		quad.position.d_right	= dest_rect.d_right;
+		quad.position.d_top		= d_display_area.getHeight() - dest_rect.d_top;
+		quad.position.d_bottom	= d_display_area.getHeight() - dest_rect.d_bottom;
+		quad.position.offset(d_texelOffset);
+
+		// convert quad co-ordinates for a -1 to 1 co-ordinate system.
+		quad.position.d_left	/= (d_display_area.getWidth() * 0.5f);
+		quad.position.d_right	/= (d_display_area.getWidth() * 0.5f);
+		quad.position.d_top		/= (d_display_area.getHeight() * 0.5f);
+		quad.position.d_bottom	/= (d_display_area.getHeight() * 0.5f);
+		quad.position.offset(Point(-1.0f, -1.0f));
+
+		quad.z				= -1 + z;
+		quad.texture		= ((OgreCEGUITexture*)tex)->getOgreTexture();
+		quad.texPosition	= texture_rect;
+
+		// covert colours for ogre, note that top / bottom are switched.
+		quad.topLeftCol		= colourToOgre(colours.d_bottom_left);
+		quad.topRightCol	= colourToOgre(colours.d_bottom_right);
+		quad.bottomLeftCol	= colourToOgre(colours.d_top_left);
+		quad.bottomRightCol	= colourToOgre(colours.d_top_right);
+		
+		// set quad split mode
+		quad.splitMode = quad_split_mode;
+
+		d_quadlist.insert(quad);
+	}
+}
+
+
+
+/*************************************************************************
+perform final rendering for all queued renderable quads.
+*************************************************************************/
+void OgreCEGUIRenderer::doRender(void)
+{
+    // Render if overlays enabled and the quad list is not empty
+	if (d_render_sys->_getViewport()->getOverlaysEnabled() && !d_quadlist.empty())
+	{
+        /// Quad list needs to be sorted and thus the vertex buffer rebuilt. If not, we can
+        /// reuse the vertex buffer resulting in a nice speed gain.
+        if(!d_sorted)
+        {
+            sortQuads();
+            /// Resize vertex buffer if it is too small
+            size_t size = d_buffer->getNumVertices();
+            size_t requestedSize = d_quadlist.size()*VERTEX_PER_QUAD;
+            if(size < requestedSize)
+            {
+                /// Double buffer size until smaller than requested size
+                while(size < requestedSize)
+                    size = size * 2;
+                /// Reallocate the buffer
+                destroyQuadRenderOp(d_render_op, d_buffer);
+                createQuadRenderOp(d_render_op, d_buffer, size);
+            }
+            else if(requestedSize < size/2 && d_underused_framecount >= UNDERUSED_FRAME_THRESHOLD)
+            {
+                /// Resize vertex buffer if it has been to big for too long
+                size = size / 2;
+                destroyQuadRenderOp(d_render_op, d_buffer);
+                createQuadRenderOp(d_render_op, d_buffer, size);
+                /// Reset underused framecount so it takes another UNDERUSED_FRAME_THRESHOLD to half again
+                d_underused_framecount = 0;
+            }
+            /// Fill the buffer
+            QuadVertex*	buffmem;
+            buffmem = (QuadVertex*)d_buffer->lock(Ogre::HardwareVertexBuffer::HBL_DISCARD);
+            // iterate over each quad in the list
+            for (QuadList::iterator i = d_quadlist.begin(); i != d_quadlist.end(); ++i)
+            {
+                const QuadInfo& quad = (*i);
+                // setup Vertex 1...
+                buffmem->x = quad.position.d_left;
+                buffmem->y = quad.position.d_bottom;
+                buffmem->z = quad.z;
+                buffmem->diffuse = quad.topLeftCol;
+                buffmem->tu1 = quad.texPosition.d_left;
+                buffmem->tv1 = quad.texPosition.d_bottom;
+                ++buffmem;
+    
+                // setup Vertex 2...
+                
+                // top-left to bottom-right diagonal
+                if (quad.splitMode == TopLeftToBottomRight)
+                {
+                    buffmem->x = quad.position.d_right;
+                    buffmem->y = quad.position.d_bottom;
+                    buffmem->z = quad.z;
+                    buffmem->diffuse = quad.topRightCol;
+                    buffmem->tu1 = quad.texPosition.d_right;
+                    buffmem->tv1 = quad.texPosition.d_bottom;
+                }
+                // bottom-left to top-right diagonal
+                else
+                {
+                    buffmem->x = quad.position.d_right;
+                    buffmem->y = quad.position.d_top;
+                    buffmem->z = quad.z;
+                    buffmem->diffuse = quad.bottomRightCol;
+                    buffmem->tu1 = quad.texPosition.d_right;
+                    buffmem->tv1 = quad.texPosition.d_top;
+                }
+                ++buffmem;
+    
+                // setup Vertex 3...
+                buffmem->x = quad.position.d_left;
+                buffmem->y = quad.position.d_top;
+                buffmem->z = quad.z;
+                buffmem->diffuse = quad.bottomLeftCol;
+                buffmem->tu1 = quad.texPosition.d_left;
+                buffmem->tv1 = quad.texPosition.d_top;
+                ++buffmem;
+    
+                // setup Vertex 4...
+                buffmem->x = quad.position.d_right;
+                buffmem->y = quad.position.d_bottom;
+                buffmem->z = quad.z;
+                buffmem->diffuse = quad.topRightCol;
+                buffmem->tu1 = quad.texPosition.d_right;
+                buffmem->tv1 = quad.texPosition.d_bottom;
+                ++buffmem;
+    
+                // setup Vertex 5...
+                buffmem->x = quad.position.d_right;
+                buffmem->y = quad.position.d_top;
+                buffmem->z = quad.z;
+                buffmem->diffuse = quad.bottomRightCol;
+                buffmem->tu1 = quad.texPosition.d_right;
+                buffmem->tv1 = quad.texPosition.d_top;
+                ++buffmem;
+    
+                // setup Vertex 6...
+                
+                // top-left to bottom-right diagonal
+                if (quad.splitMode == TopLeftToBottomRight)
+                {
+                    buffmem->x = quad.position.d_left;
+                    buffmem->y = quad.position.d_top;
+                    buffmem->z = quad.z;
+                    buffmem->diffuse = quad.bottomLeftCol;
+                    buffmem->tu1 = quad.texPosition.d_left;
+                    buffmem->tv1 = quad.texPosition.d_top;
+                }
+                // bottom-left to top-right diagonal
+                else
+                {
+                    buffmem->x = quad.position.d_left;
+                    buffmem->y = quad.position.d_bottom;
+                    buffmem->z = quad.z;
+                    buffmem->diffuse = quad.topLeftCol;
+                    buffmem->tu1 = quad.texPosition.d_left;
+                    buffmem->tv1 = quad.texPosition.d_bottom;
+                }
+                ++buffmem;
+            }
+    
+            // ensure we leave the buffer in the unlocked state
+            d_buffer->unlock();
+        }
+        
+        /// Render the buffer
+        d_bufferPos = 0;
+		bool first = true;
+
+        // Iterate over each quad in the list and render it
+        QuadList::iterator i = d_quadlist.begin();
+        while(i != d_quadlist.end())
+        {
+            
+            d_currTexture = i->texture;
+            d_render_op.vertexData->vertexStart = d_bufferPos;
+            for (; i != d_quadlist.end(); ++i)
+            {
+                const QuadInfo& quad = (*i);
+                if (d_currTexture != quad.texture)
+				{
+                    /// If it has a different texture, render this quad in next operation
+					/// also need to reset render states
+					first = true;
+		            break;
+				}
+                d_bufferPos += VERTEX_PER_QUAD;
+            }
+            d_render_op.vertexData->vertexCount = d_bufferPos - d_render_op.vertexData->vertexStart;
+            /// Set texture, and do the render
+            d_render_sys->_setTexture(0, true, d_currTexture);
+			if (first)
+			{
+				initRenderStates();
+				first = false;
+			}
+            d_render_sys->_render(d_render_op);
+        }
+
+	}
+    /// Count frames to check if utilization of vertex buffer was below half the capacity for 500,000 frames
+    if(d_bufferPos < d_buffer->getNumVertices()/2)
+       d_underused_framecount++;
+    else
+       d_underused_framecount = 0;
+}
+
+
+/*************************************************************************
+	clear the queue
+*************************************************************************/
+void OgreCEGUIRenderer::clearRenderList(void)
+{
+	d_sorted = true;
+	d_quadlist.clear();
+}
+
+
+/*************************************************************************
+	create an empty texture
+*************************************************************************/
+Texture* OgreCEGUIRenderer::createTexture(void)
+{
+	OgreCEGUITexture* tex = new OgreCEGUITexture(this);
+	d_texturelist.push_back(tex);
+	return tex;
+}
+
+
+/*************************************************************************
+	create a texture and load it with the specified file.
+*************************************************************************/
+Texture* OgreCEGUIRenderer::createTexture(const String& filename, const String& resourceGroup)
+{
+	OgreCEGUITexture* tex = (OgreCEGUITexture*)createTexture();
+	tex->loadFromFile(filename, resourceGroup);
+
+	return tex;
+}
+
+
+/*************************************************************************
+	create a texture and set it to the specified size
+*************************************************************************/
+Texture* OgreCEGUIRenderer::createTexture(float size)
+{
+	OgreCEGUITexture* tex = (OgreCEGUITexture*)createTexture();
+	tex->setOgreTextureSize((uint)size);
+
+	return tex;
+}
+
+
+/*************************************************************************
+	destroy the given texture
+*************************************************************************/
+void OgreCEGUIRenderer::destroyTexture(Texture* texture)
+{
+	if (texture != NULL)
+	{
+		OgreCEGUITexture* tex = (OgreCEGUITexture*)texture;
+
+		d_texturelist.remove(tex);
+		delete tex;
+	}
+}
+
+
+/*************************************************************************
+	destroy all textures still active
+*************************************************************************/
+void OgreCEGUIRenderer::destroyAllTextures(void)
+{
+	while (!d_texturelist.empty())
+	{
+		destroyTexture(*(d_texturelist.begin()));
+	}
+}
+
+
+/*************************************************************************
+	setup states etc	
+*************************************************************************/
+void OgreCEGUIRenderer::initRenderStates(void)
+{
+	using namespace Ogre;
+
+	// set-up matrices
+	d_render_sys->_setWorldMatrix(Matrix4::IDENTITY);
+	d_render_sys->_setViewMatrix(Matrix4::IDENTITY);
+	d_render_sys->_setProjectionMatrix(Matrix4::IDENTITY);
+
+	// initialise render settings
+	d_render_sys->setLightingEnabled(false);
+	d_render_sys->_setDepthBufferParams(false, false);
+	d_render_sys->_setDepthBias(0, 0);
+	d_render_sys->_setCullingMode(CULL_NONE);
+	d_render_sys->_setFog(FOG_NONE);
+	d_render_sys->_setColourBufferWriteEnabled(true, true, true, true);
+	d_render_sys->unbindGpuProgram(GPT_FRAGMENT_PROGRAM);
+	d_render_sys->unbindGpuProgram(GPT_VERTEX_PROGRAM);
+	d_render_sys->setShadingType(SO_GOURAUD);
+	d_render_sys->_setPolygonMode(PM_SOLID);
+
+	// initialise texture settings
+	d_render_sys->_setTextureCoordCalculation(0, TEXCALC_NONE);
+	d_render_sys->_setTextureCoordSet(0, 0);
+	d_render_sys->_setTextureUnitFiltering(0, FO_LINEAR, FO_LINEAR, FO_POINT);
+	d_render_sys->_setTextureAddressingMode(0, d_uvwAddressMode);
+	d_render_sys->_setTextureMatrix(0, Matrix4::IDENTITY);
+#if OGRE_VERSION >= 0x010600
+	d_render_sys->_setAlphaRejectSettings(CMPF_ALWAYS_PASS, 0, false);
+#else
+	d_render_sys->_setAlphaRejectSettings(CMPF_ALWAYS_PASS, 0);
+#endif
+	d_render_sys->_setTextureBlendMode(0, d_colourBlendMode);
+	d_render_sys->_setTextureBlendMode(0, d_alphaBlendMode);
+	d_render_sys->_disableTextureUnitsFrom(1);
+
+	// enable alpha blending
+	d_render_sys->_setSceneBlending(SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA);
+}
+
+
+ 
+/*************************************************************************
+	sort quads list according to texture	
+*************************************************************************/
+void OgreCEGUIRenderer::sortQuads(void)
+{
+	if (!d_sorted)
+	{
+		d_sorted = true;
+	}
+
+}
+
+/*************************************************************************
+render a quad directly to the display
+*************************************************************************/
+void OgreCEGUIRenderer::renderQuadDirect(const Rect& dest_rect, float z, const Texture* tex, const Rect& texture_rect, const ColourRect& colours, QuadSplitMode quad_split_mode)
+{
+	if (d_render_sys->_getViewport()->getOverlaysEnabled())
+	{
+		z = -1 + z;
+
+		Rect final_rect;
+
+		// set quad position, flipping y co-ordinates, and applying appropriate texel origin offset
+		final_rect.d_left	= dest_rect.d_left;
+		final_rect.d_right	= dest_rect.d_right;
+		final_rect.d_top	= d_display_area.getHeight() - dest_rect.d_top;
+		final_rect.d_bottom	= d_display_area.getHeight() - dest_rect.d_bottom;
+		final_rect.offset(d_texelOffset);
+
+		// convert quad co-ordinates for a -1 to 1 co-ordinate system.
+		final_rect.d_left	/= (d_display_area.getWidth() * 0.5f);
+		final_rect.d_right	/= (d_display_area.getWidth() * 0.5f);
+		final_rect.d_top	/= (d_display_area.getHeight() * 0.5f);
+		final_rect.d_bottom	/= (d_display_area.getHeight() * 0.5f);
+		final_rect.offset(Point(-1.0f, -1.0f));
+
+		// convert colours for ogre, note that top / bottom are switched.
+        uint32 topLeftCol	= colourToOgre(colours.d_bottom_left);
+        uint32 topRightCol	= colourToOgre(colours.d_bottom_right);
+        uint32 bottomLeftCol	= colourToOgre(colours.d_top_left);
+        uint32 bottomRightCol= colourToOgre(colours.d_top_right);
+
+		QuadVertex*	buffmem = (QuadVertex*)d_direct_buffer->lock(Ogre::HardwareVertexBuffer::HBL_DISCARD);
+
+		// setup Vertex 1...
+		buffmem->x	= final_rect.d_left;
+		buffmem->y	= final_rect. d_bottom;
+		buffmem->z	= z;
+		buffmem->diffuse = topLeftCol;
+		buffmem->tu1	= texture_rect.d_left;
+		buffmem->tv1	= texture_rect.d_bottom;
+		++buffmem;
+
+		// setup Vertex 2...
+		
+		// top-left to bottom-right diagonal
+		if (quad_split_mode == TopLeftToBottomRight)
+		{
+			buffmem->x	= final_rect.d_right;
+			buffmem->y = final_rect.d_bottom;
+			buffmem->z	= z;
+			buffmem->diffuse = topRightCol;
+			buffmem->tu1	= texture_rect.d_right;
+			buffmem->tv1	= texture_rect.d_bottom;
+			++buffmem;
+		}
+		// bottom-left to top-right diagonal
+		else
+		{
+			buffmem->x	= final_rect.d_right;
+			buffmem->y = final_rect.d_top;
+			buffmem->z	= z;
+			buffmem->diffuse = bottomRightCol;
+			buffmem->tu1	= texture_rect.d_right;
+			buffmem->tv1	= texture_rect.d_top;
+			++buffmem;
+		}
+
+		// setup Vertex 3...
+		buffmem->x	= final_rect.d_left;
+		buffmem->y	= final_rect.d_top;
+		buffmem->z	= z;
+		buffmem->diffuse = bottomLeftCol;
+		buffmem->tu1	= texture_rect.d_left;
+		buffmem->tv1	= texture_rect.d_top;
+		++buffmem;
+
+		// setup Vertex 4...
+		buffmem->x	= final_rect.d_right;
+		buffmem->y	= final_rect.d_bottom;
+		buffmem->z	= z;
+		buffmem->diffuse = topRightCol;
+		buffmem->tu1	= texture_rect.d_right;
+		buffmem->tv1	= texture_rect.d_bottom;
+		++buffmem;
+
+		// setup Vertex 5...
+		buffmem->x	= final_rect.d_right;
+		buffmem->y	= final_rect.d_top;
+		buffmem->z	= z;
+		buffmem->diffuse = bottomRightCol;
+		buffmem->tu1	= texture_rect.d_right;
+		buffmem->tv1	= texture_rect.d_top;
+		++buffmem;
+
+		// setup Vertex 6...
+		
+		// top-left to bottom-right diagonal
+		if (quad_split_mode == TopLeftToBottomRight)
+		{
+			buffmem->x	= final_rect.d_left;
+			buffmem->y = final_rect.d_top;
+			buffmem->z	= z;
+			buffmem->diffuse = bottomLeftCol;
+			buffmem->tu1	= texture_rect.d_left;
+			buffmem->tv1	= texture_rect.d_top;
+		}
+		// bottom-left to top-right diagonal
+		else
+		{
+			buffmem->x	= final_rect.d_left;
+			buffmem->y = final_rect.d_bottom;
+			buffmem->z	= z;
+			buffmem->diffuse = topLeftCol;
+			buffmem->tu1	= texture_rect.d_left;
+			buffmem->tv1	= texture_rect.d_bottom;
+		}
+
+		d_direct_buffer->unlock();
+
+        //
+		// perform rendering...
+		//
+		d_render_sys->_setTexture(0, true, ((OgreCEGUITexture*)tex)->getOgreTexture()->getName());
+		initRenderStates();
+		d_direct_render_op.vertexData->vertexCount = VERTEX_PER_QUAD;
+		d_render_sys->_render(d_direct_render_op);
+	}
+
+}
+
+/*************************************************************************
+	convert ARGB colour value to whatever the Ogre render system is
+	expecting.	
+*************************************************************************/
+uint32 OgreCEGUIRenderer::colourToOgre(const colour& col) const
+{
+	Ogre::ColourValue cv(col.getRed(), col.getGreen(), col.getBlue(), col.getAlpha());
+
+    uint32 final;
+	d_render_sys->convertColourValue(cv, &final);
+
+	return final;
+}
+
+
+/*************************************************************************
+	Set the scene manager to be used for rendering the GUI.	
+*************************************************************************/
+void OgreCEGUIRenderer::setTargetSceneManager(Ogre::SceneManager* scene_manager)
+{
+	// unhook from current scene manager.
+	if (d_sceneMngr != NULL)
+	{
+		d_sceneMngr->removeRenderQueueListener(d_ourlistener);
+		d_sceneMngr = NULL;
+	}
+
+	// hook new scene manager if that is not NULL
+	if (scene_manager != NULL)
+	{
+		d_sceneMngr = scene_manager;
+		d_sceneMngr->addRenderQueueListener(d_ourlistener);
+	}
+
+}
+
+
+/*************************************************************************
+	Set the target render queue for GUI rendering.	
+*************************************************************************/
+void OgreCEGUIRenderer::setTargetRenderQueue(Ogre::uint8 queue_id, bool post_queue)
+{
+	d_queue_id		= queue_id;
+	d_post_queue	= post_queue;
+
+	if (d_ourlistener != NULL)
+	{
+		d_ourlistener->setTargetRenderQueue(queue_id);
+		d_ourlistener->setPostRenderQueue(post_queue);
+	}
+
+}
+
+
+/*************************************************************************
+	perform main work of the constructor
+*************************************************************************/
+void OgreCEGUIRenderer::constructor_impl(Ogre::RenderWindow* window, Ogre::uint8 queue_id, bool post_queue, uint max_quads)
+{
+	using namespace Ogre;
+
+	// initialise the renderer fields
+	d_queueing		= true;
+	d_queue_id		= queue_id;
+	d_currTexture.isNull();
+	d_post_queue	= post_queue;
+	d_sceneMngr		= NULL;
+	d_bufferPos		= 0;
+	d_sorted		= true;
+	d_ogre_root		= Root::getSingletonPtr();
+	d_render_sys	= d_ogre_root->getRenderSystem();
+    // set ID string
+    d_identifierString = "CEGUI::OgreRenderer - Official Ogre based renderer module for CEGUI";
+
+	// Create and initialise the Ogre specific parts required for use in rendering later.
+    // Main GUI
+    createQuadRenderOp(d_render_op, d_buffer, VERTEXBUFFER_INITIAL_CAPACITY);
+    d_underused_framecount = 0;
+
+    // Mouse cursor
+    createQuadRenderOp(d_direct_render_op, d_direct_buffer, VERTEX_PER_QUAD);
+
+	// Discover display settings and setup d_display_area
+	d_display_area.d_left	= 0;
+	d_display_area.d_top	= 0;
+	d_display_area.d_right	= window->getWidth();
+	d_display_area.d_bottom	= window->getHeight();
+
+	// initialise required texel offset
+	d_texelOffset = Point((float)d_render_sys->getHorizontalTexelOffset(), -(float)d_render_sys->getVerticalTexelOffset());
+
+	// create listener which will handler the rendering side of things for us.
+	d_ourlistener = new CEGUIRQListener(this, queue_id, post_queue);
+
+	// Initialise blending modes to be used.
+	d_colourBlendMode.blendType	= Ogre::LBT_COLOUR;
+	d_colourBlendMode.source1	= Ogre::LBS_TEXTURE;
+	d_colourBlendMode.source2	= Ogre::LBS_DIFFUSE;
+	d_colourBlendMode.operation	= Ogre::LBX_MODULATE;
+
+	d_alphaBlendMode.blendType	= Ogre::LBT_ALPHA;
+	d_alphaBlendMode.source1	= Ogre::LBS_TEXTURE;
+	d_alphaBlendMode.source2	= Ogre::LBS_DIFFUSE;
+	d_alphaBlendMode.operation	= Ogre::LBX_MODULATE;
+
+	d_uvwAddressMode.u = Ogre::TextureUnitState::TAM_CLAMP;
+	d_uvwAddressMode.v = Ogre::TextureUnitState::TAM_CLAMP;
+	d_uvwAddressMode.w = Ogre::TextureUnitState::TAM_CLAMP;
+}
+
+
+/*************************************************************************
+	Create a texture from an existing Ogre::TexturePtr object	
+*************************************************************************/
+Texture* OgreCEGUIRenderer::createTexture(Ogre::TexturePtr& texture)
+{
+	OgreCEGUITexture* t = (OgreCEGUITexture*)createTexture();
+
+	if (!texture.isNull())
+	{
+		t->setOgreTexture(texture);
+	}
+
+	return t;
+
+}
+
+/*************************************************************************
+	Create a resource provider object
+*************************************************************************/
+ResourceProvider* OgreCEGUIRenderer::createResourceProvider(void)
+{
+    d_resourceProvider = new OgreCEGUIResourceProvider();
+    return d_resourceProvider;
+}
+
+/*************************************************************************
+Set the size of the display in pixels.	
+*************************************************************************/
+void OgreCEGUIRenderer::setDisplaySize(const Size& sz)
+{
+	if (d_display_area.getSize() != sz)
+	{
+		d_display_area.setSize(sz);
+
+		EventArgs args;
+		fireEvent(EventDisplaySizeChanged, args, EventNamespace);
+	}
+
+}
+
+/*************************************************************************
+	Callback from Ogre invoked before other stuff in our target queue
+	is rendered
+*************************************************************************/
+void CEGUIRQListener::renderQueueStarted(Ogre::uint8 id, const Ogre::String& invocation, 
+										 bool& skipThisQueue)
+{
+	if ((!d_post_queue) && (d_queue_id == id))
+	{
+		CEGUI::System::getSingleton().renderGUI();
+	}
+
+}
+
+
+/*************************************************************************
+Callback from Ogre invoked after other stuff in our target queue
+is rendered
+*************************************************************************/
+void CEGUIRQListener::renderQueueEnded(Ogre::uint8 id, const Ogre::String& invocation, bool& repeatThisQueue)
+{
+	if ((d_post_queue) && (d_queue_id == id))
+	{
+		CEGUI::System::getSingleton().renderGUI();
+	}
+
+}
+
+} // End of  CEGUI namespace section
Index: /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUIRenderer.h
===================================================================
--- /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUIRenderer.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUIRenderer.h	(revision 6952)
@@ -0,0 +1,464 @@
+/************************************************************************
+	filename: 	OgreCEGUIRenderer.h
+	created:	11/5/2004
+	author:		Paul D Turner
+
+	purpose:	Interface for main Ogre GUI renderer class
+*************************************************************************/
+/*************************************************************************
+    Crazy Eddie's GUI System (http://www.cegui.org.uk)
+    Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*************************************************************************/
+/*************************************************************************
+	This file contains code that is specific to Ogre (http://www.ogre3d.org)
+*************************************************************************/
+#ifndef _OgreCEGUIRenderer_h_
+#define _OgreCEGUIRenderer_h_
+
+#include <CEGUIBase.h>
+#include <CEGUIRenderer.h>
+#include <CEGUITexture.h>
+
+#include <OgreRenderQueueListener.h>
+#include <OgreSceneManagerEnumerator.h>
+#include <OgreTextureUnitState.h>
+
+#if (OGRE_PLATFORM == OGRE_PLATFORM_WIN32) && !defined(OGRE_STATIC_LIB)
+#   ifdef OGRE_GUIRENDERER_EXPORTS
+#       define OGRE_GUIRENDERER_API __declspec(dllexport)
+#   else
+#       if defined(__MINGW32__)
+#           define OGRE_GUIRENDERER_API
+#       else
+#           define OGRE_GUIRENDERER_API __declspec(dllimport)
+#       endif
+#   endif
+#elif defined ( OGRE_GCC_VISIBILITY )
+#    define OGRE_GUIRENDERER_API  __attribute__ ((visibility("default")))
+#else
+#    define OGRE_GUIRENDERER_API
+#endif
+
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+/*************************************************************************
+	Forward refs
+*************************************************************************/
+class OgreCEGUITexture;
+class OgreCEGUIRenderer;
+
+
+/*!
+\brief
+	RenderQueueListener based class used to hook into the ogre rendering system
+*/
+class _OgrePrivate CEGUIRQListener : public Ogre::RenderQueueListener
+{
+public:
+	CEGUIRQListener(OgreCEGUIRenderer* renderer, Ogre::uint8 queue_id, bool post_queue)
+	{
+		d_renderer		= renderer;
+		d_queue_id		= queue_id;
+		d_post_queue	= post_queue;
+	}
+
+	virtual ~CEGUIRQListener() {}
+
+	virtual void	renderQueueStarted(Ogre::uint8 id, const Ogre::String& invocation, bool& skipThisQueue);
+	virtual void	renderQueueEnded(Ogre::uint8 id, const Ogre::String& invocation, bool& repeatThisQueue);
+
+	// methods for adjusting target queue settings
+	void	setTargetRenderQueue(Ogre::uint8 queue_id)		{d_queue_id = queue_id;}
+	void	setPostRenderQueue(bool post_queue)		{d_post_queue = post_queue;}
+
+private:
+	/*************************************************************************
+		Implementation Data
+	*************************************************************************/
+	OgreCEGUIRenderer*				d_renderer;		//!< CEGUI renderer object for Ogre.
+	Ogre::uint8	d_queue_id;		//!< ID of the queue that we are hooked into
+	bool						d_post_queue;	//!< true if we render after everything else in our queue.
+};
+
+
+/*!
+\brief
+	Renderer class to interface with Ogre engine.
+*/
+class OGRE_GUIRENDERER_API OgreCEGUIRenderer : public Renderer
+{
+public:
+	/*!
+	\brief
+		Constructor for renderer class that uses Ogre for rendering. Note that if
+		you use this option you must call setTargetSceneManager before rendering.
+
+	\param window
+		Pointer to an Ogre::RenderWindow object.
+
+	\param queue_id
+		Ogre::uint8 value that specifies where the GUI should appear in the ogre rendering output.
+
+	\param post_queue
+		set to true to have GUI rendered after render queue \a queue_id, or false to have the GUI rendered before render queue
+		\a queue_id.
+
+	\param max_quads
+		Obsolete.  Set to 0.
+
+	*/
+	OgreCEGUIRenderer(Ogre::RenderWindow* window,
+		Ogre::uint8 queue_id = Ogre::RENDER_QUEUE_OVERLAY,
+		bool post_queue = false, uint max_quads = 0);
+
+
+	/*!
+	\brief
+		Constructor for renderer class that uses Ogre for rendering.
+
+	\param window
+		Pointer to an Ogre::RenderWindow object.
+
+	\param queue_id
+		Ogre::uint8 value that specifies where the GUI should appear in the ogre rendering output.
+
+	\param post_queue
+		set to true to have GUI rendered after render queue \a queue_id, or false to have the GUI rendered before render queue
+		\a queue_id.
+
+	\param max_quads
+		Obsolete.  Set to 0.
+
+	\param scene_manager
+		Pointer to an Ogre::SceneManager object that is to be used for GUI rendering.
+	*/
+	OgreCEGUIRenderer(Ogre::RenderWindow* window, Ogre::uint8 queue_id, bool post_queue, uint max_quads, Ogre::SceneManager* scene_manager);
+
+
+	/*!
+	\brief
+		Destructor for Ogre renderer.
+	*/
+	virtual ~OgreCEGUIRenderer(void);
+
+
+
+	// add's a quad to the list to be rendered
+	virtual	void	addQuad(const Rect& dest_rect, float z, const Texture* tex, const Rect& texture_rect, const ColourRect& colours, QuadSplitMode quad_split_mode);
+
+	// perform final rendering for all queued renderable quads.
+	virtual	void	doRender(void);
+
+	// clear the queue
+	virtual	void	clearRenderList(void);
+
+
+	/*!
+	\brief
+		Enable or disable the queueing of quads from this point on.
+
+		This only affects queueing.  If queueing is turned off, any calls to addQuad will cause the quad to be rendered directly.  Note that
+		disabling queueing will not cause currently queued quads to be rendered, nor is the queue cleared - at any time the queue can still
+		be drawn by calling doRender, and the list can be cleared by calling clearRenderList.  Re-enabling the queue causes subsequent quads
+		to be added as if queueing had never been disabled.
+
+	\param setting
+		true to enable queueing, or false to disable queueing (see notes above).
+
+	\return
+		Nothing
+	*/
+	virtual void	setQueueingEnabled(bool setting)		{d_queueing = setting;}
+
+
+	// create an empty texture
+	virtual	Texture*	createTexture(void);
+
+	// create a texture and load it with the specified file.
+	virtual	Texture*	createTexture(const String& filename, const String& resourceGroup = "General");
+
+	// create a texture and set it to the specified size
+	virtual	Texture*	createTexture(float size);
+
+    // create an OGRE resource provider.
+    virtual ResourceProvider* createResourceProvider(void);
+
+	// destroy the given texture
+	virtual	void		destroyTexture(Texture* texture);
+
+	// destroy all textures still active
+	virtual void		destroyAllTextures(void);
+
+
+	/*!
+	\brief
+		Return whether queueing is enabled.
+
+	\return
+		true if queueing is enabled, false if queueing is disabled.
+	*/
+	virtual bool	isQueueingEnabled(void) const	{return d_queueing;}
+
+
+	/*!
+	\brief
+	Return the current width of the display in pixels
+
+	\return
+	float value equal to the current width of the display in pixels.
+	*/
+	virtual float	getWidth(void) const		{return d_display_area.getWidth();}
+
+
+	/*!
+	\brief
+	Return the current height of the display in pixels
+
+	\return
+	float value equal to the current height of the display in pixels.
+	*/
+	virtual float	getHeight(void) const		{return d_display_area.getHeight();}
+
+
+	/*!
+	\brief
+	Return the size of the display in pixels
+
+	\return
+	Size object describing the dimensions of the current display.
+	*/
+	virtual Size	getSize(void) const			{return d_display_area.getSize();}
+
+
+	/*!
+	\brief
+	Return a Rect describing the screen
+
+	\return
+	A Rect object that describes the screen area.  Typically, the top-left values are always 0, and the size of the area described is
+	equal to the screen resolution.
+	*/
+	virtual Rect	getRect(void) const			{return d_display_area;}
+
+
+	/*!
+	\brief
+		Return the maximum texture size available
+
+	\return
+		Size of the maximum supported texture in pixels (textures are always assumed to be square)
+	*/
+	virtual	uint	getMaxTextureSize(void) const		{return 2048;}		// TODO: Change to proper value
+
+
+	/*!
+	\brief
+		Return the horizontal display resolution dpi
+
+	\return
+		horizontal resolution of the display in dpi.
+	*/
+	virtual	uint	getHorzScreenDPI(void) const	{return 96;}
+
+
+	/*!
+	\brief
+		Return the vertical display resolution dpi
+
+	\return
+		vertical resolution of the display in dpi.
+	*/
+	virtual	uint	getVertScreenDPI(void) const	{return 96;}
+
+
+	/*!
+	\brief
+		Set the scene manager to be used for rendering the GUI.
+
+		The GUI system will be unhooked from the current scene manager and attached to what ever
+		is specified here.
+
+	\param scene_manager
+		Pointer to an Ogre::SceneManager object that is the new target Ogre::SceneManager to be
+		used for GUI rendering.
+
+	\return
+		Nothing.
+	*/
+	void	setTargetSceneManager(Ogre::SceneManager* scene_manager);
+
+
+	/*!
+	\brief
+		Set the target render queue for GUI rendering.
+
+	\param queue_id
+		Ogre::uint8 value specifying the render queue that the GUI system should attach to.
+
+	\param post_queue
+		- true to specify that the GUI should render after everything else in render queue \a queue_id.
+		- false to specify the GUI should render before everything else in render queue \a queue_id.
+
+	\return
+		Nothing.
+	*/
+	void	setTargetRenderQueue(Ogre::uint8 queue_id, bool post_queue);
+
+
+	/*!
+	\brief
+		Create a texture from an existing Ogre::TexturePtr object.
+
+	\note
+		If you want to use an Ogre::RenderTexture (for putting rendered output onto Gui elements or other
+		advanced techniques), you can get the Ogre::TexturePtr to be used by calling Ogre::TextureManager::getByName()
+		passing the name returned from Ogre::RenderTexture::getName() (and casting the result as necessary).
+
+	\param texture
+		pointer to an Ogre::TexturePtr object to be used as the basis for the new CEGUI::Texture
+
+	\return
+		Pointer to the newly created CEGUI::TexturePtr object.
+	*/
+	Texture*	createTexture(Ogre::TexturePtr& texture);
+
+
+	/*!
+	\brief
+	Set the size of the display in pixels.
+
+	You do not have to call this method under normal operation as the system
+	will automatically extract the size from the current view port.
+
+	\note
+	This method will cause the EventDisplaySizeChanged event to fire if the
+	display size has changed.
+
+	\param sz
+	Size object describing the size of the display.
+
+	\return
+	Nothing.
+	*/
+	void	setDisplaySize(const Size& sz);
+
+
+private:
+	/************************************************************************
+		Implementation Constants
+	************************************************************************/
+	static const size_t    VERTEX_PER_QUAD;						 //!< number of vertices per quad
+	static const size_t    VERTEX_PER_TRIANGLE;					 //!< number of vertices for a triangle
+    static const size_t    VERTEXBUFFER_INITIAL_CAPACITY;		 //!< initial capacity of the allocated vertex buffer
+    static const size_t    UNDERUSED_FRAME_THRESHOLD;            //!< number of frames to wait before shrinking buffer
+
+	/*************************************************************************
+	    Implementation Structs & classes
+	*************************************************************************/
+	/*!
+	\brief
+		structure used for all vertices.
+	*/
+	struct QuadVertex {
+		float x, y, z;			//!< The position for the vertex.
+		Ogre::RGBA diffuse;		//!< colour of the vertex
+		float tu1, tv1;			//!< texture coordinates
+	};
+
+	/*!
+	\brief
+		structure holding details about a quad to be drawn
+	*/
+	struct QuadInfo
+	{
+		Ogre::TexturePtr		texture;
+		Rect				position;
+		float				z;
+		Rect				texPosition;
+        uint32		        topLeftCol;
+        uint32		        topRightCol;
+        uint32		        bottomLeftCol;
+        uint32		        bottomRightCol;
+
+        QuadSplitMode		splitMode;
+
+		bool operator<(const QuadInfo& other) const
+		{
+			// this is intentionally reversed.
+			return z > other.z;
+		}
+	};
+
+
+	/*************************************************************************
+	    Implementation Methods
+	*************************************************************************/
+	// setup states etc
+	void	initRenderStates(void);
+
+	// sort quads list according to texture
+	void	sortQuads(void);
+
+	// render a quad directly to the display
+	void	renderQuadDirect(const Rect& dest_rect, float z, const Texture* tex, const Rect& texture_rect, const ColourRect& colours, QuadSplitMode quad_split_mode);
+
+	// convert colour value to whatever the Ogre render system is expecting.
+    uint32    colourToOgre(const colour& col) const;
+
+	// perform main work of the constructor.  This does everything except the final hook into the render system.
+	void	constructor_impl(Ogre::RenderWindow* window, Ogre::uint8 queue_id, bool post_queue, uint max_quads);
+
+
+	/*************************************************************************
+	    Implementation Data
+	*************************************************************************/
+	Rect				d_display_area;
+
+	typedef std::multiset<QuadInfo>		QuadList;
+	QuadList d_quadlist;
+	bool	 d_queueing;		//!< setting for queueing control.
+
+	// Ogre specific bits.
+	Ogre::Root*					d_ogre_root;		//!< pointer to the Ogre root object that we attach to
+	Ogre::RenderSystem*			d_render_sys;		//!< Pointer to the render system for Ogre.
+	Ogre::uint8	d_queue_id;			//!< ID of the queue that we are hooked into
+	Ogre::TexturePtr			d_currTexture;		//!< currently set texture;
+	Ogre::RenderOperation		d_render_op;		//!< Ogre render operation we use to do our stuff.
+	Ogre::HardwareVertexBufferSharedPtr	d_buffer;	//!< vertex buffer to queue sprite rendering
+    size_t d_underused_framecount;                  //!< Number of frames elapsed since buffer utilization was above half the capacity
+    Ogre::RenderOperation		d_direct_render_op;		//!< Renderop for cursor
+	Ogre::HardwareVertexBufferSharedPtr	d_direct_buffer;	//!< Renderop for cursor
+	Ogre::SceneManager*			d_sceneMngr;		//!< The scene manager we are hooked into.
+	Ogre::LayerBlendModeEx		d_colourBlendMode;	//!< Controls colour blending mode used.
+	Ogre::LayerBlendModeEx		d_alphaBlendMode;	//!< Controls alpha blending mode used.
+	Ogre::TextureUnitState::UVWAddressingMode d_uvwAddressMode;
+
+	CEGUIRQListener*			d_ourlistener;
+	bool						d_post_queue;		//!< true if we render after everything else in our queue.
+	size_t						d_bufferPos;		//!< index into buffer where next vertex should be put.
+	bool						d_sorted;			//!< true when data in quad list is sorted.
+	Point						d_texelOffset;		//!< Offset required for proper texel mapping.
+
+	std::list<OgreCEGUITexture*> d_texturelist;		//!< List used to track textures.
+};
+
+} // End of  CEGUI namespace section
+
+
+#endif	// end of guard _OgreCEGUIRenderer_h_
Index: /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUIResourceProvider.cpp
===================================================================
--- /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUIResourceProvider.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUIResourceProvider.cpp	(revision 6952)
@@ -0,0 +1,97 @@
+/************************************************************************
+	filename: 	OgreCEGUIResourceProvider.cpp
+	created:	8/7/2004
+	author:		James '_mental_' O'Sullivan
+
+	purpose:	Implements the Resource Provider common functionality
+*************************************************************************/
+/*************************************************************************
+    Crazy Eddie's GUI System (http://www.cegui.org.uk)
+    Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*************************************************************************/
+#include "OgreCEGUIResourceProvider.h"
+
+#include <CEGUIExceptions.h>
+#include <OgreArchiveManager.h>
+
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+    OgreCEGUIResourceProvider::OgreCEGUIResourceProvider() : ResourceProvider()
+    {
+        // set deafult resource group for Ogre
+        d_defaultResourceGroup = Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME.c_str();
+    }
+
+//    void OgreResourceProvider::loadInputSourceContainer(const String& filename, InputSourceContainer& output)
+//   {
+//        Ogre::DataStreamPtr input = Ogre::ResourceGroupManager::getSingleton().openResource(filename.c_str());
+//
+//		if (input.isNull())
+//		{
+//			throw InvalidRequestException((utf8*)
+//				"Scheme::Scheme - Filename supplied for Scheme loading must be valid");
+//		}
+//
+//       XERCES_CPP_NAMESPACE_USE
+//        size_t buffsz = input->size();
+//        unsigned char* mem = reinterpret_cast<unsigned char*>(XMLPlatformUtils::fgArrayMemoryManager->allocate(buffsz));
+//        memcpy(mem, input.getPointer()->getAsString().c_str(), buffsz);
+//        InputSource* mInputSource = new MemBufInputSource(mem, buffsz, filename.c_str(), true);
+//        input.setNull();
+//
+//       output.setData(mInputSource);
+//    }
+
+    void OgreCEGUIResourceProvider::loadRawDataContainer(const String& filename, RawDataContainer& output,  const String& resourceGroup)
+    {
+        String orpGroup;
+        if (resourceGroup.empty())
+            orpGroup = d_defaultResourceGroup.empty() ? Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME.c_str() : d_defaultResourceGroup;
+        else
+            orpGroup = resourceGroup;
+
+        Ogre::DataStreamPtr input =
+            Ogre::ResourceGroupManager::getSingleton().openResource(filename.c_str(), orpGroup.c_str());
+
+		if (input.isNull())
+		{
+            throw InvalidRequestException((utf8*)
+                "OgreCEGUIResourceProvider::loadRawDataContainer - Unable to open resource file '" + filename + (utf8*)"' in resource group '" + orpGroup + (utf8*)"'.");
+        }
+
+		Ogre::String buf = input->getAsString();
+		const size_t memBuffSize = buf.length();
+
+        unsigned char* mem = new unsigned char[memBuffSize];
+        memcpy(mem, buf.c_str(), memBuffSize);
+
+        output.setData(mem);
+        output.setSize(memBuffSize);
+    }
+
+	void OgreCEGUIResourceProvider::unloadRawDataContainer(RawDataContainer& data)
+	{
+		if (data.getDataPtr())
+		{
+			delete[] data.getDataPtr();
+			data.setData(0);
+			data.setSize(0);
+		}
+	}
+} // End of  CEGUI namespace section
Index: /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUIResourceProvider.h
===================================================================
--- /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUIResourceProvider.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUIResourceProvider.h	(revision 6952)
@@ -0,0 +1,52 @@
+/************************************************************************
+	filename: 	CEGUIOgreResourceProvider.h
+	created:	8/7/2004
+	author:		James '_mental_' O'Sullivan
+	
+	purpose:	Defines abstract base class for CEGUIData objects
+*************************************************************************/
+/*************************************************************************
+    Crazy Eddie's GUI System (http://www.cegui.org.uk)
+    Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*************************************************************************/
+#ifndef _OgreCEGUIResourceProvider_h_
+#define _OgreCEGUIResourceProvider_h_
+
+#include <CEGUIResourceProvider.h>
+#include "OgreCEGUIRenderer.h"
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+class _OgrePrivate OgreCEGUIResourceProvider : public ResourceProvider
+{
+public:
+	/*************************************************************************
+		Construction and Destruction
+	*************************************************************************/
+	OgreCEGUIResourceProvider();
+
+	~OgreCEGUIResourceProvider(void) {}
+
+//    void loadInputSourceContainer(const String& filename, InputSourceContainer& output);
+    void loadRawDataContainer(const String& filename, RawDataContainer& output, const String& resourceGroup);
+    void unloadRawDataContainer(RawDataContainer& output);
+};
+
+} // End of  CEGUI namespace section
+
+#endif	// end of guard _OgreCEGUIResourceProvider_h_
Index: /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUITexture.cpp
===================================================================
--- /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUITexture.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUITexture.cpp	(revision 6952)
@@ -0,0 +1,268 @@
+/************************************************************************
+	filename: 	OgreCEGUITexture.cpp
+	created:	11/5/2004
+	author:		Paul D Turner
+	
+	purpose:	Implementation of Texture using Ogre engine
+*************************************************************************/
+/*************************************************************************
+    Crazy Eddie's GUI System (http://www.cegui.org.uk)
+    Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*************************************************************************/
+
+#include <CEGUISystem.h>
+#include <CEGUIExceptions.h>
+#include "OgreCEGUITexture.h"
+#include "OgreCEGUIRenderer.h"
+
+#include <OgreTextureManager.h>
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+/*************************************************************************
+	Static data definition / initialisation
+*************************************************************************/
+uint32 OgreCEGUITexture::d_texturenumber		= 0;
+
+
+/*************************************************************************
+	Constructor
+*************************************************************************/
+OgreCEGUITexture::OgreCEGUITexture(Renderer* owner) :
+	Texture(owner)
+{
+	d_ogre_texture.setNull();
+	d_isLinked = false;
+}
+
+
+/*************************************************************************
+	Destructor
+*************************************************************************/
+OgreCEGUITexture::~OgreCEGUITexture(void)
+{
+	freeOgreTexture();
+}
+
+
+/*************************************************************************
+	Loads the specified image file into the texture.  The texture is
+	resized as required to hold the image.	
+*************************************************************************/
+void OgreCEGUITexture::loadFromFile(const String& filename, const String& resourceGroup)
+{
+	using namespace Ogre;
+
+	// unload old ogre texture
+	freeOgreTexture();
+
+	// create / load a new ogre texture from the specified image
+	try
+	{
+		TextureManager& textureManager = TextureManager::getSingleton();
+
+		// see if texture already exists
+		Ogre::TexturePtr ogreTexture = (Ogre::TexturePtr)textureManager.getByName(filename.c_str());
+
+		if (!ogreTexture.isNull())
+		{
+			// texture already exists, so create a 'linked' texture (ensures texture is not destroyed twice)
+			d_ogre_texture = ogreTexture;
+			d_isLinked = true;
+		}
+		// texture does not already exist, so load it in
+		else
+		{
+            String orpGroup;
+            if (resourceGroup.empty())
+            {
+                const String& defGrp = CEGUI::System::getSingleton().getResourceProvider()->getDefaultResourceGroup();
+                orpGroup = defGrp.empty() ? Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME.c_str() : defGrp;
+            }
+            else
+            {
+                orpGroup = resourceGroup;
+            }
+
+			d_ogre_texture = TextureManager::getSingleton().load(filename.c_str(), orpGroup.c_str(), TEX_TYPE_2D, 0, 1.0f);
+			d_isLinked = false;
+		}
+
+	}
+	catch(Ogre::Exception e)
+	{
+		throw RendererException((utf8*)"Failed to create Texture object from file '" + filename + "'. Additional Information:\n" + e.getFullDescription().c_str());
+	}
+
+	// if we got a pointer cache some details
+	if (!d_ogre_texture.isNull())
+	{
+		d_width		= d_ogre_texture->getWidth();
+		d_height	= d_ogre_texture->getHeight();
+	}
+	// no texture from image so throw.
+	else
+	{
+		throw RendererException((utf8*)"Failed to create Texture object from file '" + filename + "'.  Ogre returned a NULL pointer.");
+	}
+
+}
+
+
+/*************************************************************************
+	Loads (copies) an image in memory into the texture.  The texture is
+	resized as required to hold the image.	
+*************************************************************************/
+
+void _byteSwap(unsigned char* b, int n)
+{
+    register int i = 0;
+    register int j = n-1;
+    while (i<j)
+    {
+        std::swap(b[i], b[j]);
+        i++, j--;
+    }
+}
+#define byteSwap(x) _byteSwap((unsigned char*) &x,sizeof(x))
+
+void OgreCEGUITexture::loadFromMemory(const void* buffPtr, uint buffWidth, uint buffHeight, PixelFormat pixelFormat)
+{
+	using namespace Ogre;
+
+	// get rid of old texture
+	freeOgreTexture();
+
+	// wrap input buffer with an Ogre DataChunk
+    uint32 bytesize = ((buffWidth * sizeof(uint32)) * buffHeight);
+
+#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
+    uint32* swappedBuffer = new uint32[bytesize/4];
+    memcpy(swappedBuffer, buffPtr, bytesize);
+
+    for (int i=0; i < bytesize/4; i++)
+        byteSwap(swappedBuffer[i]);
+
+    DataStreamPtr odc(new MemoryDataStream(static_cast<void*>(swappedBuffer), bytesize, false));
+#else
+	DataStreamPtr odc(new MemoryDataStream(const_cast<void*>(buffPtr), bytesize, false));
+#endif
+
+	// get pixel type for the target texture - the elements here might look wrong, but is just
+	// differences in definition (at the core level, between GL and D3D).
+	Ogre::PixelFormat targetFmt =
+		(pixelFormat == PF_RGBA) ? Ogre::PF_A8R8G8B8 : Ogre::PF_R8G8B8;
+
+	// try to create a Ogre::Texture from the input data
+	d_ogre_texture = TextureManager::getSingleton().loadRawData(getUniqueName(), "General", odc, buffWidth, buffHeight, targetFmt , TEX_TYPE_2D, 0, 1.0f);
+
+	// if we got a pointer cache some details
+	if (!d_ogre_texture.isNull())
+	{
+		d_width		= d_ogre_texture->getWidth();
+		d_height	= d_ogre_texture->getHeight();
+	}
+	// no texture from memory so throw.
+	else
+	{
+		throw RendererException((utf8*)"Failed to create Texture object from memory:  Ogre returned a NULL Ogre::Texture pointer.");
+	}
+
+}
+
+
+/*************************************************************************
+	set the size of the internal Ogre texture.  Previous Ogre texture
+	is lost.	
+*************************************************************************/
+void OgreCEGUITexture::setOgreTextureSize(uint size)
+{
+	using namespace Ogre;
+
+	// unload any current Ogre::Texture
+	freeOgreTexture();
+
+	// Try to create an empty texture of the given size
+	d_ogre_texture = TextureManager::getSingleton().createManual(getUniqueName(), "General", TEX_TYPE_2D, size, size, 0, PF_A8R8G8B8, TU_DEFAULT);
+
+	// if we got a pointer cache some details
+	if (!d_ogre_texture.isNull())
+	{
+		d_width		= d_ogre_texture->getWidth();
+		d_height	= d_ogre_texture->getHeight();
+	}
+	// no texture so throw.
+	else
+	{
+		throw RendererException((utf8*)"Failed to create texture of specified size: Ogre::Texture creation failed.");
+	}
+
+}
+
+
+/*************************************************************************
+	safely free Ogre::Texture texture (can be called multiple times with
+	no ill effect)
+*************************************************************************/
+void OgreCEGUITexture::freeOgreTexture(void)
+{
+	if ((!d_ogre_texture.isNull()) && !d_isLinked)
+	{
+		Ogre::TextureManager::getSingleton().remove(d_ogre_texture->getHandle());
+	}
+	d_ogre_texture.setNull();
+}
+
+
+/*************************************************************************
+	return a Ogre::string that contains a unique name.	
+*************************************************************************/
+Ogre::String OgreCEGUITexture::getUniqueName(void)
+{
+	Ogre::String str;
+
+#ifdef CEGUI_USEOLDOGRESTRING
+	str << "_cegui_ogre_" << d_texturenumber;
+#else
+	Ogre::StringUtil::StrStreamType strstream;
+	strstream << "_cegui_ogre_" << d_texturenumber;
+	str = strstream.str();
+#endif
+
+	++d_texturenumber;
+
+	return str;
+}
+
+
+/*************************************************************************
+	Set the internal Ogre::Texture object.
+*************************************************************************/
+void OgreCEGUITexture::setOgreTexture(Ogre::TexturePtr& texture)
+{
+	freeOgreTexture();
+
+	d_ogre_texture = texture;
+	d_width	 = d_ogre_texture->getWidth();
+	d_height = d_ogre_texture->getHeight();
+	d_isLinked = true;
+}
+
+
+} // End of  CEGUI namespace section
+
Index: /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUITexture.h
===================================================================
--- /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUITexture.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ogreceguirenderer/OgreCEGUITexture.h	(revision 6952)
@@ -0,0 +1,179 @@
+/************************************************************************
+	filename: 	OgreCEGUITexture.h
+	created:	11/5/2004
+	author:		Paul D Turner
+	
+	purpose:	Interface to Texture implemented via Ogre engine
+*************************************************************************/
+/*************************************************************************
+    Crazy Eddie's GUI System (http://www.cegui.org.uk)
+    Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*************************************************************************/
+#ifndef _OgreCEGUITexture_h_
+#define _OgreCEGUITexture_h_
+
+#include <CEGUIBase.h>
+#include <CEGUIRenderer.h>
+#include <CEGUITexture.h>
+#include "OgreCEGUIRenderer.h"
+
+// Start of CEGUI namespace section
+namespace CEGUI
+{
+/*!
+\brief
+	Texture class that is created by OgreCEGUIRenderer objects
+*/
+class _OgrePrivate OgreCEGUITexture : public Texture
+{
+private:
+	/*************************************************************************
+		Friends (to allow construction and destruction)
+	*************************************************************************/
+	friend	Texture* OgreCEGUIRenderer::createTexture(void);
+	friend	Texture* OgreCEGUIRenderer::createTexture(const String& filename, const String& resourceGroup);
+	friend	Texture* OgreCEGUIRenderer::createTexture(float size);
+	friend	void	 OgreCEGUIRenderer::destroyTexture(Texture* texture);
+
+
+	/*************************************************************************
+		Construction & Destruction (by Renderer object only)
+	*************************************************************************/
+	OgreCEGUITexture(Renderer* owner);
+	virtual ~OgreCEGUITexture(void);
+
+public:
+	/*!
+	\brief
+		Returns the current pixel width of the texture
+
+	\return
+		ushort value that is the current width of the texture in pixels
+	*/
+	virtual	ushort	getWidth(void) const		{return d_width;}
+
+
+	/*!
+	\brief
+		Returns the current pixel height of the texture
+
+	\return
+		ushort value that is the current height of the texture in pixels
+	*/
+	virtual	ushort	getHeight(void) const		{return d_height;}
+
+
+	/*!
+	\brief
+		Loads the specified image file into the texture.  The texture is resized as required to hold the image.
+
+	\param filename
+		The filename of the image file that is to be loaded into the texture
+
+	\return
+		Nothing.
+	*/
+	virtual void	loadFromFile(const String& filename, const String& resourceGroup);
+
+
+	/*!
+	\brief
+		Loads (copies) an image in memory into the texture.  The texture is resized as required to hold the image.
+	
+	\param buffPtr
+		Pointer to the buffer containing the image data
+	
+	\param buffWidth
+		Width of the buffer (in pixels as specified by \a pixelFormat )
+	
+	\param buffHeight
+		Height of the buffer (in pixels as specified by \a pixelFormat )
+	
+	\param pixelFormat
+	PixelFormat value describing the format contained in \a buffPtr
+	
+	\return
+		Nothing.
+	*/
+	virtual void	loadFromMemory(const void* buffPtr, uint buffWidth, uint buffHeight, PixelFormat pixelFormat);
+
+
+	/*!
+	\brief
+		Return a pointer to the internal Ogre::Texture object
+
+	\return
+		Pointer to the Ogre::Texture object currently being used by this Texture object
+	*/
+	Ogre::TexturePtr	getOgreTexture(void) const		{return d_ogre_texture;}
+
+
+	/*!
+	\brief
+		set the size of the internal Ogre texture.  Previous Ogre texture is lost.
+
+	\param size
+		pixel size of the new internal texture.  This will be rounded up to a power of 2.
+
+	\return
+		Nothing.
+	*/
+	void	setOgreTextureSize(uint size);
+
+
+	/*!
+	\brief
+		Set the internal Ogre::TexturePtr object.
+
+	\param texture
+		Reference to an Ogre::TexturePtr object that is to be used by this Texture object.
+
+	\return
+		Nothing.
+	*/
+	void	setOgreTexture(Ogre::TexturePtr& texture);
+
+
+private:
+	/*************************************************************************
+		Implementation Functions
+	*************************************************************************/
+	// safely free Ogre::Texture texture (can be called multiple times with no ill effect)
+	void	freeOgreTexture(void);
+
+	// return a Ogre::string that contains a unique name.
+	Ogre::String	getUniqueName(void);
+
+
+	/*************************************************************************
+		Implementation Data
+	*************************************************************************/
+	static	uint32          d_texturenumber;	//!< Counter used to provide unique texture names.
+
+	Ogre::TexturePtr		d_ogre_texture;		//!< The 'real' texture.
+
+	ushort					d_width;			//!< cached width of the texture
+	ushort					d_height;			//!< cached height of the texture
+
+	bool	d_isLinked;		//!< True if we are linked to a texture we did not actually create.
+};
+
+
+} // End of  CEGUI namespace section
+
+
+#endif	// end of guard _OgreCEGUITexture_h_
Index: /code/branches/rocket2/src/external/ogreceguirenderer/VERSION
===================================================================
--- /code/branches/rocket2/src/external/ogreceguirenderer/VERSION	(revision 6952)
+++ /code/branches/rocket2/src/external/ogreceguirenderer/VERSION	(revision 6952)
@@ -0,0 +1,22 @@
+This library is part of the OGRE v1.6.1 source.
+
+-----
+
+Copyright 1999-2004 The OGRE Team.
+
+This file is part of OGRE (Object-Oriented Graphics Rendering Engine).
+
+OGRE is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+OGRE 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 Lesser General Public License
+along with OGRE; see the file COPYING.  If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
Index: /code/branches/rocket2/src/external/ogreceguirenderer/changes_orxonox.diff
===================================================================
--- /code/branches/rocket2/src/external/ogreceguirenderer/changes_orxonox.diff	(revision 6952)
+++ /code/branches/rocket2/src/external/ogreceguirenderer/changes_orxonox.diff	(revision 6952)
@@ -0,0 +1,96 @@
+--- OgreCEGUIRenderer.cpp	Wed Jan 28 21:14:09 2009
++++ OgreCEGUIRenderer.cpp	Wed Jan 28 21:07:10 2009
+@@ -24,11 +24,11 @@
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *************************************************************************/
+ 
+-#include <CEGUI/CEGUIImagesetManager.h>
+-#include <CEGUI/CEGUIImageset.h>
+-#include <CEGUI/CEGUIImage.h>
+-#include <CEGUI/CEGUIExceptions.h>
+-#include <CEGUI/CEGUISystem.h>
++#include <CEGUIImagesetManager.h>
++#include <CEGUIImageset.h>
++#include <CEGUIImage.h>
++#include <CEGUIExceptions.h>
++#include <CEGUISystem.h>
+ 
+ #include "OgreCEGUIRenderer.h"
+ #include "OgreCEGUITexture.h"
+@@ -454,7 +454,11 @@
+ 	d_render_sys->_setTextureUnitFiltering(0, FO_LINEAR, FO_LINEAR, FO_POINT);
+ 	d_render_sys->_setTextureAddressingMode(0, d_uvwAddressMode);
+ 	d_render_sys->_setTextureMatrix(0, Matrix4::IDENTITY);
++#if OGRE_VERSION >= 0x010600
++	d_render_sys->_setAlphaRejectSettings(CMPF_ALWAYS_PASS, 0, false);
++#else
+ 	d_render_sys->_setAlphaRejectSettings(CMPF_ALWAYS_PASS, 0);
++#endif
+ 	d_render_sys->_setTextureBlendMode(0, d_colourBlendMode);
+ 	d_render_sys->_setTextureBlendMode(0, d_alphaBlendMode);
+ 	d_render_sys->_disableTextureUnitsFrom(1);
+--- OgreCEGUIRenderer.h	Wed Jan 28 21:14:09 2009
++++ OgreCEGUIRenderer.h	Wed Jan 28 21:06:46 2009
+@@ -29,9 +29,9 @@
+ #ifndef _OgreCEGUIRenderer_h_
+ #define _OgreCEGUIRenderer_h_
+ 
+-#include <CEGUI/CEGUIBase.h>
+-#include <CEGUI/CEGUIRenderer.h>
+-#include <CEGUI/CEGUITexture.h>
++#include <CEGUIBase.h>
++#include <CEGUIRenderer.h>
++#include <CEGUITexture.h>
+ 
+ #include <OgreRenderQueueListener.h>
+ #include <OgreSceneManagerEnumerator.h>
+--- OgreCEGUIResourceProvider.cpp	Wed Jan 28 21:14:09 2009
++++ OgreCEGUIResourceProvider.cpp	Wed Jan 28 21:07:15 2009
+@@ -25,7 +25,7 @@
+ *************************************************************************/
+ #include "OgreCEGUIResourceProvider.h"
+ 
+-#include <CEGUI/CEGUIExceptions.h>
++#include <CEGUIExceptions.h>
+ #include <OgreArchiveManager.h>
+ 
+ 
+--- OgreCEGUIResourceProvider.h	Wed Jan 28 21:14:09 2009
++++ OgreCEGUIResourceProvider.h	Wed Jan 28 21:06:51 2009
+@@ -26,7 +26,7 @@
+ #ifndef _OgreCEGUIResourceProvider_h_
+ #define _OgreCEGUIResourceProvider_h_
+ 
+-#include <CEGUI/CEGUIResourceProvider.h>
++#include <CEGUIResourceProvider.h>
+ #include "OgreCEGUIRenderer.h"
+ 
+ // Start of CEGUI namespace section
+--- OgreCEGUITexture.cpp	Wed Jan 28 21:14:09 2009
++++ OgreCEGUITexture.cpp	Wed Jan 28 21:07:21 2009
+@@ -24,8 +24,8 @@
+     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *************************************************************************/
+ 
+-#include <CEGUI/CEGUISystem.h>
+-#include <CEGUI/CEGUIExceptions.h>
++#include <CEGUISystem.h>
++#include <CEGUIExceptions.h>
+ #include "OgreCEGUITexture.h"
+ #include "OgreCEGUIRenderer.h"
+ 
+--- OgreCEGUITexture.h	Wed Jan 28 21:14:09 2009
++++ OgreCEGUITexture.h	Wed Jan 28 21:07:06 2009
+@@ -26,9 +26,9 @@
+ #ifndef _OgreCEGUITexture_h_
+ #define _OgreCEGUITexture_h_
+ 
+-#include <CEGUI/CEGUIBase.h>
+-#include <CEGUI/CEGUIRenderer.h>
+-#include <CEGUI/CEGUITexture.h>
++#include <CEGUIBase.h>
++#include <CEGUIRenderer.h>
++#include <CEGUITexture.h>
+ #include "OgreCEGUIRenderer.h"
+ 
+ // Start of CEGUI namespace section
Index: /code/branches/rocket2/src/external/ois/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/ois/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,68 @@
+ #
+ #             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.
+ #
+
+SET_SOURCE_FILES(OIS_FILES
+  OIS.h
+  OISConfig.h
+  OISEffect.h
+  OISEvents.h
+  OISException.h
+  OISFactoryCreator.h
+  OISForceFeedback.h
+  OISInputManager.h
+  OISInterface.h
+  OISJoyStick.h
+  OISKeyboard.h
+  OISMouse.h
+  OISObject.h
+  OISPrereqs.h
+
+COMPILATION_BEGIN OISCompilation.cpp
+  OISEffect.cpp
+  OISException.cpp
+  OISForceFeedback.cpp
+  OISInputManager.cpp
+  OISJoyStick.cpp
+  OISKeyboard.cpp
+  OISObject.cpp
+COMPILATION_END
+)
+IF(WIN32)
+  ADD_SUBDIRECTORY(win32)
+ELSEIF(APPLE)
+  ADD_SUBDIRECTORY(mac)
+ELSEIF(UNIX)
+  ADD_SUBDIRECTORY(linux)
+ENDIF()
+
+INCLUDE_DIRECTORIES(.)
+
+ORXONOX_ADD_LIBRARY(ois_orxonox
+  ORXONOX_EXTERNAL
+  DEFINE_SYMBOL
+    "OIS_NONCLIENT_BUILD"
+  VERSION
+    1.2
+  SOURCE_FILES
+    ${OIS_FILES}
+)
+
+IF(WIN32)
+  TARGET_LINK_LIBRARIES(ois_orxonox ${DIRECTX_LIBRARIES})
+ENDIF()
Index: /code/branches/rocket2/src/external/ois/OIS.h
===================================================================
--- /code/branches/rocket2/src/external/ois/OIS.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OIS.h	(revision 6952)
@@ -0,0 +1,40 @@
+/*
+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_OISALL_H
+#define OIS_OISALL_H
+
+#include "OISPrereqs.h"
+#include "OISObject.h"
+#include "OISMouse.h"
+#include "OISKeyboard.h"
+#include "OISJoyStick.h"
+#include "OISInputManager.h"
+#include "OISFactoryCreator.h"
+#include "OISException.h"
+#include "OISEvents.h"
+
+#include "OISEffect.h"
+#include "OISInterface.h"
+#include "OISForceFeedback.h"
+
+#endif
Index: /code/branches/rocket2/src/external/ois/OISConfig.h
===================================================================
--- /code/branches/rocket2/src/external/ois/OISConfig.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISConfig.h	(revision 6952)
@@ -0,0 +1,77 @@
+/*
+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_CONFIG_HEADER
+#define OIS_CONFIG_HEADER
+
+//----------------------------------------------------------------------------//
+//* This file contains defines for building certain parts of this Lib
+//*	This file is not meant for External inclusion. However, you can edit this 
+//* file before a build to effect what features are used internally
+//----------------------------------------------------------------------------//
+
+/** 
+@remarks
+	These lines have no bearing on internal build of OIS. This is here for
+	external build settings. Meaning, changing this does not require a
+	rebuild of OIS. This just affects VC dll import settings, as the DLL
+	build already defines this during its build for setting dll exports.
+	The undefine here is here just incase you decide to only use
+	DLL, and want to set it permently and recompile OIS too.. Avoid redefinition
+	from DLL build of OIS.
+
+	So, if wanting to link against DLL version, just uncomment these lines.
+*/
+//#ifdef OIS_DYNAMIC_LIB
+//#  undef OIS_DYNAMIC_LIB
+//#endif
+//#define OIS_DYNAMIC_LIB
+
+/**
+@remarks
+	Build in support for LIRC / WinLIRC - remote control support.
+	Requires Boost::asio
+@notes
+	Experimental - Supports connecting and enumerating. Control does not
+	yet return state or events
+*/
+//#define OIS_LIRC_SUPPORT
+
+/**
+@remarks
+	Build in support for PC Nintendo WiiMote Win32 HID interface.
+	Requires Boost::threads
+@notes
+	Useable, but not quite finished - supports rumble, all buttons, & main orientation axis.
+	Still needs Nunchuck, IR, and LED/Battery support.
+*/
+//#define OIS_WIN32_WIIMOTE_SUPPORT
+
+/**
+@remarks
+	Build in support for Win32 XInput (Xbox 360 Controller)
+@notes
+	Not Yet Implemented
+*/
+//#define OIS_WIN32_XINPUT_SUPPORT
+
+#endif
Index: /code/branches/rocket2/src/external/ois/OISEffect.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/OISEffect.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISEffect.cpp	(revision 6952)
@@ -0,0 +1,128 @@
+/*
+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 "OISEffect.h"
+#include "OISException.h"
+
+using namespace OIS;
+
+//VC7.1 had a problem with these not getting included.. 
+//Perhaps a case of a crazy extreme optimizer :/ (moved to header)
+//const unsigned int Effect::OIS_INFINITE = 0xFFFFFFFF;
+
+//------------------------------------------------------------------------------//
+static const char* pszEForceString[] = 
+  { "UnknownForce",
+    "ConstantForce", 
+    "RampForce", 
+    "PeriodicForce", 
+    "ConditionalForce", 
+    "CustomForce" };
+
+const char* Effect::getForceTypeName(Effect::EForce eValue)
+{
+  return (eValue >= 0 && eValue < _ForcesNumber) ? pszEForceString[eValue] : "<Bad force type>";
+}
+
+static const char* pszETypeString[] = 
+  { "Unknown",
+    "Constant",
+    "Ramp",
+    "Square", "Triangle", "Sine", "SawToothUp", "SawToothDown",
+    "Friction", "Damper", "Inertia", "Spring",
+    "Custom" };
+
+const char* Effect::getEffectTypeName(Effect::EType eValue)
+{
+  return (eValue >= 0 && eValue < _TypesNumber) ? pszETypeString[eValue] : "<Bad effect type>";
+}
+
+static const char* pszEDirectionString[] = 
+  { "NorthWest", "North", "NorthEast", "East", "SouthEast", "South", "SouthWest", "West"};
+
+const char* Effect::getDirectionName(Effect::EDirection eValue)
+{
+  return (eValue >= 0 && eValue < _DirectionsNumber) ? pszEDirectionString[eValue] : "<Bad direction>";
+}
+
+//------------------------------------------------------------------------------//
+Effect::Effect() : 
+	force(UnknownForce), 
+	type(Unknown),
+	effect(0),
+	axes(1)
+{
+}
+
+//------------------------------------------------------------------------------//
+Effect::Effect(EForce ef, EType et) : 
+	force(ef), 
+	type(et),
+	direction(North), 
+	trigger_button(-1),
+	trigger_interval(0),
+	replay_length(Effect::OIS_INFINITE),
+	replay_delay(0),
+	_handle(-1),
+	axes(1)
+{
+	effect = 0;
+
+	switch( ef )
+	{
+	case ConstantForce:    effect = new ConstantEffect(); break;
+	case RampForce:	       effect = new RampEffect(); break;
+	case PeriodicForce:    effect = new PeriodicEffect(); break;
+	case ConditionalForce: effect = new ConditionalEffect(); break;
+	default: break;
+	}
+}
+
+//------------------------------------------------------------------------------//
+Effect::~Effect()
+{
+	delete effect;
+}
+
+//------------------------------------------------------------------------------//
+ForceEffect* Effect::getForceEffect() const
+{
+	//If no effect was created in constructor, then we raise an error here
+	if( effect == 0 )
+		OIS_EXCEPT( E_NotSupported, "Requested ForceEffect is null!" );
+
+	return effect;
+}
+
+//------------------------------------------------------------------------------//
+void Effect::setNumAxes(short nAxes)
+{
+	//Can only be set before a handle was assigned (effect created)
+	if( _handle != -1 )
+        axes = nAxes;
+}
+
+//------------------------------------------------------------------------------//
+short Effect::getNumAxes() const
+{
+	return axes;
+}
Index: /code/branches/rocket2/src/external/ois/OISEffect.h
===================================================================
--- /code/branches/rocket2/src/external/ois/OISEffect.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISEffect.h	(revision 6952)
@@ -0,0 +1,278 @@
+/*
+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_Effect_H
+#define OIS_Effect_H
+
+#include "OISPrereqs.h"
+
+namespace OIS
+{
+	//Predeclare some Effect Property structs
+	class ForceEffect;
+	class ConstantEffect;
+	class RampEffect;
+	class PeriodicEffect;
+	class ConditionalEffect;
+
+	/**
+		Force Feedback is a relatively complex set of properties to upload to a device.
+		The best place for information on the different properties, effects, etc is in
+		the DX Documentation and MSDN - there are even pretty graphs ther =)
+		As this class is modeled on the the DX interface you can apply that same
+		knowledge to creating effects via this class on any OS supported by OIS.
+
+		In anycase, this is the main class you will be using. There is *absolutely* no
+		need to instance any of the supporting ForceEffect classes yourself.
+	*/
+	class _OISExport Effect
+	{
+		/**
+			hidden so this class cannot be instanced with default constructor
+		*/
+		Effect();
+	public:
+		//! Type of force
+		enum EForce
+		{
+			UnknownForce = 0,
+			ConstantForce,
+			RampForce,
+			PeriodicForce,
+			ConditionalForce,
+			CustomForce,
+			_ForcesNumber // Always keep in last position.
+		};
+
+		static const char* getForceTypeName(EForce eValue);
+
+		//! Type of effect
+		enum EType
+		{
+			//Type ----- Pairs with force:
+			Unknown = 0, //UnknownForce
+			Constant,    //ConstantForce
+			Ramp,        //RampForce
+			Square,      //PeriodicForce
+			Triangle,    //PeriodicForce
+            Sine,        //PeriodicForce
+			SawToothUp,  //PeriodicForce
+			SawToothDown,//PeriodicForce
+			Friction,    //ConditionalForce
+			Damper,      //ConditionalForce
+			Inertia,     //ConditionalForce
+			Spring,      //ConditionalForce
+			Custom,      //CustomForce
+			_TypesNumber // Always keep in last position.
+		};
+
+		static const char* getEffectTypeName(EType eValue);
+
+		//! Direction of the Force
+		enum EDirection
+		{
+			NorthWest,
+			North,
+			NorthEast,
+			East,
+			SouthEast,
+			South,
+			SouthWest,
+			West,
+			_DirectionsNumber // Always keep in last position.
+		};
+
+		static const char* getDirectionName(EDirection eValue);
+
+		/**
+			This constructor allows you to set the force type and effect.
+		*/
+		Effect(EForce ef, EType et);
+		virtual ~Effect();
+
+		const EForce force;
+		const EType type;
+
+		//Infinite Time
+		static const unsigned int OIS_INFINITE = 0xFFFFFFFF;
+
+		//-------------------------------------------------------------------//
+		//--- Set these variables before uploading or modifying an effect ---//
+
+		//Direction to apply to the force - affects two axes+ effects
+		EDirection direction;
+
+		//Number of button triggering an effect (-1 means no trigger)
+		short trigger_button;
+
+		//Time to wait before an effect can be re-triggered (microseconds)
+		unsigned int trigger_interval;
+
+		//Duration of an effect (microseconds)
+		unsigned int replay_length;
+
+		//Time to wait before to start playing an effect (microseconds)
+		unsigned int replay_delay;
+
+		//Get the specific Force Effect. This should be cast depending on the EForce
+		ForceEffect* getForceEffect() const;
+
+		/**
+		@remarks
+			Set the number of Axes to use before the initial creation of the effect.
+			Can only be done prior to creation! Use the FF interface to determine
+			how many axes can be used (are availiable)
+		*/
+		void setNumAxes(short nAxes);
+
+		/**
+		@remarks
+			Returns the number of axes used in this effect
+		*/
+		short getNumAxes() const;
+
+		//------------- Library Internal -------------------------------------//
+		/**
+			set internally.. do not change or you will not be able to upload/stop
+			this effect any more. It will become lost. It is mutable so even
+			with const reference it can/will be changed by this lib
+		*/
+		mutable int _handle;
+	protected:
+		ForceEffect* effect; //Properties depend on EForce
+		short axes;          //Number of axes to use in effect
+	};
+
+	//-----------------------------------------------------------------------------//
+	/**
+		Base class of all effect property classes
+	*/
+	class _OISExport ForceEffect
+	{
+	public:
+		virtual ~ForceEffect() {}
+	};
+
+	//-----------------------------------------------------------------------------//
+	/**
+		An optional envelope to be applied to the start/end of an effect. If any of
+		these values are nonzero, then the envelope will be used in setting up the
+		effect.
+	*/
+	class _OISExport Envelope : public ForceEffect
+	{
+	public:
+		Envelope() : attackLength(0), attackLevel(0), fadeLength(0), fadeLevel(0) {}
+#if defined(OIS_MSVC_COMPILER)
+  #pragma warning (push)
+  #pragma warning (disable : 4800)
+#endif
+		bool isUsed() const { return attackLength | attackLevel | fadeLength | fadeLevel; }
+#if defined(OIS_MSVC_COMPILER)
+  #pragma warning (pop)
+#endif
+
+		// Duration of the attack (microseconds)
+		unsigned int attackLength;
+
+		// Absolute level at the beginning of the attack (0 to 10K)
+		// (automatically signed when necessary by FF core according to effect level sign)
+		unsigned short attackLevel;
+
+		// Duration of fade (microseconds)
+		unsigned int fadeLength;
+
+		// Absolute level at the end of fade (0 to 10K)
+		// (automatically signed when necessary by FF core according to effect level sign)
+		unsigned short fadeLevel;
+	};
+
+	//-----------------------------------------------------------------------------//
+	/**
+		Use this class when dealing with Force type of Constant
+	*/
+	class _OISExport ConstantEffect : public ForceEffect
+	{
+	public:
+		ConstantEffect() : level(5000) {}
+
+		class Envelope envelope; //Optional envolope
+		signed short level;       //-10K to +10k
+	};
+
+	//-----------------------------------------------------------------------------//
+	/**
+		Use this class when dealing with Force type of Ramp
+	*/
+	class _OISExport RampEffect : public ForceEffect
+	{
+	public:
+		RampEffect() : startLevel(0), endLevel(0) {}
+
+        class Envelope envelope; //Optional envelope
+		signed short startLevel;  //-10K to +10k
+		signed short endLevel;    //-10K to +10k
+	};
+
+	//-----------------------------------------------------------------------------//
+	/**
+		Use this class when dealing with Force type of Periodic
+	*/
+	class _OISExport PeriodicEffect : public ForceEffect
+	{
+	public:
+		PeriodicEffect() : magnitude(0), offset(0), phase(0), period(0) {}
+
+		class Envelope envelope;  //Optional Envelope
+
+		unsigned short magnitude;  //0 to 10,0000
+		signed short   offset;
+		unsigned short phase;      //Position at which playback begins 0 to 35,999
+		unsigned int   period;     //Period of effect (microseconds)
+	};
+
+	//-----------------------------------------------------------------------------//
+	/**
+		Use this class when dealing with Force type of Condional
+	*/
+	class _OISExport ConditionalEffect : public ForceEffect
+	{
+	public:
+		ConditionalEffect() :
+            rightCoeff(0), leftCoeff(0), rightSaturation(0), leftSaturation(0),
+			deadband(0), center(0) {}
+
+		signed short   rightCoeff;      //-10k to +10k (Positive Coeff)
+		signed short   leftCoeff;       //-10k to +10k (Negative Coeff)
+
+		unsigned short rightSaturation; //0 to 10k (Pos Saturation)
+		unsigned short leftSaturation;  //0 to 10k (Neg Saturation)
+
+		//Region around center in which the condition is not active, in the range
+		//from 0 through 10,000
+		unsigned short deadband;
+
+		//(Offset in DX) -10k and 10k
+		signed short center;
+	};
+}
+#endif //OIS_Effect_H
Index: /code/branches/rocket2/src/external/ois/OISEvents.h
===================================================================
--- /code/branches/rocket2/src/external/ois/OISEvents.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISEvents.h	(revision 6952)
@@ -0,0 +1,43 @@
+/*
+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_EVENTHEADERS_
+#define _OIS_EVENTHEADERS_
+#include "OISPrereqs.h"
+
+namespace OIS
+{
+	/**
+		Base class of all events
+	*/
+	class _OISExport EventArg
+	{
+	public:
+		EventArg( Object* obj ) : device(obj) {}
+		virtual ~EventArg() {}
+
+		//! Pointer to the Input Device
+		const Object* device;
+	};
+}
+
+#endif //_OIS_EVENTHEADERS_
Index: /code/branches/rocket2/src/external/ois/OISException.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/OISException.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISException.cpp	(revision 6952)
@@ -0,0 +1,32 @@
+/*
+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 "OISException.h"
+
+using namespace OIS;
+
+//----------------------------------------------------------------------------//
+const char* Exception::what() const throw()
+{
+	return eText;
+}
+
Index: /code/branches/rocket2/src/external/ois/OISException.h
===================================================================
--- /code/branches/rocket2/src/external/ois/OISException.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISException.h	(revision 6952)
@@ -0,0 +1,78 @@
+/*
+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_EXCEPTION_HEADER_
+#define _OIS_EXCEPTION_HEADER_
+#include "OISPrereqs.h"
+#include <exception>
+
+namespace OIS
+{
+	//! Simple enum's for dealing with exceptions
+    enum OIS_ERROR
+	{
+		E_InputDisconnected,
+		E_InputDeviceNonExistant,
+		E_InputDeviceNotSupported,
+		E_DeviceFull,
+		E_NotSupported,
+		E_NotImplemented,
+		E_Duplicate,
+		E_InvalidParam,
+		E_General
+	};
+
+	/**
+	@remarks
+		Class for handling OIS exceptions. Much cleaner than checking every method for reurn value.
+		Inherits from std::exception so you can simply log those messages if you want to be generic.
+		Also note that this has a source file now since OSX was not finding the OIS::Exception symbol
+		which would cause program abortion with now correponding exception type.
+	*/
+	class _OISExport Exception : public std::exception
+	{
+		//! Hidden default
+		Exception() : eType(E_General), eLine(0), eFile(0) {}
+	public:
+		//! Creates exception object
+		Exception( OIS_ERROR err, const char* str, int line, const char *file )
+			: eType(err), eLine(line), eFile(file), eText(str) {}
+
+		~Exception() throw() {}
+
+		virtual const char* what() const throw();
+
+		//! The type of exception raised
+		const OIS_ERROR eType;
+		//! The line number it occurred on
+		const int eLine;
+		//! The source file
+		const char* eFile;
+		//! A message passed along when the exception was raised
+		const char* eText;
+	};
+}
+
+//! Use this macro to handle exceptions easily
+#define OIS_EXCEPT( err, str ) throw( OIS::Exception(err, str, __LINE__, __FILE__) )
+
+#endif //_OIS_EXCEPTION_HEADER_
Index: /code/branches/rocket2/src/external/ois/OISFactoryCreator.h
===================================================================
--- /code/branches/rocket2/src/external/ois/OISFactoryCreator.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISFactoryCreator.h	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+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_FactoryCreator_H
+#define OIS_FactoryCreator_H
+
+#include "OISPrereqs.h"
+
+namespace OIS
+{
+	/**
+		Interface for creating devices - all devices ultimately get enumerated/created via a factory.
+		A factory can create multiple types of objects.
+	*/
+	class _OISExport FactoryCreator
+	{
+	public:
+		/**
+			@remarks Virtual Destructor
+		*/
+		virtual ~FactoryCreator() {};
+
+		/**
+			@remarks Return a list of all unused devices the factory maintains
+		*/
+		virtual DeviceList freeDeviceList() = 0;
+
+		/**
+			@remarks Number of total devices of requested type
+			@param iType Type of devices to check
+		*/
+		virtual int totalDevices(Type iType) = 0;
+
+		/**
+			@remarks Number of free devices of requested type
+			@param iType Type of devices to check
+		*/
+		virtual int freeDevices(Type iType) = 0;
+
+		/**
+			@remarks Does a Type exist with the given vendor name
+			@param iType Type to check
+			@param vendor Vendor name to test
+		*/
+		virtual bool vendorExist(Type iType, const std::string & vendor) = 0;
+
+		/**
+			@remarks Creates the object
+			@param iType Type to create
+			@param bufferMode True to setup for buffered events
+			@param vendor Create a device with the vendor name, "" means vendor name is unimportant
+		*/
+		virtual Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor = "") = 0;
+
+		/**
+			@remarks Destroys object
+			@param obj Object to destroy
+		*/
+		virtual void destroyObject(Object* obj) = 0;
+	};
+}
+#endif //OIS_FactoryCreator_H
Index: /code/branches/rocket2/src/external/ois/OISForceFeedback.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/OISForceFeedback.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISForceFeedback.cpp	(revision 6952)
@@ -0,0 +1,74 @@
+/*
+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 "OISForceFeedback.h"
+#include "OISException.h"
+
+using namespace OIS;
+
+//-------------------------------------------------------------//
+ForceFeedback::ForceFeedback() : mSetGainSupport(false), mSetAutoCenterSupport(false)
+{
+}
+
+//-------------------------------------------------------------//
+void ForceFeedback::_addEffectTypes( Effect::EForce force, Effect::EType type )
+{
+	if( force <= Effect::UnknownForce || force >= Effect::_ForcesNumber
+		|| type <= Effect::Unknown || type >= Effect::_TypesNumber )
+		OIS_EXCEPT( E_General, "Can't add unknown effect Force/Type to the supported list" );
+
+	mSupportedEffects.insert(std::pair<Effect::EForce, Effect::EType>(force, type));
+}
+
+//-------------------------------------------------------------//
+void ForceFeedback::_setGainSupport( bool on )
+{
+	mSetGainSupport = on;
+}
+
+//-------------------------------------------------------------//
+void ForceFeedback::_setAutoCenterSupport( bool on )
+{
+	mSetAutoCenterSupport = on;
+}
+
+//-------------------------------------------------------------//
+const ForceFeedback::SupportedEffectList& ForceFeedback::getSupportedEffects() const
+{
+	return mSupportedEffects;
+}
+
+//-------------------------------------------------------------//
+bool ForceFeedback::supportsEffect(Effect::EForce force, Effect::EType type) const
+{
+    const std::pair<SupportedEffectList::const_iterator, SupportedEffectList::const_iterator> 
+	    iterRange = mSupportedEffects.equal_range(force);
+	SupportedEffectList::const_iterator iter;
+	for (iter = iterRange.first; iter != iterRange.second; iter++)
+	{
+	  if ((*iter).second == type)
+		return true;
+	}
+
+	return false;
+}
Index: /code/branches/rocket2/src/external/ois/OISForceFeedback.h
===================================================================
--- /code/branches/rocket2/src/external/ois/OISForceFeedback.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISForceFeedback.h	(revision 6952)
@@ -0,0 +1,120 @@
+/*
+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_ForceFeedBack_H
+#define OIS_ForceFeedBack_H
+
+#include "OISPrereqs.h"
+#include "OISInterface.h"
+#include "OISEffect.h"
+
+namespace OIS
+{
+	/**
+		Interface class for dealing with Force Feedback devices
+	*/
+	class _OISExport ForceFeedback : public Interface
+	{
+	public:
+		ForceFeedback();
+		virtual ~ForceFeedback() {}
+
+		/**
+		@remarks
+			This is like setting the master volume of an audio device.
+			Individual effects have gain levels; however, this affects all
+			effects at once.
+			Note: If the device does not support master gain setting, nothing is done
+		@param level
+			A value between 0.0 and 1.0 represent the percentage of gain. 1.0
+			being the highest possible force level (means no scaling).
+		*/
+		virtual void setMasterGain( float level ) = 0;
+		
+		/**
+		@remarks
+			If using Force Feedback effects, this should be turned off
+			before uploading any effects. Auto centering is the motor moving
+			the joystick back to center. DirectInput only has an on/off setting,
+			whereas linux has levels.. Though, we go with DI's on/off mode only
+			Note: If the device does not support auto-centering, nothing is done
+		@param auto_on
+			true to turn auto centering on, false to turn off.
+		*/
+		virtual void setAutoCenterMode( bool auto_on ) = 0;
+
+		/**
+		@remarks
+			Creates and Plays the effect immediately. If the device is full
+			of effects, it will fail to be uploaded. You will know this by
+			an invalid Effect Handle
+		*/
+		virtual void upload( const Effect* effect ) = 0;
+
+		/**
+		@remarks
+			Modifies an effect that is currently playing
+		*/
+		virtual void modify( const Effect* effect ) = 0;
+
+		/**
+		@remarks
+			Remove the effect from the device
+		*/
+		virtual void remove( const Effect* effect ) = 0;
+
+		/**
+		@remarks
+			Get the number of supported Axes for FF usage
+		*/
+        virtual short getFFAxesNumber() = 0;
+
+		/**
+		@remarks
+			Get the current load (%, in [0, 100] of the FF device memory 
+		*/
+		virtual unsigned short getFFMemoryLoad() = 0;
+
+		typedef std::multimap<Effect::EForce, Effect::EType> SupportedEffectList;
+		/**
+		@remarks
+			Get a list of all supported effects
+		*/
+		const SupportedEffectList& getSupportedEffects() const;
+
+		/**
+		@remarks
+			Tell if a given force / effect type pair is supported
+		*/
+		bool supportsEffect(Effect::EForce force, Effect::EType type) const;
+
+		void _addEffectTypes( Effect::EForce force, Effect::EType type );
+		void _setGainSupport( bool on );
+		void _setAutoCenterSupport( bool on );
+
+	protected:
+		SupportedEffectList mSupportedEffects;
+		bool mSetGainSupport;
+		bool mSetAutoCenterSupport;
+	};
+}
+#endif //OIS_ForceFeedBack_H
Index: /code/branches/rocket2/src/external/ois/OISInputManager.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/OISInputManager.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISInputManager.cpp	(revision 6952)
@@ -0,0 +1,284 @@
+/*
+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 "OISInputManager.h"
+#include "OISException.h"
+#include "OISFactoryCreator.h"
+#include "OISObject.h"
+#include <sstream>
+#include <algorithm>
+
+//Bring in correct Header / InputManager for current build platform
+#if defined OIS_SDL_PLATFORM
+#  include "SDL/SDLInputManager.h"
+#elif defined OIS_WIN32_PLATFORM
+#  include "win32/Win32InputManager.h"
+#elif defined OIS_LINUX_PLATFORM
+#  include "linux/LinuxInputManager.h"
+#elif defined OIS_APPLE_PLATFORM
+#  include "mac/MacInputManager.h"
+#elif defined OIS_XBOX_PLATFORM
+#  include "xbox/XBoxInputManager.h"
+#endif
+
+//Bring in extra controls
+#if defined OIS_LIRC_SUPPORT
+#  include "extras/LIRC/OISLIRCFactoryCreator.h"
+#endif
+#if defined OIS_WIN32_WIIMOTE_SUPPORT
+#  include "win32/extras/WiiMote/OISWiiMoteFactoryCreator.h"
+#endif
+
+
+using namespace OIS;
+
+//----------------------------------------------------------------------------//
+InputManager::InputManager(const std::string& name) :
+	m_VersionName(OIS_VERSION_NAME),
+	mInputSystemName(name),
+	m_lircSupport(0),
+	m_wiiMoteSupport(0)
+{
+}
+
+//----------------------------------------------------------------------------//
+InputManager::~InputManager()
+{
+#if defined OIS_LIRC_SUPPORT
+	delete m_lircSupport;
+#endif
+
+#if defined OIS_WIN32_WIIMOTE_SUPPORT
+	delete m_wiiMoteSupport;
+#endif
+}
+
+//----------------------------------------------------------------------------//
+unsigned int InputManager::getVersionNumber()
+{
+	return OIS_VERSION;
+}
+
+//----------------------------------------------------------------------------//
+const std::string &InputManager::getVersionName()
+{
+	return m_VersionName;
+}
+
+//----------------------------------------------------------------------------//
+InputManager* InputManager::createInputSystem( std::size_t windowhandle )
+{
+	ParamList pl;
+	std::ostringstream wnd;
+	wnd << windowhandle;
+	pl.insert(std::make_pair( std::string("WINDOW"), wnd.str() ));
+
+	return createInputSystem( pl );
+}
+
+//----------------------------------------------------------------------------//
+InputManager* InputManager::createInputSystem( ParamList &paramList )
+{
+	InputManager* im = 0;
+
+#if defined OIS_SDL_PLATFORM
+	im = new SDLInputManager();
+#elif defined OIS_WIN32_PLATFORM
+	im = new Win32InputManager();
+#elif defined OIS_XBOX_PLATFORM
+	im = new XBoxInputManager();
+#elif defined OIS_LINUX_PLATFORM
+	im = new LinuxInputManager();
+#elif defined OIS_APPLE_PLATFORM
+	im = new MacInputManager();
+#else
+	OIS_EXCEPT(E_General, "No platform library.. check build platform defines!");
+#endif 
+
+	try
+	{
+		im->_initialize(paramList);
+	}
+	catch(...)
+	{
+		delete im;
+		throw; //rethrow
+	}
+
+	return im;
+}
+
+//----------------------------------------------------------------------------//
+void InputManager::destroyInputSystem(InputManager* manager)
+{
+	if( manager == 0 )
+		return;
+
+	//Cleanup before deleting...
+	for( FactoryCreatedObject::iterator i = manager->mFactoryObjects.begin(); 
+		i != manager->mFactoryObjects.end(); ++i )
+	{
+		i->second->destroyObject( i->first );
+	}
+
+	manager->mFactoryObjects.clear();
+	delete manager;
+}
+
+//--------------------------------------------------------------------------------//
+const std::string& InputManager::inputSystemName()
+{
+	return mInputSystemName;
+}
+
+//--------------------------------------------------------------------------------//
+int InputManager::getNumberOfDevices( Type iType )
+{
+	//Count up all the factories devices
+	int factoyObjects = 0;
+	FactoryList::iterator i = mFactories.begin(), e = mFactories.end();
+	for( ; i != e; ++i )
+		factoyObjects += (*i)->totalDevices(iType);
+
+	return factoyObjects;
+}
+
+//----------------------------------------------------------------------------//
+DeviceList InputManager::listFreeDevices()
+{
+	DeviceList list;
+	FactoryList::iterator i = mFactories.begin(), e = mFactories.end();
+	for( ; i != e; ++i )
+	{
+		DeviceList temp = (*i)->freeDeviceList();
+		list.insert(temp.begin(), temp.end());
+	}
+
+	return list;
+}
+
+//----------------------------------------------------------------------------//
+Object* InputManager::createInputObject( Type iType, bool bufferMode, const std::string &vendor )
+{
+	Object* obj = 0;
+	FactoryList::iterator i = mFactories.begin(), e = mFactories.end();
+	for( ; i != e; ++i)
+	{
+		if( (*i)->freeDevices(iType) > 0 )
+		{
+			if( vendor == "" || (*i)->vendorExist(iType, vendor) )
+			{
+				obj = (*i)->createObject(this, iType, bufferMode, vendor);
+				mFactoryObjects[obj] = (*i);
+				break;
+			}
+		}
+	}
+
+	if(!obj)
+		OIS_EXCEPT(E_InputDeviceNonExistant, "No devices match requested type.");
+
+	try
+	{	//Intialize device
+		obj->_initialize();
+	}
+	catch(...)
+	{	//Somekind of error, cleanup and rethrow
+		destroyInputObject(obj);
+		throw;
+	}
+
+	return obj;
+}
+
+//----------------------------------------------------------------------------//
+void InputManager::destroyInputObject( Object* obj )
+{
+	if( obj == 0 )
+		return;
+
+	FactoryCreatedObject::iterator i = mFactoryObjects.find(obj);
+	if( i != mFactoryObjects.end() )
+	{
+		i->second->destroyObject(obj);
+		mFactoryObjects.erase(i);
+	}
+	else
+	{
+		OIS_EXCEPT(E_General, "Object creator not known.");
+	}
+}
+
+//----------------------------------------------------------------------------//
+void InputManager::addFactoryCreator( FactoryCreator* factory )
+{
+	if(factory != 0)
+		mFactories.push_back(factory);
+}
+
+//----------------------------------------------------------------------------//
+void InputManager::removeFactoryCreator( FactoryCreator* factory )
+{
+	if(factory != 0)
+	{
+		//First, destroy all devices created with the factory
+		for( FactoryCreatedObject::iterator i = mFactoryObjects.begin(); i != mFactoryObjects.end(); ++i )
+		{
+			if( i->second == factory )
+			{
+				i->second->destroyObject(i->first);
+				mFactoryObjects.erase(i++);
+			}
+		}
+
+		//Now, remove the factory itself
+		FactoryList::iterator fact = std::find(mFactories.begin(), mFactories.end(), factory);
+		if( fact != mFactories.end() )
+			mFactories.erase(fact);
+	}
+}
+
+//----------------------------------------------------------------------------//
+void InputManager::enableAddOnFactory(AddOnFactories factory)
+{
+#if defined OIS_LIRC_SUPPORT
+	if( factory == AddOn_LIRC || factory == AddOn_All )
+	{
+		if( m_lircSupport == 0 )
+		{
+			m_lircSupport = new LIRCFactoryCreator();
+			addFactoryCreator(m_lircSupport);
+		}
+	}
+#endif
+
+#if defined OIS_WIN32_WIIMOTE_SUPPORT
+	if( factory == AddOn_WiiMote || factory == AddOn_All )
+	{
+		if( m_wiiMoteSupport == 0 )
+		{
+			m_wiiMoteSupport = new WiiMoteFactoryCreator();
+			addFactoryCreator(m_wiiMoteSupport);
+		}
+	}
+#endif
+}
Index: /code/branches/rocket2/src/external/ois/OISInputManager.h
===================================================================
--- /code/branches/rocket2/src/external/ois/OISInputManager.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISInputManager.h	(revision 6952)
@@ -0,0 +1,205 @@
+/*
+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_InputManager_H
+#define OIS_InputManager_H
+
+#include "OISPrereqs.h"
+
+namespace OIS
+{
+	//Forward declare a couple of classes we might use later
+	class LIRCFactoryCreator;
+	class WiiMoteFactoryCreator;
+
+	/**
+		Base Manager class. No longer a Singleton; so feel free to create as many InputManager's as you have
+		windows.
+	*/
+	class _OISExport InputManager
+	{
+	public:
+		/**
+		@remarks
+			Returns version number (useful in DLL/SO libs)
+		@returns
+			Bits: 1-8 Patch number, 9-16 Minor version, 17-32 Major version
+		*/
+		static unsigned int getVersionNumber();
+
+		/**
+		@remarks
+			Returns version string (useful in DLL/SO libs)
+		@returns
+			Version name
+		*/
+		const std::string &getVersionName();
+
+		/**
+		@remarks
+			Creates appropriate input system dependent on platform. 
+		@param winHandle
+			Contains OS specific window handle (such as HWND or X11 Window)
+		@returns
+			A pointer to the created manager, or raises Exception
+		*/
+		static InputManager* createInputSystem( std::size_t winHandle );
+
+		/**
+		@remarks
+			Creates appropriate input system dependent on platform. 
+		@param paramList
+			ParamList contains OS specific info (such as HWND and HINSTANCE for window apps),
+			and access mode.
+		@returns
+			A pointer to the created manager, or raises Exception
+		*/
+		static InputManager* createInputSystem( ParamList &paramList );
+
+		/**
+		@remarks
+			Destroys the InputManager
+		@param manager
+			Manager to destroy
+		*/
+		static void destroyInputSystem(InputManager* manager);
+
+		/**
+		@remarks Gets the name of the current platform input system
+		*/
+		const std::string& inputSystemName();
+
+		/**
+		@remarks
+			Returns the number of the specified OIS::Type devices discovered by OIS
+		@param iType
+			Type that you are interested in
+		*/
+		int getNumberOfDevices( Type iType );
+
+		/**
+		@remarks
+			Lists all unused devices
+		@returns
+			DeviceList which contains Type and vendor of device
+		*/
+		DeviceList listFreeDevices();
+
+		/**
+		@remarks
+			Tries to create an object with the specified vendor. If you have no
+			preference of vendor, leave vender as default (""). Raises exception on failure
+		*/
+		Object* createInputObject( Type iType, bool bufferMode, const std::string &vendor = "");
+
+		/**
+		@remarks Destroys Input Object
+		*/
+		void destroyInputObject( Object* obj );
+
+		/**
+		@remarks
+			Add a custom object factory to allow for user controls.
+		@param factory
+			Factory instance to add
+		@notes
+			Make sure you do not delete the factory before devices created from
+			the factory are destroyed (either by calling RemoveFactoryCreator, or shutting down
+			the input system). Order should be something like the following:
+				* Create Input System
+				* Create Factory Instance
+				* AddFactoryCreator(factory)
+				* Create a device from the InputManager (device created by factory)
+				* One of the follwoing:
+					* removeFactoryCreator(factory)
+					* inputManager->destroyInputObject(obj)
+				* destroyInputSystem(inputManager)
+				* destroy Factory Instance
+			You can safely delete the factory instance once you have removed it or shut down the
+			input manager.
+		*/
+		void addFactoryCreator( FactoryCreator* factory );
+
+		/**
+		@remarks
+			Remove a previously added object factory
+		@param factory
+			Factory object to remove.
+		@notes
+			Removing a factory will automatically destroy any Objects created from the factory
+		*/
+		void removeFactoryCreator( FactoryCreator* factory );
+
+		//! All generic devices OIS supports internally (if they are compiled in)
+		enum AddOnFactories
+		{
+			AddOn_All = 0,		//All Devices
+			AddOn_LIRC = 1,		//PC Linux Infrared Remote Control
+			AddOn_WiiMote = 2	//PC WiiMote Support
+		};
+
+		/**
+		@remarks
+			Enable an addon FactoryCreator extension. By default, none are activated.
+			If the desired support was not compiled in, this has no effect. Calling
+			multiple times has no effect. Once activated, there is no way to deactivate -
+			simply destroy and recreate input manager.
+		*/
+		void enableAddOnFactory(AddOnFactories factory);
+
+	protected:
+		/**
+		@remarks
+			Called from createInputSystem, gives derived input class a chance to setup after it is created
+		*/
+		virtual void _initialize(ParamList &paramList) = 0;
+
+		/**
+		@remarks
+			Derived classes must provide input system name
+		*/
+		InputManager(const std::string& name);
+
+		/**
+		@remarks
+			Virtual Destructor - this base class will clean up all devices still opened in mFactoryObjects list
+		*/
+		virtual ~InputManager();
+
+		//! OIS Version name
+		const std::string m_VersionName;
+
+		//! FactoryCreator list	
+		FactoryList mFactories;
+
+		//! Factory created objects - useful so we can find creator to send destruction request to
+		FactoryCreatedObject mFactoryObjects;
+
+		//! Name of the input system
+		const std::string mInputSystemName;
+
+		//! Extra factory (not enabled by default)
+		LIRCFactoryCreator *m_lircSupport;
+		WiiMoteFactoryCreator *m_wiiMoteSupport;
+	};
+}
+#endif
Index: /code/branches/rocket2/src/external/ois/OISInterface.h
===================================================================
--- /code/branches/rocket2/src/external/ois/OISInterface.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISInterface.h	(revision 6952)
@@ -0,0 +1,47 @@
+/*
+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_Interface_H
+#define OIS_Interface_H
+
+#include "OISPrereqs.h"
+
+namespace OIS
+{
+	/**
+		An Object's interface is a way to gain write access to devices which support
+		it. For example, force feedack.
+	*/
+	class _OISExport Interface
+	{
+	public:
+		virtual ~Interface() {};
+
+		//! Type of Interface
+		enum IType
+		{
+			ForceFeedback,
+			Reserved
+		};
+	};
+}
+#endif //OIS_Interface_H
Index: /code/branches/rocket2/src/external/ois/OISJoyStick.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/OISJoyStick.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISJoyStick.cpp	(revision 6952)
@@ -0,0 +1,73 @@
+/*
+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 "OISJoyStick.h"
+
+using namespace OIS;
+
+//----------------------------------------------------------------------------//
+JoyStick::JoyStick(const std::string &vendor, bool buffered, int devID, InputManager* creator) :
+	Object(vendor, OISJoyStick, buffered, devID, creator),
+	mSliders(0),
+	mPOVs(0),
+	mListener(0),
+	mVector3Sensitivity(OIS_JOYSTICK_VECTOR3_DEFAULT)
+{
+}
+
+//----------------------------------------------------------------------------//
+int JoyStick::getNumberOfComponents(ComponentType cType) const
+{
+	switch( cType )
+	{
+	case OIS_Button:	return (int)mState.mButtons.size();
+	case OIS_Axis:		return (int)mState.mAxes.size();
+	case OIS_Slider:	return mSliders;
+	case OIS_POV:		return mPOVs;
+	case OIS_Vector3:	return (int)mState.mVectors.size();
+	default:			return 0;
+	}
+}
+
+//----------------------------------------------------------------------------//
+void JoyStick::setVector3Sensitivity(float degrees)
+{
+	mVector3Sensitivity = degrees;
+}
+
+//----------------------------------------------------------------------------//
+float JoyStick::getVector3Sensitivity() const
+{
+	return mVector3Sensitivity;
+}
+
+//----------------------------------------------------------------------------//
+void JoyStick::setEventCallback( JoyStickListener *joyListener )
+{
+	mListener = joyListener;
+}
+
+//----------------------------------------------------------------------------//
+JoyStickListener* JoyStick::getEventCallback() const
+{
+	return mListener;
+}
Index: /code/branches/rocket2/src/external/ois/OISJoyStick.h
===================================================================
--- /code/branches/rocket2/src/external/ois/OISJoyStick.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISJoyStick.h	(revision 6952)
@@ -0,0 +1,228 @@
+/*
+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_Joystick_H
+#define OIS_Joystick_H
+#include "OISObject.h"
+#include "OISEvents.h"
+
+namespace OIS
+{
+	/** @remarks default sensitivity for vector3 component of joystick */
+	#define OIS_JOYSTICK_VECTOR3_DEFAULT 2.28f
+
+	//! POV / HAT Joystick component
+	class _OISExport Pov : public Component
+	{
+	public:
+		Pov() : Component(OIS_POV), direction(0) {}
+
+		static const int Centered  = 0x00000000;
+		static const int North     = 0x00000001;
+		static const int South     = 0x00000010;
+		static const int East      = 0x00000100;
+		static const int West      = 0x00001000;
+		static const int NorthEast = 0x00000101;
+		static const int SouthEast = 0x00000110;
+		static const int NorthWest = 0x00001001;
+		static const int SouthWest = 0x00001010;
+
+		int direction;
+	};
+
+	//! A sliding axis - only used in Win32 Right Now
+	class _OISExport Slider : public Component
+	{
+	public:
+		Slider() : Component(OIS_Slider), abX(0), abY(0) {};
+		//! true if pushed, false otherwise
+		int abX, abY;
+	};
+
+	/**
+		Represents the state of the joystick
+		All members are valid for both buffered and non buffered mode
+		Sticks with zero values are not present on the device
+	*/
+	class _OISExport JoyStickState
+	{
+	public:
+		//! Constructor
+		JoyStickState() { clear(); }
+
+		//! Represents all the buttons (uses a bitset)
+		std::vector<bool> mButtons;
+
+		//! Represents all the single axes on the device
+		std::vector<Axis> mAxes;
+
+		//! Represents the value of a POV. Maximum of 4
+		Pov mPOV[4];
+
+		//! Represent the max sliders
+		Slider mSliders[4];
+
+		//! Represents all Vector type controls the device exports
+		std::vector<Vector3> mVectors;
+
+		//! internal method to reset all variables to initial values
+		void clear()
+		{
+			for( std::vector<bool>::iterator i = mButtons.begin(), e = mButtons.end(); i != e; ++i )
+			{
+				(*i) = false;
+			}
+
+			for( std::vector<Axis>::iterator i = mAxes.begin(), e = mAxes.end(); i != e; ++i )
+			{
+				i->absOnly = true; //Currently, joysticks only report Absolute values
+				i->clear();
+			}
+
+			for( std::vector<Vector3>::iterator i = mVectors.begin(), e = mVectors.end(); i != e; ++i )
+			{
+				i->clear();
+			}
+
+			for( int i = 0; i < 4; ++i )
+			{
+				mPOV[i].direction = Pov::Centered;
+				mSliders[i].abX = mSliders[i].abY = 0;
+			}
+		}
+	};
+
+	/** Specialised for joystick events */
+	class _OISExport JoyStickEvent : public EventArg
+	{
+	public:
+		JoyStickEvent( Object* obj, const JoyStickState &st ) : EventArg(obj), state(st) {}
+		virtual ~JoyStickEvent() {}
+
+		const JoyStickState &state;
+	};
+
+	/**
+		To recieve buffered joystick input, derive a class from this, and implement the
+		methods here. Then set the call back to your JoyStick instance with JoyStick::setEventCallback
+		Each JoyStick instance can use the same callback class, as a devID number will be provided
+		to differentiate between connected joysticks. Of course, each can have a seperate
+		callback instead.
+	*/
+	class _OISExport JoyStickListener
+	{
+	public:
+		virtual ~JoyStickListener() {}
+		/** @remarks Joystick button down event */
+		virtual bool buttonPressed( const JoyStickEvent &arg, int button ) = 0;
+		
+		/** @remarks Joystick button up event */
+		virtual bool buttonReleased( const JoyStickEvent &arg, int button ) = 0;
+
+		/** @remarks Joystick axis moved event */
+		virtual bool axisMoved( const JoyStickEvent &arg, int axis ) = 0;
+
+		//-- Not so common control events, so are not required --//
+		//! Joystick Event, and sliderID
+		virtual bool sliderMoved( const JoyStickEvent &, int index) {return true;}
+		
+		//! Joystick Event, and povID
+		virtual bool povMoved( const JoyStickEvent &arg, int index) {return true;}
+
+		//! Joystick Event, and Vector3ID
+		virtual bool vector3Moved( const JoyStickEvent &arg, int index) {return true;}
+	};
+
+	/**
+		Joystick base class. To be implemented by specific system (ie. DirectX joystick)
+		This class is useful as you remain OS independent using this common interface.
+	*/
+	class _OISExport JoyStick : public Object
+	{
+	public:
+		virtual ~JoyStick() {}
+
+		/**
+		@remarks
+			Returns the number of requested components
+		@param cType
+			The ComponentType you are interested in knowing about
+		*/
+		int getNumberOfComponents(ComponentType cType) const;
+
+		/**
+		@remarks
+			Sets a cutoff limit for changes in the Vector3 component for movement to 
+			be ignored. Helps reduce much event traffic for frequent small/sensitive
+			changes
+		@param degrees
+			The degree under which Vector3 events should be discarded
+		*/
+		void setVector3Sensitivity(float degrees = OIS_JOYSTICK_VECTOR3_DEFAULT);
+
+		/**
+		@remarks
+			Returns the sensitivity cutoff for Vector3 Component
+		*/
+		float getVector3Sensitivity() const;
+
+		/**
+		@remarks
+			Register/unregister a JoyStick Listener - Only one allowed for simplicity. If broadcasting
+			is neccessary, just broadcast from the callback you registered.
+		@param joyListener
+			Send a pointer to a class derived from JoyStickListener or 0 to clear the callback
+		*/
+		virtual void setEventCallback( JoyStickListener *joyListener );
+
+		/** @remarks Returns currently set callback.. or null */
+		JoyStickListener* getEventCallback() const;
+
+		/** @remarks Returns the state of the joystick - is valid for both buffered and non buffered mode */
+		const JoyStickState& getJoyStickState() const { return mState; }
+
+		//! The minimal axis value
+		static const int MIN_AXIS = -32768;
+
+		//! The maximum axis value
+		static const int MAX_AXIS = 32767;
+
+	protected:
+		JoyStick(const std::string &vendor, bool buffered, int devID, InputManager* creator);
+
+		//! Number of sliders
+		int mSliders;
+
+		//! Number of POVs
+		int mPOVs;
+
+		//! The JoyStickState structure (contains all component values)
+		JoyStickState mState;
+
+		//! The callback listener
+		JoyStickListener *mListener;
+
+		//! Adjustment factor for orientation vector accuracy
+		float mVector3Sensitivity;
+	};
+}
+#endif
Index: /code/branches/rocket2/src/external/ois/OISKeyboard.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/OISKeyboard.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISKeyboard.cpp	(revision 6952)
@@ -0,0 +1,45 @@
+/*
+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 "OISKeyboard.h"
+#include "OISException.h"
+
+using namespace OIS;
+
+//----------------------------------------------------------------------//
+void Keyboard::setTextTranslation( TextTranslationMode mode )
+{
+	mTextMode = mode;
+}
+
+//----------------------------------------------------------------------//
+bool Keyboard::isModifierDown( Modifier mod ) const
+{
+#if defined(OIS_MSVC_COMPILER)
+  #pragma warning (push)
+  #pragma warning (disable : 4800)
+#endif
+	return (mModifiers & mod);
+#if defined(OIS_MSVC_COMPILER)
+  #pragma warning (pop)
+#endif
+}
Index: /code/branches/rocket2/src/external/ois/OISKeyboard.h
===================================================================
--- /code/branches/rocket2/src/external/ois/OISKeyboard.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISKeyboard.h	(revision 6952)
@@ -0,0 +1,312 @@
+/*
+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_Keyboard_H
+#define OIS_Keyboard_H
+#include "OISObject.h"
+#include "OISEvents.h"
+
+namespace OIS
+{
+	//! Keyboard scan codes
+	enum KeyCode
+	{
+		KC_UNASSIGNED  = 0x00,
+		KC_ESCAPE      = 0x01,
+		KC_1           = 0x02,
+		KC_2           = 0x03,
+		KC_3           = 0x04,
+		KC_4           = 0x05,
+		KC_5           = 0x06,
+		KC_6           = 0x07,
+		KC_7           = 0x08,
+		KC_8           = 0x09,
+		KC_9           = 0x0A,
+		KC_0           = 0x0B,
+		KC_MINUS       = 0x0C,    // - on main keyboard
+		KC_EQUALS      = 0x0D,
+		KC_BACK        = 0x0E,    // backspace
+		KC_TAB         = 0x0F,
+		KC_Q           = 0x10,
+		KC_W           = 0x11,
+		KC_E           = 0x12,
+		KC_R           = 0x13,
+		KC_T           = 0x14,
+		KC_Y           = 0x15,
+		KC_U           = 0x16,
+		KC_I           = 0x17,
+		KC_O           = 0x18,
+		KC_P           = 0x19,
+		KC_LBRACKET    = 0x1A,
+		KC_RBRACKET    = 0x1B,
+		KC_RETURN      = 0x1C,    // Enter on main keyboard
+		KC_LCONTROL    = 0x1D,
+		KC_A           = 0x1E,
+		KC_S           = 0x1F,
+		KC_D           = 0x20,
+		KC_F           = 0x21,
+		KC_G           = 0x22,
+		KC_H           = 0x23,
+		KC_J           = 0x24,
+		KC_K           = 0x25,
+		KC_L           = 0x26,
+		KC_SEMICOLON   = 0x27,
+		KC_APOSTROPHE  = 0x28,
+		KC_GRAVE       = 0x29,    // accent
+		KC_LSHIFT      = 0x2A,
+		KC_BACKSLASH   = 0x2B,
+		KC_Z           = 0x2C,
+		KC_X           = 0x2D,
+		KC_C           = 0x2E,
+		KC_V           = 0x2F,
+		KC_B           = 0x30,
+		KC_N           = 0x31,
+		KC_M           = 0x32,
+		KC_COMMA       = 0x33,
+		KC_PERIOD      = 0x34,    // . on main keyboard
+		KC_SLASH       = 0x35,    // / on main keyboard
+		KC_RSHIFT      = 0x36,
+		KC_MULTIPLY    = 0x37,    // * on numeric keypad
+		KC_LMENU       = 0x38,    // left Alt
+		KC_SPACE       = 0x39,
+		KC_CAPITAL     = 0x3A,
+		KC_F1          = 0x3B,
+		KC_F2          = 0x3C,
+		KC_F3          = 0x3D,
+		KC_F4          = 0x3E,
+		KC_F5          = 0x3F,
+		KC_F6          = 0x40,
+		KC_F7          = 0x41,
+		KC_F8          = 0x42,
+		KC_F9          = 0x43,
+		KC_F10         = 0x44,
+		KC_NUMLOCK     = 0x45,
+		KC_SCROLL      = 0x46,    // Scroll Lock
+		KC_NUMPAD7     = 0x47,
+		KC_NUMPAD8     = 0x48,
+		KC_NUMPAD9     = 0x49,
+		KC_SUBTRACT    = 0x4A,    // - on numeric keypad
+		KC_NUMPAD4     = 0x4B,
+		KC_NUMPAD5     = 0x4C,
+		KC_NUMPAD6     = 0x4D,
+		KC_ADD         = 0x4E,    // + on numeric keypad
+		KC_NUMPAD1     = 0x4F,
+		KC_NUMPAD2     = 0x50,
+		KC_NUMPAD3     = 0x51,
+		KC_NUMPAD0     = 0x52,
+		KC_DECIMAL     = 0x53,    // . on numeric keypad
+		KC_OEM_102     = 0x56,    // < > | on UK/Germany keyboards
+		KC_F11         = 0x57,
+		KC_F12         = 0x58,
+		KC_F13         = 0x64,    //                     (NEC PC98)
+		KC_F14         = 0x65,    //                     (NEC PC98)
+		KC_F15         = 0x66,    //                     (NEC PC98)
+		KC_KANA        = 0x70,    // (Japanese keyboard)
+		KC_ABNT_C1     = 0x73,    // / ? on Portugese (Brazilian) keyboards
+		KC_CONVERT     = 0x79,    // (Japanese keyboard)
+		KC_NOCONVERT   = 0x7B,    // (Japanese keyboard)
+		KC_YEN         = 0x7D,    // (Japanese keyboard)
+		KC_ABNT_C2     = 0x7E,    // Numpad . on Portugese (Brazilian) keyboards
+		KC_NUMPADEQUALS= 0x8D,    // = on numeric keypad (NEC PC98)
+		KC_PREVTRACK   = 0x90,    // Previous Track (KC_CIRCUMFLEX on Japanese keyboard)
+		KC_AT          = 0x91,    //                     (NEC PC98)
+		KC_COLON       = 0x92,    //                     (NEC PC98)
+		KC_UNDERLINE   = 0x93,    //                     (NEC PC98)
+		KC_KANJI       = 0x94,    // (Japanese keyboard)
+		KC_STOP        = 0x95,    //                     (NEC PC98)
+		KC_AX          = 0x96,    //                     (Japan AX)
+		KC_UNLABELED   = 0x97,    //                        (J3100)
+		KC_NEXTTRACK   = 0x99,    // Next Track
+		KC_NUMPADENTER = 0x9C,    // Enter on numeric keypad
+		KC_RCONTROL    = 0x9D,
+		KC_MUTE        = 0xA0,    // Mute
+		KC_CALCULATOR  = 0xA1,    // Calculator
+		KC_PLAYPAUSE   = 0xA2,    // Play / Pause
+		KC_MEDIASTOP   = 0xA4,    // Media Stop
+		KC_VOLUMEDOWN  = 0xAE,    // Volume -
+		KC_VOLUMEUP    = 0xB0,    // Volume +
+		KC_WEBHOME     = 0xB2,    // Web home
+		KC_NUMPADCOMMA = 0xB3,    // , on numeric keypad (NEC PC98)
+		KC_DIVIDE      = 0xB5,    // / on numeric keypad
+		KC_SYSRQ       = 0xB7,
+		KC_RMENU       = 0xB8,    // right Alt
+		KC_PAUSE       = 0xC5,    // Pause
+		KC_HOME        = 0xC7,    // Home on arrow keypad
+		KC_UP          = 0xC8,    // UpArrow on arrow keypad
+		KC_PGUP        = 0xC9,    // PgUp on arrow keypad
+		KC_LEFT        = 0xCB,    // LeftArrow on arrow keypad
+		KC_RIGHT       = 0xCD,    // RightArrow on arrow keypad
+		KC_END         = 0xCF,    // End on arrow keypad
+		KC_DOWN        = 0xD0,    // DownArrow on arrow keypad
+		KC_PGDOWN      = 0xD1,    // PgDn on arrow keypad
+		KC_INSERT      = 0xD2,    // Insert on arrow keypad
+		KC_DELETE      = 0xD3,    // Delete on arrow keypad
+		KC_LWIN        = 0xDB,    // Left Windows key
+		KC_RWIN        = 0xDC,    // Right Windows key
+		KC_APPS        = 0xDD,    // AppMenu key
+		KC_POWER       = 0xDE,    // System Power
+		KC_SLEEP       = 0xDF,    // System Sleep
+		KC_WAKE        = 0xE3,    // System Wake
+		KC_WEBSEARCH   = 0xE5,    // Web Search
+		KC_WEBFAVORITES= 0xE6,    // Web Favorites
+		KC_WEBREFRESH  = 0xE7,    // Web Refresh
+		KC_WEBSTOP     = 0xE8,    // Web Stop
+		KC_WEBFORWARD  = 0xE9,    // Web Forward
+		KC_WEBBACK     = 0xEA,    // Web Back
+		KC_MYCOMPUTER  = 0xEB,    // My Computer
+		KC_MAIL        = 0xEC,    // Mail
+		KC_MEDIASELECT = 0xED     // Media Select
+	};
+
+	/**
+		Specialised for key events
+	*/
+	class _OISExport KeyEvent : public EventArg
+	{
+	public:
+		KeyEvent( Object* obj, KeyCode kc, unsigned int txt ) : EventArg(obj), key(kc), text(txt) {}
+		virtual ~KeyEvent() {}
+
+		//! KeyCode of event
+		const KeyCode key;
+		//! Text character, depends on current TextTranslationMode
+		unsigned int text;
+	};
+
+	/**
+		To recieve buffered keyboard input, derive a class from this, and implement the
+		methods here. Then set the call back to your Keyboard instance with Keyboard::setEventCallback
+	*/
+	class _OISExport KeyListener
+	{
+	public:
+		virtual ~KeyListener() {}
+		virtual bool keyPressed( const KeyEvent &arg ) = 0;
+		virtual bool keyReleased( const KeyEvent &arg ) = 0;		
+	};
+
+	/**
+		Keyboard base class. To be implemented by specific system (ie. DirectX Keyboard)
+		This class is useful as you remain OS independent using this common interface.
+	*/
+	class _OISExport Keyboard : public Object
+	{
+	public:
+		virtual ~Keyboard() {};
+		
+		/**
+		@remarks
+			Returns true if key is donwn
+		@param key
+			A KeyCode to check
+		*/
+		virtual bool isKeyDown( KeyCode key ) const = 0;
+
+		/**
+		@remarks
+			Register/unregister a Keyboard Listener - Only one allowed for simplicity. If broadcasting
+			is neccessary, just broadcast from the callback you registered.
+		@param keyListener
+			Send a pointer to a class derived from KeyListener or 0 to clear the callback
+		*/
+		virtual void setEventCallback( KeyListener *keyListener ) { mListener = keyListener;}
+
+		/**
+		@remarks
+			Returns currently set callback.. or 0
+		*/
+		KeyListener* getEventCallback() const {return mListener;}
+
+		//! TextTranslation Mode
+		enum TextTranslationMode
+		{
+			Off,
+			Unicode,
+			Ascii
+		};
+
+		/**
+		@remarks
+			Enable extra processing to translate KC_*** to an
+			actual text character based off of locale. Different 
+			managers may implement none or all. Check the 
+			translation mode after setting to be sure
+		@param mode
+			Off, Unicode, Ascii
+		*/
+		virtual void setTextTranslation( TextTranslationMode mode );
+
+		/**
+		@remarks
+			Returns current translation mode
+		*/
+		TextTranslationMode getTextTranslation() const {return mTextMode;}
+		
+		/**
+		@remarks
+			Translates KeyCode to string representation.
+			For example, KC_ENTER will be "Enter" - Locale
+			specific of course.
+		@param kc
+			KeyCode to convert
+		@returns
+			The string as determined from the current locale
+		*/
+		virtual const std::string& getAsString( KeyCode kc ) = 0;
+
+		//! Enum of bit position of modifer
+		enum Modifier
+		{
+			Shift = 0x0000001,
+			Ctrl  = 0x0000010,
+			Alt   = 0x0000100
+		};
+
+		/**
+		@remarks
+			Check modifier status
+		*/
+		bool isModifierDown( Modifier mod ) const;
+
+		/**
+		@remarks
+			Copies the state of the keys into the sent buffer
+			(in the form of 1 is down and 0 is up)
+		*/
+		virtual void copyKeyStates( char keys[256] ) const = 0;
+		
+	protected:
+		Keyboard(const std::string &vendor, bool buffered, int devID, InputManager* creator)
+			: Object(vendor, OISKeyboard, buffered, devID, creator),
+			mModifiers(0), mListener(0), mTextMode(Unicode) {}
+
+		//! Bit field that holds status of Alt, Ctrl, Shift
+		unsigned int mModifiers;
+
+		//! Used for buffered/actionmapping callback
+		KeyListener *mListener;
+
+		//! The current translation mode
+		TextTranslationMode mTextMode;
+	};
+}
+#endif
Index: /code/branches/rocket2/src/external/ois/OISMouse.h
===================================================================
--- /code/branches/rocket2/src/external/ois/OISMouse.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISMouse.h	(revision 6952)
@@ -0,0 +1,138 @@
+/*
+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_Mouse_H
+#define OIS_Mouse_H
+#include "OISObject.h"
+#include "OISEvents.h"
+
+namespace OIS
+{
+	//! Button ID for mouse devices
+	enum MouseButtonID
+	{
+		MB_Left = 0, MB_Right, MB_Middle,
+		MB_Button3, MB_Button4,	MB_Button5, MB_Button6,	MB_Button7
+	};
+
+	/**
+		Represents the state of the mouse
+		All members are valid for both buffered and non buffered mode
+	*/
+	class _OISExport MouseState
+	{
+	public:
+		MouseState() : width(50), height(50), buttons(0) {};
+
+		/** Represents the height/width of your display area.. used if mouse clipping
+		or mouse 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;
+
+		//! represents all buttons - bit position indicates button down
+		int buttons;
+
+		//! Button down test
+		inline bool buttonDown( MouseButtonID button ) const
+		{
+			return ((buttons & ( 1L << button )) == 0) ? false : true;
+		}
+
+		//! Clear all the values
+		void clear()
+		{
+			X.clear();
+			Y.clear();
+			Z.clear();
+			buttons = 0;
+		}
+	};
+
+	/** Specialised for mouse events */
+	class _OISExport MouseEvent : public EventArg
+	{
+	public:
+		MouseEvent( Object *obj, const MouseState &ms )	: EventArg(obj), state(ms) {}
+		virtual ~MouseEvent() {}
+
+		//! The state of the mouse - including buttons and axes
+		const MouseState &state;
+	};
+
+	/**
+		To recieve buffered mouse input, derive a class from this, and implement the
+		methods here. Then set the call back to your Mouse instance with Mouse::setEventCallback
+	*/
+	class _OISExport MouseListener
+	{
+	public:
+		virtual ~MouseListener() {}
+		virtual bool mouseMoved( const MouseEvent &arg ) = 0;
+		virtual bool mousePressed( const MouseEvent &arg, MouseButtonID id ) = 0;
+		virtual bool mouseReleased( const MouseEvent &arg, MouseButtonID id ) = 0;
+	};
+
+	/**
+		Mouse base class. To be implemented by specific system (ie. DirectX Mouse)
+		This class is useful as you remain OS independent using this common interface.
+	*/
+	class _OISExport Mouse : public Object
+	{
+	public:
+		virtual ~Mouse() {}
+
+		/**
+		@remarks
+			Register/unregister a Mouse Listener - Only one allowed for simplicity. If broadcasting
+			is neccessary, just broadcast from the callback you registered.
+		@param mouseListener
+			Send a pointer to a class derived from MouseListener or 0 to clear the callback
+		*/
+		virtual void setEventCallback( MouseListener *mouseListener ) {mListener = mouseListener;}
+
+		/** @remarks Returns currently set callback.. or 0 */
+		MouseListener* getEventCallback() const {return mListener;}
+
+		/** @remarks Returns the state of the mouse - is valid for both buffered and non buffered mode */
+		const MouseState& getMouseState() const { return mState; }
+
+	protected:
+		Mouse(const std::string &vendor, bool buffered, int devID, InputManager* creator)
+			: Object(vendor, OISMouse, buffered, devID, creator), mListener(0) {}
+
+		//! The state of the mouse
+		MouseState mState;
+
+		//! Used for buffered/actionmapping callback
+		MouseListener *mListener;
+	};
+}
+#endif
Index: /code/branches/rocket2/src/external/ois/OISObject.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/OISObject.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISObject.cpp	(revision 6952)
@@ -0,0 +1,23 @@
+/*
+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 "OISObject.h"
Index: /code/branches/rocket2/src/external/ois/OISObject.h
===================================================================
--- /code/branches/rocket2/src/external/ois/OISObject.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISObject.h	(revision 6952)
@@ -0,0 +1,95 @@
+/*
+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_Object_H
+#define OIS_Object_H
+
+#include "OISPrereqs.h"
+#include "OISInterface.h"
+
+namespace OIS
+{
+	/**	The base class of all input types. */
+	class _OISExport Object
+	{
+	public:
+		virtual ~Object() {}
+
+		/**	@remarks Get the type of device	*/
+		Type type() const { return mType; }
+
+		/**	@remarks Get the vender string name	*/
+		const std::string& vendor() const { return mVendor; }
+
+		/**	@remarks Get buffered mode - true is buffered, false otherwise */
+		virtual bool buffered() const { return mBuffered; }
+
+		/** @remarks Returns this input object's creator */
+		InputManager* getCreator() const { return mCreator; }
+
+		/** @remarks Sets buffered mode	*/
+		virtual void setBuffered(bool buffered) = 0;
+
+		/**	@remarks Used for updating call once per frame before checking state or to update events */
+		virtual void capture() = 0;
+
+		/**	@remarks This may/may not) differentiate the different controllers based on (for instance) a port number (useful for console InputManagers) */
+		virtual int getID() const {return mDevID;}
+
+		/**
+		@remarks
+			If available, get an interface to write to some devices.
+			Examples include, turning on and off LEDs, ForceFeedback, etc
+		@param type
+			The type of interface you are looking for
+		*/
+		virtual Interface* queryInterface(Interface::IType type) = 0;
+
+		/**	@remarks Internal... Do not call this directly. */
+		virtual void _initialize() = 0;
+
+	protected:
+		Object(const std::string &vendor, Type iType, bool buffered,
+			   int devID, InputManager* creator) :
+					mVendor(vendor),
+					mType(iType),
+					mBuffered(buffered),
+					mDevID(devID),
+					mCreator(creator) {}
+
+		//! Vendor name if applicable/known
+		std::string mVendor;
+
+		//! Type of controller object
+		Type mType;
+
+		//! Buffered flag
+		bool mBuffered;
+
+		//! Not fully implemented yet
+		int mDevID;
+
+		//! The creator who created this object
+		InputManager* mCreator;
+	};
+}
+#endif
Index: /code/branches/rocket2/src/external/ois/OISPrereqs.h
===================================================================
--- /code/branches/rocket2/src/external/ois/OISPrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/OISPrereqs.h	(revision 6952)
@@ -0,0 +1,217 @@
+/*
+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_Prereqs_H
+#define OIS_Prereqs_H
+//----------------------------------------------------------------------------//
+// This Header File contains: forward declared classes
+//  * Forward Declarations of all public API classes
+//  * Several typedef's used around the library
+//  * Base class component types
+//  * Preprocessor definitons
+//----------------------------------------------------------------------------//
+
+//-------------- Common STL Containers ---------------------------------------//
+#include <vector>
+#include <string>
+#include <map>
+#include "OISConfig.h"
+
+// Default is blank for most OS's
+#define _OISExport
+
+//-------------- Determine Compiler ---------------------------------
+#if defined( _MSC_VER )
+#	define OIS_MSVC_COMPILER
+#elif defined( __GNUC__ )
+#	if defined( __WIN32__ ) || defined( _WIN32 )
+#		define OIS_MINGW_COMPILER
+#	else
+#		define OIS_GCC_COMPILER
+#	endif
+#elif defined( __BORLANDC__ )
+#	define OIS_BORLAND_COMPILER
+#else
+#	error No Recognized Compiler!
+#endif
+
+// --------------- Determine Operating System Platform ---------------
+#if defined( __WIN32__ ) || defined( _WIN32 ) // Windows 2000, XP, ETC
+#	if defined ( _XBOX )
+#		define OIS_XBOX_PLATFORM
+#	else
+#		define OIS_WIN32_PLATFORM
+#		if defined( OIS_DYNAMIC_LIB )
+#			undef _OISExport
+			//Ignorable Dll interface warning...
+#           if !defined(OIS_MINGW_COMPILER)
+#			    pragma warning (disable : 4251)
+#           endif
+#			if defined( OIS_NONCLIENT_BUILD )
+#				define _OISExport __declspec( dllexport )
+#			else
+#               if defined(OIS_MINGW_COMPILER)
+#                   define _OISExport
+#               else
+#				    define _OISExport __declspec( dllimport )
+#               endif
+#			endif
+#		endif
+#	endif
+#elif defined( __APPLE_CC__ ) // Apple OS X
+#	define OIS_APPLE_PLATFORM
+#	undef _OISExport
+#	define _OISExport __attribute__((visibility("default")))
+#else //Probably Linux
+#	define OIS_LINUX_PLATFORM
+#endif
+
+//Is Processor 32 or 64 bits...
+#if defined(__x86_64__)
+#	define OIS_ARCH_64
+#else
+#	define OIS_ARCH_32
+#endif
+
+//-------------- Common Classes, Enums, and Typdef's -------------------------//
+#define OIS_VERSION_MAJOR 1
+#define OIS_VERSION_MINOR 2 
+#define OIS_VERSION_PATCH 0
+#define OIS_VERSION_NAME "Smash"
+
+#define OIS_VERSION ((OIS_VERSION_MAJOR << 16) | (OIS_VERSION_MINOR << 8) | OIS_VERSION_PATCH)
+
+namespace OIS
+{
+	//Forward Declarations
+	class InputManager;
+	class FactoryCreator;
+	class Object;
+	class Keyboard;
+	class Mouse;
+	class JoyStick;
+	class KeyListener;
+	class MouseListener;
+	class JoyStickListener;
+	class Interface;
+	class ForceFeedback;
+	class Effect;
+	class Exception;
+
+	//! Way to send OS nuetral parameters.. ie OS Window handles, modes, flags
+	typedef std::multimap<std::string, std::string> ParamList;
+
+	//! List of FactoryCreator's
+	typedef std::vector<FactoryCreator*> FactoryList;
+
+	//! Map of FactoryCreator created Objects
+	typedef std::map<Object*, FactoryCreator*> FactoryCreatedObject;
+
+	//! Each Input class has a General Type variable, a form of RTTI
+    enum Type
+	{
+		OISUnknown   = 0,
+		OISKeyboard  = 1,
+		OISMouse     = 2,
+		OISJoyStick  = 3,
+		OISTablet    = 4
+	};
+
+	//! Map of device objects connected and their respective vendors
+	typedef std::multimap<Type, std::string> DeviceList;
+
+	//--------     Shared common components    ------------------------//
+
+	//! Base type for all device components (button, axis, etc)
+    enum ComponentType
+	{
+		OIS_Unknown = 0,
+		OIS_Button  = 1, //ie. Key, mouse button, joy button, etc
+		OIS_Axis    = 2, //ie. A joystick or mouse axis
+		OIS_Slider  = 3, //
+		OIS_POV     = 4, //ie. Arrow direction keys
+		OIS_Vector3 = 5  //ie. WiiMote orientation
+	};
+
+	//! Base of all device components (button, axis, etc)
+	class _OISExport Component
+	{
+	public:
+		Component() : cType(OIS_Unknown) {};
+		Component(ComponentType type) : cType(type) {};
+		//! Indicates what type of coponent this is
+		ComponentType cType;
+	};
+
+	//! Button can be a keyboard key, mouse button, etc
+	class _OISExport Button : public Component
+	{
+	public:
+		Button() : Component(OIS_Button), pushed(false) {}
+		Button(bool bPushed) : Component(OIS_Button), pushed(bPushed) {}
+		//! true if pushed, false otherwise
+		bool pushed;
+	};
+
+	//! Axis component
+	class _OISExport Axis : public Component
+	{
+	public:
+		Axis() : Component(OIS_Axis), abs(0), rel(0), absOnly(false) {};
+
+		//! Absoulte and Relative value components
+		int abs, rel;
+
+		//! Indicates if this Axis only supports Absoulte (ie JoyStick)
+		bool absOnly;
+
+		//! Used internally by OIS
+		void clear()
+		{
+			abs = rel = 0;
+		}
+	};
+
+	//! A 3D Vector component (perhaps an orientation, as in the WiiMote)
+	class _OISExport Vector3 : public Component
+	{
+	public:
+		Vector3() {}
+		Vector3(float _x, float _y, float _z) : Component(OIS_Vector3), x(_x), y(_y), z(_z) {};
+		
+		//! X component of vector
+		float x;
+		
+		//! Y component of vector
+		float y;
+
+		//! Z component of vector
+		float z;
+
+		void clear()
+		{
+			x = y = z = 0.0f;
+		}
+	};
+}
+
+#endif //end if prereq header defined
Index: /code/branches/rocket2/src/external/ois/ReadMe.txt
===================================================================
--- /code/branches/rocket2/src/external/ois/ReadMe.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/ReadMe.txt	(revision 6952)
@@ -0,0 +1,87 @@
+======================================================================================
+================ LICENSE =============================================================
+======================================================================================
+
+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.
+
+
+======================================================================================
+================ LICENSE EXPLAINED ===================================================
+======================================================================================
+In case the license was not clear enough... Basically, you can link with this lib 
+which puts no restrictions on what you have to license your code as. You can modify 
+this lib, and not have release your changes. Though, as explained above, <bold> 
+Altered source versions must be plainly marked as such, and must not be misrepresented
+as being the original software </bold>
+
+This is to allow users the greatest flexibility in what you can use this lib for.
+
+======================================================================================
+================ INFO ================================================================
+======================================================================================
+
+Cross Platform Object Oriented Input Lib System. Meant to be very robust and 
+compatiable with many systems and operating systems
+
+Win32/
+	Contains Visual Studio .Net Solution Files
+	Contains CodeBlocks + MinGW + StlPort 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
+
+	Steps to build on Linux:
+	./bootstrap
+	./configure
+	./make && make install
+
+	---- 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/
+        Contains CodeBlock files for building OIS and Demos with codeblocks
+        This project file looks for Ogre and other dependencies in /usr/local/lib
+        and /usr/local/include. If installed elsewhere, modify the project
+        settings. It also installs libOIS to ~/libs
+
+Mac/
+	
+	XCode-1.5/
+		Non-complete native OIS port.
+
+	XCode-2.2/
+		Working, complete, OIS port to OSX using SDL as a backend.
Index: /code/branches/rocket2/src/external/ois/VERSION
===================================================================
--- /code/branches/rocket2/src/external/ois/VERSION	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/VERSION	(revision 6952)
@@ -0,0 +1,3 @@
+OIS v1_2 CVS updated on 2009/01/24
+Note that this is not CVS HEAD, but v1_2 branch!
+
Index: /code/branches/rocket2/src/external/ois/changes_orxonox.diff
===================================================================
--- /code/branches/rocket2/src/external/ois/changes_orxonox.diff	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/changes_orxonox.diff	(revision 6952)
@@ -0,0 +1,35 @@
+--- linux/EventHelpers.cpp	(revision 5668)
++++ linux/EventHelpers.cpp	(working copy)
+@@ -35,6 +35,20 @@
+ # include <iostream>
+ #endif
+ 
++// Fixes for missing macros in input.h
++#ifndef FF_EFFECT_MIN
++#define FF_EFFECT_MIN FF_RUMBLE
++#endif
++#ifndef FF_EFFECT_MAX
++#define FF_EFFECT_MAX FF_RAMP
++#endif
++#ifndef FF_WAVEFORM_MIN
++#define FF_WAVEFORM_MIN FF_SQUARE
++#endif
++#ifndef FF_WAVEFORM_MAX
++#define FF_WAVEFORM_MAX FF_CUSTOM
++#endif
++
+ using namespace std;
+ using namespace OIS;
+ 
+
+--- win32/Win32ForceFeedback.cpp
++++ win32/Win32ForceFeedback.cpp
+@@ -25,7 +25,7 @@
+ #include <Math.h>
+ 
+ // 0 = No trace; 1 = Important traces; 2 = Debug traces
+-#define OIS_WIN32_JOYFF_DEBUG 1
++#define OIS_WIN32_JOYFF_DEBUG 0
+ 
+ #if (defined (_DEBUG) || defined(OIS_WIN32_JOYFF_DEBUG))
+   #include <iostream>
Index: /code/branches/rocket2/src/external/ois/linux/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/ois/linux/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/linux/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,18 @@
+ADD_SOURCE_FILES(OIS_FILES
+  EventHelpers.h
+  LinuxForceFeedback.h
+  LinuxInputManager.h
+  LinuxJoyStickEvents.h
+  LinuxKeyboard.h
+  LinuxMouse.h
+  LinuxPrereqs.h
+
+COMPILATION_BEGIN OISLinuxCompilation.cpp
+  EventHelpers.cpp
+  LinuxForceFeedback.cpp
+  LinuxInputManager.cpp
+  LinuxJoyStickEvents.cpp
+  LinuxKeyboard.cpp
+  LinuxMouse.cpp
+COMPILATION_END
+)
Index: /code/branches/rocket2/src/external/ois/linux/EventHelpers.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/linux/EventHelpers.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/linux/EventHelpers.cpp	(revision 6952)
@@ -0,0 +1,391 @@
+/*
+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 "linux/EventHelpers.h"
+#include "linux/LinuxPrereqs.h"
+#include "linux/LinuxForceFeedback.h"
+#include "OISException.h"
+#include "OISJoyStick.h"
+
+#include <linux/input.h>
+#include <cstring>
+
+//#define OIS_LINUX_JOY_DEBUG
+
+#ifdef OIS_LINUX_JOY_DEBUG
+# include <iostream>
+#endif
+
+// Fixes for missing macros in input.h
+#ifndef FF_EFFECT_MIN
+#define FF_EFFECT_MIN FF_RUMBLE
+#endif
+#ifndef FF_EFFECT_MAX
+#define FF_EFFECT_MAX FF_RAMP
+#endif
+#ifndef FF_WAVEFORM_MIN
+#define FF_WAVEFORM_MIN FF_SQUARE
+#endif
+#ifndef FF_WAVEFORM_MAX
+#define FF_WAVEFORM_MAX FF_CUSTOM
+#endif
+
+using namespace std;
+using namespace OIS;
+
+class DeviceComponentInfo
+{
+public:
+	vector<int> buttons, relAxes, absAxes, hats;
+};
+
+bool inline isBitSet(unsigned char bits[], unsigned int bit)
+{
+  return (bits[(bit)/(sizeof(unsigned char)*8)] >> ((bit)%(sizeof(unsigned char)*8))) & 1;
+}
+
+//-----------------------------------------------------------------------------//
+DeviceComponentInfo getComponentInfo( int deviceID )
+{
+	unsigned char ev_bits[1 + EV_MAX/8/sizeof(unsigned char)];
+	memset( ev_bits, 0, sizeof(ev_bits) );
+
+	//Read "all" (hence 0) components of the device
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::getComponentInfo(" << deviceID 
+		 << ") : Reading device events features" << endl;
+#endif
+	if (ioctl(deviceID, EVIOCGBIT(0, sizeof(ev_bits)), ev_bits) == -1)
+		OIS_EXCEPT( E_General, "Could not read device events features");
+
+	DeviceComponentInfo components;
+
+	for (int i = 0; i < EV_MAX; i++)
+	{
+		if( isBitSet(ev_bits, i) )
+		{
+		    // Absolute axis.
+		    if(i == EV_ABS)
+			{
+			    unsigned char abs_bits[1 + ABS_MAX/8/sizeof(unsigned char)];
+			    memset( abs_bits, 0, sizeof(abs_bits) );
+
+#ifdef OIS_LINUX_JOY_DEBUG
+				cout << "EventUtils::getComponentInfo(" << deviceID 
+					 << ") : Reading device absolute axis features" << endl;
+#endif
+
+				if (ioctl(deviceID, EVIOCGBIT(i, sizeof(abs_bits)), abs_bits) == -1)
+				    OIS_EXCEPT( E_General, "Could not read device absolute axis features");
+
+				for (int j = 0; j < ABS_MAX; j++)
+				{
+				    if( isBitSet(abs_bits, j) )
+					{
+						//input_absinfo abInfo;
+						//ioctl( fd, EVIOCGABS(j), abInfo );
+						if( j >= ABS_HAT0X && j <= ABS_HAT3Y )
+						{
+							components.hats.push_back(j);
+						}
+						else
+						{
+							components.absAxes.push_back(j);
+							//input_absinfo absinfo;
+							//ioctl(deviceID, EVIOCGABS(j), &absinfo);
+							//We cannot actually change these values :|
+							//absinfo.minimum = JoyStick::MIN_AXIS;
+							//absinfo.maximum = JoyStick::MAX_AXIS;
+							//ioctl(deviceID, EVIOCSABS(j), &absinfo);
+						}
+					}
+				}
+			}
+			else if(i == EV_REL)
+			{
+			    unsigned char rel_bits[1 + REL_MAX/8/sizeof(unsigned char)];
+				memset( rel_bits, 0, sizeof(rel_bits) );
+				
+#ifdef OIS_LINUX_JOY_DEBUG
+				cout << "EventUtils::getComponentInfo(" << deviceID 
+					 << ") : Reading device relative axis features" << endl;
+#endif
+
+				if (ioctl(deviceID, EVIOCGBIT(i, sizeof(rel_bits)), rel_bits) == -1)
+				    OIS_EXCEPT( E_General, "Could not read device relative axis features");
+				
+				for (int j = 0; j < REL_MAX; j++)
+				{
+				    if( isBitSet(rel_bits, j) )
+					{
+					    components.relAxes.push_back(j);
+					}
+				}
+			}
+			else if(i == EV_KEY)
+			{
+			    unsigned char key_bits[1 + KEY_MAX/8/sizeof(unsigned char)];
+				memset( key_bits, 0, sizeof(key_bits) );
+				
+#ifdef OIS_LINUX_JOY_DEBUG
+				cout << "EventUtils::getComponentInfo(" << deviceID 
+					 << ") : Reading device buttons features" << endl;
+#endif
+
+				if (ioctl(deviceID, EVIOCGBIT(i, sizeof(key_bits)), key_bits) == -1)
+				    OIS_EXCEPT( E_General, "Could not read device buttons features");
+				
+				for (int j = 0; j < KEY_MAX; j++)
+				{
+				    if( isBitSet(key_bits, j) )
+					{
+					    components.buttons.push_back(j);
+					}
+				}
+			}
+		}
+	}
+
+	return components;
+}
+
+//-----------------------------------------------------------------------------//
+bool EventUtils::isJoyStick( int deviceID, JoyStickInfo &js )
+{
+	if( deviceID == -1 ) 
+		OIS_EXCEPT( E_General, "Error with File Descriptor" );
+
+	DeviceComponentInfo info = getComponentInfo( deviceID );
+
+	int buttons = 0;
+	bool joyButtonFound = false;
+	js.button_map.clear();
+
+	#ifdef OIS_LINUX_JOY_DEBUG
+	cout << endl << "Displaying ButtonMapping Status:" << endl;
+	#endif
+	for(vector<int>::iterator i = info.buttons.begin(), e = info.buttons.end(); i != e; ++i )
+	{
+		//Check to ensure we find at least one joy only button
+		if( (*i >= BTN_JOYSTICK && *i < BTN_GAMEPAD)  
+			|| (*i >= BTN_GAMEPAD && *i < BTN_DIGI)
+			|| (*i >= BTN_WHEEL && *i < KEY_OK) )
+			joyButtonFound = true;
+
+		js.button_map[*i] = buttons++;
+
+		#ifdef OIS_LINUX_JOY_DEBUG
+		  cout << "Button Mapping ID (hex): " << hex << *i 
+			   << " OIS Button Num: " << dec << buttons-1 << endl;
+		#endif
+	}
+	#ifdef OIS_LINUX_JOY_DEBUG
+	cout << endl;
+	#endif
+
+	//Joy Buttons found, so it must be a joystick or pad
+	if( joyButtonFound )
+	{
+		js.joyFileD = deviceID;
+		js.vendor = getName(deviceID);
+		js.buttons = buttons;
+		js.axes = info.relAxes.size() + info.absAxes.size();
+		js.hats = info.hats.size();
+		#ifdef OIS_LINUX_JOY_DEBUG
+		  cout << endl << "Device name:" << js.vendor << endl;
+		  cout << "Device unique Id:" << getUniqueId(deviceID) << endl;
+		  cout << "Device physical location:" << getPhysicalLocation(deviceID) << endl;
+		#endif
+
+		//Map the Axes
+		#ifdef OIS_LINUX_JOY_DEBUG
+		  cout << endl << "Displaying AxisMapping Status:" << endl;
+		#endif
+		int axes = 0;
+		for(vector<int>::iterator i = info.absAxes.begin(), e = info.absAxes.end(); i != e; ++i )
+		{
+			js.axis_map[*i] = axes;
+
+#ifdef OIS_LINUX_JOY_DEBUG
+			cout << "EventUtils::isJoyStick(" << deviceID 
+					  << ") : Reading device absolute axis #" << *i << " features" << endl;
+#endif
+
+			input_absinfo absinfo;
+			if (ioctl(deviceID, EVIOCGABS(*i), &absinfo) == -1)
+				OIS_EXCEPT( E_General, "Could not read device absolute axis features");
+			js.axis_range[axes] = Range(absinfo.minimum, absinfo.maximum);
+
+			#ifdef OIS_LINUX_JOY_DEBUG
+			  cout << "Axis Mapping ID (hex): " << hex << *i 
+				   << " OIS Axis Num: " << dec << axes << endl;
+			#endif
+
+			++axes;
+		}
+	}
+
+	return joyButtonFound;
+}
+
+//-----------------------------------------------------------------------------//
+string EventUtils::getName( int deviceID )
+{
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::getName(" << deviceID 
+		 << ") : Reading device name" << endl;
+#endif
+
+	char name[OIS_DEVICE_NAME];
+	if (ioctl(deviceID, EVIOCGNAME(OIS_DEVICE_NAME), name) == -1)
+		OIS_EXCEPT( E_General, "Could not read device name");
+	return string(name);
+}
+
+//-----------------------------------------------------------------------------//
+string EventUtils::getUniqueId( int deviceID )
+{
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::getUniqueId(" << deviceID 
+		 << ") : Reading device unique Id" << endl;
+#endif
+
+#define OIS_DEVICE_UNIQUE_ID 128
+	char uId[OIS_DEVICE_UNIQUE_ID];
+	if (ioctl(deviceID, EVIOCGUNIQ(OIS_DEVICE_UNIQUE_ID), uId) == -1)
+		OIS_EXCEPT( E_General, "Could not read device unique Id");
+	return string(uId);
+}
+
+//-----------------------------------------------------------------------------//
+string EventUtils::getPhysicalLocation( int deviceID )
+{
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::getPhysicalLocation(" << deviceID 
+		 << ") : Reading device physical location" << endl;
+#endif
+
+#define OIS_DEVICE_PHYSICAL_LOCATION 128
+	char physLoc[OIS_DEVICE_PHYSICAL_LOCATION];
+	if (ioctl(deviceID, EVIOCGPHYS(OIS_DEVICE_PHYSICAL_LOCATION), physLoc) == -1)
+		OIS_EXCEPT( E_General, "Could not read device physical location");
+	return string(physLoc);
+}
+
+//-----------------------------------------------------------------------------//
+void EventUtils::enumerateForceFeedback( int deviceID, LinuxForceFeedback** ff )
+{
+	//Linux Event to OIS Event Mappings
+	map<int, Effect::EType> typeMap;
+	typeMap[FF_CONSTANT] = Effect::Constant;
+	typeMap[FF_RAMP]     = Effect::Ramp;
+	typeMap[FF_SPRING]   = Effect::Spring;
+	typeMap[FF_FRICTION] = Effect::Friction;
+	typeMap[FF_SQUARE]   = Effect::Square;
+	typeMap[FF_TRIANGLE] = Effect::Triangle;
+	typeMap[FF_SINE]     = Effect::Sine;
+	typeMap[FF_SAW_UP]   = Effect::SawToothUp;
+	typeMap[FF_SAW_DOWN] = Effect::SawToothDown;
+	typeMap[FF_DAMPER]   = Effect::Damper;
+	typeMap[FF_INERTIA]  = Effect::Inertia;
+	typeMap[FF_CUSTOM]   = Effect::Custom;
+
+	map<int, Effect::EForce> forceMap;
+	forceMap[FF_CONSTANT] = Effect::ConstantForce;
+	forceMap[FF_RAMP]     = Effect::RampForce;
+	forceMap[FF_SPRING]   = Effect::ConditionalForce;
+	forceMap[FF_FRICTION] = Effect::ConditionalForce;
+	forceMap[FF_SQUARE]   = Effect::PeriodicForce;
+	forceMap[FF_TRIANGLE] = Effect::PeriodicForce;
+	forceMap[FF_SINE]     = Effect::PeriodicForce;
+	forceMap[FF_SAW_UP]   = Effect::PeriodicForce;
+	forceMap[FF_SAW_DOWN] = Effect::PeriodicForce;
+	forceMap[FF_DAMPER]   = Effect::ConditionalForce;
+	forceMap[FF_INERTIA]  = Effect::ConditionalForce;
+	forceMap[FF_CUSTOM]   = Effect::CustomForce;
+
+	//Remove any previously existing memory and create fresh
+	removeForceFeedback( ff );
+	*ff = new LinuxForceFeedback(deviceID);
+
+	//Read overall force feedback features
+	unsigned char ff_bits[1 + FF_MAX/8/sizeof(unsigned char)];
+	memset(ff_bits, 0, sizeof(ff_bits));
+
+#ifdef OIS_LINUX_JOY_DEBUG
+	cout << "EventUtils::enumerateForceFeedback(" << deviceID 
+		 << ") : Reading device force feedback features" << endl;
+#endif
+
+	if (ioctl(deviceID, EVIOCGBIT(EV_FF, sizeof(ff_bits)), ff_bits) == -1)
+		OIS_EXCEPT( E_General, "Could not read device force feedback features");
+
+
+    #ifdef OIS_LINUX_JOY_DEBUG
+	cout << "FF bits: " << hex;
+	for (int i = 0; i < sizeof(ff_bits); i++)
+		cout << (int)ff_bits[i];
+	cout << endl << dec;
+    #endif
+
+	//FF Axes
+	//if( isBitSet(ff_bits, ABS_X) ) //X Axis
+	//if( isBitSet(ff_bits, ABS_Y) ) //Y Axis
+	//if( isBitSet(ff_bits, ABS_WHEEL) ) //Wheel
+
+	//FF Effects
+	for( int effect = FF_EFFECT_MIN; effect <= FF_WAVEFORM_MAX; effect++ )
+	{
+		// The RUMBLE force type is ignored, as periodic force one is more powerfull.
+		// The PERIODIC force type is processed later, for each associated periodic effect type.
+		if (effect == FF_RUMBLE || effect == FF_PERIODIC)
+			continue;
+
+		if(isBitSet(ff_bits, effect))
+		{
+			#ifdef OIS_LINUX_JOY_DEBUG
+		    cout << "  Effect Type: " << Effect::getEffectTypeName(typeMap[effect]) << endl;
+			#endif
+
+			(*ff)->_addEffectTypes( forceMap[effect], typeMap[effect] );
+		}
+	}
+
+	//FF device properties
+	if (isBitSet(ff_bits, FF_GAIN))
+		(*ff)->_setGainSupport(true);
+		
+	if (isBitSet(ff_bits, FF_AUTOCENTER))
+		(*ff)->_setAutoCenterSupport(true);
+
+	//Check to see if any effects were added, else destroy the pointer
+	const ForceFeedback::SupportedEffectList &list = (*ff)->getSupportedEffects();
+	if( list.size() == 0 )
+		removeForceFeedback( ff );
+}
+
+//-----------------------------------------------------------------------------//
+void EventUtils::removeForceFeedback( LinuxForceFeedback** ff )
+{
+	delete *ff;
+	*ff = 0;
+}
Index: /code/branches/rocket2/src/external/ois/linux/EventHelpers.h
===================================================================
--- /code/branches/rocket2/src/external/ois/linux/EventHelpers.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/linux/EventHelpers.h	(revision 6952)
@@ -0,0 +1,49 @@
+/*
+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 _LINUX_OISEVENT_HEADER_
+#define _LINUX_OISEVENT_HEADER_
+
+#include "linux/LinuxPrereqs.h"
+
+#define OIS_MAX_DEVICES 32
+#define OIS_DEVICE_NAME 128
+
+namespace OIS
+{
+	class EventUtils
+	{
+	public:
+		static bool isJoyStick( int deviceID, JoyStickInfo &js );
+		static bool isMouse( int ) {return false;}
+		static bool isKeyboard( int ) {return false;}
+
+		//Double pointer is so that we can set the value of the sent pointer
+		static void enumerateForceFeedback( int deviceID, LinuxForceFeedback** ff );
+		static void removeForceFeedback( LinuxForceFeedback** ff );
+
+		static std::string getName( int deviceID );
+		static std::string getUniqueId( int deviceID );
+		static std::string getPhysicalLocation( int deviceID );
+	};
+}
+#endif
Index: /code/branches/rocket2/src/external/ois/linux/LinuxForceFeedback.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/linux/LinuxForceFeedback.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/linux/LinuxForceFeedback.cpp	(revision 6952)
@@ -0,0 +1,559 @@
+/*
+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 "linux/LinuxForceFeedback.h"
+#include "OISException.h"
+
+#include <cstdlib>
+#include <errno.h>
+#include <memory.h>
+
+using namespace OIS;
+
+// 0 = No trace; 1 = Important traces; 2 = Debug traces
+#define OIS_LINUX_JOYFF_DEBUG 1
+
+#ifdef OIS_LINUX_JOYFF_DEBUG
+# include <iostream>
+  using namespace std;
+#endif
+
+//--------------------------------------------------------------//
+LinuxForceFeedback::LinuxForceFeedback(int deviceID) :
+	ForceFeedback(), mJoyStick(deviceID)
+{
+}
+
+//--------------------------------------------------------------//
+LinuxForceFeedback::~LinuxForceFeedback()
+{
+	// Unload all effects.
+	for(EffectList::iterator i = mEffectList.begin(); i != mEffectList.end(); ++i )
+	{
+		struct ff_effect *linEffect = i->second;
+		if( linEffect )
+			_unload(linEffect->id);
+	}
+
+	mEffectList.clear();
+}
+
+//--------------------------------------------------------------//
+unsigned short LinuxForceFeedback::getFFMemoryLoad()
+{
+	int nEffects = -1;
+	if (ioctl(mJoyStick, EVIOCGEFFECTS, &nEffects) == -1)
+		OIS_EXCEPT(E_General, "Unknown error reading max number of uploaded effects.");
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "LinuxForceFeedback("<< mJoyStick  
+		 << ") : Read device max number of uploaded effects : " << nEffects << endl;
+#endif
+
+	return (unsigned short int)(nEffects > 0 ? 100.0*mEffectList.size()/nEffects : 100);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::setMasterGain(float value)
+{
+	if (!mSetGainSupport)
+	{
+#if (OIS_LINUX_JOYFF_DEBUG > 0)
+		cout << "LinuxForceFeedback("<< mJoyStick << ") : Setting master gain " 
+			 << "is not supported by the device" << endl;
+#endif
+		return;
+	}
+
+	struct input_event event;
+
+	memset(&event, 0, sizeof(event));
+	event.type = EV_FF;
+	event.code = FF_GAIN;
+	if (value < 0.0)
+		value = 0.0;
+	else if (value > 1.0)
+		value = 1.0;
+	event.value = (__s32)(value * 0xFFFFUL);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 0)
+	cout << "LinuxForceFeedback("<< mJoyStick << ") : Setting master gain to " 
+		 << value << " => " << event.value << endl;
+#endif
+
+	if (write(mJoyStick, &event, sizeof(event)) != sizeof(event)) {
+		OIS_EXCEPT(E_General, "Unknown error changing master gain.");
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::setAutoCenterMode(bool enabled)
+{
+	if (!mSetAutoCenterSupport)
+	{
+#if (OIS_LINUX_JOYFF_DEBUG > 0)
+		cout << "LinuxForceFeedback("<< mJoyStick << ") : Setting auto-center mode " 
+			 << "is not supported by the device" << endl;
+#endif
+		return;
+	}
+
+	struct input_event event;
+
+	memset(&event, 0, sizeof(event));
+	event.type = EV_FF;
+	event.code = FF_AUTOCENTER;
+	event.value = (__s32)(enabled*0xFFFFFFFFUL);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 0)
+	cout << "LinuxForceFeedback("<< mJoyStick << ") : Toggling auto-center to " 
+		 << enabled << " => 0x" << hex << event.value << dec << endl;
+#endif
+
+	if (write(mJoyStick, &event, sizeof(event)) != sizeof(event)) {
+		OIS_EXCEPT(E_General, "Unknown error toggling auto-center.");
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::upload( const Effect* effect )
+{
+	switch( effect->force )
+	{
+		case OIS::Effect::ConstantForce: 
+			_updateConstantEffect(effect);	
+			break;
+		case OIS::Effect::ConditionalForce: 
+			_updateConditionalEffect(effect);
+			break;
+		case OIS::Effect::PeriodicForce: 
+			_updatePeriodicEffect(effect);
+			break;
+		case OIS::Effect::RampForce: 
+			_updateRampEffect(effect);	
+			break;
+		case OIS::Effect::CustomForce: 
+			//_updateCustomEffect(effect);
+			//break;
+		default: 
+			OIS_EXCEPT(E_NotImplemented, "Requested force not implemented yet, sorry!"); 
+			break;
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::modify( const Effect* effect )
+{
+	upload(effect);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::remove( const Effect* effect )
+{
+	//Get the effect - if it exists
+	EffectList::iterator i = mEffectList.find(effect->_handle);
+	if( i != mEffectList.end() )
+	{
+		struct ff_effect *linEffect = i->second;
+		if( linEffect )
+		{
+			_stop(effect->_handle);
+
+			_unload(effect->_handle);
+
+			free(linEffect);
+
+			mEffectList.erase(i);
+		}
+		else
+			mEffectList.erase(i);
+	}
+}
+
+//--------------------------------------------------------------//
+// To Signed16/Unsigned15 safe conversions
+#define MaxUnsigned15Value 0x7FFF
+#define toUnsigned15(value) \
+	(__u16)((value) < 0 ? 0 : ((value) > MaxUnsigned15Value ? MaxUnsigned15Value : (value)))
+
+#define MaxSigned16Value  0x7FFF
+#define MinSigned16Value -0x7FFF
+#define toSigned16(value) \
+  (__s16)((value) < MinSigned16Value ? MinSigned16Value : ((value) > MaxSigned16Value ? MaxSigned16Value : (value)))
+
+// OIS to Linux duration
+#define LinuxInfiniteDuration 0xFFFF
+#define OISDurationUnitMS 1000 // OIS duration unit (microseconds), expressed in milliseconds (theLinux duration unit)
+
+// linux/input.h : All duration values are expressed in ms. Values above 32767 ms (0x7fff)
+//                 should not be used and have unspecified results.
+#define LinuxDuration(oisDuration) ((oisDuration) == Effect::OIS_INFINITE ? LinuxInfiniteDuration \
+									: toUnsigned15((oisDuration)/OISDurationUnitMS))
+
+
+// OIS to Linux levels
+#define OISMaxLevel 10000
+#define LinuxMaxLevel 0x7FFF
+
+// linux/input.h : Valid range for the attack and fade levels is 0x0000 - 0x7fff
+#define LinuxPositiveLevel(oisLevel) toUnsigned15(LinuxMaxLevel*(long)(oisLevel)/OISMaxLevel)
+
+#define LinuxSignedLevel(oisLevel) toSigned16(LinuxMaxLevel*(long)(oisLevel)/OISMaxLevel)
+
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_setCommonProperties(struct ff_effect *event, 
+											  struct ff_envelope *ffenvelope, 
+											  const Effect* effect, const Envelope *envelope )
+{
+	memset(event, 0, sizeof(struct ff_effect));
+
+	if (envelope && ffenvelope && envelope->isUsed()) {
+		ffenvelope->attack_length = LinuxDuration(envelope->attackLength);
+		ffenvelope->attack_level = LinuxPositiveLevel(envelope->attackLevel);
+		ffenvelope->fade_length = LinuxDuration(envelope->fadeLength);
+		ffenvelope->fade_level = LinuxPositiveLevel(envelope->fadeLevel);
+	}
+	
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << endl;
+	if (envelope && ffenvelope)
+	{
+		cout << "  Enveloppe :" << endl
+			 << "    AttackLen : " << envelope->attackLength
+			 << " => " << ffenvelope->attack_length << endl 
+			 << "    AttackLvl : " << envelope->attackLevel
+			 << " => " << ffenvelope->attack_level << endl 
+			 << "    FadeLen   : " << envelope->fadeLength
+			 << " => " << ffenvelope->fade_length << endl
+			 << "    FadeLvl   : " << envelope->fadeLevel
+			 << " => " << ffenvelope->fade_level << endl;
+	}
+#endif
+	
+	event->direction = (__u16)(1 + (effect->direction*45.0+135.0)*0xFFFFUL/360.0);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Direction : " << Effect::getDirectionName(effect->direction)
+		 << " => 0x" << hex << event->direction << dec << endl;
+#endif
+
+	// TODO trigger_button 0 vs. -1
+	event->trigger.button = effect->trigger_button; // < 0 ? 0 : effect->trigger_button;
+	event->trigger.interval = LinuxDuration(effect->trigger_interval);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Trigger :" << endl
+		 << "    Button   : " << effect->trigger_button 
+		 << " => " << event->trigger.button << endl
+		 << "    Interval : " << effect->trigger_interval 
+		 << " => " << event->trigger.interval << endl;
+#endif
+
+	event->replay.length = LinuxDuration(effect->replay_length);
+	event->replay.delay = LinuxDuration(effect->replay_delay);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Replay :" << endl
+		 << "    Length : " << effect->replay_length 
+		 << " => " << event->replay.length << endl
+		 << "    Delay  : " << effect->replay_delay 
+		 << " => " << event->replay.delay << endl;
+#endif
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_updateConstantEffect( const Effect* eff )
+{
+	struct ff_effect event;
+
+	ConstantEffect *effect = static_cast<ConstantEffect*>(eff->getForceEffect());
+
+	_setCommonProperties(&event, &event.u.constant.envelope, eff, &effect->envelope);
+
+	event.type = FF_CONSTANT;
+	event.id = -1;
+
+	event.u.constant.level = LinuxSignedLevel(effect->level);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Level : " << effect->level
+		 << " => " << event.u.constant.level << endl;
+#endif
+
+	_upload(&event, eff);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_updateRampEffect( const Effect* eff )
+{
+	struct ff_effect event;
+
+	RampEffect *effect = static_cast<RampEffect*>(eff->getForceEffect());
+
+	_setCommonProperties(&event, &event.u.constant.envelope, eff, &effect->envelope);
+
+	event.type = FF_RAMP;
+	event.id = -1;
+
+	event.u.ramp.start_level = LinuxSignedLevel(effect->startLevel);
+	event.u.ramp.end_level = LinuxSignedLevel(effect->endLevel);
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  StartLevel : " << effect->startLevel
+		 << " => " << event.u.ramp.start_level << endl
+		 << "  EndLevel   : " << effect->endLevel
+		 << " => " << event.u.ramp.end_level << endl;
+#endif
+
+	_upload(&event, eff);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_updatePeriodicEffect( const Effect* eff )
+{
+	struct ff_effect event;
+
+	PeriodicEffect *effect = static_cast<PeriodicEffect*>(eff->getForceEffect());
+
+	_setCommonProperties(&event, &event.u.periodic.envelope, eff, &effect->envelope);
+
+	event.type = FF_PERIODIC;
+	event.id = -1;
+
+	switch( eff->type )
+	{
+		case OIS::Effect::Square:
+			event.u.periodic.waveform = FF_SQUARE;
+			break;
+		case OIS::Effect::Triangle:
+			event.u.periodic.waveform = FF_TRIANGLE;
+			break;
+		case OIS::Effect::Sine:
+			event.u.periodic.waveform = FF_SINE;
+			break;
+		case OIS::Effect::SawToothUp:
+			event.u.periodic.waveform = FF_SAW_UP;
+			break;
+		case OIS::Effect::SawToothDown:
+			event.u.periodic.waveform = FF_SAW_DOWN;
+			break;
+		// Note: No support for Custom periodic force effect for the moment
+		//case OIS::Effect::Custom:
+			//event.u.periodic.waveform = FF_CUSTOM;
+			//break;
+		default:
+			OIS_EXCEPT(E_General, "No such available effect for Periodic force!"); 
+			break;
+	}
+
+	event.u.periodic.period    = LinuxDuration(effect->period);
+	event.u.periodic.magnitude = LinuxPositiveLevel(effect->magnitude);
+	event.u.periodic.offset    = LinuxPositiveLevel(effect->offset);
+	event.u.periodic.phase     = (__u16)(effect->phase*event.u.periodic.period/36000.0); // ?????
+
+	// Note: No support for Custom periodic force effect for the moment
+	event.u.periodic.custom_len = 0;
+	event.u.periodic.custom_data = 0;
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Magnitude : " << effect->magnitude
+		 << " => " << event.u.periodic.magnitude << endl
+		 << "  Period    : " << effect->period
+		 << " => " << event.u.periodic.period  << endl
+		 << "  Offset    : " << effect->offset
+		 << " => " << event.u.periodic.offset << endl
+		 << "  Phase     : " << effect->phase
+		 << " => " << event.u.periodic.phase << endl;
+#endif
+
+	_upload(&event, eff);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_updateConditionalEffect( const Effect* eff )
+{
+	struct ff_effect event;
+
+	ConditionalEffect *effect = static_cast<ConditionalEffect*>(eff->getForceEffect());
+
+	_setCommonProperties(&event, NULL, eff, NULL);
+
+	switch( eff->type )
+	{
+		case OIS::Effect::Friction:
+			event.type = FF_FRICTION; 
+			break;
+		case OIS::Effect::Damper:
+			event.type = FF_DAMPER; 
+			break;
+		case OIS::Effect::Inertia:
+			event.type = FF_INERTIA; 
+			break;
+		case OIS::Effect::Spring:
+			event.type = FF_SPRING;
+			break;
+		default:
+			OIS_EXCEPT(E_General, "No such available effect for Conditional force!"); 
+			break;
+	}
+
+	event.id = -1;
+
+	event.u.condition[0].right_saturation = LinuxSignedLevel(effect->rightSaturation);
+	event.u.condition[0].left_saturation  = LinuxSignedLevel(effect->leftSaturation);
+	event.u.condition[0].right_coeff      = LinuxSignedLevel(effect->rightCoeff);
+	event.u.condition[0].left_coeff       = LinuxSignedLevel(effect->leftCoeff);
+	event.u.condition[0].deadband         = LinuxPositiveLevel(effect->deadband);// Unit ?? 
+	event.u.condition[0].center           = LinuxSignedLevel(effect->center); // Unit ?? TODO ?
+
+	// TODO support for second condition
+	event.u.condition[1] = event.u.condition[0];
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "  Condition[0] : " << endl
+		 << "    RightSaturation  : " << effect->rightSaturation
+		 << " => " << event.u.condition[0].right_saturation << endl
+		 << "    LeftSaturation   : " << effect->leftSaturation
+		 << " => " << event.u.condition[0]. left_saturation << endl
+		 << "    RightCoefficient : " << effect->rightCoeff
+		 << " => " << event.u.condition[0].right_coeff << endl
+		 << "    LeftCoefficient : " << effect->leftCoeff
+		 << " => " << event.u.condition[0].left_coeff << endl
+		 << "    DeadBand        : " << effect->deadband
+		 << " => " << event.u.condition[0].deadband  << endl
+		 << "    Center          : " << effect->center
+		 << " => " << event.u.condition[0].center << endl;
+	cout << "  Condition[1] : Not implemented" << endl;
+#endif
+	_upload(&event, eff);
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_upload( struct ff_effect* ffeffect, const Effect* effect)
+{
+	struct ff_effect *linEffect = 0;
+
+	//Get the effect - if it exists
+	EffectList::iterator i = mEffectList.find(effect->_handle);
+	//It has been created already
+	if( i != mEffectList.end() )
+		linEffect = i->second;
+
+	if( linEffect == 0 )
+	{
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+		cout << endl << "LinuxForceFeedback("<< mJoyStick << ") : Adding new effect : " 
+			 << Effect::getEffectTypeName(effect->type) << endl;
+#endif
+
+		//This effect has not yet been created, so create it in the device
+		if (ioctl(mJoyStick, EVIOCSFF, ffeffect) == -1) {
+			// TODO device full check
+			// OIS_EXCEPT(E_DeviceFull, "Remove an effect before adding more!");
+			OIS_EXCEPT(E_General, "Unknown error creating effect (may be the device is full)->..");
+		}
+
+		// Save returned effect handle
+		effect->_handle = ffeffect->id;
+
+		// Save a copy of the uploaded effect for later simple modifications
+		linEffect = (struct ff_effect *)calloc(1, sizeof(struct ff_effect));
+		memcpy(linEffect, ffeffect, sizeof(struct ff_effect));
+
+		mEffectList[effect->_handle] = linEffect;
+
+		// Start playing the effect.
+		_start(effect->_handle);
+	}
+	else
+	{
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+		cout << endl << "LinuxForceFeedback("<< mJoyStick << ") : Replacing effect : " 
+			 << Effect::getEffectTypeName(effect->type) << endl;
+#endif
+
+		// Keep same id/handle, as this is just an update in the device.
+		ffeffect->id = effect->_handle;
+
+		// Update effect in the device.
+		if (ioctl(mJoyStick, EVIOCSFF, ffeffect) == -1) {
+			OIS_EXCEPT(E_General, "Unknown error updating an effect->..");
+		}
+
+		// Update local linEffect for next time.
+		memcpy(linEffect, ffeffect, sizeof(struct ff_effect));
+	}
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << "LinuxForceFeedback("<< mJoyStick 
+		 << ") : Effect handle : " << effect->_handle << endl;
+#endif
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_stop( int handle) {
+	struct input_event stop;
+
+	stop.type = EV_FF;
+	stop.code = handle;
+	stop.value = 0;
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << endl << "LinuxForceFeedback("<< mJoyStick 
+		 << ") : Stopping effect with handle " << handle << endl;
+#endif
+
+	if (write(mJoyStick, &stop, sizeof(stop)) != sizeof(stop)) {
+		OIS_EXCEPT(E_General, "Unknown error stopping effect->..");
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_start( int handle) {
+	struct input_event play;
+
+	play.type = EV_FF;
+	play.code = handle;
+	play.value = 1; // Play once.
+
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << endl << "LinuxForceFeedback("<< mJoyStick 
+		 << ") : Starting effect with handle " << handle << endl;
+#endif
+
+	if (write(mJoyStick, &play, sizeof(play)) != sizeof(play)) {
+		OIS_EXCEPT(E_General, "Unknown error playing effect->..");
+	}
+}
+
+//--------------------------------------------------------------//
+void LinuxForceFeedback::_unload( int handle)
+{
+#if (OIS_LINUX_JOYFF_DEBUG > 1)
+	cout << endl << "LinuxForceFeedback("<< mJoyStick 
+		 << ") : Removing effect with handle " << handle << endl;
+#endif
+
+	if (ioctl(mJoyStick, EVIOCRMFF, handle) == -1) {
+		OIS_EXCEPT(E_General, "Unknown error removing effect->..");
+	}
+}
Index: /code/branches/rocket2/src/external/ois/linux/LinuxForceFeedback.h
===================================================================
--- /code/branches/rocket2/src/external/ois/linux/LinuxForceFeedback.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/linux/LinuxForceFeedback.h	(revision 6952)
@@ -0,0 +1,85 @@
+/*
+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_LinuxForceFeedBack_H
+#define OIS_LinuxForceFeedBack_H
+
+#include "linux/LinuxPrereqs.h"
+#include "OISForceFeedback.h"
+#include <linux/input.h>
+
+namespace OIS
+{
+	class LinuxForceFeedback : public ForceFeedback
+	{
+	public:
+		LinuxForceFeedback(int deviceID);
+		~LinuxForceFeedback();
+
+		/** @copydoc ForceFeedback::setMasterGain */
+		void setMasterGain(float);
+		
+		/** @copydoc ForceFeedback::setAutoCenterMode */
+		void setAutoCenterMode(bool);
+
+		/** @copydoc ForceFeedback::upload */
+		void upload( const Effect* effect );
+
+		/** @copydoc ForceFeedback::modify */
+		void modify( const Effect* effect );
+
+		/** @copydoc ForceFeedback::remove */
+		void remove( const Effect* effect );
+
+		/** FF is not yet implemented fully on Linux.. just return -1 for now. todo, xxx */
+		short int getFFAxesNumber() { return -1; }
+
+		/** @copydoc ForceFeedback::getFFMemoryLoad */
+		unsigned short getFFMemoryLoad();
+
+	protected:
+
+		//Sets the common properties to all effects
+		void _setCommonProperties(struct ff_effect *event, struct ff_envelope *ffenvelope, 
+								  const Effect* effect, const Envelope *envelope );
+
+		//Specific Effect Settings
+		void _updateConstantEffect( const Effect* effect );
+		void _updateRampEffect( const Effect* effect );
+		void _updatePeriodicEffect( const Effect* effect );
+		void _updateConditionalEffect( const Effect* effect );
+		//void _updateCustomEffect( const Effect* effect );
+
+		void _upload( struct ff_effect* ffeffect, const Effect* effect);
+		void _stop( int handle);
+		void _start( int handle);
+		void _unload( int handle);
+
+		// Map of currently uploaded effects (handle => effect)
+		typedef std::map<int, struct ff_effect *> EffectList;
+		EffectList mEffectList;
+
+		// Joystick device (file) descriptor.
+		int mJoyStick;
+	};
+}
+#endif //OIS_LinuxForceFeedBack_H
Index: /code/branches/rocket2/src/external/ois/linux/LinuxInputManager.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/linux/LinuxInputManager.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/linux/LinuxInputManager.cpp	(revision 6952)
@@ -0,0 +1,218 @@
+/*
+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 "linux/LinuxInputManager.h"
+#include "linux/LinuxKeyboard.h"
+#include "linux/LinuxJoyStickEvents.h"
+#include "linux/LinuxMouse.h"
+#include "OISException.h"
+#include <cstdlib>
+
+using namespace OIS;
+
+//--------------------------------------------------------------------------------//
+LinuxInputManager::LinuxInputManager() : InputManager("X11InputManager")
+{
+	window = 0;
+
+	//Default settings
+	grabMouse = true;
+	grabKeyboard = true;
+	hideMouse = true;
+	mGrabs = true;
+	useXRepeat = false;
+	keyboardUsed = mouseUsed = false;
+
+	//Setup our internal factories
+	mFactories.push_back(this);
+}
+
+//--------------------------------------------------------------------------------//
+LinuxInputManager::~LinuxInputManager()
+{
+	//Close all joysticks
+	LinuxJoyStick::_clearJoys(unusedJoyStickList);
+}
+
+//--------------------------------------------------------------------------------//
+void LinuxInputManager::_initialize( ParamList &paramList )
+{
+	_parseConfigSettings( paramList );
+
+	//Enumerate all devices attached
+	_enumerateDevices();
+}
+
+//--------------------------------------------------------------------------------//
+void LinuxInputManager::_parseConfigSettings( ParamList &paramList )
+{
+	ParamList::iterator i = paramList.find("WINDOW");
+	if( i == paramList.end() ) 
+		OIS_EXCEPT( E_InvalidParam, "LinuxInputManager >> No WINDOW!" );
+
+	//TODO 64 bit proof this little conversion xxx wip
+	window  = strtoul(i->second.c_str(), 0, 10);
+
+	//--------- 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() )
+		if( i->second == "false" )
+			grabKeyboard = false;
+
+	//--------- Mouse Settings ------------//
+	i = paramList.find("x11_mouse_grab");
+	if( i != paramList.end() )
+		if( i->second == "false" )
+			grabMouse = false;
+
+	i = paramList.find("x11_mouse_hide");
+	if( i != paramList.end() )
+		if( i->second == "false" )
+			hideMouse = false;
+}
+
+//--------------------------------------------------------------------------------//
+void LinuxInputManager::_enumerateDevices()
+{
+	//Enumerate all attached devices
+	unusedJoyStickList = LinuxJoyStick::_scanJoys();
+	joySticks = unusedJoyStickList.size();
+}
+
+//----------------------------------------------------------------------------//
+DeviceList LinuxInputManager::freeDeviceList()
+{
+	DeviceList ret;
+
+	if( keyboardUsed == false )
+		ret.insert(std::make_pair(OISKeyboard, mInputSystemName));
+
+	if( mouseUsed == false )
+		ret.insert(std::make_pair(OISMouse, mInputSystemName));
+
+	for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
+		ret.insert(std::make_pair(OISJoyStick, i->vendor));
+
+	return ret;
+}
+
+//----------------------------------------------------------------------------//
+int LinuxInputManager::totalDevices(Type iType)
+{
+	switch(iType)
+	{
+	case OISKeyboard: return 1;
+	case OISMouse: return 1;
+	case OISJoyStick: return joySticks;
+	default: return 0;
+	}
+}
+
+//----------------------------------------------------------------------------//
+int LinuxInputManager::freeDevices(Type iType)
+{
+	switch(iType)
+	{
+	case OISKeyboard: return keyboardUsed ? 0 : 1;
+	case OISMouse: return mouseUsed ? 0 : 1;
+	case OISJoyStick: return (int)unusedJoyStickList.size();
+	default: return 0;
+	}
+}
+
+//----------------------------------------------------------------------------//
+bool LinuxInputManager::vendorExist(Type iType, const std::string & vendor)
+{
+	if( (iType == OISKeyboard || iType == OISMouse) && vendor == mInputSystemName )
+	{
+		return true;
+	}
+	else if( iType == OISJoyStick )
+	{
+		for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
+			if(i->vendor == vendor)
+				return true;
+	}
+
+	return false;
+}
+
+//----------------------------------------------------------------------------//
+Object* LinuxInputManager::createObject(InputManager *creator, Type iType, bool bufferMode, const std::string & vendor)
+{
+	Object *obj = 0;
+
+	switch(iType)
+	{
+	case OISKeyboard:
+	{
+		if( keyboardUsed == false )
+			obj = new LinuxKeyboard(this, bufferMode, grabKeyboard, useXRepeat);
+		break;
+	}
+	case OISMouse:
+	{
+		if( mouseUsed == false )
+			obj = new LinuxMouse(this, bufferMode, grabMouse, hideMouse);
+		break;
+	}
+	case OISJoyStick:
+	{
+		for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
+		{
+			if(vendor == "" || i->vendor == vendor)
+			{
+				obj = new LinuxJoyStick(this, bufferMode, *i);
+				unusedJoyStickList.erase(i);
+				break;
+			}
+		}
+		break;
+	}
+	default:
+		break;
+	}
+
+	if( obj == 0 )
+		OIS_EXCEPT(E_InputDeviceNonExistant, "No devices match requested type.");
+
+	return obj;
+}
+
+//----------------------------------------------------------------------------//
+void LinuxInputManager::destroyObject( Object* obj )
+{
+	if( obj )
+	{
+		if( obj->type() == OISJoyStick )
+		{
+			unusedJoyStickList.push_back( ((LinuxJoyStick*)obj)->_getJoyInfo() );
+		}
+
+		delete obj;
+	}
+}
Index: /code/branches/rocket2/src/external/ois/linux/LinuxInputManager.h
===================================================================
--- /code/branches/rocket2/src/external/ois/linux/LinuxInputManager.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/linux/LinuxInputManager.h	(revision 6952)
@@ -0,0 +1,108 @@
+/*
+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_LinuxInputManager_H
+#define OIS_LinuxInputManager_H
+
+#include "linux/LinuxPrereqs.h"
+#include "OISFactoryCreator.h"
+#include "OISInputManager.h"
+#include <X11/Xlib.h>
+
+namespace OIS
+{
+	/**
+		Linux X11 InputManager specialization - Using lowlevel joys
+	*/
+	class LinuxInputManager : public InputManager, public FactoryCreator
+	{
+	public:
+		LinuxInputManager();
+		virtual ~LinuxInputManager();
+
+		//InputManager Overrides
+		/** @copydoc InputManager::_initialize */
+		void _initialize( ParamList &paramList );
+
+		//FactoryCreator Overrides
+		/** @copydoc FactoryCreator::deviceList */
+		DeviceList freeDeviceList();
+
+		/** @copydoc FactoryCreator::totalDevices */
+		int totalDevices(Type iType);
+
+		/** @copydoc FactoryCreator::freeDevices */
+		int freeDevices(Type iType);
+
+		/** @copydoc FactoryCreator::vendorExist */
+		bool vendorExist(Type iType, const std::string & vendor);
+
+		/** @copydoc FactoryCreator::createObject */
+		Object* createObject(InputManager *creator, Type iType, bool bufferMode, const std::string & vendor = "");
+
+		/** @copydoc FactoryCreator::destroyObject */
+		void destroyObject(Object* obj);
+
+		//Internal Items
+		//! Method for retrieving the XWindow Handle
+		Window _getWindow() {return window;}
+
+		//! Internal method for checking if regrabbing is needed
+		void _setGrabState(bool grab) {mGrabs = grab;}
+		bool _getGrabState() {return mGrabs;}
+
+		//! Internal method, used for flaggin keyboard as available/unavailable for creation
+		void _setKeyboardUsed(bool used) {keyboardUsed = used; }
+
+		//! Internal method, used for flaggin mouse as available/unavailable for creation
+		void _setMouseUsed(bool used) { mouseUsed = used; }
+		
+	protected:
+		//! internal class method for dealing with param list
+		void _parseConfigSettings( ParamList &paramList );
+		//! internal class method for finding attached devices
+		void _enumerateDevices();
+
+		//! List of unused joysticks ready to be used
+		JoyStickInfoList unusedJoyStickList;
+		//! Number of joysticks found
+		char joySticks;
+
+		//! Used to know if we used up keyboard
+		bool keyboardUsed;
+
+		//! Used to know if we used up mouse
+		bool mouseUsed;
+
+		//! X11 Stuff
+		Window window;
+		
+		/// Keyboard, Mouse Settings
+		bool grabMouse, grabKeyboard;
+		bool mGrabs;
+		bool hideMouse;
+
+		//! By default, keyboard disables XRepeatRate
+		bool useXRepeat;
+	};
+}
+#endif
Index: /code/branches/rocket2/src/external/ois/linux/LinuxJoyStickEvents.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/linux/LinuxJoyStickEvents.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/linux/LinuxJoyStickEvents.cpp	(revision 6952)
@@ -0,0 +1,302 @@
+/*
+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 "OISConfig.h"
+
+#include "linux/LinuxJoyStickEvents.h"
+#include "linux/LinuxInputManager.h"
+#include "linux/LinuxForceFeedback.h"
+#include "linux/EventHelpers.h"
+
+#include "OISEvents.h"
+#include "OISException.h"
+
+#include <fcntl.h>        //Needed to Open a file descriptor
+#include <cassert>	
+#include <linux/input.h>
+
+
+#include <sstream>
+# include <iostream>
+using namespace std;
+
+using namespace OIS;
+
+//#define OIS_LINUX_JOY_DEBUG
+
+//-------------------------------------------------------------------//
+LinuxJoyStick::LinuxJoyStick(InputManager* creator, bool buffered, const JoyStickInfo& js)
+	: JoyStick(js.vendor, buffered, js.devId, creator)
+{
+	mJoyStick = js.joyFileD;
+
+	mState.mAxes.clear();
+	mState.mAxes.resize(js.axes);
+	mState.mButtons.clear();
+	mState.mButtons.resize(js.buttons);
+
+	mPOVs = js.hats;
+
+	mButtonMap = js.button_map;
+	mAxisMap = js.axis_map;
+	mRanges = js.axis_range;
+
+	ff_effect = 0;
+}
+
+//-------------------------------------------------------------------//
+LinuxJoyStick::~LinuxJoyStick()
+{
+	EventUtils::removeForceFeedback( &ff_effect );
+}
+
+//-------------------------------------------------------------------//
+void LinuxJoyStick::_initialize()
+{
+	//Clear old joy state
+	mState.mAxes.resize(mAxisMap.size());
+	mState.clear();
+
+	//This will create and new us a force feedback structure if it exists
+	EventUtils::enumerateForceFeedback( mJoyStick, &ff_effect );
+
+	if( mJoyStick == -1 )
+		OIS_EXCEPT(E_InputDeviceNonExistant, "LinuxJoyStick::_initialize() >> JoyStick Not Found!");
+}
+
+//-------------------------------------------------------------------//
+void LinuxJoyStick::capture()
+{
+	static const short POV_MASK[8] = {0,0,1,1,2,2,3,3};
+
+	//Used to determine if an axis has been changed and needs an event
+	bool axisMoved[32] = {false, false, false, false, false, false, false, false, false, false, false, false, false,
+						  false, false, false, false, false, false, false, false, false, false, false, false, false,
+						  false, false, false, false, false, false};
+
+	//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)
+	{
+		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
+			{
+				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;
+				}
+				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));
+				}
+			}
+			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)
+				{
+					//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;
+			}
+			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;
+		}
+	}
+
+	//All axes and POVs are combined into one movement per pair per captured frame
+	if( mBuffered && mListener )
+	{
+		for( int i = 0; i < 32; ++i )
+			if( axisMoved[i] )
+				if( mListener->axisMoved( JoyStickEvent(this,mState), i) == false )
+					return;
+	}
+}
+
+//-------------------------------------------------------------------//
+void LinuxJoyStick::setBuffered(bool buffered)
+{
+	if( buffered != mBuffered )
+	{
+		mBuffered = buffered;
+		_initialize();
+	}
+}
+
+//-------------------------------------------------------------------//
+JoyStickInfo LinuxJoyStick::_getJoyInfo()
+{
+	JoyStickInfo js;
+
+	js.devId = mDevID;
+	js.joyFileD = mJoyStick;
+	js.vendor = mVendor;
+	js.axes = (int)mState.mAxes.size();
+	js.buttons = (int)mState.mButtons.size();
+	js.hats = mPOVs;
+	js.button_map = mButtonMap;
+	js.axis_map = mAxisMap;
+	js.axis_range = mRanges;
+
+	return js;
+}
+
+//-------------------------------------------------------------------//
+JoyStickInfoList LinuxJoyStick::_scanJoys()
+{
+	JoyStickInfoList joys;
+
+	//Search through all of the event devices.. and identify which ones are joysticks
+	//xxx move this to InputManager, as it can also scan all other events
+	for(int i = 0; i < 64; ++i )
+	{
+		stringstream s;
+		s << "/dev/input/event" << i;
+		int fd = open( s.str().c_str(), O_RDWR |O_NONBLOCK );
+		if(fd == -1)
+			continue;
+
+        #ifdef OIS_LINUX_JOY_DEBUG
+		  cout << "Opening " << s.str() << "..." << endl;
+        #endif
+		try
+		{
+			JoyStickInfo js;
+			if( EventUtils::isJoyStick(fd, js) )
+			{
+				joys.push_back(js);
+                #ifdef OIS_LINUX_JOY_DEBUG
+                  cout << "=> Joystick added to list." << endl;
+                #endif
+			}
+			else
+			{
+                #ifdef OIS_LINUX_JOY_DEBUG
+                  cout << "=> Not a joystick." << endl;
+                #endif
+				close(fd);
+			}
+		}
+		catch(...)
+		{
+            #ifdef OIS_LINUX_JOY_DEBUG
+              cout << "Exception caught!!" << endl;
+            #endif
+			close(fd);
+		}
+	}
+
+	return joys;
+}
+
+//-------------------------------------------------------------------//
+void LinuxJoyStick::_clearJoys(JoyStickInfoList &joys)
+{
+	for(JoyStickInfoList::iterator i = joys.begin(); i != joys.end(); ++i)
+		close(i->joyFileD);
+	joys.clear();
+}
+
+//-------------------------------------------------------------------//
+Interface* LinuxJoyStick::queryInterface(Interface::IType type)
+{
+	if( ff_effect && type == Interface::ForceFeedback )
+		return ff_effect;
+
+	return 0;
+}
Index: /code/branches/rocket2/src/external/ois/linux/LinuxJoyStickEvents.h
===================================================================
--- /code/branches/rocket2/src/external/ois/linux/LinuxJoyStickEvents.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/linux/LinuxJoyStickEvents.h	(revision 6952)
@@ -0,0 +1,72 @@
+/*
+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 _LINUX_JOYSTICK_H_EADER_
+#define _LINUX_JOYSTICK_H_EADER_
+
+#include "linux/LinuxPrereqs.h"
+#include "OISJoyStick.h"
+
+namespace OIS
+{
+	/**
+		Linux specialization of JoyStick class.. This version is favored over the other.. and has the
+		*possibility* of Force Feedback.. notice I say possibility, i make no gaurantees under linux,
+		as FF support is sketchy at best AFAIK.
+	*/
+	class LinuxJoyStick : public JoyStick
+	{
+	public:
+		LinuxJoyStick(InputManager* creator, bool buffered, const JoyStickInfo& js);
+		virtual ~LinuxJoyStick();
+
+		/** @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();
+
+		/**
+		@remarks
+			For internal use only... Returns a structure to the manager, to make the device
+			availiable for use again
+		*/
+		JoyStickInfo _getJoyInfo();
+
+		static JoyStickInfoList _scanJoys();
+		static void _clearJoys(JoyStickInfoList &joys);
+	protected:
+
+		int mJoyStick;
+		LinuxForceFeedback* ff_effect;
+		std::map <int, int> mButtonMap;
+		std::map <int, int> mAxisMap;
+		std::map <int, Range> mRanges;
+	};
+}
+#endif //_LINUX_JOYSTICK_H_EADER_
Index: /code/branches/rocket2/src/external/ois/linux/LinuxKeyboard.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/linux/LinuxKeyboard.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/linux/LinuxKeyboard.cpp	(revision 6952)
@@ -0,0 +1,444 @@
+/*
+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 "linux/LinuxInputManager.h"
+#include "linux/LinuxKeyboard.h"
+#include "OISException.h"
+#include "OISEvents.h"
+
+#include <X11/keysym.h>
+#include <X11/Xutil.h>
+#include <cstring>
+
+using namespace OIS;
+#include <iostream>
+//-------------------------------------------------------------------//
+LinuxKeyboard::LinuxKeyboard(InputManager* creator, bool buffered, bool grab, bool useXRepeat)
+	: Keyboard(creator->inputSystemName(), buffered, 0, creator)
+{
+	setlocale(LC_CTYPE, ""); //Set the locale to (hopefully) the users LANG UTF-8 Env var
+
+	display = 0;
+	window = 0;
+
+	grabKeyboard = grab;
+	keyFocusLost = false;
+
+	xAutoRepeat = useXRepeat;
+	oldXAutoRepeat = false;
+
+	//X Key Map to KeyCode
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_1, KC_1));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_2, KC_2));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_3, KC_3));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_4, KC_4));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_5, KC_5));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_6, KC_6));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_7, KC_7));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_8, KC_8));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_9, KC_9));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_0, KC_0));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_BackSpace, KC_BACK));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_minus, KC_MINUS));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_equal, KC_EQUALS));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_space, KC_SPACE));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_comma, KC_COMMA));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_period, KC_PERIOD));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_backslash, KC_BACKSLASH));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_slash, KC_SLASH));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_bracketleft, KC_LBRACKET));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_bracketright, KC_RBRACKET));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Escape,KC_ESCAPE));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Caps_Lock, KC_CAPITAL));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Tab, KC_TAB));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Return, KC_RETURN));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Control_L, KC_LCONTROL));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Control_R, KC_RCONTROL));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_colon, KC_COLON));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_semicolon, KC_SEMICOLON));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_apostrophe, KC_APOSTROPHE));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_grave, KC_GRAVE));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_b, KC_B));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_a, KC_A));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_c, KC_C));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_d, KC_D));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_e, KC_E));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_f, KC_F));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_g, KC_G));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_h, KC_H));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_i, KC_I));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_j, KC_J));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_k, KC_K));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_l, KC_L));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_m, KC_M));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_n, KC_N));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_o, KC_O));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_p, KC_P));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_q, KC_Q));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_r, KC_R));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_s, KC_S));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_t, KC_T));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_u, KC_U));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_v, KC_V));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_w, KC_W));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_x, KC_X));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_y, KC_Y));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_z, KC_Z));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F1, KC_F1));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F2, KC_F2));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F3, KC_F3));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F4, KC_F4));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F5, KC_F5));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F6, KC_F6));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F7, KC_F7));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F8, KC_F8));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F9, KC_F9));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F10, KC_F10));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F11, KC_F11));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F12, KC_F12));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F13, KC_F13));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F14, KC_F14));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_F15, KC_F15));
+
+	//Keypad
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_0, KC_NUMPAD0));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_1, KC_NUMPAD1));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_2, KC_NUMPAD2));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_3, KC_NUMPAD3));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_4, KC_NUMPAD4));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_5, KC_NUMPAD5));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_6, KC_NUMPAD6));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_7, KC_NUMPAD7));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_8, KC_NUMPAD8));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_9, KC_NUMPAD9));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Add, KC_ADD));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Subtract, KC_SUBTRACT));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Decimal, KC_DECIMAL));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Equal, KC_NUMPADEQUALS));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Divide, KC_DIVIDE));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Multiply, KC_MULTIPLY));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Enter, KC_NUMPADENTER));
+
+	//Keypad with numlock off
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Home, KC_NUMPAD7));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Up, KC_NUMPAD8));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Page_Up, KC_NUMPAD9));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Left, KC_NUMPAD4));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Begin, KC_NUMPAD5));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Right, KC_NUMPAD6));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_End, KC_NUMPAD1));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Down, KC_NUMPAD2));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Page_Down, KC_NUMPAD3));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Insert, KC_NUMPAD0));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_KP_Delete, KC_DECIMAL));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Up, KC_UP));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Down, KC_DOWN));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Left, KC_LEFT));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Right, KC_RIGHT));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Page_Up, KC_PGUP));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Page_Down, KC_PGDOWN));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Home, KC_HOME));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_End, KC_END));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Num_Lock, KC_NUMLOCK));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Print, KC_SYSRQ));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Scroll_Lock, KC_SCROLL));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Pause, KC_PAUSE));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Shift_R, KC_RSHIFT));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Shift_L, KC_LSHIFT));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Alt_R, KC_RMENU));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Alt_L, KC_LMENU));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Insert, KC_INSERT));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Delete, KC_DELETE));
+
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Super_L, KC_LWIN));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Super_R, KC_RWIN));
+	keyConversion.insert(XtoOIS_KeyMap::value_type(XK_Menu, KC_APPS));
+
+	static_cast<LinuxInputManager*>(mCreator)->_setKeyboardUsed(true);
+}
+
+//-------------------------------------------------------------------//
+void LinuxKeyboard::_initialize()
+{
+	//Clear our keyboard state buffer
+	memset( &KeyBuffer, 0, 256 );
+	mModifiers = 0;
+
+	if( display ) XCloseDisplay(display);
+	display = 0;
+	window = static_cast<LinuxInputManager*>(mCreator)->_getWindow();
+
+	//Create our local X mListener connection
+	if( !(display = XOpenDisplay(0)) )
+		OIS_EXCEPT(E_General, "LinuxKeyboard::_initialize >> Error opening X!");
+
+	//Set it to recieve Input events
+	if( XSelectInput(display, window, KeyPressMask | KeyReleaseMask) == BadWindow )
+		OIS_EXCEPT(E_General, "LinuxKeyboard::_initialize: X error!");
+
+	if( grabKeyboard )
+		XGrabKeyboard(display,window,True,GrabModeAsync,GrabModeAsync,CurrentTime);
+
+	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 );
+	}
+}
+
+//-------------------------------------------------------------------//
+LinuxKeyboard::~LinuxKeyboard()
+{
+	if( display )
+	{
+		if( oldXAutoRepeat )
+			XAutoRepeatOn(display);
+
+		if( grabKeyboard )
+			XUngrabKeyboard(display, CurrentTime);
+
+		XCloseDisplay(display);
+	}
+
+	static_cast<LinuxInputManager*>(mCreator)->_setKeyboardUsed(true);
+}
+
+//-------------------------------------------------------------------//
+unsigned int UTF8ToUTF32(unsigned char* buf)
+{
+	unsigned char &FirstChar = buf[0];
+
+	if(FirstChar < 128)
+		return FirstChar;
+
+	unsigned int val = 0;
+	unsigned int len = 0;
+
+	if((FirstChar & 0xE0) == 0xC0) //2 Chars
+	{
+		len = 2;
+		val = FirstChar & 0x1F;
+	}
+	else if((FirstChar & 0xF0) == 0xE0) //3 Chars
+	{
+		len = 3;
+		val = FirstChar & 0x0F;
+	}
+	else if((FirstChar & 0xF8) == 0xF0) //4 Chars
+	{
+		len = 4;
+		val = FirstChar & 0x07;
+	}
+	else if((FirstChar & 0xFC) == 0xF8) //5 Chars
+	{
+		len = 5;
+		val = FirstChar & 0x03;
+	}
+	else // if((FirstChar & 0xFE) == 0xFC) //6 Chars
+	{
+		len = 6;
+		val = FirstChar & 0x01;
+	}
+
+	for(int i = 1; i < len; i++)
+		val = (val << 6) | (buf[i] & 0x3F);
+
+	return val;
+}
+
+//-------------------------------------------------------------------//
+bool LinuxKeyboard::isKeyDown( KeyCode key ) const
+{
+	return (KeyBuffer[key]);
+}
+
+//-------------------------------------------------------------------//
+void LinuxKeyboard::capture()
+{
+	KeySym key;
+	XEvent event;
+	LinuxInputManager* linMan = static_cast<LinuxInputManager*>(mCreator);
+
+	while( XPending(display) > 0 )
+	{ 		XNextEvent(display, &event);  		if( KeyPress == event.type )
+		{
+			unsigned int character = 0;
+
+			if( mTextMode != Off )
+			{
+				unsigned char buffer[6] = {0,0,0,0,0,0};
+				XLookupString(&event.xkey, (char*)buffer, 6, &key, 0);
+
+				if( mTextMode == Unicode )
+					character = UTF8ToUTF32(buffer);
+				else if( mTextMode == Ascii)
+					character = buffer[0];
+			}
+
+			//Mask out the modifier states X11 sets and read again
+			event.xkey.state &= ~ShiftMask;
+			event.xkey.state &= ~LockMask;
+			XLookupString(&event.xkey, 0, 0,&key, 0);
+
+			_injectKeyDown(key, character);
+
+			//Just printing out some debugging info.. to verify all chars are mapped
+			//std::cout << "KEY PRESSED X=" << event.xkey.keycode;
+			//std::cout << "\n KeySym=" << key << std::endl;
+
+			//Check for Alt-Tab
+			if( event.xkey.state & Mod1Mask && key == XK_Tab )
+				linMan->_setGrabState(false);
+		} 		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 grabbing mode is on.. Handle focus lost/gained via Alt-Tab and mouse clicks
+	if( grabKeyboard )
+	{
+		if( linMan->_getGrabState() == false )
+		{
+			// are no longer grabbing
+			if( keyFocusLost == false )
+			{
+				//UnGrab KeyBoard
+				XUngrabKeyboard(display, CurrentTime);
+				keyFocusLost = true;
+			}
+		}
+		else
+		{
+			//We are grabbing - and regained focus
+			if( keyFocusLost == true )
+			{
+				//ReGrab KeyBoard
+				XGrabKeyboard(display, window, True, GrabModeAsync, GrabModeAsync, CurrentTime);
+				keyFocusLost = false;
+			}
+		}
+	}
+}
+
+//-------------------------------------------------------------------//
+void LinuxKeyboard::setBuffered(bool buffered)
+{
+	mBuffered = buffered;
+}
+
+//-------------------------------------------------------------------//
+bool LinuxKeyboard::_injectKeyDown( KeySym key, int text )
+{
+	KeyCode kc = keyConversion[key];
+	KeyBuffer[kc] = 1;
+
+	//Turn on modifier flags
+	if( kc == KC_LCONTROL || kc == KC_RCONTROL)
+		mModifiers |= Ctrl;
+	else if( kc == KC_LSHIFT || kc == KC_RSHIFT )
+		mModifiers |= Shift;
+	else if( kc == KC_LMENU || kc == KC_RMENU )
+		mModifiers |= Alt;
+
+	if( mBuffered && mListener )
+		return mListener->keyPressed(KeyEvent(this,kc,text));
+
+	return true;
+}
+
+//-------------------------------------------------------------------//
+bool LinuxKeyboard::_injectKeyUp( KeySym key )
+{
+	KeyCode kc = keyConversion[key];
+	KeyBuffer[kc] = 0;
+
+	//Turn off modifier flags
+	if( kc == KC_LCONTROL || kc == KC_RCONTROL)
+		mModifiers &= ~Ctrl;
+	else if( kc == KC_LSHIFT || kc == KC_RSHIFT )
+		mModifiers &= ~Shift;
+	else if( kc == KC_LMENU || kc == KC_RMENU )
+		mModifiers &= ~Alt;
+
+	if( mBuffered && mListener )
+		return mListener->keyReleased(KeyEvent(this, kc, 0));
+
+	return true;
+}
+
+//-------------------------------------------------------------------//
+const std::string& LinuxKeyboard::getAsString( KeyCode kc )
+{
+	mGetString = "Unknown";
+	char *temp = 0;
+
+	XtoOIS_KeyMap::iterator i = keyConversion.begin(),
+				e = keyConversion.end();
+
+	for( ; i != e; ++i )
+	{
+		if( i->second == kc )
+		{
+			temp = XKeysymToString(i->first);
+			if( temp )
+				mGetString = temp;
+			break;
+		}
+	}
+
+	return mGetString;
+}
+
+//-------------------------------------------------------------------//
+void LinuxKeyboard::copyKeyStates( char keys[256] ) const
+{
+	memcpy( keys, KeyBuffer, 256 );
+}
Index: /code/branches/rocket2/src/external/ois/linux/LinuxKeyboard.h
===================================================================
--- /code/branches/rocket2/src/external/ois/linux/LinuxKeyboard.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/linux/LinuxKeyboard.h	(revision 6952)
@@ -0,0 +1,84 @@
+/*
+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 _LINUX_KEYBOARD_H_EADER_
+#define _LINUX_KEYBOARD_H_EADER_
+
+#include "linux/LinuxPrereqs.h"
+#include "OISKeyboard.h"
+#include <X11/Xlib.h>
+
+namespace OIS
+{
+	/** Linux implementation of Keyboard object - uses x11 */
+	class LinuxKeyboard : public Keyboard
+	{
+	public:
+		LinuxKeyboard(InputManager* creator, bool buffered, bool grab, bool useXRepeat );
+		virtual ~LinuxKeyboard();
+
+		/** @copydoc Keyboard::isKeyDown */
+		virtual bool isKeyDown( KeyCode key ) const;
+
+		/** @copydoc Keyboard::getAsString */
+		virtual const std::string& getAsString( KeyCode kc );
+
+		/** @copydoc Keyboard::copyKeyStates */
+		virtual void copyKeyStates( char keys[256] ) const;
+
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+
+		/** @copydoc Object::capture */
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType) {return 0;}
+
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+
+	protected:
+		bool _injectKeyDown( KeySym key, int text );
+		bool _injectKeyUp( KeySym key );
+
+		//! 1:1 Conversion Map between X Key Events and OIS KeyCodes
+		typedef std::map<KeySym, KeyCode> XtoOIS_KeyMap;
+		XtoOIS_KeyMap keyConversion;
+
+		//! Depressed Key List
+		char KeyBuffer[256];
+
+		//! X11 Stuff
+		Window window;
+		Display *display;
+		bool grabKeyboard;
+		bool keyFocusLost;
+
+		bool xAutoRepeat;
+		bool oldXAutoRepeat;
+
+		std::string mGetString;
+	};
+}
+
+#endif //_LINUX_KEYBOARD_H_EADER_
Index: /code/branches/rocket2/src/external/ois/linux/LinuxMouse.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/linux/LinuxMouse.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/linux/LinuxMouse.cpp	(revision 6952)
@@ -0,0 +1,270 @@
+/*
+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 friosom any source distribution.
+*/
+#include "linux/LinuxMouse.h"
+#include "linux/LinuxInputManager.h"
+#include "OISException.h"
+#include "OISEvents.h"
+
+using namespace OIS;
+
+//-------------------------------------------------------------------//
+LinuxMouse::LinuxMouse(InputManager* creator, bool buffered, bool grab, bool hide)
+	: Mouse(creator->inputSystemName(), buffered, 0, creator)
+{
+	display = 0;
+	window = 0;
+	cursor = 0;
+
+	grabMouse = grab;
+	hideMouse = hide;
+
+	static_cast<LinuxInputManager*>(mCreator)->_setMouseUsed(true);
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouse::_initialize()
+{
+	//Clear old state
+	mState.clear();
+	mMoved  = false;
+	mWarped = false;
+
+	//6 is just some random value... hardly ever would anyone have a window smaller than 6
+	oldXMouseX = oldXMouseY = 6;
+	oldXMouseZ = 0;
+
+	if( display ) XCloseDisplay(display);
+	display = 0;
+	window = static_cast<LinuxInputManager*>(mCreator)->_getWindow();
+
+	//Create our local X mListener connection
+	if( !(display = XOpenDisplay(0)) )
+		OIS_EXCEPT(E_General, "LinuxMouse::_initialize >> Error opening X!");
+
+	//Set it to recieve Mouse Input events
+	if( XSelectInput(display, window, ButtonPressMask | ButtonReleaseMask | PointerMotionMask) == BadWindow )
+		OIS_EXCEPT(E_General, "LinuxMouse::_initialize >> X error!");
+
+	//Warp mouse inside window
+	XWarpPointer(display,None,window,0,0,0,0, 6,6);
+
+	//Create a blank cursor:
+	Pixmap bm_no;
+	XColor black, dummy;
+	Colormap colormap;
+	static char no_data[] = { 0,0,0,0,0,0,0,0 };
+
+	colormap = DefaultColormap( display, DefaultScreen(display) );
+	XAllocNamedColor( display, colormap, "black", &black, &dummy );
+	bm_no = XCreateBitmapFromData( display, window, no_data, 8, 8 );
+	cursor = XCreatePixmapCursor( display, bm_no, bm_no, &black, &black, 0, 0 );
+
+	grab( grabMouse );
+	hide( hideMouse );
+
+	mouseFocusLost = false;
+}
+
+//-------------------------------------------------------------------//
+LinuxMouse::~LinuxMouse()
+{
+	if( display )
+	{
+		grab(false);
+		hide(false);
+		XFreeCursor(display, cursor);
+		XCloseDisplay(display);
+	}
+
+	static_cast<LinuxInputManager*>(mCreator)->_setMouseUsed(false);
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouse::setBuffered(bool buffered)
+{
+	mBuffered = buffered;
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouse::capture()
+{
+	//Clear out last frames values
+	mState.X.rel = 0;
+	mState.Y.rel = 0;
+	mState.Z.rel = 0;
+
+	_processXEvents();
+
+	mWarped = false;
+
+	if( mMoved == true )
+	{
+		if( mBuffered && mListener )
+			mListener->mouseMoved( MouseEvent( this, mState ) );
+
+		mMoved = false;
+	}
+
+	//Check for losing/gaining mouse grab focus (alt-tab, etc)
+	if( grabMouse )
+	{
+		if( static_cast<LinuxInputManager*>(mCreator)->_getGrabState() )
+		{
+			if( mouseFocusLost )	//We just regained mouse grab focus
+			{
+				grab( true );
+				hide( hideMouse );
+				mouseFocusLost = false;
+			}
+		}
+		else
+		{
+			if( mouseFocusLost == false )	//We just lost mouse grab focus
+			{
+				grab( false );
+				hide( false );
+				mouseFocusLost = true;
+			}
+		}
+	}
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouse::_processXEvents()
+{
+	//X11 Button Events: 1=left 2=middle 3=right; Our Bit Postion: 1=Left 2=Right 3=Middle
+	char mask[4] = {0,1,4,2};
+	XEvent event;
+
+	//Poll x11 for events mouse events
+	while( XPending(display) > 0 ) 
+	{
+		XNextEvent(display, &event);
+
+		if( event.type == MotionNotify )
+		{	//Mouse moved
+			//Ignore out of bounds mouse if we just warped
+			if( mWarped )
+			{
+				if(event.xmotion.x < 5 || event.xmotion.x > mState.width - 5 ||
+				   event.xmotion.y < 5 || event.xmotion.y > mState.height - 5)
+					continue;
+			}
+
+			//Compute this frames Relative X & Y motion
+			mState.X.rel = event.xmotion.x - oldXMouseX;
+			mState.Y.rel = event.xmotion.y - oldXMouseY;
+		
+			//Store old values for next time to compute relative motion
+			oldXMouseX = event.xmotion.x;
+			oldXMouseY = event.xmotion.y;
+
+			mState.X.abs += mState.X.rel;
+			mState.Y.abs += mState.Y.rel;
+
+			//Check to see if we are grabbing the mouse to the window (requires clipping and warping)
+			if( grabMouse )
+			{
+				if( mState.X.abs < 0 )
+					mState.X.abs = 0;
+				else if( mState.X.abs > mState.width )
+					mState.X.abs = mState.width;
+
+				if( mState.Y.abs < 0 )
+					mState.Y.abs = 0;
+				else if( mState.Y.abs > mState.height )
+					mState.Y.abs = mState.height;
+
+				if( mouseFocusLost == false )
+				{
+					//Keep mouse in window (fudge factor)
+					if(event.xmotion.x < 5 || event.xmotion.x > mState.width - 5 ||
+					   event.xmotion.y < 5 || event.xmotion.y > mState.height - 5 )
+					{
+						oldXMouseX = mState.width >> 1;  //center x
+						oldXMouseY = mState.height >> 1; //center y
+						XWarpPointer(display, None, window, 0, 0, 0, 0, oldXMouseX, oldXMouseY);
+						mWarped = true;
+					}
+				}
+			}
+			mMoved = true;
+		}
+		else if( event.type == ButtonPress )
+		{	//Button down
+			static_cast<LinuxInputManager*>(mCreator)->_setGrabState(true);
+
+			if( event.xbutton.button < 4 )
+			{
+				mState.buttons |= mask[event.xbutton.button];
+				if( mBuffered && mListener )
+					if( mListener->mousePressed( MouseEvent( this, mState ),
+						(MouseButtonID)(mask[event.xbutton.button] >> 1)) == false )
+						return;
+			}
+		}
+		else if( event.type == ButtonRelease )
+		{	//Button up
+			if( event.xbutton.button < 4 )
+			{
+				mState.buttons &= ~mask[event.xbutton.button];
+				if( mBuffered && mListener )
+					if( mListener->mouseReleased( MouseEvent( this, mState ),
+						(MouseButtonID)(mask[event.xbutton.button] >> 1)) == false )
+						return;
+			}
+			//The Z axis gets pushed/released pair message (this is up)
+			else if( event.xbutton.button == 4 )
+			{
+				mState.Z.rel += 120;
+				mState.Z.abs += 120;
+				mMoved = true;
+			}
+			//The Z axis gets pushed/released pair message (this is down)
+			else if( event.xbutton.button == 5 )
+			{
+				mState.Z.rel -= 120;
+				mState.Z.abs -= 120;
+				mMoved = true;
+			}
+		}
+	}
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouse::grab(bool grab)
+{
+	if( grab )
+		XGrabPointer(display, window, True, 0, GrabModeAsync, GrabModeAsync, window, None, CurrentTime);
+	else
+		XUngrabPointer(display, CurrentTime);
+}
+
+//-------------------------------------------------------------------//
+void LinuxMouse::hide(bool hide)
+{
+	if( hide )
+		XDefineCursor(display, window, cursor);
+	else
+		XUndefineCursor(display, window);
+}
Index: /code/branches/rocket2/src/external/ois/linux/LinuxMouse.h
===================================================================
--- /code/branches/rocket2/src/external/ois/linux/LinuxMouse.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/linux/LinuxMouse.h	(revision 6952)
@@ -0,0 +1,75 @@
+/*
+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 _LINUX_MOUSE_H_EADER_
+#define _LINUX_MOUSE_H_EADER_
+
+#include "linux/LinuxPrereqs.h"
+#include "OISMouse.h"
+#include <X11/Xlib.h>
+
+namespace OIS
+{
+	class LinuxMouse : public Mouse
+	{
+	public:
+		LinuxMouse(InputManager* creator, bool buffered, bool grab, bool hide);
+		virtual ~LinuxMouse();
+
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+
+		/**
+		@remarks
+			Note: Calling this will also update the keyboard (X11 updates in a single
+			event queue). Updates State and/or raises event for buffered mode..
+		*/
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType) {return 0;}
+
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+
+		void grab(bool grab);
+		void hide(bool hide);
+
+	protected:
+		void _processXEvents();
+
+		bool mMoved, mWarped;
+
+		//Since X11 provides us with absolute values, we need to keep track of relative values
+		long oldXMouseX, oldXMouseY, oldXMouseZ;
+
+		Window window;		//The X Window
+		Display *display;	//The X display
+		Cursor cursor;		//A blank cursor
+
+		bool grabMouse;		//Are we grabbing the mouse to the window?
+		bool hideMouse;		//Are we hiding OS mouse?
+		bool mouseFocusLost;//Has the mouse just lost focus?
+	};
+}
+
+#endif //_LINUX_MOUSE_H_EADER_
Index: /code/branches/rocket2/src/external/ois/linux/LinuxPrereqs.h
===================================================================
--- /code/branches/rocket2/src/external/ois/linux/LinuxPrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/linux/LinuxPrereqs.h	(revision 6952)
@@ -0,0 +1,82 @@
+/*
+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 _LINUX_INPUTSYSTEM_PREREQS_H
+#define _LINUX_INPUTSYSTEM_PREREQS_H
+
+//Bring in any auto generated config files
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "OISPrereqs.h"
+
+//! Max number of elements to collect from buffered input
+#define JOY_BUFFERSIZE 10
+
+namespace OIS
+{
+	class LinuxInputManager;
+	class LinuxKeyboard;
+	class LinuxJoyStick;
+	class LinuxMouse;
+	
+	class LinuxForceFeedback;
+
+	class Range
+	{
+	public:
+		Range() {};
+		Range(int _min, int _max) : min(_min), max(_max) {};
+		int min, max;
+	};
+
+	class JoyStickInfo
+	{
+	public:
+		JoyStickInfo(): devId(-1),joyFileD(-1),version(0),axes(0),buttons(0),hats(0) {}
+		//! Device number (/dev/input/j#) or /dev/input/event#
+		int devId;
+		//! File descriptor
+		int joyFileD;
+		//! Driver version
+		int version;
+		//! Joy vendor
+		std::string vendor;
+		//! Number of axes
+		unsigned char axes;
+		//! Number of buttons
+		unsigned char buttons;
+		//! Number of hats
+		unsigned char hats;
+		//! Maps Linux button values to OIS buttons values
+		std::map<int, int> button_map;
+		//! Maps Linux axis values to OIS axis
+		std::map<int, int> axis_map;
+		//! Maps OIS axis values to it's range
+		std::map<int, Range> axis_range;
+	};
+
+	typedef std::vector< JoyStickInfo > JoyStickInfoList;
+}
+
+#endif //_LINUX_INPUTSYSTEM_PREREQS_H
Index: /code/branches/rocket2/src/external/ois/mac/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/ois/mac/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/mac/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,16 @@
+ADD_SOURCE_FILES(OIS_FILES
+  MacHelpers.h
+  MacHIDManager.h
+  MacInputManager.h
+  MacKeyboard.h
+  MacMouse.h
+  MacPrereqs.h
+
+COMPILATION_BEGIN OISMacCompilation.cpp
+  MacHelpers.cpp
+  MacHIDManager.cpp
+  MacInputManager.cpp
+  MacKeyboard.cpp
+  MacMouse.cpp
+COMPILATION_END
+)
Index: /code/branches/rocket2/src/external/ois/mac/MacHIDManager.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/mac/MacHIDManager.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/mac/MacHIDManager.cpp	(revision 6952)
@@ -0,0 +1,392 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Phillip Castaneda
+ 
+ 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/MacHIDManager.h"
+#include "OISException.h"
+#include "OISObject.h"
+
+#include <iostream>
+using namespace std;
+
+using namespace OIS;
+
+//------------------------------------------------------------------------------------------------------//
+//------------------------------------------------------------------------------------------------------//
+template<typename T>
+T getDictionaryItemAsRef(CFDictionaryRef dict, const char* keyName)
+{
+	return CFDictionaryGetValue(dict, OIS_CFString(keyName));
+}
+
+template<>
+CFArrayRef getDictionaryItemAsRef(CFDictionaryRef dict, const char* keyName)
+{
+	CFTypeRef temp = CFDictionaryGetValue(dict, OIS_CFString(keyName));
+
+	if(temp && CFGetTypeID(temp) == CFArrayGetTypeID())
+		return (CFArrayRef)temp;
+	else
+		return 0;
+}
+
+template<>
+CFStringRef getDictionaryItemAsRef(CFDictionaryRef dict, const char* keyName)
+{
+	CFTypeRef temp = CFDictionaryGetValue(dict, OIS_CFString(keyName));
+
+	if(temp && CFGetTypeID(temp) == CFStringGetTypeID())
+		return (CFStringRef)temp;
+	else
+		return 0;
+}
+
+template<>
+CFNumberRef getDictionaryItemAsRef(CFDictionaryRef dict, const char* keyName)
+{
+	CFTypeRef temp = CFDictionaryGetValue(dict, OIS_CFString(keyName));
+
+	if(temp && CFGetTypeID(temp) == CFNumberGetTypeID())
+		return (CFNumberRef)temp;
+	else
+		return 0;
+}
+
+//------------------------------------------------------------------------------------------------------//
+//------------------------------------------------------------------------------------------------------//
+template<typename T>
+T getArrayItemAsRef(CFArrayRef array, CFIndex idx)
+{
+	return CFArrayGetValueAtIndex(array, idx);
+}
+
+template<>
+CFDictionaryRef getArrayItemAsRef(CFArrayRef array, CFIndex idx)
+{
+	CFTypeRef temp = CFArrayGetValueAtIndex(array, idx);
+
+	if(temp && CFGetTypeID(temp) == CFDictionaryGetTypeID())
+		return (CFDictionaryRef)temp;
+	else
+		return 0;
+}
+
+//------------------------------------------------------------------------------------------------------//
+int getInt32(CFNumberRef ref)
+{
+   int r = 0;
+   if (r) 
+      CFNumberGetValue(ref, kCFNumberIntType, &r);
+   return r;
+}
+
+//--------------------------------------------------------------------------------//
+MacHIDManager::MacHIDManager()
+{
+}
+
+//--------------------------------------------------------------------------------//
+MacHIDManager::~MacHIDManager()
+{
+}
+
+//------------------------------------------------------------------------------------------------------//
+void MacHIDManager::initialize()
+{
+	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);
+
+	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)
+		{
+			//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)
+					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);
+				//}
+				//
+			}
+		}
+
+		IOObjectRelease(iterator);
+	}
+
+	CFRelease(usageRef);
+	CFRelease(pageRef);
+}
+
+//------------------------------------------------------------------------------------------------------//
+HidInfo* MacHIDManager::enumerateDeviceProperties(CFMutableDictionaryRef propertyMap)
+{
+	HidInfo* info = new HidInfo();
+	
+	info->type = OISJoyStick;
+	
+	CFStringRef str = getDictionaryItemAsRef<CFStringRef>(propertyMap, kIOHIDManufacturerKey);
+	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);
+	if (array)
+		for (int i = 0; i < CFArrayGetCount(array); i++)
+			parseDeviceProperties(getArrayItemAsRef<CFDictionaryRef>(array, i));
+
+	return info;
+}
+
+//------------------------------------------------------------------------------------------------------//
+void MacHIDManager::parseDeviceProperties(CFDictionaryRef properties)
+{
+	if(!properties)
+		return;
+
+	CFArrayRef array = getDictionaryItemAsRef<CFArrayRef>(properties, kIOHIDElementKey);
+	if (array)
+	{
+		for (int i = 0; i < CFArrayGetCount(array); i++)
+		{
+			CFDictionaryRef element = getArrayItemAsRef<CFDictionaryRef>(array, i);
+			if (element)
+			{
+				if(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementTypeKey)) == kIOHIDElementTypeCollection) 
+				{	//Check if we need to recurse further intoi another collection
+					if(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsagePageKey)) == kHIDPage_GenericDesktop)
+						parseDeviceProperties(element);
+				}
+				else
+				{
+					switch(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsagePageKey)))
+					{
+					case kHIDPage_GenericDesktop:
+						switch(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsageKey)))
+						{
+						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 kHIDPage_Button:
+						cout << "\tkHIDPage_Button\n";
+						break;
+					}
+				}
+			}
+		}
+	}
+}
+
+//------------------------------------------------------------------------------------------------------//
+void MacHIDManager::parseDevicePropertiesGroup(CFDictionaryRef properties)
+{
+	if(!properties)
+		return;
+
+	CFArrayRef array = getDictionaryItemAsRef<CFArrayRef>(properties, kIOHIDElementKey);
+	if(array)
+	{
+		for (int i = 0; i < CFArrayGetCount(array); i++)
+		{
+			CFDictionaryRef element = getArrayItemAsRef<CFDictionaryRef>(array, i);
+			if (element)
+			{
+				switch(getInt32(getDictionaryItemAsRef<CFNumberRef>(element, kIOHIDElementUsagePageKey)))
+				{
+				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";
+						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:
+					break;
+				}
+			}
+		}
+	}
+}
+
+//--------------------------------------------------------------------------------//
+DeviceList MacHIDManager::freeDeviceList()
+{
+	DeviceList ret;
+	HidInfoList::iterator it = mDeviceList.begin(), end = mDeviceList.end();
+	for(; it != end; ++it)
+	{
+		if((*it)->inUse == false)
+			ret.insert(std::make_pair((*it)->type, (*it)->combinedKey));
+	}
+
+	return ret;
+}
+
+//--------------------------------------------------------------------------------//
+int MacHIDManager::totalDevices(Type iType)
+{
+	int ret = 0;
+	HidInfoList::iterator it = mDeviceList.begin(), end = mDeviceList.end();
+
+	for(; it != end; ++it)
+	{
+		if((*it)->type == iType)
+			ret++;
+	}
+	
+	return ret;
+}
+
+//--------------------------------------------------------------------------------//
+int MacHIDManager::freeDevices(Type iType)
+{
+	int ret = 0;
+	HidInfoList::iterator it = mDeviceList.begin(), end = mDeviceList.end();
+
+	for(; it != end; ++it)
+	{
+		if((*it)->inUse == false && (*it)->type == iType)
+			ret++;
+	}
+
+	return ret;
+}
+
+//--------------------------------------------------------------------------------//
+bool MacHIDManager::vendorExist(Type iType, const std::string & vendor)
+{
+	HidInfoList::iterator it = mDeviceList.begin(), end = mDeviceList.end();
+
+	for(; it != end; ++it)
+	{
+		if((*it)->type == iType && (*it)->combinedKey == vendor)
+			return true;
+	}
+	
+	return false;
+}
+
+//--------------------------------------------------------------------------------//
+Object* MacHIDManager::createObject(InputManager* creator, Type iType, bool bufferMode, 
+									  const std::string & vendor)
+{
+	Object *obj = 0;
+
+	HidInfoList::iterator it = mDeviceList.begin(), end = mDeviceList.end();
+	for(; it != end; ++it)
+	{
+		if((*it)->inUse == false && (*it)->type == iType && (vendor == "" || (*it)->combinedKey == vendor))
+		{
+			//create device
+		}
+	}
+
+	if( obj == 0 )
+		OIS_EXCEPT(E_InputDeviceNonExistant, "No devices match requested type.");
+
+	return obj;
+}
+
+//--------------------------------------------------------------------------------//
+void MacHIDManager::destroyObject(Object* obj)
+{
+	delete obj;
+}
Index: /code/branches/rocket2/src/external/ois/mac/MacHIDManager.h
===================================================================
--- /code/branches/rocket2/src/external/ois/mac/MacHIDManager.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/mac/MacHIDManager.h	(revision 6952)
@@ -0,0 +1,100 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2007 Phillip
+ 
+ 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_MacHIDManager_Header
+#define OIS_MacHIDManager_Header
+
+#include "OISPrereqs.h"
+#include "mac/MacPrereqs.h"
+#include "OISFactoryCreator.h"
+
+#import <CoreFoundation/CFString.h>
+#import <IOKit/IOKitLib.h>
+#import <IOKit/IOCFPlugIn.h>
+#import <IOKit/hid/IOHIDLib.h>
+#import <IOKit/hid/IOHIDKeys.h>
+#import <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>
+
+namespace OIS
+{
+	//Information needed to create Mac HID Devices
+	class HidInfo
+	{
+	public:
+		HidInfo() : type(OISUnknown), numButtons(0), numHats(0), numAxes(0), inUse(false), interface(0)
+		{
+		}
+
+		//Useful tracking information
+		Type type;
+		std::string vendor;
+		std::string productKey;
+		std::string combinedKey;
+
+		//Retain some count information for recreating devices without having to reparse
+		int numButtons;
+		int numHats;
+		int numAxes;
+		bool inUse;
+
+		//Used for opening a read/write/tracking interface to device
+		IOHIDDeviceInterface **interface;
+	};
+
+	typedef std::vector<HidInfo*> HidInfoList;
+		
+	class MacHIDManager : public FactoryCreator
+	{
+	public:
+		MacHIDManager();
+		~MacHIDManager();
+
+		void initialize();
+
+		//FactoryCreator Overrides
+		/** @copydoc FactoryCreator::deviceList */
+		DeviceList freeDeviceList();
+
+		/** @copydoc FactoryCreator::totalDevices */
+		int totalDevices(Type iType);
+
+		/** @copydoc FactoryCreator::freeDevices */
+		int freeDevices(Type iType);
+
+		/** @copydoc FactoryCreator::vendorExist */
+		bool vendorExist(Type iType, const std::string & vendor);
+
+		/** @copydoc FactoryCreator::createObject */
+		Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor = "");
+
+		/** @copydoc FactoryCreator::destroyObject */
+		void destroyObject(Object* obj);
+
+	private:
+		HidInfo* enumerateDeviceProperties(CFMutableDictionaryRef propertyMap);
+		void parseDeviceProperties(CFDictionaryRef properties);
+		void parseDevicePropertiesGroup(CFDictionaryRef properties);
+
+		HidInfoList mDeviceList;		
+	};
+}
+#endif
Index: /code/branches/rocket2/src/external/ois/mac/MacHelpers.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/mac/MacHelpers.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/mac/MacHelpers.cpp	(revision 6952)
@@ -0,0 +1,158 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ 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/MacHelpers.h"
+#include "mac/MacKeyboard.h"
+#include "mac/MacMouse.h"
+#include "OISException.h"
+
+#include <Carbon/Carbon.h>
+
+using namespace OIS;
+    
+//-------------------------------------------------------------------//
+OSStatus KeyDownWrapper( EventHandlerCallRef nextHandler,
+                        EventRef               theEvent,
+                        void*                  callClass )
+{
+    // TODO find a better way. This cast isn't very safe
+    if (callClass != NULL) {
+        ((MacKeyboard*)callClass)->_keyDownCallback( theEvent );
+        
+        // propagate the event down the chain
+        return CallNextEventHandler( nextHandler, theEvent );
+    }
+    else {
+        OIS_EXCEPT(E_General, "KeyDownWrapper >> Being called by something other than our event handler!");
+        return noErr;
+    }
+}
+
+
+//-------------------------------------------------------------------//
+OSStatus KeyUpWrapper( EventHandlerCallRef nextHandler,
+                       EventRef               theEvent,
+                       void*                  callClass )
+{
+    if (callClass != NULL) {
+        ((MacKeyboard*)callClass)->_keyUpCallback( theEvent );
+        
+        // propagate the event down the chain
+        return CallNextEventHandler( nextHandler, theEvent );
+    }
+    else {
+        OIS_EXCEPT(E_General, "KeyUpWrapper >> Being called by something other than our event handler!");
+        return noErr;
+    }
+}
+
+
+//-------------------------------------------------------------------//
+OSStatus KeyModWrapper( EventHandlerCallRef nextHandler,
+                        EventRef               theEvent,
+                        void*                  callClass )
+{
+    if (callClass != NULL) {
+        ((MacKeyboard*)callClass)->_modChangeCallback( theEvent );
+        
+        // propagate the event down the chain
+        return CallNextEventHandler( nextHandler, theEvent );
+        
+    }
+    else {
+        OIS_EXCEPT(E_General, "KeyModWrapper >> Being called by something other than our event handler!");
+        return noErr;
+    }
+}
+
+/*
+//-------------------------------------------------------------------//
+OSStatus MouseMoveWrapper( EventHandlerCallRef nextHandler,
+                           EventRef            theEvent,
+                           void*               callClass )
+{
+    if (callClass != NULL) {
+        ((MacMouse*)callClass)->_mouseMoveCallback( theEvent );
+        
+        // propagate the event down the chain
+        return CallNextEventHandler( nextHandler, theEvent );
+        
+    }
+    else {
+        OIS_EXCEPT(E_General, "MouseMoveWrapper >> Being called by something other than our event handler!");
+        return noErr;
+    }
+}
+
+
+//-------------------------------------------------------------------//
+OSStatus MouseScrollWrapper( EventHandlerCallRef nextHandler,
+                             EventRef            theEvent,
+                             void*               callClass )
+{
+    if (callClass != NULL) {
+        ((MacMouse*)callClass)->_mouseScrollCallback( theEvent );
+        
+        // propagate the event down the chain
+        return CallNextEventHandler( nextHandler, theEvent );
+        
+    }
+    else {
+        OIS_EXCEPT(E_General, "MouseScrollWrapper >> Being called by something other than our event handler!");
+        return noErr;
+    }
+}
+
+
+//-------------------------------------------------------------------//
+OSStatus MouseButtonWrapper( EventHandlerCallRef nextHandler,
+                             EventRef            theEvent,
+                             void*               callClass )
+{
+    if (callClass != NULL) {
+        ((MacMouse*)callClass)->_mouseButtonCallback( theEvent );
+        
+        // propagate the event down the chain
+        return CallNextEventHandler( nextHandler, theEvent );
+        
+    }
+    else {
+        OIS_EXCEPT(E_General, "MouseButtonWrapper >> Being called by something other than our event handler!");
+        return noErr;
+    }
+}
+*/
+
+//-------------------------------------------------------------------//
+OSStatus MouseWrapper( EventHandlerCallRef nextHandler, EventRef theEvent, void* callClass )
+{
+    if (callClass != NULL)
+	{
+        ((MacMouse*)callClass)->_mouseCallback( theEvent );
+
+        // propagate the event down the chain
+        return CallNextEventHandler( nextHandler, theEvent );        
+    }
+    else
+        OIS_EXCEPT(E_General, "MouseWrapper >> Being called by something other than our event handler!");
+}
Index: /code/branches/rocket2/src/external/ois/mac/MacHelpers.h
===================================================================
--- /code/branches/rocket2/src/external/ois/mac/MacHelpers.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/mac/MacHelpers.h	(revision 6952)
@@ -0,0 +1,94 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ 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_MacHelpers_H
+#define OIS_MacHelpers_H
+
+#include "mac/MacPrereqs.h"
+#include "OISEvents.h"
+#include "OISKeyboard.h"
+#include "OISMouse.h"
+
+#include <Carbon/Carbon.h>
+
+// This is a hack needed to get the event handler working. 
+// The carbon lib expects a "OSStatus (*)(EventHandlerCallRef, EventRef, void*)",
+// so I cannot give it a class member function (unless it is static which is pointless)
+// Instead, I just pass the class* through the last paramter that gets passed to the
+// callback every time an event occurs. Then I dereference it and call the member function.
+OSStatus KeyDownWrapper( EventHandlerCallRef nextHandler, EventRef theEvent, void* callClass );
+
+OSStatus KeyUpWrapper( EventHandlerCallRef nextHandler, EventRef theEvent, void* callClass );
+
+OSStatus KeyModWrapper( EventHandlerCallRef nextHandler, EventRef theEvent, void* callClass );
+
+OSStatus MouseWrapper( EventHandlerCallRef nextHandler, EventRef theEvent, void* callClass );
+
+
+// This is needed for keeping an event stack for keyboard and mouse
+namespace OIS
+{
+    
+    // used in the eventStack to store the type
+    enum Mac_EventType { MAC_KEYUP = 0,
+                         MAC_KEYDOWN = 1,
+                         MAC_KEYREPEAT,
+                         MAC_MOUSEDOWN,
+                         MAC_MOUSEUP,
+                         MAC_MOUSEMOVED,
+                         MAC_MOUSESCROLL};
+    typedef enum Mac_EventType MacEventType;
+    
+    
+    // only used by MacKeyboard
+    typedef class Mac_KeyStackEvent
+    {
+        friend class MacKeyboard;
+        
+        
+    private:
+        Mac_KeyStackEvent( KeyEvent event, MacEventType type ) : Event(event), Type(type) {}
+        
+        MacEventType Type;
+        KeyEvent Event;
+    } MacKeyStackEvent;
+ 
+    
+
+    // only used by MacMouse
+    typedef class Mac_MouseStackEvent
+    {
+        friend class MacMouse;
+        
+    private:
+        Mac_MouseStackEvent( MouseEvent event, MacEventType type,  MouseButtonID button) : Event(event), Type(type), Button(button) {}
+        
+        MacEventType Type;
+        MouseEvent Event;
+		MouseButtonID Button;
+        
+    } MacMouseStackEvent;
+        
+}
+
+
+#endif
Index: /code/branches/rocket2/src/external/ois/mac/MacInputManager.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/mac/MacInputManager.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/mac/MacInputManager.cpp	(revision 6952)
@@ -0,0 +1,203 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ 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/MacInputManager.h"
+#include "mac/MacKeyboard.h"
+#include "mac/MacMouse.h"
+#include "mac/MacHIDManager.h"
+#include "OISException.h"
+
+#include <Carbon/Carbon.h>
+
+#include <iostream>
+using namespace std;
+
+using namespace OIS;
+
+//--------------------------------------------------------------------------------//
+MacInputManager::MacInputManager() : InputManager("Mac OSX Input Manager")
+{
+    mHideMouse = true;
+    mUseRepeat = false;
+    mEventTargetRef = NULL;
+	mWindow = NULL;
+
+	keyboardUsed = mouseUsed = false;
+
+	//Setup our internal factories
+	mFactories.push_back(this);
+
+	mHIDManager = new MacHIDManager();
+	mFactories.push_back(mHIDManager);
+}
+
+//--------------------------------------------------------------------------------//
+MacInputManager::~MacInputManager()
+{
+	delete mHIDManager;
+}
+
+//--------------------------------------------------------------------------------//
+void MacInputManager::_initialize( ParamList &paramList )
+{
+	_parseConfigSettings( paramList );
+    
+	//Enumerate all devices attached
+	_enumerateDevices();
+	
+	mHIDManager->initialize();
+}
+
+//--------------------------------------------------------------------------------//
+void MacInputManager::_parseConfigSettings( ParamList &paramList )
+{
+    // Some carbon apps are running in a window, however full screen apps
+	// do not have a window, so we need to account for that too.
+	ParamList::iterator i = paramList.find("WINDOW");
+	if(i != paramList.end())
+	{
+		mWindow = (WindowRef)strtoul(i->second.c_str(), 0, 10);
+		if(mWindow == 0)
+		{
+			mWindow = NULL;
+			mEventTargetRef = GetApplicationEventTarget();
+		}
+		else
+		{
+			//mEventTargetRef = GetWindowEventTarget(mWindow);
+			mEventTargetRef = GetApplicationEventTarget();
+		}
+    }
+	else
+	{
+		// else get the main active window.. user might not have access to it through some
+		// graphics libraries, if that fails then try at the application level.
+		mWindow = ActiveNonFloatingWindow();
+		if(mWindow == NULL)
+		{
+			mEventTargetRef = GetApplicationEventTarget();
+		}
+		else
+		{
+			//mEventTargetRef = GetWindowEventTarget(mWindow);
+			mEventTargetRef = GetApplicationEventTarget();
+		}
+	}
+	
+	if(mEventTargetRef == NULL)
+		OIS_EXCEPT( E_General, "MacInputManager::_parseConfigSettings >> Unable to find a window or event target" );
+    
+    // Keyboard
+    if(paramList.find("MacAutoRepeatOn") != paramList.end())
+	{
+        if(paramList.find("MacAutoRepeatOn")->second == "true")
+		{
+            mUseRepeat = true;
+        }
+    }
+}
+
+//--------------------------------------------------------------------------------//
+void MacInputManager::_enumerateDevices()
+{
+}
+
+//--------------------------------------------------------------------------------//
+DeviceList MacInputManager::freeDeviceList()
+{
+	DeviceList ret;
+
+	if( keyboardUsed == false )
+		ret.insert(std::make_pair(OISKeyboard, mInputSystemName));
+
+	if( mouseUsed == false )
+		ret.insert(std::make_pair(OISMouse, mInputSystemName));
+
+	return ret;
+}
+
+//--------------------------------------------------------------------------------//
+int MacInputManager::totalDevices(Type iType)
+{
+	switch(iType)
+	{
+	case OISKeyboard: return 1;
+	case OISMouse: return 1;
+	default: return 0;
+	}
+}
+
+//--------------------------------------------------------------------------------//
+int MacInputManager::freeDevices(Type iType)
+{
+	switch(iType)
+	{
+	case OISKeyboard: return keyboardUsed ? 0 : 1;
+	case OISMouse: return mouseUsed ? 0 : 1;
+	default: return 0;
+	}
+}
+
+//--------------------------------------------------------------------------------//
+bool MacInputManager::vendorExist(Type iType, const std::string & vendor)
+{
+	if( (iType == OISKeyboard || iType == OISMouse) && vendor == mInputSystemName )
+		return true;
+
+	return false;
+}
+
+//--------------------------------------------------------------------------------//
+Object* MacInputManager::createObject(InputManager* creator, Type iType, bool bufferMode, 
+									  const std::string & vendor)
+{
+	Object *obj = 0;
+
+	switch(iType)
+	{
+	case OISKeyboard: 
+	{
+		if( keyboardUsed == false )
+			obj = new MacKeyboard(this, bufferMode, mUseRepeat);
+		break;
+	}
+	case OISMouse:
+	{
+		if( mouseUsed == false )
+			obj = new MacMouse(this, bufferMode);
+		break;
+	}
+	default:
+		break;
+	}
+
+	if( obj == 0 )
+		OIS_EXCEPT(E_InputDeviceNonExistant, "No devices match requested type.");
+
+	return obj;
+}
+
+//--------------------------------------------------------------------------------//
+void MacInputManager::destroyObject(Object* obj)
+{
+	delete obj;
+}
Index: /code/branches/rocket2/src/external/ois/mac/MacInputManager.h
===================================================================
--- /code/branches/rocket2/src/external/ois/mac/MacInputManager.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/mac/MacInputManager.h	(revision 6952)
@@ -0,0 +1,101 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ 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_MacInputManager_H
+#define OIS_MacInputManager_H
+
+#include "OISInputManager.h"
+#include "OISFactoryCreator.h"
+#include "mac/MacPrereqs.h"
+#include <Carbon/Carbon.h>
+
+namespace OIS
+{
+    
+    class MacInputManager : public InputManager, public FactoryCreator
+    {
+    public:
+        MacInputManager();
+        virtual ~MacInputManager();
+        
+		//InputManager Overrides
+		/** @copydoc InputManager::_initialize */
+		void _initialize( ParamList &paramList );
+
+		//FactoryCreator Overrides
+		/** @copydoc FactoryCreator::deviceList */
+		DeviceList freeDeviceList();
+
+		/** @copydoc FactoryCreator::totalDevices */
+		int totalDevices(Type iType);
+
+		/** @copydoc FactoryCreator::freeDevices */
+		int freeDevices(Type iType);
+
+		/** @copydoc FactoryCreator::vendorExist */
+		bool vendorExist(Type iType, const std::string & vendor);
+
+		/** @copydoc FactoryCreator::createObject */
+		Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor = "");
+
+		/** @copydoc FactoryCreator::destroyObject */
+		void destroyObject(Object* obj);
+
+		//Internal Items
+		//! Internal method, used for flaggin keyboard as available/unavailable for creation
+		void _setKeyboardUsed(bool used) {keyboardUsed = used; }
+
+		//! Internal method, used for flaggin mouse as available/unavailable for creation
+		void _setMouseUsed(bool used) { mouseUsed = used; }
+        
+        //! methodfor getting the event target
+        EventTargetRef _getEventTarget() {return mEventTargetRef;}
+        
+        //! method for getting window
+        WindowRef _getWindow() {return mWindow;}
+        
+    protected:        
+        void _parseConfigSettings( ParamList& paramList );
+        
+        void _enumerateDevices();
+        
+        static const std::string iName;
+        
+        // Mac stuff
+		EventTargetRef mEventTargetRef;
+		WindowRef mWindow;
+        
+        // settings
+        bool mHideMouse;
+        bool mUseRepeat;
+
+		//! Used to know if we used up keyboard
+		bool keyboardUsed;
+
+		//! Used to know if we used up mouse
+		bool mouseUsed;
+		
+		//! HID Manager class handling devices other than keyboard/mouse
+		MacHIDManager *mHIDManager;
+    };
+}
+#endif
Index: /code/branches/rocket2/src/external/ois/mac/MacKeyboard.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/mac/MacKeyboard.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/mac/MacKeyboard.cpp	(revision 6952)
@@ -0,0 +1,467 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ 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/MacKeyboard.h"
+#include "mac/MacInputManager.h"
+#include "mac/MacHelpers.h"
+#include "OISException.h"
+#include "OISEvents.h"
+
+#include <Carbon/Carbon.h>
+
+#include <list>
+#include <string>
+
+const EventTypeSpec DownSpec[] = {{kEventClassKeyboard, kEventRawKeyDown},	//non - repeats
+							{kEventClassKeyboard, kEventRawKeyRepeat}}; //repeats
+const EventTypeSpec UpSpec = {kEventClassKeyboard, kEventRawKeyUp},
+			  ModSpec = {kEventClassKeyboard, kEventRawKeyModifiersChanged};
+
+const EventTypeSpec AllSpecs[] = {{kEventClassKeyboard, kEventRawKeyDown},
+						  {kEventClassKeyboard, kEventRawKeyRepeat},
+						  {kEventClassKeyboard, kEventRawKeyUp},
+						  {kEventClassKeyboard, kEventRawKeyModifiersChanged}};
+
+using namespace OIS;
+
+//-------------------------------------------------------------------//
+MacKeyboard::MacKeyboard( InputManager* creator, bool buffered, bool repeat )
+	: Keyboard(creator->inputSystemName(), buffered, 0, creator)
+{
+	keyDownEventRef = NULL;
+	keyUpEventRef = NULL;
+	keyModEventRef = NULL;
+	
+	useRepeat = repeat;
+
+	// Get a so-called "Univeral procedure pointer" for our callback
+	keyDownUPP = NewEventHandlerUPP( KeyDownWrapper );
+	keyUpUPP   = NewEventHandlerUPP( KeyUpWrapper );
+	keyModUPP  = NewEventHandlerUPP( KeyModWrapper );
+	
+	// populate the conversion map
+	populateKeyConversion();
+
+	static_cast<MacInputManager*>(mCreator)->_setKeyboardUsed(true);
+}
+
+//-------------------------------------------------------------------//
+MacKeyboard::~MacKeyboard()
+{
+	// Remove our handlers so that this instance doesn't get called
+	// after it is deleted
+	if (keyDownEventRef != NULL)
+		RemoveEventHandler(keyDownEventRef);
+		
+	if (keyUpEventRef != NULL)
+		RemoveEventHandler(keyUpEventRef);
+	
+	if (keyModEventRef != NULL)
+		RemoveEventHandler(keyModEventRef);
+	
+	// dispose of our UPPs
+	DisposeEventHandlerUPP(keyDownUPP);
+	DisposeEventHandlerUPP(keyUpUPP);
+	DisposeEventHandlerUPP(keyModUPP);
+
+	//Free the input managers keyboard
+	static_cast<MacInputManager*>(mCreator)->_setKeyboardUsed(false);
+}
+
+//-------------------------------------------------------------------//
+void MacKeyboard::_initialize()
+{
+	EventTargetRef event = ((MacInputManager*)mCreator)->_getEventTarget();
+
+	memset( &KeyBuffer, 0, 256 );
+	mModifiers = 0;
+	prevModMask = 0;
+	
+	// just in case this gets called after the first time.. better safe
+	if (keyDownEventRef != NULL)
+		RemoveEventHandler(keyDownEventRef);
+		
+	if (keyUpEventRef != NULL)
+		RemoveEventHandler(keyUpEventRef);
+		
+	if (keyModEventRef != NULL)
+		RemoveEventHandler(keyModEventRef);
+   
+	keyDownEventRef = NULL;
+	keyUpEventRef = NULL;
+	keyModEventRef = NULL;
+
+	OSStatus status;
+	// send both elements of downspec array... second index is for repeat events
+	if ( useRepeat )
+		status = InstallEventHandler( event, keyDownUPP, 2, DownSpec, this, &keyDownEventRef );
+	else
+		status = InstallEventHandler( event, keyDownUPP, 1, DownSpec, this, &keyDownEventRef );
+		
+	if (status != noErr)
+		OIS_EXCEPT( E_General, "MacKeyboard::_initialize >> Error loading KeyDown event handler" );
+
+	if (InstallEventHandler( event, keyUpUPP, 1, &UpSpec, this, &keyUpEventRef ) != noErr)
+		OIS_EXCEPT( E_General, "MacKeyboard::_initialize >> Error loading KeyUp event handler" );
+
+	if (InstallEventHandler( event, keyModUPP, 1, &ModSpec, this, &keyModEventRef ) != noErr )
+		OIS_EXCEPT( E_General, "MacKeyboard::_initialize >> Error loading Keymods event handler" );
+}
+
+//-------------------------------------------------------------------//
+bool MacKeyboard::isKeyDown( KeyCode key ) const
+{
+	return (bool)KeyBuffer[key];
+}
+
+
+//-------------------------------------------------------------------//
+void MacKeyboard::capture()
+{
+	// if not buffered just return, we update the unbuffered automatically
+	if ( !mBuffered || !mListener )
+		return;
+	
+	//If the mListener returns false, that means that we are probably deleted...
+	//send no more events and just leave as the this pointer is invalid now...
+	bool ret = true;
+	
+	// run through our event stack
+	eventStack::iterator cur_it;
+	
+	for (cur_it = pendingEvents.begin(); cur_it != pendingEvents.end(); cur_it++)
+	{
+		
+		if ( (*cur_it).Type == MAC_KEYDOWN || (*cur_it).Type == MAC_KEYREPEAT)
+			mListener->keyPressed( (*cur_it).Event );
+		else if ( (*cur_it).Type == MAC_KEYUP )
+			mListener->keyReleased( (*cur_it).Event );
+	}
+	
+	pendingEvents.clear();
+}
+
+
+//-------------------------------------------------------------------//
+std::string& MacKeyboard::getAsString( KeyCode key )
+{
+	getString = "";
+	
+	return getString;
+}
+
+//-------------------------------------------------------------------//
+void MacKeyboard::setBuffered( bool buffered )
+{
+	mBuffered = buffered;
+}
+
+#include <iostream>
+//-------------------------------------------------------------------//
+void MacKeyboard::_keyDownCallback( EventRef theEvent )
+{
+	
+	UInt32 virtualKey;
+	OSStatus status;
+	
+	unsigned int time = (unsigned int)GetEventTime(theEvent);
+	
+	status = GetEventParameter(theEvent,
+					'kcod',			// get it in virtual keycode
+					typeUInt32, NULL,	// desired return type
+					sizeof(UInt32), NULL, 	// bufsize
+					&virtualKey );
+	
+	KeyCode kc = keyConversion[virtualKey];
+
+	// record what kind of text we should pass the KeyEvent
+	UniChar text[10];
+	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)
+		{
+			// for each unicode char, send an event
+			stringsize--; // no termination char
+			for ( int i = 0; i < stringsize; i++ )
+			{
+				injectEvent( kc, time, MAC_KEYDOWN, (unsigned int)text[i] );
+			}
+		}
+	} 
+	else if (mTextMode == Ascii)
+	{
+		 
+		status = GetEventParameter( theEvent, 'kchr', typeChar, NULL, sizeof(char), NULL, &macChar );
+		injectEvent( kc, time, MAC_KEYDOWN, (unsigned int)macChar );
+	}
+	else
+	{
+		injectEvent( kc, time, MAC_KEYDOWN );
+	}
+}
+
+//-------------------------------------------------------------------//
+void MacKeyboard::_keyUpCallback( EventRef theEvent )
+{
+	UInt32 virtualKey;
+	
+	OSStatus status;
+	status = GetEventParameter( theEvent, kEventParamKeyCode, typeUInt32,
+								NULL, sizeof(UInt32), NULL, &virtualKey );
+	
+	KeyCode kc = keyConversion[virtualKey];
+	injectEvent( kc, (int)GetEventTime(theEvent), MAC_KEYUP );
+	
+}
+
+//-------------------------------------------------------------------//
+void MacKeyboard::_modChangeCallback( EventRef theEvent )
+{
+	UInt32 mods;
+	
+	OSStatus status;
+	status = GetEventParameter( theEvent, kEventParamKeyModifiers,
+								typeUInt32, NULL, sizeof(UInt32), NULL, &mods );
+	
+	// find the changed bit
+	UInt32 change = prevModMask ^ mods;
+	MacEventType newstate = ((change & prevModMask) > 0) ? MAC_KEYUP : MAC_KEYDOWN;
+	unsigned int time = (int)GetEventTime( theEvent );
+	
+	//cout << "preMask: " << hex << prevModMask << endl;
+	//cout << "ModMask: " << hex << mods << endl;
+	//cout << "Change:  " << hex << (change & prevModMask) << endl << endl;
+	
+	// TODO test modifiers on a full keyboard to check if different mask for left/right
+	switch (change)
+	{
+		case (shiftKey): // shift
+			mModifiers &= (newstate == MAC_KEYDOWN) ? Shift : ~Shift;
+			injectEvent( KC_LSHIFT, time, newstate );
+			//injectEvent( KC_RSHIFT, time, newstate );
+			break;
+			
+		case (optionKey): // option (alt)
+			mModifiers &= (newstate == MAC_KEYDOWN) ? Alt : -Alt;
+			//injectEvent( KC_RMENU, time, newstate );
+			injectEvent( KC_LMENU, time, newstate );
+			break;
+			
+		case (controlKey): // Ctrl
+			mModifiers += (newstate == MAC_KEYDOWN) ? Ctrl : -Ctrl;
+			//injectEvent( KC_RCONTROL, time, newstate );
+			injectEvent( KC_LCONTROL, time, newstate );
+			break;
+	
+		case (cmdKey): // apple
+			//injectEvent( KC_RWIN, time, newstate );
+			injectEvent( KC_LWIN, time, newstate );
+			break;
+	
+		case (kEventKeyModifierFnMask): // fn key
+			injectEvent( KC_APPS, time, newstate );
+			break;
+			
+		case (kEventKeyModifierNumLockMask): // numlock
+			injectEvent( KC_NUMLOCK, time, newstate );
+			break;
+			
+		case (alphaLock): // caps lock
+			injectEvent( KC_CAPITAL, time, newstate );
+			break;
+	}
+	
+	prevModMask = mods;
+}
+
+//-------------------------------------------------------------------//
+void MacKeyboard::injectEvent( KeyCode kc, unsigned int time, MacEventType type, unsigned int txt )
+{
+	// set to 1 if this is either a keydown or repeat
+	KeyBuffer[kc] = ( type == MAC_KEYUP ) ? 0 : 1;
+	
+	if ( mBuffered && mListener )
+		pendingEvents.push_back( MacKeyStackEvent( KeyEvent(this, kc, txt), type) );
+}
+
+
+//-------------------------------------------------------------------//
+void MacKeyboard::copyKeyStates( char keys[256] ) const
+{
+	memcpy( keys, KeyBuffer, 256 );
+}
+
+
+
+//-------------------------------------------------------------------//
+void MacKeyboard::populateKeyConversion()
+{
+	// TODO finish the key mapping
+	
+	// Virtual Key Map to KeyCode
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x12, KC_1));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x13, KC_2));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x14, KC_3));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x15, KC_4));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x17, KC_5));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x16, KC_6));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x1A, KC_7));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x1C, KC_8));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x19, KC_9));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x1D, KC_0));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x33, KC_BACK));  // might be wrong
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x1B, KC_MINUS));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x18, KC_EQUALS));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x31, KC_SPACE));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x2B, KC_COMMA));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x2F, KC_PERIOD));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x2A, KC_BACKSLASH));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x2C, KC_SLASH));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x21, KC_LBRACKET));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x1E, KC_RBRACKET));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x35, KC_ESCAPE));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x39, KC_CAPITAL));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x30, KC_TAB));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x24, KC_RETURN));  // double check return/enter
+	
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_colon, KC_COLON));	 // no colon?
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x29, KC_SEMICOLON));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x27, KC_APOSTROPHE));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x32, KC_GRAVE));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x0B, KC_B));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x00, KC_A));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x08, KC_C));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x02, KC_D));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x0E, KC_E));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x03, KC_F));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x05, KC_G));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x04, KC_H));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x22, KC_I));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x26, KC_J));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x28, KC_K));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x25, KC_L));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x2E, KC_M));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x2D, KC_N));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x1F, KC_O));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x23, KC_P));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x0C, KC_Q));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x0F, KC_R));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x01, KC_S));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x11, KC_T));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x20, KC_U));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x09, KC_V));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x0D, KC_W));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x07, KC_X));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x10, KC_Y));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x06, KC_Z));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x7A, KC_F1));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x78, KC_F2));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x63, KC_F3));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x76, KC_F4));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x60, KC_F5));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x61, KC_F6));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x62, KC_F7));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x64, KC_F8));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x65, KC_F9));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x6D, KC_F10));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x67, KC_F11));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x6F, KC_F12));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x69, KC_F13));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x6B, KC_F14));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x71, KC_F15));
+	
+	//Keypad
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x52, KC_NUMPAD0));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x53, KC_NUMPAD1));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x54, KC_NUMPAD2));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x55, KC_NUMPAD3));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x56, KC_NUMPAD4));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x57, KC_NUMPAD5));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x58, KC_NUMPAD6));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x59, KC_NUMPAD7));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x5B, KC_NUMPAD8));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x5C, KC_NUMPAD9));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x45, KC_ADD));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x4E, KC_SUBTRACT));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x41, KC_DECIMAL));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x51, KC_NUMPADEQUALS));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x4B, KC_DIVIDE));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x43, KC_MULTIPLY));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x4C, KC_NUMPADENTER));
+	
+	//Keypad with numlock off
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x73, KC_NUMPAD7));  // not sure of these
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Up, KC_NUMPAD8)); // check on a non-laptop
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Page_Up, KC_NUMPAD9));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Left, KC_NUMPAD4));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Begin, KC_NUMPAD5));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Right, KC_NUMPAD6));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_End, KC_NUMPAD1));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Down, KC_NUMPAD2));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Page_Down, KC_NUMPAD3));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Insert, KC_NUMPAD0));
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_KP_Delete, KC_DECIMAL));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x7E, KC_UP));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x7D, KC_DOWN));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x7B, KC_LEFT));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x7C, KC_RIGHT));
+	
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x74, KC_PGUP));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x79, KC_PGDOWN));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x73, KC_HOME));
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x77, KC_END));
+	
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_Print, KC_SYSRQ));		// ??
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_Scroll_Lock, KC_SCROLL)); // ??
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_Pause, KC_PAUSE));		// ??
+	
+	
+	//keyConversion.insert(VirtualtoOIS_KeyMap::value_type(XK_Insert, KC_INSERT));	  // ??
+	keyConversion.insert(VirtualtoOIS_KeyMap::value_type(0x75, KC_DELETE)); // del under help key?
+}
+
+
+
+
Index: /code/branches/rocket2/src/external/ois/mac/MacKeyboard.h
===================================================================
--- /code/branches/rocket2/src/external/ois/mac/MacKeyboard.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/mac/MacKeyboard.h	(revision 6952)
@@ -0,0 +1,102 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ 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_MacKeyboard_H
+#define OIS_MacKeyboard_H
+
+#include "OISKeyboard.h"
+#include "mac/MacHelpers.h"
+#include "mac/MacPrereqs.h"
+
+#include <Carbon/Carbon.h>
+
+namespace OIS
+{
+    
+    class MacKeyboard : public Keyboard
+    {
+    public:
+        MacKeyboard( InputManager* creator, bool buffered, bool repeat );
+        virtual ~MacKeyboard();
+        
+        // Sets buffered mode
+        virtual void setBuffered( bool buffered );
+        
+        // unbuffered keydown check
+        virtual bool isKeyDown( KeyCode key ) const;
+        
+        // This will send listener events if buffered is on.
+        // Note that in the mac implementation, unbuffered input is
+        // automatically updated without calling this.
+        virtual void capture();
+        
+        // Copies the current key buffer
+        virtual void copyKeyStates( char keys[256] ) const;
+        
+        // Returns a description of the given key
+        virtual std::string& getAsString( KeyCode key );
+        
+        virtual Interface* queryInterface( Interface::IType type ) { return 0; }
+        
+        
+        // Public but reserved for internal use:
+        virtual void _initialize();
+        void _keyDownCallback( EventRef theEvent );
+        void _keyUpCallback( EventRef theEvent );
+        void _modChangeCallback( EventRef theEvent );
+        
+
+    protected:
+        // just to get this out of the way
+        void populateKeyConversion();
+        
+        // updates the keybuffer and optionally the eventStack
+        void injectEvent(KeyCode kc, unsigned int time, MacEventType type, unsigned int txt = 0 );
+                
+        typedef std::map<UInt32, KeyCode> VirtualtoOIS_KeyMap;
+        VirtualtoOIS_KeyMap keyConversion;
+        
+        std::string getString;
+        
+        char KeyBuffer[256];
+        UInt32 prevModMask;
+        
+        
+        // "universal procedure pointers" - required reference for callbacks
+        EventHandlerUPP keyDownUPP;
+        EventHandlerUPP keyUpUPP;
+        EventHandlerUPP keyModUPP;
+        
+        // so we can delete the handlers on destruction
+        EventHandlerRef keyDownEventRef;
+        EventHandlerRef keyUpEventRef;
+        EventHandlerRef keyModEventRef;
+        
+        // buffered events, fifo stack
+        typedef std::list<MacKeyStackEvent> eventStack;
+        eventStack pendingEvents;
+        
+        bool useRepeat;
+        
+    };
+}
+#endif
Index: /code/branches/rocket2/src/external/ois/mac/MacMouse.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/mac/MacMouse.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/mac/MacMouse.cpp	(revision 6952)
@@ -0,0 +1,346 @@
+#include "mac/MacMouse.h"
+#include "mac/MacInputManager.h"
+#include "mac/MacHelpers.h"
+#include "OISException.h"
+#include "OISEvents.h"
+
+#include <Carbon/Carbon.h>
+
+#include <list>
+
+#include <iostream>
+
+using namespace OIS;
+
+//Events we subscribe to and remove from queue
+const EventTypeSpec mouseEvents[] = {
+	{ kEventClassMouse, kEventMouseDown },
+	{ kEventClassMouse, kEventMouseUp },
+	{ kEventClassMouse, kEventMouseMoved },
+	{ kEventClassMouse, kEventMouseDragged },
+	{ kEventClassMouse, kEventMouseWheelMoved }		
+};
+
+const EventTypeSpec WinFocusAcquired [] = {{kEventClassApplication, kEventAppDeactivated}};
+
+//-------------------------------------------------------------------//
+MacMouse::MacMouse( InputManager* creator, bool buffered )
+	: Mouse(creator->inputSystemName(), buffered, 0, creator), mNeedsToRegainFocus( false )
+{
+    mouseEventRef = NULL;
+	mWindowFocusHandler = NULL;
+
+    // Get a "Univeral procedure pointer" for our callback
+    mouseUPP = NewEventHandlerUPP(MouseWrapper);
+	mWindowFocusListener = NewEventHandlerUPP(WindowFocusChanged);
+
+	static_cast<MacInputManager*>(mCreator)->_setMouseUsed(true);
+}
+
+MacMouse::~MacMouse()
+{
+    if(mouseEventRef != NULL)
+		RemoveEventHandler(mouseEventRef);
+
+	if(mWindowFocusHandler != NULL)
+		RemoveEventHandler(mWindowFocusHandler);
+	
+	DisposeEventHandlerUPP(mouseUPP);
+	DisposeEventHandlerUPP(mWindowFocusListener);
+	
+	// Restore Mouse
+	CGAssociateMouseAndMouseCursorPosition(TRUE);
+	CGDisplayShowCursor(kCGDirectMainDisplay);
+
+	static_cast<MacInputManager*>(mCreator)->_setMouseUsed(false);
+}
+
+void MacMouse::_initialize()
+{
+	mState.clear();
+	mTempState.clear();
+	mMouseWarped = false;
+	
+	// Hide OS Mouse
+ 	CGDisplayHideCursor(kCGDirectMainDisplay);
+
+	MacInputManager* im = static_cast<MacInputManager*>(mCreator);
+	WindowRef win = im->_getWindow();
+	
+	if(win)
+	{
+		Rect clipRect = {0.0f, 0.0f, 0.0f, 0.0f};
+		GetWindowBounds(win, kWindowContentRgn, &clipRect);
+		
+		CGPoint warpPoint;
+		warpPoint.x = ((clipRect.right - clipRect.left) / 2) + clipRect.left;
+		warpPoint.y = ((clipRect.bottom - clipRect.top) / 2) + clipRect.top;
+		CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, warpPoint); //Place at display origin
+		
+		mMouseWarped = true;
+	}
+
+	//Now that mouse is warped, start listening for events
+	EventTargetRef event = ((MacInputManager*)mCreator)->_getEventTarget();
+    
+	if(mouseEventRef != NULL)
+		RemoveEventHandler(mouseEventRef);
+		
+	if(mWindowFocusHandler != NULL)
+		RemoveEventHandler(mWindowFocusHandler);
+
+	mouseEventRef = mWindowFocusHandler = NULL;
+
+	if(InstallEventHandler(event, mouseUPP, GetEventTypeCount(mouseEvents), mouseEvents, this, &mouseEventRef) != noErr)
+		OIS_EXCEPT( E_General, "MacMouse::_initialize >> Error loading Mouse event handler" );
+
+	if(InstallEventHandler(event, mWindowFocusListener, GetEventTypeCount(WinFocusAcquired), WinFocusAcquired, this, &mWindowFocusHandler) != noErr)
+		OIS_EXCEPT( E_General, "MacMouse::_initialize >> Error loading Mouse event handler" );		
+
+	//Lock OS Mouse movement
+	mNeedsToRegainFocus = false;
+	CGAssociateMouseAndMouseCursorPosition(FALSE);
+}
+
+OSStatus MacMouse::WindowFocusChanged(EventHandlerCallRef nextHandler, EventRef event, void* macMouse)
+{
+	//std::cout << "Window Focus Changed\n";
+
+	MacMouse* _this = static_cast<MacMouse*>(macMouse);
+    if (_this)
+	{
+		_this->mNeedsToRegainFocus = true;
+		CGAssociateMouseAndMouseCursorPosition(TRUE);
+
+        // propagate the event down the chain
+        return CallNextEventHandler(nextHandler, event);
+    }
+    else
+        OIS_EXCEPT(E_General, "MouseWrapper >> Being called by something other than our event handler!");
+}
+
+void MacMouse::setBuffered( bool buffered )
+{
+	mBuffered = buffered;
+}
+
+void MacMouse::capture()
+{
+	mState.X.rel = 0;
+	mState.Y.rel = 0;
+	mState.Z.rel = 0;
+	    
+	if(mTempState.X.rel || mTempState.Y.rel || mTempState.Z.rel)
+	{
+		//printf("%i %i %i\n\n", mTempState.X.rel, mTempState.Y.rel, mTempState.Z.rel);
+
+		//Set new relative motion values
+		mState.X.rel = mTempState.X.rel;
+		mState.Y.rel = mTempState.Y.rel;
+		mState.Z.rel = mTempState.Z.rel;
+		
+		//Update absolute position
+		mState.X.abs += mTempState.X.rel;
+		mState.Y.abs += mTempState.Y.rel;
+		
+		if(mState.X.abs > mState.width)
+			mState.X.abs = mState.width;
+		else if(mState.X.abs < 0)
+			mState.X.abs = 0;
+
+		if(mState.Y.abs > mState.height)
+			mState.Y.abs = mState.height;
+		else if(mState.Y.abs < 0)
+			mState.Y.abs = 0;
+			
+		mState.Z.abs += mTempState.Z.rel;
+		
+		//Fire off event
+		if(mListener && mBuffered)
+			mListener->mouseMoved(MouseEvent(this, mState));
+	}
+
+	mTempState.clear();
+}
+
+void MacMouse::_mouseCallback( EventRef theEvent )
+{
+	OSStatus result = eventNotHandledErr;
+    UInt32 kind = GetEventKind (theEvent);
+
+	switch(kind)
+	{
+		case kEventMouseDragged:
+		case kEventMouseMoved:
+		{
+			//HIPoint location = {0.0f, 0.0f};
+			HIPoint delta = {0.0f, 0.0f};
+			//Rect clipRect = {0.0f, 0.0f, 0.0f, 0.0f};
+			
+			if(mNeedsToRegainFocus)
+				break;
+
+			// Capture the parameters
+			// TODO: Look into HIViewNewTrackingArea
+			//GetEventParameter(theEvent, kEventParamMouseLocation, typeHIPoint, NULL, sizeof(HIPoint), NULL, &location);
+			GetEventParameter(theEvent, kEventParamMouseDelta, typeHIPoint, NULL, sizeof(HIPoint), NULL, &delta);
+			
+			// Mouse X and Y are the position on the screen, 
+			// startng from top-left at 0,0 caps at full monitor resolution
+			
+			// If we have a window we need to return adjusted coordinates
+			// If not, just use raw coordinates - only do this if showing OS mouse
+			//MacInputManager* im = static_cast<MacInputManager*>(mCreator);
+			//WindowRef win = im->_getWindow();
+			
+			//if(win != NULL)
+			//{
+			//	GetWindowBounds(win, kWindowContentRgn, &clipRect);
+			//}
+            //else
+            //{
+            //    clipRect.right = mState.width;
+            //    clipRect.bottom = mState.height;
+            //}
+                
+            // clip the mouse, absolute positioning
+            //if (location.x <= clipRect.left)
+			//	mState.X.abs = 0;
+			//else if(location.x >= clipRect.right)
+			//	mState.X.abs = clipRect.right - clipRect.left;
+			//else
+			//	mState.X.abs = location.x - clipRect.left;
+			
+			//if (location.y <= clipRect.top)
+			//	mState.Y.abs = 0;
+			//else if(location.y >= clipRect.bottom)
+			//	mState.Y.abs = clipRect.bottom - clipRect.top;
+			//else
+			//	mState.Y.abs = location.y - clipRect.top;
+			
+			// relative positioning
+			if(!mMouseWarped)
+			{
+				mTempState.X.rel += delta.x;
+				mTempState.Y.rel += delta.y;
+			}
+			
+			mMouseWarped = false;
+
+			break;
+		}
+		case kEventMouseDown:
+		{
+			EventMouseButton button = 0;
+			int mouseButton = 3;
+			UInt32 modifiers = 0;
+			
+			if(mNeedsToRegainFocus)
+				break;
+
+			// Capture parameters
+			GetEventParameter(theEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(EventMouseButton), NULL, &button);
+			GetEventParameter(theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
+			
+			if((button == kEventMouseButtonTertiary) || ((button == kEventMouseButtonPrimary) && (modifiers & optionKey)))
+			{
+				mouseButton = 2;
+				mState.buttons |= 1 << mouseButton;
+			}
+            else if((button == kEventMouseButtonSecondary) || ((button == kEventMouseButtonPrimary) && (modifiers & controlKey)))
+            {	
+                mouseButton = 1;
+                mState.buttons |= 1 << mouseButton;
+            }
+            else if(button == kEventMouseButtonPrimary)
+            {
+                mouseButton = 0;
+                mState.buttons |= 1 << mouseButton;
+            }
+
+            if( mListener && mBuffered )
+                mListener->mousePressed( MouseEvent( this, mState ), (MouseButtonID)mouseButton );
+
+            break;
+		}
+		case kEventMouseUp:
+		{
+			EventMouseButton button = 0;
+			int mouseButton = 3;
+			UInt32 modifiers = 0;
+			
+			if(mNeedsToRegainFocus)
+			{
+				mNeedsToRegainFocus = false;
+				CGAssociateMouseAndMouseCursorPosition(false);
+				
+				MacInputManager* im = static_cast<MacInputManager*>(mCreator);
+				WindowRef win = im->_getWindow();
+				
+				if(win)
+				{
+					Rect clipRect = {0.0f, 0.0f, 0.0f, 0.0f};
+					GetWindowBounds(win, kWindowContentRgn, &clipRect);
+					
+					CGPoint warpPoint;
+					warpPoint.x = ((clipRect.right - clipRect.left) / 2) + clipRect.left;
+					warpPoint.y = ((clipRect.bottom - clipRect.top) / 2) + clipRect.top;
+					CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, warpPoint); //Place at display origin
+					
+					CGDisplayHideCursor(kCGDirectMainDisplay);
+					
+					mMouseWarped = true;
+				}
+				
+				//Once we regain focus, we do not really know what state all the buttons are in - for now, set to not pressed. todo, check current status
+				//compare against old status, and send off any needed events
+				mState.buttons = 0;
+				
+				break;
+			}
+			
+			// Capture parameters
+			GetEventParameter(theEvent, kEventParamMouseButton, typeMouseButton, NULL, sizeof(EventMouseButton), NULL, &button);
+			GetEventParameter(theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifiers);
+			
+			if ((button == kEventMouseButtonTertiary) || ((button == kEventMouseButtonPrimary) && (modifiers & optionKey)))
+			{
+				mouseButton = 2;
+				mState.buttons &= ~(1 << mouseButton);
+			}
+            else if ((button == kEventMouseButtonSecondary) || ((button == kEventMouseButtonPrimary) && (modifiers & controlKey)))
+            {	
+                mouseButton = 1;
+                mState.buttons &= ~(1 << mouseButton);
+            }
+            else if (button == kEventMouseButtonPrimary)
+            {
+                mouseButton = 0;
+                mState.buttons &= ~(1 << mouseButton);
+            }
+
+            if( mListener && mBuffered )
+                mListener->mouseReleased( MouseEvent( this, mState ), (MouseButtonID)mouseButton );
+
+            break;
+		}
+		case kEventMouseWheelMoved:
+		{
+			SInt32 wheelDelta = 0;
+			EventMouseWheelAxis	wheelAxis = 0; 
+
+			// Capture parameters
+			GetEventParameter(theEvent, kEventParamMouseWheelAxis, typeMouseWheelAxis, NULL, sizeof(EventMouseWheelAxis), NULL, &wheelAxis);
+			GetEventParameter(theEvent, kEventParamMouseWheelDelta, typeSInt32, NULL, sizeof(SInt32), NULL, &wheelDelta);
+			
+			// If the Y axis of the wheel changed, then update the Z
+			// Does OIS care about the X wheel axis?
+			if(wheelAxis == kEventMouseWheelAxisY)
+				mTempState.Z.rel += (wheelDelta * 60);
+
+            break;
+		}
+		default:
+			break;
+	}    
+}
Index: /code/branches/rocket2/src/external/ois/mac/MacMouse.h
===================================================================
--- /code/branches/rocket2/src/external/ois/mac/MacMouse.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/mac/MacMouse.h	(revision 6952)
@@ -0,0 +1,51 @@
+#ifndef OIS_MacMouse_H
+#define OIS_MacMouse_H
+
+#include "OISMouse.h"
+#include "mac/MacHelpers.h"
+#include "mac/MacPrereqs.h"
+
+#include <Carbon/Carbon.h>
+
+namespace OIS
+{
+	class MacMouse : public Mouse
+    {
+	public:
+		MacMouse( InputManager* creator, bool buffered );
+		virtual ~MacMouse();
+		
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+
+		/** @copydoc Object::capture */
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType type) {return 0;}
+
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+        
+	public:
+        void _mouseCallback( EventRef theEvent );
+
+	protected:
+		static OSStatus WindowFocusChanged(EventHandlerCallRef nextHandler, EventRef event, void* macMouse);
+        
+        // "universal procedure pointers" - required reference for callbacks
+		EventHandlerUPP mouseUPP;
+		EventHandlerRef mouseEventRef;
+		
+		EventHandlerUPP mWindowFocusListener;
+		EventHandlerRef mWindowFocusHandler;
+		
+		bool mNeedsToRegainFocus;
+		bool mMouseWarped;
+		
+		MouseState mTempState;
+	};
+}
+
+
+#endif // OIS_MacMouse_H
Index: /code/branches/rocket2/src/external/ois/mac/MacPrereqs.h
===================================================================
--- /code/branches/rocket2/src/external/ois/mac/MacPrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/mac/MacPrereqs.h	(revision 6952)
@@ -0,0 +1,57 @@
+/*
+ The zlib/libpng License
+ 
+ Copyright (c) 2006 Chris Snyder 
+ 
+ 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_MacPrereqs_H
+#define OIS_MacPrereqs_H
+
+#include <string>
+#include <list>
+#include <CoreFoundation/CoreFoundation.h>
+
+namespace OIS
+{
+    class MacInputManager;
+	class MacHIDManager;
+	class MacMouse;
+    class MacKeyboard;
+
+	/** 
+		Simple wrapper class for CFString which will create a valid CFString and retain ownership until class instance is outof scope
+		To Access the CFStringRef instance, simply cast to void*, pass into a function expecting a void* CFStringRef object, or access via cf_str() method
+	*/
+	class OIS_CFString
+	{
+	public:
+		OIS_CFString() { m_StringRef = CFStringCreateWithCString(NULL, "", kCFStringEncodingUTF8); }
+		OIS_CFString(const char* c_str) { m_StringRef = CFStringCreateWithCString(NULL, c_str, kCFStringEncodingUTF8); }
+		OIS_CFString(const std::string &s_str) { m_StringRef = CFStringCreateWithCString(NULL, s_str.c_str(), kCFStringEncodingUTF8); }
+		~OIS_CFString() { CFRelease(m_StringRef); }
+
+		//Allow this class to be autoconverted to base class of StringRef (void*)
+		operator void*() { return (void*)m_StringRef; }
+		CFStringRef cf_str() { return m_StringRef; }
+	
+	private:
+		CFStringRef m_StringRef;
+	};
+}
+#endif
Index: /code/branches/rocket2/src/external/ois/win32/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/ois/win32/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/win32/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,16 @@
+ADD_SOURCE_FILES(OIS_FILES
+  Win32ForceFeedback.h
+  Win32InputManager.h
+  Win32JoyStick.h
+  Win32KeyBoard.h
+  Win32Mouse.h
+  Win32Prereqs.h
+
+COMPILATION_BEGIN OISWin32Compilation.cpp
+  Win32ForceFeedback.cpp
+  Win32InputManager.cpp
+  Win32JoyStick.cpp
+  Win32KeyBoard.cpp
+  Win32Mouse.cpp
+COMPILATION_END
+)
Index: /code/branches/rocket2/src/external/ois/win32/Win32ForceFeedback.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/win32/Win32ForceFeedback.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/win32/Win32ForceFeedback.cpp	(revision 6952)
@@ -0,0 +1,543 @@
+/*
+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 "Win32/Win32ForceFeedback.h"
+#include "OISException.h"
+#include <Math.h>
+
+// 0 = No trace; 1 = Important traces; 2 = Debug traces
+#define OIS_WIN32_JOYFF_DEBUG 0
+
+#if (defined (_DEBUG) || defined(OIS_WIN32_JOYFF_DEBUG))
+  #include <iostream>
+  #include <sstream>
+  using namespace std;
+#endif
+
+using namespace OIS;
+
+//--------------------------------------------------------------//
+Win32ForceFeedback::Win32ForceFeedback(IDirectInputDevice8* pDIJoy, const DIDEVCAPS* pDIJoyCaps) :
+  mHandles(0), mJoyStick(pDIJoy), mFFAxes(0), mpDIJoyCaps(pDIJoyCaps)
+{
+#if (OIS_WIN32_JOYFF_DEBUG > 0)
+  cout << "FFSamplePeriod      : " << mpDIJoyCaps->dwFFSamplePeriod << " mu-s, "
+	   << "FFMinTimeResolution : " << mpDIJoyCaps->dwFFMinTimeResolution << " mu-s,"
+	   << "" << endl;
+#endif
+}
+
+//--------------------------------------------------------------//
+Win32ForceFeedback::~Win32ForceFeedback()
+{
+	//Get the effect - if it exists
+	for(EffectList::iterator i = mEffectList.begin(); i != mEffectList.end(); ++i )
+	{
+		LPDIRECTINPUTEFFECT dxEffect = i->second;
+		if( dxEffect )
+		{
+			dxEffect->Unload();
+			dxEffect->Release();
+		}
+	}
+
+	mEffectList.clear();
+}
+
+//--------------------------------------------------------------//
+short Win32ForceFeedback::getFFAxesNumber()
+{
+	return mFFAxes;
+}
+
+//--------------------------------------------------------------//
+unsigned short Win32ForceFeedback::getFFMemoryLoad()
+{
+    DIPROPDWORD dipdw;  // DIPROPDWORD contains a DIPROPHEADER structure. 
+	dipdw.diph.dwSize       = sizeof(DIPROPDWORD); 
+	dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER); 
+	dipdw.diph.dwObj        = 0; // device property 
+	dipdw.diph.dwHow        = DIPH_DEVICE;
+	dipdw.dwData            = 0; // In case of any error.
+
+	const HRESULT hr = mJoyStick->GetProperty(DIPROP_FFLOAD, &dipdw.diph);
+	if(FAILED(hr))
+	{
+	    if (hr == DIERR_NOTEXCLUSIVEACQUIRED)
+		    OIS_EXCEPT(E_General, "Can't query FF memory load as device was not acquired in exclusive mode");
+		else
+		    OIS_EXCEPT(E_General, "Unknown error querying FF memory load ->..");
+	}
+
+	return (unsigned short)dipdw.dwData;
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::upload( const Effect* effect )
+{
+	switch( effect->force )
+	{
+		case OIS::Effect::ConstantForce: _updateConstantEffect(effect);	break;
+		case OIS::Effect::RampForce: _updateRampEffect(effect);	break;
+		case OIS::Effect::PeriodicForce: _updatePeriodicEffect(effect);	break;
+		case OIS::Effect::ConditionalForce:	_updateConditionalEffect(effect); break;
+		//case OIS::Effect::CustomForce: _updateCustomEffect(effect); break;
+		default: OIS_EXCEPT(E_NotImplemented, "Requested Force not Implemented yet, sorry!"); break;
+	}
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::modify( const Effect* eff )
+{
+	//Modifying is essentially the same as an upload, so, just reuse that function
+	upload(eff);
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::remove( const Effect* eff )
+{
+	//Get the effect - if it exists
+	EffectList::iterator i = mEffectList.find(eff->_handle);
+	if( i != mEffectList.end() )
+	{
+		LPDIRECTINPUTEFFECT dxEffect = i->second;
+		if( dxEffect )
+		{
+			dxEffect->Stop();
+			//We care about the return value - as the effect might not
+			//have been unlaoded
+			if( SUCCEEDED(dxEffect->Unload()) )
+			{
+			    dxEffect->Release();
+				mEffectList.erase(i);
+			}
+		}
+		else
+			mEffectList.erase(i);
+	}
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::setMasterGain( float level )
+{
+	//Between 0 - 10,000
+	int gain_level = (int)(10000.0f * level);
+
+	if( gain_level > 10000 )
+		gain_level = 10000;
+	else if( gain_level < 0 )
+		gain_level = 0;
+
+	DIPROPDWORD DIPropGain;
+	DIPropGain.diph.dwSize       = sizeof(DIPropGain);
+	DIPropGain.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+	DIPropGain.diph.dwObj        = 0;
+	DIPropGain.diph.dwHow        = DIPH_DEVICE;
+	DIPropGain.dwData            = gain_level;
+
+#if (OIS_WIN32_JOYFF_DEBUG > 0)
+	cout << "Win32ForceFeedback("<< mJoyStick << ") : Setting master gain to " 
+		 << level << " => " << DIPropGain.dwData << endl;
+#endif
+
+	const HRESULT hr = mJoyStick->SetProperty(DIPROP_FFGAIN, &DIPropGain.diph);
+
+#if defined (_DEBUG)
+	if(FAILED(hr))
+	    cout << "Failed to change master gain" << endl;
+#endif
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::setAutoCenterMode( bool auto_on )
+{
+	DIPROPDWORD DIPropAutoCenter;
+	DIPropAutoCenter.diph.dwSize       = sizeof(DIPropAutoCenter);
+	DIPropAutoCenter.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+	DIPropAutoCenter.diph.dwObj        = 0;
+	DIPropAutoCenter.diph.dwHow        = DIPH_DEVICE;
+	DIPropAutoCenter.dwData            = (auto_on ? DIPROPAUTOCENTER_ON : DIPROPAUTOCENTER_OFF);
+
+#if (OIS_WIN32_JOYFF_DEBUG > 0)
+	cout << "Win32ForceFeedback("<< mJoyStick << ") : Setting auto-center mode to " 
+		 << auto_on << " => " << DIPropAutoCenter.dwData << endl;
+#endif
+
+	const HRESULT hr = mJoyStick->SetProperty(DIPROP_AUTOCENTER, &DIPropAutoCenter.diph);
+
+#if defined (_DEBUG)
+	if(FAILED(hr))
+	    cout << "Failed to change auto-center mode" << endl;
+#endif
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_updateConstantEffect( const Effect* effect )
+{
+	ConstantEffect *eff = static_cast<ConstantEffect*>(effect->getForceEffect());
+
+	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
+	LONG            rglDirection[2] = { 0, 0 };
+	DIENVELOPE      diEnvelope;
+	DICONSTANTFORCE cf;
+	DIEFFECT        diEffect;
+
+	//Currently only support 1 axis
+	//if( effect->getNumAxes() == 1 )
+	cf.lMagnitude = eff->level;
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	cout << "  Level : " << eff->level
+		 << " => " << cf.lMagnitude << endl;
+#endif
+
+	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICONSTANTFORCE), &cf, effect, &eff->envelope);
+	_upload(GUID_ConstantForce, &diEffect, effect);
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_updateRampEffect( const Effect* effect )
+{
+	RampEffect *eff = static_cast<RampEffect*>(effect->getForceEffect());
+
+	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
+	LONG            rglDirection[2] = { 0, 0 };
+	DIENVELOPE      diEnvelope;
+	DIRAMPFORCE     rf;
+	DIEFFECT        diEffect;
+
+	//Currently only support 1 axis
+	rf.lStart = eff->startLevel;
+	rf.lEnd = eff->endLevel;
+
+	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DIRAMPFORCE), &rf, effect, &eff->envelope );
+	_upload(GUID_RampForce, &diEffect, effect);
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_updatePeriodicEffect( const Effect* effect )
+{
+	PeriodicEffect *eff = static_cast<PeriodicEffect*>(effect->getForceEffect());
+
+	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
+	LONG            rglDirection[2] = { 0, 0 };
+	DIENVELOPE      diEnvelope;
+	DIPERIODIC      pf;
+	DIEFFECT        diEffect;
+
+	//Currently only support 1 axis
+	pf.dwMagnitude = eff->magnitude;
+	pf.lOffset = eff->offset;
+	pf.dwPhase = eff->phase;
+	pf.dwPeriod = eff->period;
+
+	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DIPERIODIC), &pf, effect, &eff->envelope );
+
+	switch( effect->type )
+	{
+	case OIS::Effect::Square: _upload(GUID_Square, &diEffect, effect); break;
+	case OIS::Effect::Triangle: _upload(GUID_Triangle, &diEffect, effect); break;
+	case OIS::Effect::Sine: _upload(GUID_Sine, &diEffect, effect); break;
+	case OIS::Effect::SawToothUp: _upload(GUID_SawtoothUp, &diEffect, effect); break;
+	case OIS::Effect::SawToothDown:	_upload(GUID_SawtoothDown, &diEffect, effect); break;
+	default: break;
+	}
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_updateConditionalEffect( const Effect* effect )
+{
+	ConditionalEffect *eff = static_cast<ConditionalEffect*>(effect->getForceEffect());
+
+	DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
+	LONG            rglDirection[2] = { 0, 0 };
+	DIENVELOPE      diEnvelope;
+	DICONDITION     cf;
+	DIEFFECT        diEffect;
+
+	cf.lOffset = eff->deadband;
+	cf.lPositiveCoefficient = eff->rightCoeff;
+	cf.lNegativeCoefficient = eff->leftCoeff;
+	cf.dwPositiveSaturation = eff->rightSaturation;
+	cf.dwNegativeSaturation = eff->leftSaturation;
+	cf.lDeadBand = eff->deadband;
+
+	_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICONDITION), &cf, effect, 0 );
+
+	switch( effect->type )
+	{
+	case OIS::Effect::Friction:	_upload(GUID_Friction, &diEffect, effect); break;
+	case OIS::Effect::Damper: _upload(GUID_Damper, &diEffect, effect); break;
+	case OIS::Effect::Inertia: _upload(GUID_Inertia, &diEffect, effect); break;
+	case OIS::Effect::Spring: _upload(GUID_Spring, &diEffect, effect); break;
+	default: break;
+	}
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_updateCustomEffect( const Effect* /*effect*/ )
+{
+    //CustomEffect *eff = static_cast<CustomEffect*>(effect->getForceEffect());
+    //
+	//DWORD           rgdwAxes[2]     = { DIJOFS_X, DIJOFS_Y };
+	//LONG            rglDirection[2] = { 0, 0 };
+	//DIENVELOPE      diEnvelope;
+	//DICUSTOMFORCE cf;
+	//DIEFFECT        diEffect;
+	//cf.cChannels = 0;
+	//cf.dwSamplePeriod = 0;
+	//cf.cSamples = 0;
+	//cf.rglForceData = 0;
+	//_setCommonProperties(&diEffect, rgdwAxes, rglDirection, &diEnvelope, sizeof(DICUSTOMFORCE), &cf, effect, &eff->envelope);
+	//_upload(GUID_CustomForce, &diEffect, effect);
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_setCommonProperties(
+		DIEFFECT* diEffect, DWORD* rgdwAxes,
+		LONG* rglDirection, DIENVELOPE* diEnvelope, DWORD struct_size,
+		LPVOID struct_type, const Effect* effect, const Envelope* envelope )
+{
+	ZeroMemory(diEffect, sizeof(DIEFFECT));
+
+	diEffect->dwSize                  = sizeof(DIEFFECT);
+	diEffect->dwFlags                 = DIEFF_CARTESIAN | DIEFF_OBJECTOFFSETS;
+	diEffect->dwGain                  = DI_FFNOMINALMAX;
+
+	diEffect->dwTriggerButton         = DIEB_NOTRIGGER; // effect->trigger_button; // TODO: Conversion
+	diEffect->dwTriggerRepeatInterval = effect->trigger_interval;
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	cout << "  Trigger :" << endl
+		 << "    Button   : " << effect->trigger_button 
+		 << " => " << diEffect->dwTriggerButton << endl
+		 << "    Interval : " << effect->trigger_interval 
+		 << " => " << diEffect->dwTriggerRepeatInterval << endl;
+#endif
+
+	diEffect->cAxes                   = 1; // effect->getNumAxes();
+	diEffect->rgdwAxes                = rgdwAxes;
+
+	diEffect->rglDirection            = rglDirection; // TODO: conversion from effect->direction
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	cout << "  Direction : " << Effect::getDirectionName(effect->direction)
+		 << " => {";
+	for (int iDir=0; iDir < (int)diEffect->cAxes; iDir++)
+	  cout << " " << diEffect->rglDirection[iDir];
+	cout << "}" << endl;
+#endif
+
+	if (diEnvelope && envelope && envelope->isUsed())
+	{
+	    diEnvelope->dwSize = sizeof(DIENVELOPE);
+	    diEnvelope->dwAttackLevel = envelope->attackLevel;
+	    diEnvelope->dwAttackTime  = envelope->attackLength;
+	    diEnvelope->dwFadeLevel   = envelope->fadeLevel;
+	    diEnvelope->dwFadeTime    = envelope->fadeLength;
+	    diEffect->lpEnvelope = diEnvelope;
+	}
+	else
+	    diEffect->lpEnvelope = 0;
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	if (diEnvelope && envelope && envelope->isUsed())
+	{
+		cout << "  Enveloppe :" << endl
+			 << "    AttackLen : " << envelope->attackLength
+			 << " => " << diEnvelope->dwAttackTime << endl 
+			 << "    AttackLvl : " << envelope->attackLevel
+			 << " => " << diEnvelope->dwAttackLevel << endl 
+			 << "    FadeLen   : " << envelope->fadeLength
+			 << " => " << diEnvelope->dwFadeTime << endl
+			 << "    FadeLvl   : " << envelope->fadeLevel
+			 << " => " << diEnvelope->dwFadeLevel << endl;
+	}
+#endif
+
+	diEffect->dwSamplePeriod          = 0;
+	diEffect->dwDuration              = effect->replay_length;
+	diEffect->dwStartDelay            = effect->replay_delay;
+
+#if (OIS_WIN32_JOYFF_DEBUG > 1)
+	cout << "  Replay :" << endl
+		 << "    Length : " << effect->replay_length 
+		 << " => " << diEffect->dwDuration << endl
+		 << "    Delay  : " << effect->replay_delay 
+		 << " => " << diEffect->dwStartDelay << endl;
+#endif
+
+	diEffect->cbTypeSpecificParams    = struct_size;
+	diEffect->lpvTypeSpecificParams   = struct_type;
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_upload( GUID guid, DIEFFECT* diEffect, const Effect* effect)
+{
+	LPDIRECTINPUTEFFECT dxEffect = 0;
+
+	//Get the effect - if it exists
+	EffectList::iterator i = mEffectList.find(effect->_handle);
+	//It has been created already
+	if( i != mEffectList.end() )
+		dxEffect = i->second;
+	else //This effect has not yet been created - generate a handle
+		effect->_handle = mHandles++;
+
+	if( dxEffect == 0 )
+	{
+		//This effect has not yet been created, so create it
+		HRESULT hr = mJoyStick->CreateEffect(guid, diEffect, &dxEffect, NULL);
+		if(SUCCEEDED(hr))
+		{
+			mEffectList[effect->_handle] = dxEffect;
+			dxEffect->Start(INFINITE,0);
+		}
+		else if( hr == DIERR_DEVICEFULL )
+			OIS_EXCEPT(E_DeviceFull, "Remove an effect before adding more!");
+		else
+			OIS_EXCEPT(E_General, "Unknown error creating effect->..");
+	}
+	else
+	{
+		//ToDo -- Update the Effect
+		HRESULT hr = dxEffect->SetParameters( diEffect, DIEP_DIRECTION |
+			DIEP_DURATION | DIEP_ENVELOPE | DIEP_STARTDELAY | DIEP_TRIGGERBUTTON |
+			DIEP_TRIGGERREPEATINTERVAL | DIEP_TYPESPECIFICPARAMS | DIEP_START );
+
+		if(FAILED(hr)) OIS_EXCEPT(E_InvalidParam, "Error updating device!");
+	}
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_addEffectSupport( LPCDIEFFECTINFO pdei )
+{
+#if (OIS_WIN32_JOYFF_DEBUG > 0)
+    // Dump some usefull information about the effect type.
+    cout << "Adding support for '" << pdei->tszName << "' effect type" << endl;
+	cout << "  Supported static params: ";
+	if (pdei->dwStaticParams & DIEP_AXES) cout << " Axes";
+	if (pdei->dwStaticParams & DIEP_DIRECTION) cout << " Direction";
+	if (pdei->dwStaticParams & DIEP_DURATION) cout << " Duration";
+	if (pdei->dwStaticParams & DIEP_ENVELOPE) cout << " Envelope";
+	if (pdei->dwStaticParams & DIEP_GAIN) cout << " Gain";
+	if (pdei->dwStaticParams & DIEP_SAMPLEPERIOD) cout << " SamplePeriod";
+	if (pdei->dwStaticParams & DIEP_STARTDELAY) cout << " StartDelay";
+	if (pdei->dwStaticParams & DIEP_TRIGGERBUTTON) cout << " TriggerButton";
+	if (pdei->dwStaticParams & DIEP_TRIGGERREPEATINTERVAL) cout << " TriggerRepeatInterval";
+	if (pdei->dwStaticParams & DIEP_TYPESPECIFICPARAMS) cout << " TypeSpecificParams";
+	cout << endl;
+	cout << "  Supported dynamic params: ";
+	if (pdei->dwDynamicParams & DIEP_AXES) cout << " Axes";
+	if (pdei->dwDynamicParams & DIEP_DIRECTION) cout << " Direction";
+	if (pdei->dwDynamicParams & DIEP_DURATION) cout << " Duration";
+	if (pdei->dwDynamicParams & DIEP_ENVELOPE) cout << " Envelope";
+	if (pdei->dwDynamicParams & DIEP_GAIN) cout << " Gain";
+	if (pdei->dwDynamicParams & DIEP_SAMPLEPERIOD) cout << " SamplePeriod";
+	if (pdei->dwDynamicParams & DIEP_STARTDELAY) cout << " StartDelay";
+	if (pdei->dwDynamicParams & DIEP_TRIGGERBUTTON) cout << " TriggerButton";
+	if (pdei->dwDynamicParams & DIEP_TRIGGERREPEATINTERVAL) cout << " TriggerRepeatInterval";
+	if (pdei->dwDynamicParams & DIEP_TYPESPECIFICPARAMS) cout << " TypeSpecificParams";
+	cout << endl;
+	cout << "  More details about supported parameters support: ";
+	if (pdei->dwEffType & DIEFT_STARTDELAY) cout << " StartDelay";
+	if (pdei->dwEffType & DIEFT_FFATTACK) cout << " Attack";
+	if (pdei->dwEffType & DIEFT_FFFADE) cout << " Fade";
+	if (pdei->dwEffType & DIEFT_DEADBAND) cout << " DeadBand";
+	if (pdei->dwEffType & DIEFT_SATURATION) cout << " Saturation";
+	if (pdei->dwEffType & DIEFT_POSNEGSATURATION) cout << " PosNegaturation";
+	if (pdei->dwEffType & DIEFT_POSNEGCOEFFICIENTS) cout << " PosNegCoefficients";
+	if (pdei->dwEffType & DIEFT_HARDWARE) cout << " HardwareSpecific";
+	cout << endl;
+#endif
+
+    Effect::EForce eForce;
+	switch (DIEFT_GETTYPE(pdei->dwEffType))
+	{
+	    case DIEFT_CONSTANTFORCE:
+		    eForce = Effect::ConstantForce;
+			break;
+	    case DIEFT_RAMPFORCE:
+		    eForce = Effect::RampForce;
+			break;
+	    case DIEFT_PERIODIC:
+		    eForce = Effect::PeriodicForce;
+			break;
+	    case DIEFT_CONDITION:
+		    eForce = Effect::ConditionalForce;
+			break;
+	    case DIEFT_CUSTOMFORCE:
+		    eForce = Effect::CustomForce;
+			break;
+	    default:
+		    eForce = Effect::UnknownForce;
+#if defined (_DEBUG)
+			cout << "Win32ForceFeedback: DirectInput8 Effect type support not implemented: " 
+				 << "DIEFT_GETTYPE="<< (int)DIEFT_GETTYPE(pdei->dwEffType) << endl;
+#endif
+			return;
+	}
+
+	//Determine what the effect type is and how it corresponds to our OIS's Enums
+	//We could save the GUIDs too, however, we will just use the predefined ones later
+	if( pdei->guid == GUID_ConstantForce )
+		_addEffectTypes(eForce, Effect::Constant );
+	else if( pdei->guid == GUID_Triangle )
+		_addEffectTypes(eForce, Effect::Triangle );
+	else if( pdei->guid == GUID_Spring )
+		_addEffectTypes(eForce, Effect::Spring );
+	else if( pdei->guid == GUID_Friction )
+		_addEffectTypes(eForce, Effect::Friction );
+	else if( pdei->guid == GUID_Square )
+		_addEffectTypes(eForce, Effect::Square );
+	else if( pdei->guid == GUID_Sine )
+		_addEffectTypes(eForce, Effect::Sine );
+	else if( pdei->guid == GUID_SawtoothUp )
+		_addEffectTypes(eForce, Effect::SawToothUp );
+	else if( pdei->guid == GUID_SawtoothDown )
+		_addEffectTypes(eForce, Effect::SawToothDown );
+	else if( pdei->guid == GUID_Damper )
+		_addEffectTypes(eForce, Effect::Damper );
+	else if( pdei->guid == GUID_Inertia )
+		_addEffectTypes(eForce, Effect::Inertia );
+	else if( pdei->guid == GUID_CustomForce )
+		_addEffectTypes(eForce, Effect::Custom );
+	else if( pdei->guid == GUID_RampForce )
+		_addEffectTypes(eForce, Effect::Ramp );
+
+#if defined (_DEBUG)
+	//Only care about this for Debugging Purposes
+	//else
+	//{
+	//	std::ostringstream ss;
+	//	ss << "Win32ForceFeedback, DirectInput8 Effect not found. Reported as: "
+	//	   << pdei->tszName;
+	//	OIS_EXCEPT( E_General, ss.str().c_str());
+	//}
+#endif
+}
+
+//--------------------------------------------------------------//
+void Win32ForceFeedback::_addFFAxis()
+{
+	mFFAxes++;
+}
Index: /code/branches/rocket2/src/external/ois/win32/Win32ForceFeedback.h
===================================================================
--- /code/branches/rocket2/src/external/ois/win32/Win32ForceFeedback.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/win32/Win32ForceFeedback.h	(revision 6952)
@@ -0,0 +1,108 @@
+/*
+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_Win32ForceFeedBack_H
+#define OIS_Win32ForceFeedBack_H
+
+#include "OISPrereqs.h"
+#include "OISForceFeedback.h"
+#include "Win32/Win32Prereqs.h"
+
+namespace OIS
+{
+	class Win32ForceFeedback : public ForceFeedback
+	{
+		Win32ForceFeedback() {}
+	public:
+		Win32ForceFeedback(IDirectInputDevice8* pDIJoy, const DIDEVCAPS* pDIJoyCaps);
+		~Win32ForceFeedback();
+
+		/** @copydoc ForceFeedback::upload */
+		void upload( const Effect* effect );
+
+		/** @copydoc ForceFeedback::modify */
+		void modify( const Effect* effect );
+
+		/** @copydoc ForceFeedback::remove */
+		void remove( const Effect* effect );
+
+		/** @copydoc ForceFeedback::setMasterGain */
+		void setMasterGain( float level );
+		
+		/** @copydoc ForceFeedback::setAutoCenterMode */
+		void setAutoCenterMode( bool auto_on );
+
+		/** @copydoc ForceFeedback::getFFAxesNumber */
+		short getFFAxesNumber();
+
+		/** @copydoc ForceFeedback::getFFMemoryLoad */
+		unsigned short getFFMemoryLoad();
+
+		/**
+			@remarks
+			Internal use.. Used during enumeration to build a list of a devices
+			support effects.
+		*/
+		void _addEffectSupport( LPCDIEFFECTINFO pdei );
+
+		/**
+			@remarks
+			Internal use.. Used during axis enumeration to get number of FF axes
+			support effects.
+		*/
+		void _addFFAxis();
+
+	protected:
+
+		//Specific Effect Settings
+		void _updateConstantEffect( const Effect* effect );
+		void _updateRampEffect( const Effect* effect );
+		void _updatePeriodicEffect( const Effect* effect );
+		void _updateConditionalEffect( const Effect* effect );
+		void _updateCustomEffect( const Effect* effect );
+
+		//Sets the common properties to all effects
+		void _setCommonProperties( DIEFFECT* diEffect, DWORD* rgdwAxes,
+									LONG* rglDirection, DIENVELOPE* diEnvelope, DWORD struct_size, 
+									LPVOID struct_type, const Effect* effect, const Envelope* envelope );
+		//Actually do the upload
+		void _upload( GUID, DIEFFECT*, const Effect* );
+
+		// Map of currently uploaded effects (handle => effect)
+		typedef std::map<int,LPDIRECTINPUTEFFECT> EffectList;
+		EffectList mEffectList;
+
+		//Simple unique handle creation - allows for upto 2+ billion effects
+		//during the lifetime of application. Hopefully, that is enough.
+		int mHandles;
+
+		// Joystick device descriptor.
+		IDirectInputDevice8* mJoyStick;
+		
+		// Joystick capabilities.
+		const DIDEVCAPS* mpDIJoyCaps;
+
+		// Number of axis supporting FF.
+		short mFFAxes;
+	};
+}
+#endif //OIS_Win32ForceFeedBack_H
Index: /code/branches/rocket2/src/external/ois/win32/Win32InputManager.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/win32/Win32InputManager.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/win32/Win32InputManager.cpp	(revision 6952)
@@ -0,0 +1,258 @@
+/*
+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 "Win32/Win32InputManager.h"
+#include "Win32/Win32Keyboard.h"
+#include "Win32/Win32Mouse.h"
+#include "Win32/Win32JoyStick.h"
+#include "OISException.h"
+
+using namespace OIS;
+
+//--------------------------------------------------------------------------------//
+Win32InputManager::Win32InputManager() : InputManager("Win32InputManager")
+{
+	hWnd = 0;
+	mDirectInput = 0;
+
+	kbSettings    = 0;
+	mouseSettings = 0;
+	joySettings   = 0;
+
+	joySticks = 0;
+	keyboardUsed = mouseUsed = false;
+
+	//Setup our internal factories
+	mFactories.push_back(this);
+}
+
+//--------------------------------------------------------------------------------//
+Win32InputManager::~Win32InputManager()
+{
+	if( mDirectInput )
+	{
+		mDirectInput->Release();
+		mDirectInput = 0;
+	}
+}
+
+//--------------------------------------------------------------------------------//
+void Win32InputManager::_initialize( ParamList &paramList )
+{
+	HINSTANCE hInst = 0;
+	HRESULT hr;
+
+	//TODO 64 bit proof this little conversion xxx wip
+	//First of all, get the Windows Handle and Instance
+	ParamList::iterator i = paramList.find("WINDOW");
+	if( i == paramList.end() ) 
+		OIS_EXCEPT( E_InvalidParam, "Win32InputManager::Win32InputManager >> No HWND found!" );
+
+	hWnd  = (HWND)strtoul(i->second.c_str(), 0, 10);
+
+	if( IsWindow(hWnd) == 0 )
+		OIS_EXCEPT( E_General, "Win32InputManager::Win32InputManager >> The sent HWND is not valid!");
+
+	hInst = GetModuleHandle(0);
+
+	//Create the input system
+	hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&mDirectInput, NULL );
+    if (FAILED(hr))	
+		OIS_EXCEPT( E_General, "Win32InputManager::Win32InputManager >> Not able to init DirectX8 Input!");
+
+	//Ok, now we have DirectInput, parse whatever extra settings were sent to us
+	_parseConfigSettings( paramList );
+
+	// Enumerate devices ...
+	_enumerateDevices();
+}
+
+//--------------------------------------------------------------------------------//
+void Win32InputManager::_parseConfigSettings( ParamList &paramList )
+{
+	//Here we pick up settings such as a device's cooperation mode
+	std::map<std::string, DWORD> temp;
+	temp["DISCL_BACKGROUND"]	= DISCL_BACKGROUND;
+	temp["DISCL_EXCLUSIVE"]		= DISCL_EXCLUSIVE;
+	temp["DISCL_FOREGROUND"]	= DISCL_FOREGROUND;
+	temp["DISCL_NONEXCLUSIVE"]	= DISCL_NONEXCLUSIVE;
+	temp["DISCL_NOWINKEY"]		= DISCL_NOWINKEY;
+
+	//Check for pairs: ie. ("w32_keyboard","DISCL_NOWINKEY")("w32_keyboard","DISCL_FOREGROUND")
+	ParamList::iterator i = paramList.begin(), e = paramList.end();
+	for( ; i != e; ++i ) 
+	{
+		if( i->first == "w32_keyboard" )
+				kbSettings |= temp[i->second];
+		else if( i->first == "w32_mouse" )
+				mouseSettings |= temp[i->second];
+		else if( i->first == "w32_joystick" )
+				joySettings |= temp[i->second];
+	}
+	if( kbSettings == 0 ) kbSettings = DISCL_FOREGROUND | DISCL_NONEXCLUSIVE | DISCL_NOWINKEY;
+	if( mouseSettings == 0 ) mouseSettings = DISCL_FOREGROUND | DISCL_EXCLUSIVE;
+	if( joySettings == 0 ) joySettings = DISCL_FOREGROUND | DISCL_EXCLUSIVE;
+}
+
+//--------------------------------------------------------------------------------//
+void Win32InputManager::_enumerateDevices()
+{
+	//Enumerate all attached devices
+	mDirectInput->EnumDevices(NULL , _DIEnumDevCallback, this, DIEDFL_ATTACHEDONLY); 
+}
+
+//--------------------------------------------------------------------------------//
+BOOL CALLBACK Win32InputManager::_DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef)
+{
+	Win32InputManager *_this_ = static_cast<Win32InputManager*>(pvRef);
+
+	// Register only game devices (keyboard and mouse are managed differently).
+	if( GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_JOYSTICK ||
+		GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_GAMEPAD ||
+		GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_1STPERSON ||
+		GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_DRIVING ||
+		GET_DIDEVICE_TYPE(lpddi->dwDevType) == DI8DEVTYPE_FLIGHT)
+	{
+		JoyStickInfo jsInfo;
+		jsInfo.deviceID = lpddi->guidInstance;
+		jsInfo.vendor = lpddi->tszInstanceName;
+		jsInfo.devId = _this_->joySticks;
+
+		_this_->joySticks++;
+		
+		_this_->unusedJoyStickList.push_back( jsInfo );
+	}
+
+	return DIENUM_CONTINUE;
+}
+
+//----------------------------------------------------------------------------//
+void Win32InputManager::_returnJoyStick(const JoyStickInfo& joystick)
+{
+	unusedJoyStickList.push_back(joystick);
+}
+
+//----------------------------------------------------------------------------//
+DeviceList Win32InputManager::freeDeviceList()
+{
+	DeviceList ret;
+
+	if( keyboardUsed == false )
+		ret.insert(std::make_pair(OISKeyboard, mInputSystemName));
+
+	if( mouseUsed == false )
+		ret.insert(std::make_pair(OISMouse, mInputSystemName));
+
+	for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
+		ret.insert(std::make_pair(OISJoyStick, i->vendor));
+
+	return ret;
+}
+
+//----------------------------------------------------------------------------//
+int Win32InputManager::totalDevices(Type iType)
+{
+	switch(iType)
+	{
+	case OISKeyboard: return 1;
+	case OISMouse: return 1;
+	case OISJoyStick: return joySticks;
+	default: return 0;
+	}
+}
+
+//----------------------------------------------------------------------------//
+int Win32InputManager::freeDevices(Type iType)
+{
+	switch(iType)
+	{
+	case OISKeyboard: return keyboardUsed ? 0 : 1;
+	case OISMouse: return mouseUsed ? 0 : 1;
+	case OISJoyStick: return (int)unusedJoyStickList.size();
+	default: return 0;
+	}
+}
+
+//----------------------------------------------------------------------------//
+bool Win32InputManager::vendorExist(Type iType, const std::string & vendor)
+{
+	if( (iType == OISKeyboard || iType == OISMouse) && vendor == mInputSystemName )
+	{
+		return true;
+	}
+	else if( iType == OISJoyStick )
+	{
+		for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
+			if(i->vendor == vendor)
+				return true;
+	}
+
+	return false;
+}
+
+//----------------------------------------------------------------------------//
+Object* Win32InputManager::createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor)
+{
+	Object *obj = 0;
+
+	switch(iType)
+	{
+	case OISKeyboard: 
+	{
+		if( keyboardUsed == false )
+			obj = new Win32Keyboard(this, mDirectInput, bufferMode, kbSettings);
+		break;
+	}
+	case OISMouse:
+	{
+		if( mouseUsed == false )
+			obj = new Win32Mouse(this, mDirectInput, bufferMode, mouseSettings);
+		break;
+	}
+	case OISJoyStick:
+	{
+		for(JoyStickInfoList::iterator i = unusedJoyStickList.begin(); i != unusedJoyStickList.end(); ++i)
+		{
+			if(vendor == "" || i->vendor == vendor)
+			{
+				obj = new Win32JoyStick(this, mDirectInput, bufferMode, joySettings, *i);
+				unusedJoyStickList.erase(i);
+				break;
+			}
+		}
+		break;
+	}
+	default:
+		break;
+	}
+
+	if( obj == 0 )
+		OIS_EXCEPT(E_InputDeviceNonExistant, "No devices match requested type.");
+
+	return obj;
+}
+
+//----------------------------------------------------------------------------//
+void Win32InputManager::destroyObject(Object* obj)
+{
+	delete obj;
+}
Index: /code/branches/rocket2/src/external/ois/win32/Win32InputManager.h
===================================================================
--- /code/branches/rocket2/src/external/ois/win32/Win32InputManager.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/win32/Win32InputManager.h	(revision 6952)
@@ -0,0 +1,113 @@
+/*
+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_Win32InputManager_H
+#define OIS_Win32InputManager_H
+
+#include "OISInputManager.h"
+#include "OISFactoryCreator.h"
+#include "Win32/Win32Prereqs.h"
+
+namespace OIS
+{
+	/**	Win32InputManager specialization - Using DirectInput8 */
+	class Win32InputManager : public InputManager, public FactoryCreator
+	{
+	public:
+		Win32InputManager();
+		virtual ~Win32InputManager();
+
+		//InputManager Overrides
+		/** @copydoc InputManager::_initialize */
+		void _initialize( ParamList &paramList );
+
+		//FactoryCreator Overrides
+		/** @copydoc FactoryCreator::deviceList */
+		DeviceList freeDeviceList();
+
+		/** @copydoc FactoryCreator::totalDevices */
+		int totalDevices(Type iType);
+
+		/** @copydoc FactoryCreator::freeDevices */
+		int freeDevices(Type iType);
+
+		/** @copydoc FactoryCreator::vendorExist */
+		bool vendorExist(Type iType, const std::string & vendor);
+
+		/** @copydoc FactoryCreator::createObject */
+		Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string & vendor = "");
+
+		/** @copydoc FactoryCreator::destroyObject */
+		void destroyObject(Object* obj);
+
+		//Internal Items
+		//! Internal method, used for flaggin keyboard as available/unavailable for creation
+		void _setKeyboardUsed(bool used) {keyboardUsed = used; }
+
+		//! Internal method, used for flaggin mouse as available/unavailable for creation
+		void _setMouseUsed(bool used) { mouseUsed = used; }
+		
+		//! Internal method, return unused joystick to queue
+		void _returnJoyStick(const JoyStickInfo& joystick);
+
+		//! Returns HWND needed by DirectInput Device Object
+		HWND getWindowHandle() { return hWnd; }
+
+	protected:
+		//! internal class method for dealing with param list
+		void _parseConfigSettings( ParamList &paramList );
+		
+		//! internal class method for finding attached devices
+		void _enumerateDevices();
+
+		//! Used during device enumeration
+		static BOOL CALLBACK _DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
+
+		//! Keep a list of all joysticks enumerated, but not in use
+		JoyStickInfoList unusedJoyStickList;
+
+		//! The window handle we are using
+		HWND hWnd;
+
+		//! Direct Input Interface
+		IDirectInput8* mDirectInput;
+
+		//! Used for keyboard device settings
+		DWORD kbSettings;
+
+		//! Used for mouse device settings
+		DWORD mouseSettings;
+
+		//! Used for joystick device settings
+		DWORD joySettings;
+
+		//! Number of total joysticks (inuse or not)
+		char joySticks;
+
+		//! Used to know if we used up keyboard
+		bool keyboardUsed;
+
+		//! Used to know if we used up mouse
+		bool mouseUsed;
+	};
+}
+#endif
Index: /code/branches/rocket2/src/external/ois/win32/Win32JoyStick.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/win32/Win32JoyStick.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/win32/Win32JoyStick.cpp	(revision 6952)
@@ -0,0 +1,419 @@
+/*
+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 "Win32/Win32JoyStick.h"
+#include "Win32/Win32InputManager.h"
+#include "Win32/Win32ForceFeedback.h"
+#include "OISEvents.h"
+#include "OISException.h"
+
+#include <cassert>
+
+//DX Only defines macros for the JOYSTICK not JOYSTICK2, so fix it
+#undef DIJOFS_BUTTON
+#undef DIJOFS_POV
+
+#define DIJOFS_BUTTON(n)  (FIELD_OFFSET(DIJOYSTATE2, rgbButtons) + (n))
+#define DIJOFS_POV(n)     (FIELD_OFFSET(DIJOYSTATE2, rgdwPOV)+(n)*sizeof(DWORD))
+#define DIJOFS_SLIDER0(n) (FIELD_OFFSET(DIJOYSTATE2, rglSlider)+(n) * sizeof(LONG))
+#define DIJOFS_SLIDER1(n) (FIELD_OFFSET(DIJOYSTATE2, rglVSlider)+(n) * sizeof(LONG))
+#define DIJOFS_SLIDER2(n) (FIELD_OFFSET(DIJOYSTATE2, rglASlider)+(n) * sizeof(LONG))
+#define DIJOFS_SLIDER3(n) (FIELD_OFFSET(DIJOYSTATE2, rglFSlider)+(n) * sizeof(LONG))
+
+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()
+{
+	delete ff_device;
+
+	if(mJoyStick)
+	{
+		mJoyStick->Unacquire();
+		mJoyStick->Release();
+		mJoyStick = 0;
+	}
+
+	//Return joystick to pool
+	JoyStickInfo js;
+	js.deviceID = deviceGuid;
+	js.devId = mDevID;
+	js.vendor = mVendor;
+	static_cast<Win32InputManager*>(mCreator)->_returnJoyStick(js);
+}
+
+//--------------------------------------------------------------------------------------------------//
+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();
+}
+
+//--------------------------------------------------------------------------------------------------//
+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);
+}
+
+//--------------------------------------------------------------------------------------------------//
+BOOL CALLBACK Win32JoyStick::DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef)
+{
+	Win32JoyStick* _this = (Win32JoyStick*)pvRef;
+
+	//Setup mappings
+	DIPROPPOINTER diptr;
+	diptr.diph.dwSize       = sizeof(DIPROPPOINTER);
+	diptr.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+	diptr.diph.dwHow        = DIPH_BYID;
+	diptr.diph.dwObj        = lpddoi->dwType;
+	//Add a magic number to recognise we set seomthing
+	diptr.uData             = 0x13130000 | _this->_AxisNumber;
+
+	//Check if axis is slider, if so, do not treat as regular axis
+	if(GUID_Slider == lpddoi->guidType)
+	{
+		++_this->mSliders;
+
+		//Decrease Axes, since this slider shows up in a different place
+		_this->mState.mAxes.pop_back();
+	}
+	else if (FAILED(_this->mJoyStick->SetProperty(DIPROP_APPDATA, &diptr.diph)))
+	{	//If for some reason we could not set needed user data, just ignore this axis
+		return DIENUM_CONTINUE;
+	}
+
+	//Increase for next time through
+	if(GUID_Slider != lpddoi->guidType)
+		_this->_AxisNumber += 1;
+
+	//Set range
+	DIPROPRANGE diprg;
+	diprg.diph.dwSize       = sizeof(DIPROPRANGE);
+	diprg.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+	diprg.diph.dwHow        = DIPH_BYID;
+	diprg.diph.dwObj        = lpddoi->dwType;
+	diprg.lMin              = MIN_AXIS;
+	diprg.lMax              = MAX_AXIS;
+
+	if (FAILED(_this->mJoyStick->SetProperty(DIPROP_RANGE, &diprg.diph)))
+		OIS_EXCEPT( E_General, "Win32JoyStick::_DIEnumDeviceObjectsCallback >> Failed to set min/max range property" );
+
+	//Check if FF Axes, and if so, increment counter
+	if((lpddoi->dwFlags & DIDOI_FFACTUATOR) != 0 )
+	{
+		if( _this->ff_device )
+		{
+			_this->ff_device->_addFFAxis();
+		}
+	}
+
+	//Force the flags for gain and auto-center support to true,
+	//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);
+	}
+
+	return DIENUM_CONTINUE;
+}
+
+//--------------------------------------------------------------------------------------------------//
+BOOL CALLBACK Win32JoyStick::DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID pvRef)
+{
+	Win32JoyStick* _this = (Win32JoyStick*)pvRef;
+
+	//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 );
+
+	return DIENUM_CONTINUE;
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32JoyStick::capture()
+{
+	DIDEVICEOBJECTDATA diBuff[JOYSTICK_DX_BUFFERSIZE];
+	DWORD entries = JOYSTICK_DX_BUFFERSIZE;
+
+	// Poll the device to read the current state
+	HRESULT hr = mJoyStick->Poll();
+	if( hr == DI_OK )
+		hr = mJoyStick->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
+
+	if( hr != DI_OK )
+	{
+		hr = mJoyStick->Acquire();
+		while( hr == DIERR_INPUTLOST )
+			hr = mJoyStick->Acquire();
+
+		// Poll the device to read the current state
+	    mJoyStick->Poll();
+		hr = mJoyStick->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
+		//Perhaps the user just tabbed away
+		if( FAILED(hr) )
+			return;
+	}
+
+	bool axisMoved[24] = {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,
+						  false,false,false,false,false,false,false,false};
+	bool sliderMoved[4] = {false,false,false,false};
+
+	//Loop through all the events
+	for(unsigned int i = 0; i < entries; ++i)
+	{
+		//This may seem outof order, but is in order of the way these variables
+		//are declared in the JoyStick State 2 structure.
+		switch(diBuff[i].dwOfs)
+		{
+		//------ slider -//
+		case DIJOFS_SLIDER0(0):
+			sliderMoved[0] = true;
+			mState.mSliders[0].abX = diBuff[i].dwData;
+			break;
+		case DIJOFS_SLIDER0(1):
+			sliderMoved[0] = true;
+			mState.mSliders[0].abY = diBuff[i].dwData;
+			break;
+		//----- Max 4 POVs Next ---------------//
+		case DIJOFS_POV(0):
+			if(!_changePOV(0,diBuff[i]))
+				return;
+			break;
+		case DIJOFS_POV(1):
+			if(!_changePOV(1,diBuff[i]))
+				return;
+			break;
+		case DIJOFS_POV(2):
+			if(!_changePOV(2,diBuff[i]))
+				return;
+			break;
+		case DIJOFS_POV(3):
+			if(!_changePOV(3,diBuff[i]))
+				return;
+			break;
+		case DIJOFS_SLIDER1(0):
+			sliderMoved[1] = true;
+			mState.mSliders[1].abX = diBuff[i].dwData;
+			break;
+		case DIJOFS_SLIDER1(1):
+			sliderMoved[1] = true;
+			mState.mSliders[1].abY = diBuff[i].dwData;
+			break;
+		case DIJOFS_SLIDER2(0):
+			sliderMoved[2] = true;
+			mState.mSliders[2].abX = diBuff[i].dwData;
+			break;
+		case DIJOFS_SLIDER2(1):
+			sliderMoved[2] = true;
+			mState.mSliders[2].abY = diBuff[i].dwData;
+			break;
+		case DIJOFS_SLIDER3(0):
+			sliderMoved[3] = true;
+			mState.mSliders[3].abX = diBuff[i].dwData;
+			break;
+		case DIJOFS_SLIDER3(1):
+			sliderMoved[3] = true;
+			mState.mSliders[3].abY = diBuff[i].dwData;
+			break;
+		//-----------------------------------------//
+		default:
+			//Handle Button Events Easily using the DX Offset Macros
+			if( diBuff[i].dwOfs >= DIJOFS_BUTTON(0) && diBuff[i].dwOfs < DIJOFS_BUTTON(128) )
+			{
+				if(!_doButtonClick((diBuff[i].dwOfs - DIJOFS_BUTTON(0)), diBuff[i]))
+					return;
+			}
+			else if((short)(diBuff[i].uAppData >> 16) == 0x1313)
+			{	//If it was nothing else, might be axis enumerated earlier (determined by magic number)
+				int axis = (int)(0x0000FFFF & diBuff[i].uAppData); //Mask out the high bit
+				assert( axis >= 0 && axis < (int)mState.mAxes.size() && "Axis out of range!");
+
+				if(axis >= 0 && axis < (int)mState.mAxes.size())
+				{
+					mState.mAxes[axis].abs = diBuff[i].dwData;
+					axisMoved[axis] = true;
+				}
+			}
+
+			break;
+		} //end case
+	} //end for
+
+	//Check to see if any of the axes values have changed.. if so send events
+	if( mBuffered && mListener && entries > 0 )
+	{
+		JoyStickEvent temp(this, mState);
+
+		//Update axes
+		for( int i = 0; i < 24; ++i )
+			if( axisMoved[i] )
+				if( mListener->axisMoved( temp, i ) == false )
+					return;
+
+		//Now update sliders
+		for( int i = 0; i < 4; ++i )
+			if( sliderMoved[i] )
+				if( mListener->sliderMoved( temp, i ) == false )
+					return;
+	}
+}
+
+//--------------------------------------------------------------------------------------------------//
+bool Win32JoyStick::_doButtonClick( int button, DIDEVICEOBJECTDATA& di )
+{
+	if( di.dwData & 0x80 )
+	{
+		mState.mButtons[button] = true;
+		if( mBuffered && mListener )
+			return mListener->buttonPressed( JoyStickEvent( this, mState ), button );
+	}
+	else
+	{
+		mState.mButtons[button] = false;
+		if( mBuffered && mListener )
+			return mListener->buttonReleased( JoyStickEvent( this, mState ), button );
+	}
+
+	return true;
+}
+
+//--------------------------------------------------------------------------------------------------//
+bool Win32JoyStick::_changePOV( int pov, DIDEVICEOBJECTDATA& di )
+{
+	//Some drivers report a value of 65,535, instead of 1,
+	//for the center position
+	if(LOWORD(di.dwData) == 0xFFFF)
+	{
+		mState.mPOV[pov].direction = Pov::Centered;
+	}
+	else
+	{
+		switch(di.dwData)
+		{
+			case 0: mState.mPOV[pov].direction = Pov::North; break;
+			case 4500: mState.mPOV[pov].direction = Pov::NorthEast; break;
+			case 9000: mState.mPOV[pov].direction = Pov::East; break;
+			case 13500: mState.mPOV[pov].direction = Pov::SouthEast; break;
+			case 18000: mState.mPOV[pov].direction = Pov::South; break;
+			case 22500: mState.mPOV[pov].direction = Pov::SouthWest; break;
+			case 27000: mState.mPOV[pov].direction = Pov::West; break;
+			case 31500: mState.mPOV[pov].direction = Pov::NorthWest; break;
+		}
+	}
+
+	if( mBuffered && mListener )
+		return mListener->povMoved( JoyStickEvent( this, mState ), pov );
+
+	return true;
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32JoyStick::setBuffered(bool buffered)
+{
+	mBuffered = buffered;
+}
+
+//--------------------------------------------------------------------------------------------------//
+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;
+	else
+		return 0;
+}
Index: /code/branches/rocket2/src/external/ois/win32/Win32JoyStick.h
===================================================================
--- /code/branches/rocket2/src/external/ois/win32/Win32JoyStick.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/win32/Win32JoyStick.h	(revision 6952)
@@ -0,0 +1,75 @@
+/*
+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 _WIN32_JOYSTICK_H_EADER_
+#define _WIN32_JOYSTICK_H_EADER_
+
+#include "OISJoyStick.h"
+#include "Win32/Win32Prereqs.h"
+
+namespace OIS
+{
+	class Win32JoyStick : public JoyStick
+	{
+	public:
+		Win32JoyStick( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings, const JoyStickInfo &info );
+		virtual ~Win32JoyStick();
+		
+		/** @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();
+
+	protected:
+		//! Enumerates all things
+		void _enumerate();
+		//! Enumerate axis callback
+		static BOOL CALLBACK DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef);
+		//! Enumerate Force Feedback callback
+		static BOOL CALLBACK DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID pvRef);
+
+		bool _doButtonClick( int button, DIDEVICEOBJECTDATA& di );
+		bool _changePOV( int pov, DIDEVICEOBJECTDATA& di );
+
+		IDirectInput8* mDirectInput;
+		IDirectInputDevice8* mJoyStick;
+		DIDEVCAPS mDIJoyCaps;
+
+		DWORD coopSetting;
+		GUID deviceGuid;
+
+		//! A force feedback device
+		Win32ForceFeedback* ff_device;
+
+		//! Mapping
+		int _AxisNumber;
+	};
+}
+
+#endif //_WIN32_JOYSTICK_H_EADER_
Index: /code/branches/rocket2/src/external/ois/win32/Win32KeyBoard.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/win32/Win32KeyBoard.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/win32/Win32KeyBoard.cpp	(revision 6952)
@@ -0,0 +1,333 @@
+/*
+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 "Win32/Win32InputManager.h"
+#include "Win32/Win32KeyBoard.h"
+#include "OISException.h"
+#include "OISEvents.h"
+#include <sstream>
+
+using namespace OIS;
+
+//--------------------------------------------------------------------------------------------------//
+Win32Keyboard::Win32Keyboard( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings )
+	: Keyboard(creator->inputSystemName(), buffered, 0, creator)
+{
+	mKeyboard = 0;
+	mDirectInput = pDI;
+	coopSetting = coopSettings;
+
+	//Clear our keyboard state buffer
+	memset( &KeyBuffer, 0, 256 );
+	deadKey = '\0';
+	static_cast<Win32InputManager*>(mCreator)->_setKeyboardUsed(true);
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Keyboard::_initialize()
+{
+	mModifiers = 0;
+	deadKey = '\0';
+
+	if(FAILED(mDirectInput->CreateDevice(GUID_SysKeyboard, &mKeyboard, NULL)))
+		OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> Could not init device!");
+
+	if(FAILED(mKeyboard->SetDataFormat(&c_dfDIKeyboard)))
+		OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> format error!");
+
+	HWND hwin = ((Win32InputManager*)mCreator)->getWindowHandle();
+
+	if(FAILED(mKeyboard->SetCooperativeLevel( hwin, coopSetting)))
+		OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> coop error!");
+
+	if( mBuffered )
+	{
+		DIPROPDWORD dipdw;
+		dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
+		dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+		dipdw.diph.dwObj        = 0;
+		dipdw.diph.dwHow        = DIPH_DEVICE;
+		dipdw.dwData            = KEYBOARD_DX_BUFFERSIZE;
+
+		if (FAILED(mKeyboard->SetProperty( DIPROP_BUFFERSIZE, &dipdw.diph )))
+			OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> buffer error!");
+	}
+
+	HRESULT hr = mKeyboard->Acquire();
+	if(FAILED(hr) && hr != DIERR_OTHERAPPHASPRIO)
+		OIS_EXCEPT( E_General, "Win32Keyboard::Win32Keyboard >> aquire error!");
+}
+
+//--------------------------------------------------------------------------------------------------//
+Win32Keyboard::~Win32Keyboard()
+{
+	if(mKeyboard)
+	{
+		mKeyboard->Unacquire();
+		mKeyboard->Release();
+		mKeyboard = 0;
+	}
+	static_cast<Win32InputManager*>(mCreator)->_setKeyboardUsed(false);
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Keyboard::capture()
+{
+	if( mBuffered )
+		_readBuffered();
+	else
+		_read();
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Keyboard::_readBuffered()
+{
+	DIDEVICEOBJECTDATA diBuff[KEYBOARD_DX_BUFFERSIZE];
+	DWORD entries = KEYBOARD_DX_BUFFERSIZE;
+	HRESULT hr;
+	//Only one keyboard allowed per app, so static is ok
+	static bool verifyAfterAltTab = false;
+
+	hr = mKeyboard->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
+	if( hr != DI_OK )
+	{
+		hr = mKeyboard->Acquire();
+		if (hr == E_ACCESSDENIED)
+			verifyAfterAltTab = true;
+
+		while( hr == DIERR_INPUTLOST )
+			hr = mKeyboard->Acquire();
+
+		return;
+	}
+
+	if( FAILED(hr) )
+		OIS_EXCEPT( E_General, "Win32Keyboard::_readBuffered() >> Problem with Device!" );
+
+	//Update keyboard and modifier states.. And, if mListener, fire events
+	for(unsigned int i = 0; i < entries; ++i )
+	{
+		//If the listener returns false, that means that we are probably deleted...
+		//send no more events and just leave as the this pointer is invalid now...
+		bool ret = true;
+		KeyCode kc = (KeyCode)diBuff[ i ].dwOfs;
+			
+		//Store result in our keyBuffer too
+		KeyBuffer[kc] = static_cast<unsigned char>(diBuff[ i ].dwData);
+			
+		if( diBuff[ i ].dwData & 0x80 )
+		{
+			//Turn on modifier
+			if( kc == KC_LCONTROL || kc == KC_RCONTROL )
+				mModifiers |= Ctrl;
+			else if( kc == KC_LSHIFT || kc == KC_RSHIFT )
+				mModifiers |= Shift;
+			else if( kc == KC_LMENU || kc == KC_RMENU )
+				mModifiers |= Alt;
+
+			if( mListener )
+				ret = mListener->keyPressed( KeyEvent( this, kc, _translateText(kc) ) );
+		}
+		else
+		{
+			//Turn off modifier
+			if( kc == KC_LCONTROL || kc == KC_RCONTROL )
+				mModifiers &= ~Ctrl;
+			else if( kc == KC_LSHIFT || kc == KC_RSHIFT )
+				mModifiers &= ~Shift;
+			else if( kc == KC_LMENU || kc == KC_RMENU )
+				mModifiers &= ~Alt;
+
+			//Fire off event
+			if( mListener )
+				ret = mListener->keyReleased( KeyEvent( this, kc, 0 ) );
+		}
+
+		if(ret == false)
+			break;
+	}
+
+	// If a lost device/access denied was detected, recover gracefully with new events
+	if(verifyAfterAltTab)
+	{
+		bool ret = true;
+		
+		//Copy old buffer to temp location to compare against
+		unsigned char keyBufferCopy[256];
+		memcpy(keyBufferCopy, KeyBuffer, 256);
+
+		//Update new state
+		_read();
+
+		for (unsigned i = 0; i < 256; i++)
+		{
+			if (keyBufferCopy[i] != KeyBuffer[i])
+			{
+				if (mListener)
+				{
+					if (KeyBuffer[i])
+						ret = mListener->keyPressed( KeyEvent( this, (KeyCode)i, _translateText((KeyCode)i) ) );
+					else
+						ret = mListener->keyReleased( KeyEvent( this, (KeyCode)i, 0 ) );
+				}
+			}
+
+			//If user returned false from callback, return immediately
+			if(ret == false)
+				return;
+		}
+
+		verifyAfterAltTab = false;
+	}
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Keyboard::_read()
+{
+    HRESULT  hr = mKeyboard->GetDeviceState( sizeof(KeyBuffer), &KeyBuffer );
+
+	if( hr == DIERR_INPUTLOST || hr == DIERR_NOTACQUIRED )
+	{
+		hr = mKeyboard->Acquire();
+		if (hr != DIERR_OTHERAPPHASPRIO)
+			mKeyboard->GetDeviceState(sizeof(KeyBuffer), &KeyBuffer);
+	}
+
+	//Set Shift, Ctrl, Alt
+	mModifiers = 0;
+	if( isKeyDown(KC_LCONTROL) || isKeyDown(KC_RCONTROL) )
+		mModifiers |= Ctrl;
+	if( isKeyDown(KC_LSHIFT) || isKeyDown(KC_RSHIFT) )
+		mModifiers |= Shift;
+	if( isKeyDown(KC_LMENU) || isKeyDown(KC_RMENU) )
+		mModifiers |= Alt;
+}
+
+//--------------------------------------------------------------------------------------------------//
+int Win32Keyboard::_translateText( KeyCode kc )
+{
+	if( mTextMode == Off )
+		return 0;
+
+	BYTE keyState[256];
+	HKL  layout = GetKeyboardLayout(0);
+	if( GetKeyboardState(keyState) == 0 )
+		return 0;
+
+	unsigned int vk = MapVirtualKeyEx(kc, 3, layout);
+	if( vk == 0 )
+		return 0;
+
+	WCHAR buff[3] = {0};
+	int ascii = ToUnicodeEx(vk, kc, keyState, buff, 3, 0, layout);
+
+	if(ascii == 1 && deadKey != '\0' )
+	{
+		// A dead key is stored and we have just converted a character key
+		// Combine the two into a single character
+		WCHAR wcBuff[3] = {buff[0], deadKey, '\0'};
+		WCHAR out[3];
+		
+		deadKey = '\0';
+		if(FoldStringW(MAP_PRECOMPOSED, (LPWSTR)wcBuff, 3, (LPWSTR)out, 3))
+			return out[0];
+	}
+	else if (ascii == 1)
+	{	// We have a single character
+		deadKey = '\0';
+		return buff[0];
+	}
+	else if(ascii == 2)
+	{	// Convert a non-combining diacritical mark into a combining diacritical mark
+		// Combining versions range from 0x300 to 0x36F; only 5 (for French) have been mapped below
+		// http://www.fileformat.info/info/unicode/block/combining_diacritical_marks/images.htm
+		switch(buff[0])	{
+		case 0x5E: // Circumflex accent: â
+			deadKey = 0x302; break;
+		case 0x60: // Grave accent: à
+			deadKey = 0x300; break;
+		case 0xA8: // Diaeresis: ü
+			deadKey = 0x308; break;
+		case 0xB4: // Acute accent: é
+			deadKey = 0x301; break;
+		case 0xB8: // Cedilla: ç
+			deadKey = 0x327; break;
+		default:
+			deadKey = buff[0]; break;
+		}
+	}
+
+	return 0;
+}
+
+//--------------------------------------------------------------------------------------------------//
+bool Win32Keyboard::isKeyDown( KeyCode key ) const
+{
+	return (KeyBuffer[key] & 0x80) != 0;
+}
+
+//--------------------------------------------------------------------------------------------------//
+const std::string& Win32Keyboard::getAsString( KeyCode kc )
+{
+	char temp[256];
+
+	DIPROPSTRING prop;
+	prop.diph.dwSize = sizeof(DIPROPSTRING);
+	prop.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+	prop.diph.dwObj = static_cast<DWORD>(kc);
+	prop.diph.dwHow = DIPH_BYOFFSET;
+
+	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 );
+	}
+
+	std::stringstream ss;
+	ss << "Key_" << (int)kc;
+	return mGetString.assign( ss.str() );
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Keyboard::copyKeyStates( char keys[256] ) const
+{
+	for(int i = 0; i < 256; ++i)
+		keys[i] = KeyBuffer[i] > 0; //Normalise the DX values (0x80)
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Keyboard::setBuffered(bool buffered)
+{
+	if( buffered != mBuffered )
+	{
+		if(mKeyboard)
+		{
+			mKeyboard->Unacquire();
+			mKeyboard->Release();
+			mKeyboard = 0;
+		}
+		
+		mBuffered = buffered;
+		_initialize();
+	}
+}
Index: /code/branches/rocket2/src/external/ois/win32/Win32KeyBoard.h
===================================================================
--- /code/branches/rocket2/src/external/ois/win32/Win32KeyBoard.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/win32/Win32KeyBoard.h	(revision 6952)
@@ -0,0 +1,87 @@
+/*
+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 _WIN32_KEYBOARD_H_EADER_
+#define _WIN32_KEYBOARD_H_EADER_
+
+#include "OISKeyboard.h"
+#include "Win32/Win32Prereqs.h"
+
+namespace OIS
+{
+	class Win32Keyboard : public Keyboard
+	{
+	public:
+		/**
+		@remarks
+			Constructor
+		@param pDI
+			Valid DirectInput8 Interface
+		@param buffered
+			True for buffered input mode
+		@param coopSettings
+			A combination of DI Flags (see DX Help for info on input device settings)
+		*/
+		Win32Keyboard( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings );
+		virtual ~Win32Keyboard();
+
+		/** @copydoc Keyboard::isKeyDown */
+		virtual bool isKeyDown( KeyCode key ) const;
+		
+		/** @copydoc Keyboard::getAsString */
+		virtual const std::string& getAsString( KeyCode kc );
+
+		/** @copydoc Keyboard::copyKeyStates */
+		virtual void copyKeyStates( char keys[256] ) const;
+
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+		
+		/** @copydoc Object::capture */
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType type) {return 0;}
+		
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+	protected:
+		void _readBuffered();
+		void _read();
+
+		IDirectInput8* mDirectInput;
+		IDirectInputDevice8* mKeyboard;
+		DWORD coopSetting;
+
+		unsigned char KeyBuffer[256];
+		
+		//! Internal method for translating KeyCodes to Text
+		int _translateText( KeyCode kc );
+
+		//! Stored dead key from last translation
+		WCHAR deadKey;
+
+		//! used for getAsString
+		std::string mGetString;
+	};
+}
+#endif //_WIN32_KEYBOARD_H_EADER_
Index: /code/branches/rocket2/src/external/ois/win32/Win32Mouse.cpp
===================================================================
--- /code/branches/rocket2/src/external/ois/win32/Win32Mouse.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/win32/Win32Mouse.cpp	(revision 6952)
@@ -0,0 +1,216 @@
+/*
+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 "Win32/Win32Mouse.h"
+#include "Win32/Win32InputManager.h"
+#include "OISException.h"
+#include "OISEvents.h"
+
+using namespace OIS;
+
+//--------------------------------------------------------------------------------------------------//
+Win32Mouse::Win32Mouse( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings )
+	: Mouse(creator->inputSystemName(), buffered, 0, creator)
+{
+	mMouse = 0;
+	mDirectInput = pDI;
+	coopSetting = coopSettings;
+	mHwnd = 0;
+
+	static_cast<Win32InputManager*>(mCreator)->_setMouseUsed(true);
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Mouse::_initialize()
+{
+	DIPROPDWORD dipdw;
+
+	//Clear old state
+	mState.clear();
+
+    dipdw.diph.dwSize       = sizeof(DIPROPDWORD);
+    dipdw.diph.dwHeaderSize = sizeof(DIPROPHEADER);
+    dipdw.diph.dwObj        = 0;
+    dipdw.diph.dwHow        = DIPH_DEVICE;
+	dipdw.dwData            = MOUSE_DX_BUFFERSIZE;
+	
+	if( FAILED(mDirectInput->CreateDevice(GUID_SysMouse, &mMouse, NULL)) )
+		OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to create device" );
+
+	if( FAILED(mMouse->SetDataFormat(&c_dfDIMouse2)) )
+		OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set format" );
+	
+	mHwnd = ((Win32InputManager*)mCreator)->getWindowHandle();
+
+	if( FAILED(mMouse->SetCooperativeLevel(mHwnd, coopSetting)) )
+		OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set coop level" );
+	
+	if( FAILED(mMouse->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph )) )
+		OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to set property" );
+
+	HRESULT hr = mMouse->Acquire();
+	if (FAILED(hr) && hr != DIERR_OTHERAPPHASPRIO)
+		OIS_EXCEPT( E_General, "Win32Mouse::Win32Mouse >> Failed to aquire mouse!" );
+}
+
+//--------------------------------------------------------------------------------------------------//
+Win32Mouse::~Win32Mouse()
+{
+	if (mMouse)
+	{
+		mMouse->Unacquire();
+		mMouse->Release();
+		mMouse = 0;
+	}
+
+	static_cast<Win32InputManager*>(mCreator)->_setMouseUsed(false);
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Mouse::capture()
+{
+	//Clear old relative values
+	mState.X.rel = mState.Y.rel = mState.Z.rel = 0;
+
+	DIDEVICEOBJECTDATA diBuff[MOUSE_DX_BUFFERSIZE];
+	DWORD entries = MOUSE_DX_BUFFERSIZE;
+
+	HRESULT hr = mMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
+	if( hr != DI_OK )
+	{
+		hr = mMouse->Acquire();
+		while( hr == DIERR_INPUTLOST ) 
+			hr = mMouse->Acquire();
+
+		hr = mMouse->GetDeviceData( sizeof(DIDEVICEOBJECTDATA), diBuff, &entries, 0 );
+		
+		//Perhaps the user just tabbed away, and coop settings
+		//are nonexclusive..so just ignore
+		if( FAILED(hr) )
+			return;
+	}
+
+	bool axesMoved = false;
+	//Accumulate all axis movements for one axesMove message..
+	//Buttons are fired off as they are found
+	for(unsigned int i = 0; i < entries; ++i )
+	{
+		switch( diBuff[i].dwOfs )
+		{
+			case DIMOFS_BUTTON0:
+				if(!_doMouseClick(0, diBuff[i])) return;
+				break;
+			case DIMOFS_BUTTON1:
+				if(!_doMouseClick(1, diBuff[i])) return;
+				break;
+			case DIMOFS_BUTTON2:
+				if(!_doMouseClick(2, diBuff[i])) return;
+				break;
+			case DIMOFS_BUTTON3:
+				if(!_doMouseClick(3, diBuff[i])) return;
+				break;
+			case DIMOFS_BUTTON4:
+				if(!_doMouseClick(4, diBuff[i])) return;
+				break;	
+			case DIMOFS_BUTTON5:
+				if(!_doMouseClick(5, diBuff[i])) return;
+				break;
+			case DIMOFS_BUTTON6:
+				if(!_doMouseClick(6, diBuff[i])) return;
+				break;
+			case DIMOFS_BUTTON7:
+				if(!_doMouseClick(7, diBuff[i])) return;
+				break;
+			case DIMOFS_X:
+				mState.X.rel += diBuff[i].dwData;
+				axesMoved = true;
+				break;
+			case DIMOFS_Y:
+				mState.Y.rel += diBuff[i].dwData;
+				axesMoved = true;
+				break;
+			case DIMOFS_Z:
+				mState.Z.rel += diBuff[i].dwData;
+				axesMoved = true;
+				break;
+			default: break;
+		} //end switch
+	}//end for
+
+	if( axesMoved )
+	{
+		if( coopSetting & DISCL_NONEXCLUSIVE )
+		{
+			//DirectInput provides us with meaningless values, so correct that
+			POINT point;
+			GetCursorPos(&point);
+			ScreenToClient(mHwnd, &point);
+			mState.X.abs = point.x;
+			mState.Y.abs = point.y;
+		}
+		else
+		{
+			mState.X.abs +=  mState.X.rel;
+			mState.Y.abs +=  mState.Y.rel;
+		}
+		mState.Z.abs +=  mState.Z.rel;
+
+		//Clip values to window
+		if( mState.X.abs < 0 )
+			mState.X.abs = 0;
+		else if( mState.X.abs > mState.width )
+			mState.X.abs = mState.width;
+		if( mState.Y.abs < 0 )
+			mState.Y.abs = 0;
+		else if( mState.Y.abs > mState.height )
+			mState.Y.abs = mState.height;
+
+		//Do the move
+		if( mListener && mBuffered )
+			mListener->mouseMoved( MouseEvent( this, mState ) );
+	}
+}
+
+//--------------------------------------------------------------------------------------------------//
+bool Win32Mouse::_doMouseClick( int mouseButton, DIDEVICEOBJECTDATA& di )
+{
+	if( di.dwData & 0x80 )
+	{
+		mState.buttons |= 1 << mouseButton; //turn the bit flag on
+		if( mListener && mBuffered )
+			return mListener->mousePressed( MouseEvent( this, mState ), (MouseButtonID)mouseButton );
+	}
+	else
+	{
+		mState.buttons &= ~(1 << mouseButton); //turn the bit flag off
+		if( mListener && mBuffered )
+			return mListener->mouseReleased( MouseEvent( this, mState ), (MouseButtonID)mouseButton );
+	}
+
+	return true;
+}
+
+//--------------------------------------------------------------------------------------------------//
+void Win32Mouse::setBuffered(bool buffered)
+{
+	mBuffered = buffered;
+}
Index: /code/branches/rocket2/src/external/ois/win32/Win32Mouse.h
===================================================================
--- /code/branches/rocket2/src/external/ois/win32/Win32Mouse.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/win32/Win32Mouse.h	(revision 6952)
@@ -0,0 +1,59 @@
+/*
+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 _WIN32_MOUSE_H_EADER_
+#define _WIN32_MOUSE_H_EADER_
+
+#include "OISMouse.h"
+#include "Win32/Win32Prereqs.h"
+
+namespace OIS
+{
+	class Win32Mouse : public Mouse
+	{
+	public:
+		Win32Mouse( InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings );
+		virtual ~Win32Mouse();
+		
+		/** @copydoc Object::setBuffered */
+		virtual void setBuffered(bool buffered);
+
+		/** @copydoc Object::capture */
+		virtual void capture();
+
+		/** @copydoc Object::queryInterface */
+		virtual Interface* queryInterface(Interface::IType type) {return 0;}
+
+		/** @copydoc Object::_initialize */
+		virtual void _initialize();
+
+	protected:
+		bool _doMouseClick( int mouseButton, DIDEVICEOBJECTDATA& di );
+
+		IDirectInput8* mDirectInput;
+		IDirectInputDevice8* mMouse;
+		DWORD coopSetting;
+		HWND mHwnd;
+	};
+}
+
+#endif //_WIN32_MOUSE_H_EADER_
Index: /code/branches/rocket2/src/external/ois/win32/Win32Prereqs.h
===================================================================
--- /code/branches/rocket2/src/external/ois/win32/Win32Prereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/external/ois/win32/Win32Prereqs.h	(revision 6952)
@@ -0,0 +1,63 @@
+/*
+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 _WIN32_INPUTSYSTEM_PREREQS_H
+#define _WIN32_INPUTSYSTEM_PREREQS_H
+
+#define WIN32_LEAN_AND_MEAN
+#define DIRECTINPUT_VERSION 0x0800
+#include <windows.h>
+#include <dinput.h>
+
+//Max number of elements to collect from buffered DirectInput
+#define KEYBOARD_DX_BUFFERSIZE 17
+#define MOUSE_DX_BUFFERSIZE 64
+#define JOYSTICK_DX_BUFFERSIZE 124
+
+//MinGW defines
+#if defined(OIS_MINGW_COMPILER)
+#	undef FIELD_OFFSET
+#	define FIELD_OFFSET offsetof
+#endif
+
+namespace OIS
+{
+	//Local Forward declarations
+	class Win32InputManager;
+	class Win32Keyboard;
+	class Win32JoyStick;
+	class Win32Mouse;
+	class Win32ForceFeedback;
+
+	//Information needed to create DirectInput joysticks
+	class JoyStickInfo
+	{
+	public:
+		int devId;
+		GUID deviceID;
+		std::string vendor;
+	};
+
+	typedef std::vector< JoyStickInfo > JoyStickInfoList;
+}
+
+#endif //_WIN32_INPUTSYSTEM_PREREQS_H
Index: /code/branches/rocket2/src/external/tinyxml/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/tinyxml/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/tinyxml/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,42 @@
+ #
+ #             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.
+ #
+
+SET_SOURCE_FILES(TINYXML++_FILES
+  ticpp.h
+  ticpprc.h
+  tinystr.h
+  tinyxml.h
+
+COMPILATION_BEGIN TicppCompilation.cpp
+  ticpp.cpp
+  tinystr.cpp
+  tinyxml.cpp
+  tinyxmlerror.cpp
+  tinyxmlparser.cpp
+COMPILATION_END
+)
+
+ORXONOX_ADD_LIBRARY(tinyxml++_orxonox
+  ORXONOX_EXTERNAL
+  NO_DLL_INTERFACE
+  VERSION
+    2.5.3
+  SOURCE_FILES
+    ${TINYXML++_FILES}
+)
Index: /code/branches/rocket2/src/external/tinyxml/VERSION
===================================================================
--- /code/branches/rocket2/src/external/tinyxml/VERSION	(revision 6952)
+++ /code/branches/rocket2/src/external/tinyxml/VERSION	(revision 6952)
@@ -0,0 +1,1 @@
+TinyXML++ trunk checkout revision 106. Built on top of TinyXML 2.5.3
Index: /code/branches/rocket2/src/external/tinyxml/changes.txt
===================================================================
--- /code/branches/rocket2/src/external/tinyxml/changes.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/tinyxml/changes.txt	(revision 6952)
@@ -0,0 +1,269 @@
+Changes in version 1.0.1:
+- Fixed comment tags which were outputing as '<?--' instead of 
+  the correct '<!--'.
+- Implemented the Next and Prev methods of the TiXmlAttribute class.
+- Renamed 'LastAttribtute' to 'LastAttribute'
+- Fixed bad pointer to 'isspace' that could occur while parsing text.
+- Errors finding beginning and end of tags no longer throw it into an
+  infinite loop. (Hopefully.)
+
+Changes in version 1.0.2
+- Minor documentation fixes.
+
+Changes in version 1.0.3
+- After nodes are added to a document, they return a pointer
+  to the new node instead of a bool for success.
+- Elements can be constructed with a value, which is the
+  element name. Every element must have a value or it will be
+  invalid, but the code changes to enforce this are not fully
+  in place.
+
+Changes in version 1.1.0
+- Added the	TiXmlAttributeSet class to pull the attributes into
+  a seperate container.
+- Moved the doubly liked list out of XmlBase. Now XmlBase only
+  requires the Print() function and defines some utility functions.
+- Moved errors into a seperate file. (With the idea of internationalization
+  to the other latin-1 languages.)
+- Added the "NodeType"
+- Fixed white space parsing in text to conform with the standard. 
+  Basically, all white space becomes just one space.
+- Added the TiXmlDeclaration class to read xml declarations.
+
+Changes in version 1.2.0
+- Removed the factory. The factory was not really in the spirit 
+  of small and simple, confused the code, and was of limited value.
+- Added FirstChildElement and NextSiblingElement, because they
+  are such common functions.
+- Re-wrote the example to test and demonstrate more functionality.
+
+Changes in version 1.2.1
+- Fixed a bug where comments couldn't be inside elements.
+- Loading now clears out existing XML rather than appending.
+- Added the "Clear" method on a node to delete all its children.
+
+Changes in version 1.2.2
+- Fixed TiXmlAttribute::Previous actually returning "next." Thanks
+  to Rickard Troedsson for the bug fix.
+
+Changes in version 1.2.3
+- Added the TIXML prefix to the error strings to resolve conflicts
+  with #defines in OS headers. Thanks to Steve Lhomme.
+- Fixed a delete buf that should be a delete [] buf. 
+  Thanks to Ephi Sinowitz.
+
+Changes in version 1.2.4
+- ReplaceChild() was almost guarenteed to fail. Should be fixed,
+  thanks to Joe Smith. Joe also pointed out that the Print() functions
+  should take stream references: I agree, and would like to overload
+  the Print() method to take either format, but I don't want to do 
+  this in a dot release.
+- Some compilers seem to need an extra <ctype.h> include. Thanks
+  to Steve Lhomme for that.
+
+Changes in version 2.0.0 BETA
+- Made the ToXXX() casts safe if 'this' is null. 
+  When "LoadFile" is called with a filename, the value will correctly get set.
+  Thanks to Brian Yoder.
+- Fixed bug where isalpha() and isalnum() would get called with a negative value for 
+  high ascii numbers. Thanks to Alesky Aksenov.
+- Fixed some errors codes that were not getting set.
+- Made methods "const" that were not.
+- Added a switch to enable or disable the ignoring of white space. ( TiXmlDocument::SetIgnoreWhiteSpace() )
+- Greater standardization and code re-use in the parser.
+- Added a stream out operator.
+- Added a stream in operator.
+- Entity support, of predefined entites. &#x entities are untouched by input or output.
+- Improved text out formatting.
+- Fixed ReplaceChild bug, thanks to Tao Chen.
+
+Changes in version 2.0.1
+- Fixed hanging on loading a 0 length file. Thanks to Jeff Scozzafava.
+- Fixed crashing on InsertBeforeChild and InsertAfterChild. Also possibility of bad links being
+  created by same function. Thanks to Frank De prins.
+- Added missing licence text. Thanks to Lars Willemsens.
+- Added <ctype.h> include, at the suggestion of Steve Walters.
+
+Changes in version 2.1.0
+- Yves Berquin brings us the STL switch. The forum on SourceForge, and various emails to
+  me, have long debated all out STL vs. no STL at all. And now you can have it both ways.
+  TinyXml will compile either way.
+
+Changes in version 2.1.1
+- Compilation warnings.
+
+Changes in version 2.1.2
+- Uneeded code is not compiled in the STL case.
+- Changed headers so that STL can be turned on or off in tinyxml.h
+
+Changes in version 2.1.3
+- Fixed non-const reference in API; now uses a pointer.
+- Copy constructor of TiXmlString not checking for assignment to self.
+- Nimrod Cohen found a truly evil bug in the STL implementation that occurs
+  when a string is converted to a c_str and then assigned to self. Search for
+  STL_STRING_BUG for a full description. I'm asserting this is a Microsoft STL
+  bug, since &string and string.c_str() should never be the same. Nevertheless,
+  the code works around it.
+- Urivan Saaib pointed out a compiler conflict, where the C headers define
+  the isblank macro, which was wiping out the TiXmlString::isblank() method.
+  The method was unused and has been removed.
+
+Changes in version 2.1.4
+- Reworked the entity code. Entities were not correctly surving round trip input and output.
+  Will now automatically create entities for high ascii in output.
+
+Changes in version 2.1.5
+- Bug fix by kylotan : infinite loop on some input (tinyxmlparser.cpp rev 1.27)
+- Contributed by Ivica Aracic (bytelord) : 1 new VC++ project to compile versions as static libraries (tinyxml_lib.dsp), 
+  and an example usage in xmltest.dsp
+  (Patch request ID 678605)
+- A suggestion by Ronald Fenner Jr (dormlock) to add #include <istream> and <ostream> for Apple's Project Builder 
+  (Patch request ID 697642)
+- A patch from ohommes that allows to parse correctly dots in element names and attribute names
+  (Patch request 602600 and kylotan 701728)
+- A patch from  hermitgeek ( James ) and wasteland for improper error reporting
+- Reviewed by Lee, with the following changes:
+	- Got sick of fighting the STL/non-STL thing in the windows build. Broke
+	  them out as seperate projects.
+	- I have too long not included the dsw. Added.
+	- TinyXmlText had a protected Print. Odd.
+	- Made LinkEndChild public, with docs and appropriate warnings.
+	- Updated the docs.
+
+2.2.0
+- Fixed an uninitialized pointer in the TiXmlAttributes
+- Fixed STL compilation problem in MinGW (and gcc 3?) - thanks Brian Yoder for finding this one
+- Fixed a syntax error in TiXmlDeclaration - thanks Brian Yoder
+- Fletcher Dunn proposed and submitted new error handling that tracked the row and column. Lee
+  modified it to not have performance impact.
+- General cleanup suggestions from Fletcher Dunn.
+- In error handling, general errors will no longer clear the error state of specific ones.
+- Fix error in documentation : comments starting with "<?--" instead of "<!--" (thanks ion_pulse)
+- Added the TiXmlHandle. An easy, safe way to browse XML DOMs with less code.
+- Added QueryAttribute calls which have better error messaging. (Proposed by Fletcher Dunn)
+- Nodes and attributes can now print themselves to strings. (Yves suggestion)
+- Fixed bug where entities with one character would confuse parser. (Thanks Roman)
+
+2.2.1
+- Additional testing (no more bugs found to be fixed in this release)
+- Significant performance improvement to the cursor code.
+
+2.3.0
+- User Data are now defined in TiXmlBase instead of TiXmlNode
+- Character Entities are now UCS-2
+- Character Entities can be decimal or hexadecimal
+- UTF-8 conversion.
+- Fixed many, many bugs.
+
+2.3.1
+- Fixed bug in handling nulls embedded in the input.
+- Make UTF-8 parser tolerant of bad text encoding.
+- Added encoding detection. 
+- Many fixes and input from John-Philip Leonard Johansson (JP) and Ellers, 
+  including UTF-8 feedback, bug reports, and patches. Thanks!
+- Added version # constants - a suggestion from JP and Ellers.
+- [ 979180 ] Missing ; in entity reference, fix from Rob Laveaux.
+- Copy constructors and assignment have been a long time coming. Thanks to
+  Fokke and JP.
+
+2.3.2
+- Made the IsAlpha and IsAlphaNum much more tolerant of non-UTF-8 encodings. Thanks
+  Volker Boerchers for finding the issue.
+- Ran the program though the magnificent Valgrind - http://valgrind.kde.org - to check
+  for memory errors. Fixed some minor issues.
+
+2.3.3
+- Fixed crash when test program was run from incorrect directory.
+- Fixed bug 1070717 - empty document not returned correctly - thanks Katsuhisa Yuasa.
+- Bug 1079301 resolved - deprecated stdlib calls. Thanks Adrian Boeing.
+- Bug 1035218 fixed - documentation errors. Xunji Luo
+- Other bug fixes have accumulated and been fixed on the way as well; my apologies to
+  authors not credited!
+- Big fix / addition is to correctly return const values. TinyXml could basically
+  remove const in a method like this: TiXmlElement* Foo() const, where the returned element
+  was a pointer to internal data. That is now: const TiXmlElement* Foo() const and
+  TiXmlElement* Foo().
+
+2.3.4
+- Fixed additional const errors, thanks Kent Gibson.
+- Correctly re-enable warnings after tinyxml header. Thanks Cory Nelson.
+- Variety of type cleanup and warning fixes. Thanks Warren Stevens.
+- Cleaned up unneeded constructor calls in TinyString - thanks to Geoff Carlton and
+  the discussion group on sourceforge.
+
+2.4.0
+- Improved string class, thanks Tyge Lovset (whose name gets mangled in English - sorry)
+- Type cast compiler warning, thanks Rob van den Bogaard
+- Added GetText() convenience function. Thanks Ilya Parniuk & Andrew Ellers for input.
+- Many thanks to marlonism for finding an infinite loop in bad xml.
+- A patch to cleanup warnings from Robert Gebis.
+- Added ValueStr() to get the value of a node as a string.
+- TiXmlText can now parse and output as CDATA
+- Additional string improvement from James (z2895)
+- Removed extraneous 'const', thanks David Aldrich
+- First pass at switching to the "safe" stdlib functions. Many people have suggested and
+  pushed on this, but Warren Stevens put together the first proposal.
+- TinyXml now will do EOL normalization before parsing, consistent with the W3C XML spec.
+- Documents loaded with the UTF-8 BOM will now save with the UTF-8 BOM. Good suggestion 
+  from 'instructor_'
+- Ellers submitted his very popular tutorials, which have been added to the distribution.
+
+2.4.1
+- Fixed CDATA output formatting
+- Fixed memory allocators in TinyString to work with overloaded new/delete
+
+2.4.2
+- solosnake pointed out that TIXML_LOG causes problems on an XBOX. The definition in the header
+  was superflous and was moved inside of DEBUG_PARSING
+
+2.4.3
+- Fixed a test bug that caused a crash in 'xmltest'. TinyXML was fine, but it isn't good
+  to ship with a broken test suite.
+- Started converting some functions to not cast between std::string and const char* 
+  quite as often.
+- Added FILE* versions of the document loads - good suggestion from Wade Brainerd
+- Empty documents might not always return the errors they should. [1398915] Thanks to igor v.
+- Added some asserts for multiply adding a node, regardng bug [1391937] suggested by Paco Arjonilla.
+
+2.4.4
+- Bug find thanks to andre-gross found a memory leak that occured when a document failed to load.
+- Bug find (and good analysis) by VirtualJim who found a case where attribute parsing 
+  should be throwing an error and wasn't.
+- Steve Hyatt suggested the QueryValueAttribute method, which is now implemented.
+- DavidA identified a chunk of dead code.
+- Andrew Baxter sent in some compiler warnings that were good clean up points.
+
+2.5
+- Added the Visit() API. Many thanks to both Andrew Ellerton and John-Philip for all their
+  work, code, suggestion, and just general pushing that it should be done.
+- Removed existing streaming code and use TiXmlPrinter instead.
+- [ tinyxml-Bugs-1527079 ] Compile error in tinystr.cpp fixed, thanks to Paul Suggs
+- [ tinyxml-Bugs-1522890 ] SaveFile has no error checks fixed, thanks to Ivan Dobrokotov
+- Ivan Dobrokotov also reported redundant memory allocation in the Attribute() method, which
+  upon investigation was a mess. The attribute should now be fixed for both const char* and 
+  std::string, and the return types match the input parameters.
+- Feature [ 1511105 ] Make TiXmlComment constructor accept a string / char*, implemented.
+  Thanks to Karl Itschen for the feedback.
+- [ 1480108 ] Stream parsing fails when CDATA contains tags was found by Tobias Grimm, who also
+  submitted a test case and patch. A significant bug in CDATA streaming (operator>>) has now
+  been fixed.
+
+2.5.2
+- Lieven, and others, pointed out a missing const-cast that upset the Open Watcom compiler.
+  Should now be fixed.
+- ErrorRow and ErrorCol should have been const, and weren't. Fixed thanks to Dmitry Polutov.
+
+2.5.3
+- zloe_zlo identified a missing string specialization for QueryValueAttribute() [ 1695429 ]. Worked
+  on this bug, but not sure how to fix it in a safe, cross-compiler way.
+- increased warning level to 4 and turned on detect 64 bit portability issues for VC2005.
+  May address [ 1677737 ] VS2005: /Wp64 warnings
+- grosheck identified several problems with the Document copy. Many thanks for [ 1660367 ]
+- Nice catch, and suggested fix, be Gilad Novik on the Printer dropping entities.
+  "[ 1600650 ] Bug when printing xml text" is now fixed.
+- A subtle fix from Nicos Gollan in the tinystring initializer: 
+  [ 1581449 ] Fix initialiser of TiXmlString::nullrep_
+- Great catch, although there isn't a submitter for the bug. [ 1475201 ] TinyXML parses entities in comments. 
+  Comments should not, in fact, parse entities. Fixed the code path and added tests.
+- We were not catching all the returns from ftell. Thanks to Bernard for catching that.
+  
Index: /code/branches/rocket2/src/external/tinyxml/changes_orxonox.diff
===================================================================
--- /code/branches/rocket2/src/external/tinyxml/changes_orxonox.diff	(revision 6952)
+++ /code/branches/rocket2/src/external/tinyxml/changes_orxonox.diff	(revision 6952)
@@ -0,0 +1,18 @@
+--- ticpp.h	Tue Nov  4 21:55:49 2008
++++ ticpp.h	Sat Jan 10 14:48:41 2009
+@@ -1229,6 +1229,7 @@
+ 
+ 		T* m_tiXmlPointer;		/**< Internal pointer to the TiXml Class which is being wrapped */
+ 
++    public:
+ 		/**
+ 		@internal
+ 		Gets the internal TinyXML pointer.
+@@ -1240,6 +1241,7 @@
+ 			ValidatePointer();
+ 			return m_tiXmlPointer;
+ 		}
++    protected:
+ 
+ 		/**
+ 		@internal
Index: /code/branches/rocket2/src/external/tinyxml/readme.txt
===================================================================
--- /code/branches/rocket2/src/external/tinyxml/readme.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/tinyxml/readme.txt	(revision 6952)
@@ -0,0 +1,531 @@
+/** @mainpage
+
+<h1> TinyXML </h1>
+
+TinyXML is a simple, small, C++ XML parser that can be easily 
+integrated into other programs.
+
+<h2> What it does. </h2>
+	
+In brief, TinyXML parses an XML document, and builds from that a 
+Document Object Model (DOM) that can be read, modified, and saved.
+
+XML stands for "eXtensible Markup Language." It allows you to create 
+your own document markups. Where HTML does a very good job of marking 
+documents for browsers, XML allows you to define any kind of document 
+markup, for example a document that describes a "to do" list for an 
+organizer application. XML is a very structured and convenient format.
+All those random file formats created to store application data can 
+all be replaced with XML. One parser for everything.
+
+The best place for the complete, correct, and quite frankly hard to
+read spec is at <a href="http://www.w3.org/TR/2004/REC-xml-20040204/">
+http://www.w3.org/TR/2004/REC-xml-20040204/</a>. An intro to XML
+(that I really like) can be found at 
+<a href="http://skew.org/xml/tutorial/">http://skew.org/xml/tutorial</a>.
+
+There are different ways to access and interact with XML data.
+TinyXML uses a Document Object Model (DOM), meaning the XML data is parsed
+into a C++ objects that can be browsed and manipulated, and then 
+written to disk or another output stream. You can also construct an XML document 
+from scratch with C++ objects and write this to disk or another output
+stream.
+
+TinyXML is designed to be easy and fast to learn. It is two headers 
+and four cpp files. Simply add these to your project and off you go. 
+There is an example file - xmltest.cpp - to get you started. 
+
+TinyXML is released under the ZLib license, 
+so you can use it in open source or commercial code. The details
+of the license are at the top of every source file.
+
+TinyXML attempts to be a flexible parser, but with truly correct and
+compliant XML output. TinyXML should compile on any reasonably C++
+compliant system. It does not rely on exceptions or RTTI. It can be 
+compiled with or without STL support. TinyXML fully supports
+the UTF-8 encoding, and the first 64k character entities.
+
+
+<h2> What it doesn't do. </h2>
+
+TinyXML doesn't parse or use DTDs (Document Type Definitions) or XSLs
+(eXtensible Stylesheet Language.) There are other parsers out there 
+(check out www.sourceforge.org, search for XML) that are much more fully
+featured. But they are also much bigger, take longer to set up in
+your project, have a higher learning curve, and often have a more
+restrictive license. If you are working with browsers or have more
+complete XML needs, TinyXML is not the parser for you.
+
+The following DTD syntax will not parse at this time in TinyXML:
+
+@verbatim
+	<!DOCTYPE Archiv [
+	 <!ELEMENT Comment (#PCDATA)>
+	]>
+@endverbatim
+
+because TinyXML sees this as a !DOCTYPE node with an illegally 
+embedded !ELEMENT node. This may be addressed in the future.
+
+<h2> Tutorials. </h2>
+
+For the impatient, here are some tutorials to get you going. A great way to get started, 
+but it is worth your time to read this (very short) manual completely.
+
+- @subpage ticppTutorial
+- @subpage tutorial0
+
+<h2> Code Status.  </h2>
+
+TinyXML is mature, tested code. It is very stable. If you find
+bugs, please file a bug report on the sourceforge web site
+(www.sourceforge.net/projects/tinyxml). We'll get them straightened 
+out as soon as possible.
+
+There are some areas of improvement; please check sourceforge if you are
+interested in working on TinyXML.
+
+<h2> Related Projects </h2>
+
+TinyXML projects you may find useful! (Descriptions provided by the projects.)
+
+<ul>
+<li> <b>TinyXPath</b> (http://tinyxpath.sourceforge.net). TinyXPath is a small footprint 
+     XPath syntax decoder, written in C++.</li>
+<li> <b>@subpage ticpp</b> (http://code.google.com/p/ticpp/). TinyXML++ is a completely new 
+     interface to TinyXML that uses MANY of the C++ strengths. Templates, 
+	 exceptions, and much better error handling.</li>
+</ul>
+
+<h2> Features </h2>
+
+<h3> Using STL </h3>
+
+TinyXML can be compiled to use or not use STL. When using STL, TinyXML
+uses the std::string class, and fully supports std::istream, std::ostream,
+operator<<, and operator>>. Many API methods have both 'const char*' and
+'const std::string&' forms.
+
+When STL support is compiled out, no STL files are included whatsoever. All
+the string classes are implemented by TinyXML itself. API methods
+all use the 'const char*' form for input.
+
+Use the compile time #define:
+
+	TIXML_USE_STL
+
+to compile one version or the other. This can be passed by the compiler,
+or set as the first line of "tinyxml.h".
+
+Note: If compiling the test code in Linux, setting the environment
+variable TINYXML_USE_STL=YES/NO will control STL compilation. In the
+Windows project file, STL and non STL targets are provided. In your project,
+It's probably easiest to add the line "#define TIXML_USE_STL" as the first
+line of tinyxml.h.
+
+<h3> UTF-8 </h3>
+
+TinyXML supports UTF-8 allowing to manipulate XML files in any language. TinyXML
+also supports "legacy mode" - the encoding used before UTF-8 support and
+probably best described as "extended ascii".
+
+Normally, TinyXML will try to detect the correct encoding and use it. However,
+by setting the value of TIXML_DEFAULT_ENCODING in the header file, TinyXML
+can be forced to always use one encoding.
+
+TinyXML will assume Legacy Mode until one of the following occurs:
+<ol>
+	<li> If the non-standard but common "UTF-8 lead bytes" (0xef 0xbb 0xbf)
+		 begin the file or data stream, TinyXML will read it as UTF-8. </li>
+	<li> If the declaration tag is read, and it has an encoding="UTF-8", then
+		 TinyXML will read it as UTF-8. </li>
+	<li> If the declaration tag is read, and it has no encoding specified, then TinyXML will 
+		 read it as UTF-8. </li>
+	<li> If the declaration tag is read, and it has an encoding="something else", then TinyXML 
+		 will read it as Legacy Mode. In legacy mode, TinyXML will work as it did before. It's 
+		 not clear what that mode does exactly, but old content should keep working.</li>
+	<li> Until one of the above criteria is met, TinyXML runs in Legacy Mode.</li>
+</ol>
+
+What happens if the encoding is incorrectly set or detected? TinyXML will try
+to read and pass through text seen as improperly encoded. You may get some strange results or 
+mangled characters. You may want to force TinyXML to the correct mode.
+
+You may force TinyXML to Legacy Mode by using LoadFile( TIXML_ENCODING_LEGACY ) or
+LoadFile( filename, TIXML_ENCODING_LEGACY ). You may force it to use legacy mode all
+the time by setting TIXML_DEFAULT_ENCODING = TIXML_ENCODING_LEGACY. Likewise, you may 
+force it to TIXML_ENCODING_UTF8 with the same technique.
+
+For English users, using English XML, UTF-8 is the same as low-ASCII. You
+don't need to be aware of UTF-8 or change your code in any way. You can think
+of UTF-8 as a "superset" of ASCII.
+
+UTF-8 is not a double byte format - but it is a standard encoding of Unicode!
+TinyXML does not use or directly support wchar, TCHAR, or Microsoft's _UNICODE at this time. 
+It is common to see the term "Unicode" improperly refer to UTF-16, a wide byte encoding
+of unicode. This is a source of confusion.
+
+For "high-ascii" languages - everything not English, pretty much - TinyXML can
+handle all languages, at the same time, as long as the XML is encoded
+in UTF-8. That can be a little tricky, older programs and operating systems
+tend to use the "default" or "traditional" code page. Many apps (and almost all
+modern ones) can output UTF-8, but older or stubborn (or just broken) ones
+still output text in the default code page. 
+
+For example, Japanese systems traditionally use SHIFT-JIS encoding. 
+Text encoded as SHIFT-JIS can not be read by TinyXML. 
+A good text editor can import SHIFT-JIS and then save as UTF-8.
+
+The <a href="http://skew.org/xml/tutorial/">Skew.org link</a> does a great
+job covering the encoding issue.
+
+The test file "utf8test.xml" is an XML containing English, Spanish, Russian,
+and Simplified Chinese. (Hopefully they are translated correctly). The file
+"utf8test.gif" is a screen capture of the XML file, rendered in IE. Note that
+if you don't have the correct fonts (Simplified Chinese or Russian) on your
+system, you won't see output that matches the GIF file even if you can parse
+it correctly. Also note that (at least on my Windows machine) console output
+is in a Western code page, so that Print() or printf() cannot correctly display
+the file. This is not a bug in TinyXML - just an OS issue. No data is lost or 
+destroyed by TinyXML. The console just doesn't render UTF-8.
+
+
+<h3> Entities </h3>
+TinyXML recognizes the pre-defined "character entities", meaning special
+characters. Namely:
+
+@verbatim
+	&amp;	&
+	&lt;	<
+	&gt;	>
+	&quot;	"
+	&apos;	'
+@endverbatim
+
+These are recognized when the XML document is read, and translated to there
+UTF-8 equivalents. For instance, text with the XML of:
+
+@verbatim
+	Far &amp; Away
+@endverbatim
+
+will have the Value() of "Far & Away" when queried from the TiXmlText object,
+and will be written back to the XML stream/file as an ampersand. Older versions
+of TinyXML "preserved" character entities, but the newer versions will translate
+them into characters.
+
+Additionally, any character can be specified by its Unicode code point:
+The syntax "&#xA0;" or "&#160;" are both to the non-breaking space characher.
+
+<h3> Printing </h3>
+TinyXML can print output in several different ways that all have strengths and limitations.
+
+- Print( FILE* ). Output to a std-C stream, which includes all C files as well as stdout.
+	- "Pretty prints", but you don't have control over printing options.
+	- The output is streamed directly to the FILE object, so there is no memory overhead
+	  in the TinyXML code.
+	- used by Print() and SaveFile()
+
+- operator<<. Output to a c++ stream.
+	- Integrates with standart C++ iostreams.
+	- Outputs in "network printing" mode without line breaks. Good for network transmission
+	  and moving XML between C++ objects, but hard for a human to read.
+
+- TiXmlPrinter. Output to a std::string or memory buffer.
+	- API is less concise
+	- Future printing options will be put here.
+	- Printing may change slightly in future versions as it is refined and expanded.
+
+<h3> Streams </h3>
+With TIXML_USE_STL on TinyXML supports C++ streams (operator <<,>>) streams as well
+as C (FILE*) streams. There are some differences that you may need to be aware of.
+
+C style output:
+	- based on FILE*
+	- the Print() and SaveFile() methods
+
+	Generates formatted output, with plenty of white space, intended to be as 
+	human-readable as possible. They are very fast, and tolerant of ill formed 
+	XML documents. For example, an XML document that contains 2 root elements 
+	and 2 declarations, will still print.
+
+C style input:
+	- based on FILE*
+	- the Parse() and LoadFile() methods
+
+	A fast, tolerant read. Use whenever you don't need the C++ streams.
+
+C++ style output:
+	- based on std::ostream
+	- operator<<
+
+	Generates condensed output, intended for network transmission rather than
+	readability. Depending on your system's implementation of the ostream class,
+	these may be somewhat slower. (Or may not.) Not tolerant of ill formed XML:
+	a document should contain the correct one root element. Additional root level
+	elements will not be streamed out.
+
+C++ style input:
+	- based on std::istream
+	- operator>>
+
+	Reads XML from a stream, making it useful for network transmission. The tricky
+	part is knowing when the XML document is complete, since there will almost
+	certainly be other data in the stream. TinyXML will assume the XML data is
+	complete after it reads the root element. Put another way, documents that
+	are ill-constructed with more than one root element will not read correctly.
+	Also note that operator>> is somewhat slower than Parse, due to both 
+	implementation of the STL and limitations of TinyXML.
+
+<h3> White space </h3>
+The world simply does not agree on whether white space should be kept, or condensed.
+For example, pretend the '_' is a space, and look at "Hello____world". HTML, and 
+at least some XML parsers, will interpret this as "Hello_world". They condense white
+space. Some XML parsers do not, and will leave it as "Hello____world". (Remember
+to keep pretending the _ is a space.) Others suggest that __Hello___world__ should become
+Hello___world.
+
+It's an issue that hasn't been resolved to my satisfaction. TinyXML supports the
+first 2 approaches. Call TiXmlBase::SetCondenseWhiteSpace( bool ) to set the desired behavior.
+The default is to condense white space.
+
+If you change the default, you should call TiXmlBase::SetCondenseWhiteSpace( bool )
+before making any calls to Parse XML data, and I don't recommend changing it after
+it has been set.
+
+
+<h3> Handles </h3>
+
+Where browsing an XML document in a robust way, it is important to check
+for null returns from method calls. An error safe implementation can
+generate a lot of code like:
+
+@verbatim
+TiXmlElement* root = document.FirstChildElement( "Document" );
+if ( root )
+{
+	TiXmlElement* element = root->FirstChildElement( "Element" );
+	if ( element )
+	{
+		TiXmlElement* child = element->FirstChildElement( "Child" );
+		if ( child )
+		{
+			TiXmlElement* child2 = child->NextSiblingElement( "Child" );
+			if ( child2 )
+			{
+				// Finally do something useful.
+@endverbatim
+
+Handles have been introduced to clean this up. Using the TiXmlHandle class,
+the previous code reduces to:
+
+@verbatim
+TiXmlHandle docHandle( &document );
+TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
+if ( child2 )
+{
+	// do something useful
+@endverbatim
+
+Which is much easier to deal with. See TiXmlHandle for more information.
+
+
+<h3> Row and Column tracking </h3>
+Being able to track nodes and attributes back to their origin location
+in source files can be very important for some applications. Additionally,
+knowing where parsing errors occured in the original source can be very
+time saving.
+
+TinyXML can tracks the row and column origin of all nodes and attributes
+in a text file. The TiXmlBase::Row() and TiXmlBase::Column() methods return
+the origin of the node in the source text. The correct tabs can be 
+configured in TiXmlDocument::SetTabSize().
+
+
+<h2> Using and Installing </h2>
+
+To Compile and Run xmltest:
+
+A Linux Makefile and a Windows Visual C++ .dsw file is provided. 
+Simply compile and run. It will write the file demotest.xml to your 
+disk and generate output on the screen. It also tests walking the
+DOM by printing out the number of nodes found using different 
+techniques.
+
+The Linux makefile is very generic and runs on many systems - it 
+is currently tested on mingw and
+MacOSX. You do not need to run 'make depend'. The dependecies have been
+hard coded.
+
+<h3>Windows project file for VC6</h3>
+<ul>
+<li>tinyxml:		tinyxml library, non-STL </li>
+<li>tinyxmlSTL:		tinyxml library, STL </li>
+<li>tinyXmlTest:	test app, non-STL </li>
+<li>tinyXmlTestSTL: test app, STL </li>
+</ul>
+
+<h3>Makefile</h3>
+At the top of the makefile you can set:
+
+PROFILE, DEBUG, and TINYXML_USE_STL. Details (such that they are) are in
+the makefile.
+
+In the tinyxml directory, type "make clean" then "make". The executable
+file 'xmltest' will be created.
+
+
+
+<h3>To Use in an Application:</h3>
+
+Add tinyxml.cpp, tinyxml.h, tinyxmlerror.cpp, tinyxmlparser.cpp, tinystr.cpp, and tinystr.h to your
+project or make file. That's it! It should compile on any reasonably
+compliant C++ system. You do not need to enable exceptions or
+RTTI for TinyXML.
+
+
+<h2> How TinyXML works.  </h2>
+
+An example is probably the best way to go. Take:
+@verbatim
+	<?xml version="1.0" standalone=no>
+	<!-- Our to do list data -->
+	<ToDo>
+		<Item priority="1"> Go to the <bold>Toy store!</bold></Item>
+		<Item priority="2"> Do bills</Item>
+	</ToDo>
+@endverbatim
+
+Its not much of a To Do list, but it will do. To read this file 
+(say "demo.xml") you would create a document, and parse it in:
+@verbatim
+	TiXmlDocument doc( "demo.xml" );
+	doc.LoadFile();
+@endverbatim
+
+And its ready to go. Now lets look at some lines and how they 
+relate to the DOM.
+
+@verbatim
+<?xml version="1.0" standalone=no>
+@endverbatim
+
+	The first line is a declaration, and gets turned into the
+	TiXmlDeclaration class. It will be the first child of the
+	document node.
+	
+	This is the only directive/special tag parsed by by TinyXML.
+	Generally directive tags are stored in TiXmlUnknown so the 
+	commands wont be lost when it is saved back to disk.
+
+@verbatim
+<!-- Our to do list data -->
+@endverbatim
+
+	A comment. Will become a TiXmlComment object.
+
+@verbatim
+<ToDo>
+@endverbatim
+
+	The "ToDo" tag defines a TiXmlElement object. This one does not have 
+	any attributes, but does contain 2 other elements.
+
+@verbatim
+<Item priority="1"> 
+@endverbatim
+
+	Creates another TiXmlElement which is a child of the "ToDo" element. 
+	This element has 1 attribute, with the name "priority" and the value 
+	"1".
+
+@verbatim
+Go to the
+@endverbatim 
+
+	A TiXmlText. This is a leaf node and cannot contain other nodes. 
+	It is a child of the "Item" TiXmlElement.
+
+@verbatim
+<bold>
+@endverbatim
+
+	
+	Another TiXmlElement, this one a child of the "Item" element.
+
+Etc.
+
+Looking at the entire object tree, you end up with:
+@verbatim
+TiXmlDocument					"demo.xml"
+	TiXmlDeclaration			"version='1.0'" "standalone=no"
+	TiXmlComment				" Our to do list data"
+	TiXmlElement				"ToDo"
+		TiXmlElement			"Item" Attribtutes: priority = 1
+			TiXmlText			"Go to the "
+			TiXmlElement		"bold"
+				TiXmlText		"Toy store!"
+		TiXmlElement			"Item" Attributes: priority=2
+			TiXmlText			"Do bills"
+@endverbatim
+
+<h2> Documentation </h2>
+
+The documentation is build with Doxygen, using the 'dox' 
+configuration file.
+
+<h2> License </h2>
+
+TinyXML is released under the zlib license:
+
+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.
+
+<h2> References  </h2>
+
+The World Wide Web Consortium is the definitive standard body for 
+XML, and there web pages contain huge amounts of information. 
+
+The definitive spec: <a href="http://www.w3.org/TR/2004/REC-xml-20040204/">
+http://www.w3.org/TR/2004/REC-xml-20040204/</a>
+
+I also recommend "XML Pocket Reference" by Robert Eckstein and published by 
+OReilly...the book that got the whole thing started.
+
+<h2> Contributors, Contacts, and a Brief History </h2>
+
+Thanks very much to everyone who sends suggestions, bugs, ideas, and 
+encouragement. It all helps, and makes this project fun. A special thanks
+to the contributors on the web pages that keep it lively.
+
+So many people have sent in bugs and ideas, that rather than list here 
+we try to give credit due in the "changes.txt" file.
+
+TinyXML was originally written by Lee Thomason. (Often the "I" still
+in the documentation.) Lee reviews changes and releases new versions,
+with the help of Yves Berquin, Andrew Ellerton, and the tinyXml community.
+
+We appreciate your suggestions, and would love to know if you 
+use TinyXML. Hopefully you will enjoy it and find it useful. 
+Please post questions, comments, file bugs, or contact us at:
+
+www.sourceforge.net/projects/tinyxml
+
+Lee Thomason, Yves Berquin, Andrew Ellerton
+*/
Index: /code/branches/rocket2/src/external/tinyxml/ticpp.cpp
===================================================================
--- /code/branches/rocket2/src/external/tinyxml/ticpp.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/tinyxml/ticpp.cpp	(revision 6952)
@@ -0,0 +1,1150 @@
+/*
+http://code.google.com/p/ticpp/
+Copyright (c) 2006 Ryan Pusztai, Ryan Mulder
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifdef TIXML_USE_TICPP
+
+#include "ticpp.h"
+#include "ticpprc.h"
+#include "tinyxml.h"
+#include <sstream>
+
+using namespace ticpp;
+
+// In the following Visitor functions, casting away const should be safe, as the object can only be referred to by a const &
+bool Visitor::VisitEnter( const TiXmlDocument& doc )
+{
+	return VisitEnter( Document( const_cast< TiXmlDocument* >( &doc ) ) );
+}
+
+bool Visitor::VisitExit( const TiXmlDocument& doc )
+{
+	return VisitEnter( Document( const_cast< TiXmlDocument* >( &doc ) ) );
+}
+
+bool Visitor::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
+{
+	if ( 0 != firstAttribute )
+	{
+		Attribute attribute( const_cast< TiXmlAttribute* >( firstAttribute ) );
+		return VisitEnter( Element( const_cast< TiXmlElement* >( &element ) ), &attribute );
+	}
+	else
+	{
+		return VisitEnter( Element( const_cast< TiXmlElement* >( &element ) ), 0 );
+	}
+}
+
+bool Visitor::VisitExit( const TiXmlElement& element )
+{
+	return VisitExit( Element( const_cast< TiXmlElement* >( &element ) ) );
+}
+
+bool Visitor::Visit( const TiXmlDeclaration& declaration )
+{
+	return Visit( Declaration( const_cast< TiXmlDeclaration* >( &declaration ) ) );
+}
+
+bool Visitor::Visit( const TiXmlStylesheetReference& stylesheet )
+{
+	return Visit( StylesheetReference( const_cast< TiXmlStylesheetReference* >( &stylesheet ) ) );
+}
+
+bool Visitor::Visit( const TiXmlText& text )
+{
+	return Visit( Text( const_cast< TiXmlText* >( &text ) ) );
+}
+
+bool Visitor::Visit( const TiXmlComment& comment )
+{
+	return Visit( Comment( const_cast< TiXmlComment* >( &comment ) ) );
+}
+
+Attribute::Attribute()
+{
+	SetTiXmlPointer( new TiXmlAttribute() );
+	m_impRC->InitRef();
+}
+
+Attribute::Attribute( TiXmlAttribute* attribute )
+{
+	SetTiXmlPointer( attribute );
+	m_impRC->IncRef();
+}
+
+Attribute::Attribute( const std::string& name, const std::string& value )
+{
+	SetTiXmlPointer( new TiXmlAttribute( name, value ) );
+	m_impRC->InitRef();
+}
+
+void Attribute::operator=( const Attribute& copy )
+{
+	// Dropping the reference to the old object
+	this->m_impRC->DecRef();
+
+	// Pointing to the new Object
+	SetTiXmlPointer( copy.m_tiXmlPointer );
+
+	// The internal tixml pointer changed in the above line
+	this->m_impRC->IncRef();
+}
+
+Attribute::Attribute( const Attribute& copy ) : Base()
+{
+	// Dropping the reference to the old object
+	this->m_impRC->DecRef();
+
+	// Pointing to the new Object
+	SetTiXmlPointer( copy.m_tiXmlPointer );
+
+	// The internal tixml pointer changed in the above line
+	this->m_impRC->IncRef();
+}
+
+Attribute::~Attribute()
+{
+	m_impRC->DecRef();
+}
+
+std::string Attribute::Value() const
+{
+	ValidatePointer();
+	return m_tiXmlPointer->ValueStr();
+}
+
+std::string Attribute::Name() const
+{
+	ValidatePointer();
+	return m_tiXmlPointer->Name();
+}
+
+Attribute* Attribute::Next( bool throwIfNoAttribute ) const
+{
+	ValidatePointer();
+	TiXmlAttribute* attribute = m_tiXmlPointer->Next();
+	if ( 0 == attribute )
+	{
+		if ( throwIfNoAttribute )
+		{
+			TICPPTHROW( "No more attributes found" )
+		}
+		else
+		{
+			return 0;
+		}
+	}
+
+	Attribute* temp = new Attribute( attribute );
+	attribute->m_spawnedWrappers.push_back( temp );
+
+	return temp;
+}
+
+Attribute* Attribute::Previous( bool throwIfNoAttribute ) const
+{
+	ValidatePointer();
+	TiXmlAttribute* attribute = m_tiXmlPointer->Previous();
+	if ( 0 == attribute )
+	{
+		if ( throwIfNoAttribute )
+		{
+			TICPPTHROW( "No more attributes found" )
+		}
+		else
+		{
+			return 0;
+		}
+	}
+
+	Attribute* temp = new Attribute( attribute );
+	attribute->m_spawnedWrappers.push_back( temp );
+
+	return temp;
+}
+
+void Attribute::IterateNext( const std::string&, Attribute** next ) const
+{
+	*next = Next( false );
+}
+
+void Attribute::IteratePrevious( const std::string&, Attribute** previous ) const
+{
+	*previous = Previous( false );
+}
+
+void Attribute::Print( FILE* file, int depth ) const
+{
+	ValidatePointer();
+	m_tiXmlPointer->Print( file, depth );
+}
+
+void Attribute::SetTiXmlPointer( TiXmlAttribute* newPointer )
+{
+	m_tiXmlPointer = newPointer;
+	SetImpRC( newPointer );
+}
+
+//*****************************************************************************
+
+Node* Node::NodeFactory( TiXmlNode* tiXmlNode, bool throwIfNull, bool rememberSpawnedWrapper ) const
+{
+	if ( 0 == tiXmlNode )
+	{
+		if ( throwIfNull )
+		{
+			TICPPTHROW( "tiXmlNode is NULL" )
+		}
+		else
+		{
+			return 0;
+		}
+	}
+
+	Node* temp;
+	switch ( tiXmlNode->Type() )
+	{
+		case TiXmlNode::DOCUMENT:
+			temp = new Document( tiXmlNode->ToDocument() );
+			break;
+
+		case TiXmlNode::ELEMENT:
+			temp = new Element( tiXmlNode->ToElement() );
+			break;
+
+		case TiXmlNode::COMMENT:
+			temp = new Comment( tiXmlNode->ToComment() );
+			break;
+
+		case TiXmlNode::TEXT:
+			temp = new Text( tiXmlNode->ToText() );
+			break;
+
+		case TiXmlNode::DECLARATION:
+			temp = new Declaration( tiXmlNode->ToDeclaration() );
+			break;
+
+		case TiXmlNode::STYLESHEETREFERENCE:
+			temp = new StylesheetReference( tiXmlNode->ToStylesheetReference() );
+			break;
+
+		default:
+			TICPPTHROW( "Type is unsupported" )
+	}
+
+	if ( rememberSpawnedWrapper )
+	{
+		tiXmlNode->m_spawnedWrappers.push_back( temp );
+	}
+	return temp;
+}
+
+
+std::string Node::Value() const
+{
+	return GetTiXmlPointer()->ValueStr();
+}
+
+void Node::Clear()
+{
+	GetTiXmlPointer()->Clear();
+}
+
+Node* Node::Parent( bool throwIfNoParent ) const
+{
+	TiXmlNode* parent = GetTiXmlPointer()->Parent();
+	if ( ( 0 == parent ) && throwIfNoParent )
+	{
+		TICPPTHROW( "No parent exists" );
+	}
+
+	return NodeFactory( parent, false );
+}
+
+Node* Node::FirstChild( bool throwIfNoChildren ) const
+{
+	return FirstChild( "", throwIfNoChildren );
+}
+
+Node* Node::FirstChild( const std::string& value, bool throwIfNoChildren ) const
+{
+	return FirstChild( value.c_str(), throwIfNoChildren );
+}
+
+Node* Node::FirstChild( const char* value, bool throwIfNoChildren ) const
+{
+	TiXmlNode* childNode;
+	if ( 0 == strlen( value ) )
+	{
+		childNode = GetTiXmlPointer()->FirstChild();
+	}
+	else
+	{
+		childNode = GetTiXmlPointer()->FirstChild( value );
+	}
+
+	if ( ( 0 == childNode ) && throwIfNoChildren )
+	{
+		TICPPTHROW( "Child with the value of \"" << value << "\" not found" );
+	}
+
+	return NodeFactory( childNode, false );
+}
+
+Node* Node::LastChild( bool throwIfNoChildren ) const
+{
+	return LastChild( "", throwIfNoChildren );
+}
+
+Node* Node::LastChild( const std::string& value, bool throwIfNoChildren ) const
+{
+	return LastChild( value.c_str(), throwIfNoChildren );
+}
+
+Node* Node::LastChild( const char* value, bool throwIfNoChildren ) const
+{
+	TiXmlNode* childNode;
+	if ( 0 == strlen( value ) )
+	{
+		childNode = GetTiXmlPointer()->LastChild();
+	}
+	else
+	{
+		childNode = GetTiXmlPointer()->LastChild( value );
+	}
+
+	if ( ( 0 == childNode ) && throwIfNoChildren )
+	{
+		TICPPTHROW( "Child with the value of \"" << value << "\" not found" );
+	}
+
+	return NodeFactory( childNode, false );
+}
+
+Node* Node::IterateChildren ( Node* previous ) const
+{
+	TiXmlNode* pointer;
+	if ( 0 == previous )
+	{
+		pointer = GetTiXmlPointer()->IterateChildren( 0 );
+	}
+	else
+	{
+		pointer = GetTiXmlPointer()->IterateChildren( previous->GetTiXmlPointer() );
+	}
+
+	return NodeFactory( pointer, false );
+}
+
+Node* Node::IterateChildren( const std::string& value, Node* previous ) const
+{
+	TiXmlNode* pointer;
+	if ( 0 == previous )
+	{
+		pointer = GetTiXmlPointer()->IterateChildren( value, 0 );
+	}
+	else
+	{
+		pointer = GetTiXmlPointer()->IterateChildren( value, previous->GetTiXmlPointer() );
+	}
+
+	return NodeFactory( pointer, false );
+}
+
+Node* Node::InsertEndChild( Node& addThis )
+{
+	if ( addThis.Type() == TiXmlNode::DOCUMENT )
+	{
+		TICPPTHROW( "Node is a Document and can't be inserted" );
+	}
+
+	TiXmlNode* pointer = GetTiXmlPointer()->InsertEndChild( *addThis.GetTiXmlPointer() );
+	if ( 0 == pointer )
+	{
+		TICPPTHROW( "Node can't be inserted" );
+	}
+
+	return NodeFactory( pointer );
+}
+
+Node* Node::LinkEndChild( Node* childNode )
+{
+	if ( childNode->Type() == TiXmlNode::DOCUMENT )
+	{
+		TICPPTHROW( "Node is a Document and can't be linked" );
+	}
+
+	// Increment reference count when adding to the tree
+	childNode->m_impRC->IncRef();
+
+	if ( 0 == GetTiXmlPointer()->LinkEndChild( childNode->GetTiXmlPointer() ) )
+	{
+		TICPPTHROW( "Node can't be linked" );
+	}
+
+	return childNode;
+}
+
+Node* Node::InsertBeforeChild( Node* beforeThis, Node& addThis )
+{
+	if ( addThis.Type() == TiXmlNode::DOCUMENT )
+	{
+		TICPPTHROW( "Node is a Document and can't be inserted" );
+	}
+
+	// Increment reference count when adding to the tree
+	addThis.m_impRC->IncRef();
+
+	TiXmlNode* pointer = GetTiXmlPointer()->InsertBeforeChild( beforeThis->GetTiXmlPointer(), *addThis.GetTiXmlPointer() );
+	if ( 0 == pointer )
+	{
+		TICPPTHROW( "Node can't be inserted" );
+	}
+
+	return NodeFactory( pointer );
+}
+
+Node* Node::InsertAfterChild( Node* afterThis, Node& addThis )
+{
+	if ( addThis.Type() == TiXmlNode::DOCUMENT )
+	{
+		TICPPTHROW( "Node is a Document and can't be inserted" );
+	}
+
+	// Increment reference count when adding to the tree
+	addThis.m_impRC->IncRef();
+
+	TiXmlNode* pointer = GetTiXmlPointer()->InsertAfterChild( afterThis->GetTiXmlPointer(), *addThis.GetTiXmlPointer() );
+	if ( 0 == pointer )
+	{
+		TICPPTHROW( "Node can't be inserted" );
+	}
+
+	return NodeFactory( pointer );
+}
+
+Node* Node::ReplaceChild( Node* replaceThis, Node& withThis )
+{
+	if ( withThis.Type() == TiXmlNode::DOCUMENT )
+	{
+		TICPPTHROW( "Node is a Document and can't be inserted" );
+	}
+
+	// Increment reference count when adding to the tree
+	withThis.m_impRC->IncRef();
+
+	TiXmlNode* pointer = GetTiXmlPointer()->ReplaceChild( replaceThis->GetTiXmlPointer(), *withThis.GetTiXmlPointer() );
+	if ( 0 == pointer )
+	{
+		TICPPTHROW( "Node can't be inserted" );
+	}
+
+	return NodeFactory( pointer );
+}
+
+void Node::RemoveChild( Node* removeThis )
+{
+	if  ( !GetTiXmlPointer()->RemoveChild( removeThis->GetTiXmlPointer() ) )
+	{
+		TICPPTHROW( "Node to remove (" << removeThis->Value() << ") is not a child of this Node (" << Value() << ")" )
+	}
+}
+
+Node* Node::PreviousSibling( bool throwIfNoSiblings ) const
+{
+	return PreviousSibling( "", throwIfNoSiblings );
+}
+
+Node* Node::PreviousSibling( const std::string& value, bool throwIfNoSiblings ) const
+{
+	return PreviousSibling( value.c_str(), throwIfNoSiblings );
+}
+
+Node* Node::PreviousSibling( const char* value, bool throwIfNoSiblings ) const
+{
+	TiXmlNode* sibling;
+	if ( 0 == strlen( value ) )
+	{
+		sibling = GetTiXmlPointer()->PreviousSibling();
+	}
+	else
+	{
+		sibling = GetTiXmlPointer()->PreviousSibling( value );
+	}
+
+	if ( ( 0 == sibling ) && throwIfNoSiblings )
+	{
+		TICPPTHROW( "No Siblings found with value, '" << value << "', Prior to this Node (" << Value() << ")" )
+	}
+
+	return NodeFactory( sibling, false );
+}
+
+Node* Node::NextSibling( bool throwIfNoSiblings ) const
+{
+	return NextSibling( "", throwIfNoSiblings );
+}
+
+Node* Node::NextSibling( const std::string& value, bool throwIfNoSiblings ) const
+{
+	return NextSibling( value.c_str(), throwIfNoSiblings );
+}
+
+Node* Node::NextSibling( const char* value, bool throwIfNoSiblings ) const
+{
+	TiXmlNode* sibling;
+	if ( 0 == strlen( value ) )
+	{
+		sibling = GetTiXmlPointer()->NextSibling();
+	}
+	else
+	{
+		sibling = GetTiXmlPointer()->NextSibling( value );
+	}
+
+	if ( ( 0 == sibling ) && throwIfNoSiblings )
+	{
+		TICPPTHROW( "No Siblings found with value, '" << value << "', After this Node (" << Value() << ")" )
+	}
+
+	return NodeFactory( sibling, false );
+}
+
+Element* Node::NextSiblingElement( bool throwIfNoSiblings ) const
+{
+	return NextSiblingElement( "", throwIfNoSiblings );
+}
+
+Element* Node::NextSiblingElement( const std::string& value, bool throwIfNoSiblings ) const
+{
+	return NextSiblingElement( value.c_str(), throwIfNoSiblings );
+}
+
+Element* Node::NextSiblingElement( const char* value, bool throwIfNoSiblings ) const
+{
+	TiXmlElement* sibling;
+	if ( 0 == strlen( value ) )
+	{
+		sibling = GetTiXmlPointer()->NextSiblingElement();
+	}
+	else
+	{
+		sibling = GetTiXmlPointer()->NextSiblingElement( value );
+	}
+
+	if ( 0 == sibling )
+	{
+		if ( throwIfNoSiblings )
+		{
+			TICPPTHROW( "No Element Siblings found with value, '" << value << "', After this Node (" << Value() << ")" )
+		}
+		else
+		{
+			return 0;
+		}
+	}
+
+	Element* temp = new Element( sibling );
+	sibling->m_spawnedWrappers.push_back( temp );
+
+	return temp;
+}
+
+Element* Node::FirstChildElement( bool throwIfNoChildren ) const
+{
+	return FirstChildElement( "", throwIfNoChildren );
+}
+
+Element* Node::FirstChildElement( const std::string& value, bool throwIfNoChildren ) const
+{
+	return FirstChildElement( value.c_str(), throwIfNoChildren );
+}
+
+Element* Node::FirstChildElement( const char* value, bool throwIfNoChildren ) const
+{
+	TiXmlElement* element;
+	if ( 0 == strlen( value ) )
+	{
+		element = GetTiXmlPointer()->FirstChildElement();
+	}
+	else
+	{
+		element = GetTiXmlPointer()->FirstChildElement( value );
+	}
+
+	if ( 0 == element )
+	{
+		if( throwIfNoChildren )
+		{
+			TICPPTHROW( "Element (" << Value() << ") does NOT contain a child with the value of '" << value << "'" )
+		}
+		else
+		{
+			return 0;
+		}
+	}
+
+	Element* temp = new Element( element );
+	element->m_spawnedWrappers.push_back( temp );
+
+	return temp;
+}
+
+int Node::Type() const
+{
+	return GetTiXmlPointer()->Type();
+}
+
+Document* Node::GetDocument( bool throwIfNoDocument ) const
+{
+	TiXmlDocument* doc = GetTiXmlPointer()->GetDocument();
+	if ( 0 == doc )
+	{
+		if( throwIfNoDocument )
+		{
+			TICPPTHROW( "This node (" << Value() << ") is not linked under a document" )
+		}
+		else
+		{
+			return 0;
+		}
+	}
+	Document* temp = new Document( doc );
+	doc->m_spawnedWrappers.push_back( temp );
+
+	return temp;
+}
+
+bool Node::NoChildren() const
+{
+	return GetTiXmlPointer()->NoChildren();
+}
+
+Document* Node::ToDocument() const
+{
+	TiXmlDocument* doc = GetTiXmlPointer()->ToDocument();
+	if ( 0 == doc )
+	{
+		TICPPTHROW( "This node (" << Value() << ") is not a Document" )
+	}
+	Document* temp = new Document( doc );
+	doc->m_spawnedWrappers.push_back( temp );
+
+	return temp;
+}
+
+Element* Node::ToElement() const
+{
+	TiXmlElement* doc = GetTiXmlPointer()->ToElement();
+	if ( 0 == doc )
+	{
+		TICPPTHROW( "This node (" << Value() << ") is not a Element" )
+	}
+	Element* temp = new Element( doc );
+	doc->m_spawnedWrappers.push_back( temp );
+
+	return temp;
+}
+
+Comment* Node::ToComment() const
+{
+	TiXmlComment* doc = GetTiXmlPointer()->ToComment();
+	if ( 0 == doc )
+	{
+		TICPPTHROW( "This node (" << Value() << ") is not a Comment" )
+	}
+	Comment* temp = new Comment( doc );
+	doc->m_spawnedWrappers.push_back( temp );
+
+	return temp;
+}
+
+Text* Node::ToText() const
+{
+	TiXmlText* doc = GetTiXmlPointer()->ToText();
+	if ( 0 == doc )
+	{
+		TICPPTHROW( "This node (" << Value() << ") is not a Text" )
+	}
+	Text* temp = new Text( doc );
+	doc->m_spawnedWrappers.push_back( temp );
+
+	return temp;
+}
+
+Declaration* Node::ToDeclaration() const
+{
+	TiXmlDeclaration* doc = GetTiXmlPointer()->ToDeclaration();
+	if ( 0 == doc )
+	{
+		TICPPTHROW( "This node (" << Value() << ") is not a Declaration" )
+	}
+	Declaration* temp = new Declaration( doc );
+	doc->m_spawnedWrappers.push_back( temp );
+
+	return temp;
+}
+
+StylesheetReference* Node::ToStylesheetReference() const
+{
+	TiXmlStylesheetReference* doc = GetTiXmlPointer()->ToStylesheetReference();
+	if ( 0 == doc )
+	{
+		TICPPTHROW( "This node (" << Value() << ") is not a StylesheetReference" )
+	}
+	StylesheetReference* temp = new StylesheetReference( doc );
+	doc->m_spawnedWrappers.push_back( temp );
+
+	return temp;
+}
+
+std::auto_ptr< Node > Node::Clone() const
+{
+	TiXmlNode* node = GetTiXmlPointer()->Clone();
+	if ( 0 == node )
+	{
+		TICPPTHROW( "Node could not be cloned" );
+	}
+	std::auto_ptr< Node > temp( NodeFactory( node, false, false ) );
+
+	// Take ownership of the memory from TiXml
+	temp->m_impRC->InitRef();
+
+	return temp;
+}
+
+bool Node::Accept( TiXmlVisitor* visitor ) const
+{
+	return GetTiXmlPointer()->Accept( visitor );
+}
+
+//*****************************************************************************
+
+Comment::Comment()
+: NodeImp< TiXmlComment >( new TiXmlComment() )
+{
+	m_impRC->InitRef();
+}
+
+Comment::Comment( TiXmlComment* comment )
+: NodeImp< TiXmlComment >( comment )
+{
+}
+
+Comment::Comment( const std::string& comment )
+: NodeImp< TiXmlComment >( new TiXmlComment() )
+{
+	m_impRC->InitRef();
+	m_tiXmlPointer->SetValue( comment );
+}
+
+//*****************************************************************************
+
+Text::Text()
+: NodeImp< TiXmlText >( new TiXmlText("") )
+{
+	m_impRC->InitRef();
+}
+
+
+Text::Text( const std::string& value )
+: NodeImp< TiXmlText >( new TiXmlText( value ) )
+{
+	m_impRC->InitRef();
+}
+
+Text::Text( TiXmlText* text )
+: NodeImp< TiXmlText >( text )
+{
+}
+
+
+//*****************************************************************************
+
+Document::Document()
+: NodeImp< TiXmlDocument >( new TiXmlDocument() )
+{
+	m_impRC->InitRef();
+}
+
+Document::Document( TiXmlDocument* document )
+: NodeImp< TiXmlDocument >( document )
+{
+}
+
+Document::Document( const char* documentName )
+: NodeImp< TiXmlDocument >( new TiXmlDocument( documentName ) )
+{
+	m_impRC->InitRef();
+}
+
+Document::Document( const std::string& documentName )
+: NodeImp< TiXmlDocument >( new TiXmlDocument( documentName ) )
+{
+	m_impRC->InitRef();
+}
+
+void Document::LoadFile( TiXmlEncoding encoding )
+{
+	if ( !m_tiXmlPointer->LoadFile( encoding ) )
+	{
+		TICPPTHROW( "Couldn't load " << m_tiXmlPointer->Value() );
+	}
+}
+
+void Document::SaveFile( void ) const
+{
+	if ( !m_tiXmlPointer->SaveFile() )
+	{
+		TICPPTHROW( "Couldn't save " << m_tiXmlPointer->Value() );
+	}
+}
+
+void Document::LoadFile( const std::string& filename, TiXmlEncoding encoding )
+{
+	if ( !m_tiXmlPointer->LoadFile( filename.c_str(), encoding ) )
+	{
+		TICPPTHROW( "Couldn't load " << filename );
+	}
+}
+
+void Document::LoadFile( const char* filename, TiXmlEncoding encoding )
+{
+	if ( !m_tiXmlPointer->LoadFile( filename, encoding ) )
+	{
+		TICPPTHROW( "Couldn't load " << filename );
+	}
+}
+
+void Document::SaveFile( const std::string& filename ) const
+{
+	if ( !m_tiXmlPointer->SaveFile( filename.c_str() ) )
+	{
+		TICPPTHROW( "Couldn't save " << filename );
+	}
+}
+
+void Document::Parse( const std::string& xml, bool throwIfParseError, TiXmlEncoding encoding )
+{
+	m_tiXmlPointer->Parse( xml.c_str(), 0, encoding );
+	if( throwIfParseError && m_tiXmlPointer->Error() )
+	{
+		TICPPTHROW( "Error parsing xml." );
+	}
+}
+
+//*****************************************************************************
+
+Element::Element()
+: NodeImp< TiXmlElement >( new TiXmlElement( "DefaultValueCausedByCreatingAnElementWithNoParameters" ) )
+{
+	m_impRC->InitRef();
+}
+
+Element::Element( const std::string& value )
+: NodeImp< TiXmlElement >( new TiXmlElement( value ) )
+{
+	m_impRC->InitRef();
+}
+
+Element::Element( const char* value )
+: NodeImp< TiXmlElement >( new TiXmlElement( value ) )
+{
+	m_impRC->InitRef();
+}
+
+Element::Element( TiXmlElement* element )
+: NodeImp< TiXmlElement >( element )
+{
+}
+
+Attribute* Element::FirstAttribute( bool throwIfNoAttributes ) const
+{
+	ValidatePointer();
+	TiXmlAttribute* attribute = m_tiXmlPointer->FirstAttribute();
+	if ( ( 0 == attribute ) && throwIfNoAttributes )
+	{
+		TICPPTHROW( "This Element (" << Value() << ") has no attributes" )
+	}
+
+	if ( 0 == attribute )
+	{
+		if( throwIfNoAttributes )
+		{
+			TICPPTHROW( "Element (" << Value() << ") has no attributes" )
+		}
+		else
+		{
+			return 0;
+		}
+	}
+
+	Attribute* temp = new Attribute( attribute );
+	attribute->m_spawnedWrappers.push_back( temp );
+
+	return temp;
+}
+
+Attribute* Element::LastAttribute( bool throwIfNoAttributes ) const
+{
+	ValidatePointer();
+	TiXmlAttribute* attribute = m_tiXmlPointer->LastAttribute();
+	if ( ( 0 == attribute ) && throwIfNoAttributes )
+	{
+		TICPPTHROW( "This Element (" << Value() << ") has no attributes" )
+	}
+
+	if ( 0 == attribute )
+	{
+		if( throwIfNoAttributes )
+		{
+			TICPPTHROW( "Element (" << Value() << ") has no attributes" )
+		}
+		else
+		{
+			return 0;
+		}
+	}
+
+	Attribute* temp = new Attribute( attribute );
+	attribute->m_spawnedWrappers.push_back( temp );
+
+	return temp;
+}
+
+std::string Element::GetAttributeOrDefault( const std::string& name, const std::string& defaultValue ) const
+{
+	std::string value;
+	if ( !GetAttributeImp( name, &value ) )
+	{
+		return defaultValue;
+	}
+	return value;
+}
+
+std::string Element::GetAttribute( const std::string& name ) const
+{
+	return GetAttributeOrDefault( name, std::string() );
+}
+
+bool Element::HasAttribute( const std::string& name ) const
+{
+	ValidatePointer();
+	return ( 0 != m_tiXmlPointer->Attribute( name.c_str() ) );
+}
+
+void Element::RemoveAttribute( const std::string& name )
+{
+	ValidatePointer();
+	m_tiXmlPointer->RemoveAttribute( name.c_str() );
+}
+
+bool Element::GetAttributeImp( const std::string& name, std::string* value ) const
+{
+	ValidatePointer();
+
+	// Get value from TinyXML, if the attribute exists
+	const char* retVal = m_tiXmlPointer->Attribute( name.c_str() );
+
+	// TinyXML returns NULL if the attribute doesn't exist
+	if ( 0 == retVal )
+	{
+		return false;
+	}
+	else
+	{
+		*value = retVal;
+		return true;
+	}
+}
+
+bool Element::GetTextImp( std::string* value ) const
+{
+	ValidatePointer();
+
+	// Get value from TinyXML, if the attribute exists
+	const char* retVal = m_tiXmlPointer->GetText();
+
+	// TinyXML returns NULL if the attribute doesn't exist
+	if ( 0 == retVal )
+	{
+		return false;
+	}
+	else
+	{
+		*value = retVal;
+		return true;
+	}
+}
+
+//*****************************************************************************
+
+Declaration::Declaration()
+: NodeImp< TiXmlDeclaration >( new TiXmlDeclaration() )
+{
+	m_impRC->InitRef();
+}
+
+Declaration::Declaration( TiXmlDeclaration* declaration )
+: NodeImp< TiXmlDeclaration >( declaration )
+{
+}
+
+Declaration::Declaration( const std::string& version, const std::string& encoding, const std::string& standalone )
+: NodeImp< TiXmlDeclaration >( new TiXmlDeclaration( version, encoding, standalone ) )
+{
+	m_impRC->InitRef();
+}
+
+std::string Declaration::Version() const
+{
+	return m_tiXmlPointer->Version();
+}
+
+std::string Declaration::Encoding() const
+{
+	return m_tiXmlPointer->Encoding();
+}
+
+std::string Declaration::Standalone() const
+{
+	return m_tiXmlPointer->Standalone();
+}
+
+//*****************************************************************************
+
+StylesheetReference::StylesheetReference()
+: NodeImp< TiXmlStylesheetReference >( new TiXmlStylesheetReference() )
+{
+	m_impRC->InitRef();
+}
+
+StylesheetReference::StylesheetReference( TiXmlStylesheetReference* stylesheetReference )
+: NodeImp< TiXmlStylesheetReference >( stylesheetReference )
+{
+}
+
+StylesheetReference::StylesheetReference( const std::string& type, const std::string& href )
+: NodeImp< TiXmlStylesheetReference >( new TiXmlStylesheetReference( type, href ) )
+{
+	m_impRC->InitRef();
+}
+
+std::string StylesheetReference::Type() const
+{
+	return m_tiXmlPointer->Type();
+}
+
+std::string StylesheetReference::Href() const
+{
+	return m_tiXmlPointer->Href();
+}
+
+//*****************************************************************************
+
+Exception::Exception(const std::string &details)
+:
+m_details( details )
+{
+
+}
+
+Exception::~Exception() throw()
+{
+}
+
+const char* Exception::what() const throw()
+{
+	return m_details.c_str();
+}
+
+//*****************************************************************************
+
+TiCppRC::TiCppRC()
+{
+	// Spawn reference counter for this object
+	m_tiRC = new TiCppRCImp( this );
+}
+
+void TiCppRC::DeleteSpawnedWrappers()
+{
+	std::vector< Base* >::reverse_iterator wrapper;
+	for ( wrapper = m_spawnedWrappers.rbegin(); wrapper != m_spawnedWrappers.rend(); ++wrapper )
+	{
+		delete *wrapper;
+	}
+	m_spawnedWrappers.clear();
+}
+		
+TiCppRC::~TiCppRC()
+{	
+	DeleteSpawnedWrappers();
+	
+	// Set pointer held by reference counter to NULL
+	this->m_tiRC->Nullify();
+
+	// Decrement reference - so reference counter will delete itself if necessary
+	this->m_tiRC->DecRef();
+}
+
+//*****************************************************************************
+
+TiCppRCImp::TiCppRCImp( TiCppRC* tiCppRC )
+	: m_count( 1 ), m_tiCppRC ( tiCppRC )
+{
+}
+
+void TiCppRCImp::IncRef()
+{
+	m_count++;
+}
+
+void TiCppRCImp::DecRef()
+{
+	m_count--;
+	if ( 0 == m_count )
+	{
+		delete m_tiCppRC;
+		delete this;
+	}
+}
+
+void TiCppRCImp::InitRef()
+{
+	m_count = 1;
+}
+
+void TiCppRCImp::Nullify()
+{
+	m_tiCppRC = 0;
+}
+
+TiCppRC* TiCppRCImp::Get()
+{
+	return m_tiCppRC;
+}
+
+bool TiCppRCImp::IsNull()
+{
+	return 0 == m_tiCppRC;
+}
+
+#endif // TIXML_USE_TICPP
Index: /code/branches/rocket2/src/external/tinyxml/ticpp.h
===================================================================
--- /code/branches/rocket2/src/external/tinyxml/ticpp.h	(revision 6952)
+++ /code/branches/rocket2/src/external/tinyxml/ticpp.h	(revision 6952)
@@ -0,0 +1,1904 @@
+/*
+http://code.google.com/p/ticpp/
+Copyright (c) 2006 Ryan Pusztai, Ryan Mulder
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+/**
+@copydoc ticpp
+@file
+@author		Ryan Pusztai
+@author		Ryan Mulder
+@date		04/11/2006
+
+@version	0.04a by edam@waxworlds.org: based Exception based on std::exception; added stream
+					<< and >> support; added Document::Parse(); bug fix; improved THROW() macro.
+@version	0.04 Added NodeImp class. Also made all the classes inherit from NodeImp.
+@version	0.03 Added Declaration class
+@version	0.02 Added Element class
+@version	0.01 Added Exception class, Document class
+
+@todo add UNKNOWN support. See ticpp::NodeFactory.
+@todo add TYPECOUNT support. See ticpp::NodeFactory.
+@todo Add a quick reference
+*/
+#ifdef TIXML_USE_TICPP
+
+#ifndef TICPP_INCLUDED
+#define TICPP_INCLUDED
+
+#include "tinyxml.h"
+#include <sstream>
+#include <vector>
+#include <memory>
+#include <exception>
+#include <typeinfo>
+
+/**
+@subpage ticpp is a TinyXML wrapper that uses a lot more C++ ideals.
+It throws exceptions, uses templates, is in its own name space, and
+<b>requires</b> STL (Standard Template Library). This is done to ease the use
+of getting values in and out of the xml.
+
+If you don't perfer to use some of the concepts just don't use it.
+It is just a wrapper that extends TinyXML. It doesn't actually change
+any of TinyXML.
+*/
+namespace ticpp
+{
+    /**
+	This is a ticpp exception class
+	*/
+	class Exception : public std::exception
+	{
+	public:
+		/**
+		Construct an exception with a message
+		*/
+		Exception( const std::string& details );
+		~Exception() throw();
+
+		/// Override std::exception::what() to return m_details
+		const char* what() const throw();
+
+		std::string m_details; /**< Exception Details */
+	};
+
+	/**
+	This allows you to stream your exceptions in.
+	It will take care of the conversion	and throwing the exception.
+	*/
+	#define TICPPTHROW( message ) 											\
+	{																		\
+		std::ostringstream full_message;									\
+		std::string file( __FILE__ );										\
+		file = file.substr( file.find_last_of( "\\/" ) + 1 );				\
+		full_message << message << " <" << file << "@" << __LINE__ << ">";	\
+		full_message << BuildDetailedErrorString();							\
+		throw Exception( full_message.str() );								\
+	}
+
+	// Forward Declarations for Visitor, and others.
+	class Document;
+	class Element;
+	class Declaration;
+	class StylesheetReference;
+	class Text;
+	class Comment;
+	class Attribute;
+
+	/** Wrapper around TiXmlVisitor */
+	class Visitor : public TiXmlVisitor
+	{
+	public:
+		// Overload the TiXmlVisitor functions, wrap objects, call ticpp::Visitor functions
+		/// @internal
+		virtual bool VisitEnter( const TiXmlDocument& doc );
+		/// @internal
+		virtual bool VisitExit( const TiXmlDocument& doc );
+		/// @internal
+		virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
+		/// @internal
+		virtual bool VisitExit( const TiXmlElement& element );
+		/// @internal
+		virtual bool Visit( const TiXmlDeclaration& declaration );
+		/// @internal
+		virtual bool Visit( const TiXmlStylesheetReference& stylesheet );
+		/// @internal
+		virtual bool Visit( const TiXmlText& text );
+		/// @internal
+		virtual bool Visit( const TiXmlComment& comment );
+
+	public:
+		/// Visit a document.
+		virtual bool VisitEnter( const Document& /*doc*/ )			{ return true; }
+		/// Visit a document.
+		virtual bool VisitExit( const Document& /*doc*/ )			{ return true; }
+
+		/// Visit an element.
+		virtual bool VisitEnter( const Element& /*element*/, const Attribute* /*firstAttribute*/ )	{ return true; }
+		/// Visit an element.
+		virtual bool VisitExit( const Element& /*element*/ )		{ return true; }
+
+		/// Visit a declaration
+		virtual bool Visit( const Declaration& /*declaration*/ )	{ return true; }
+		/// Visit a stylesheet reference
+		virtual bool Visit( const StylesheetReference& /*stylesheet*/ )	{ return true; }
+		/// Visit a text node
+		virtual bool Visit( const Text& /*text*/ )					{ return true; }
+		/// Visit a comment node
+		virtual bool Visit( const Comment& /*comment*/ )			{ return true; }
+	};
+
+	/** Wrapper around TiXmlBase */
+	class Base
+	{
+	public:
+
+		/**
+		Converts any class with a proper overload of the << opertor to a std::string
+		@param value The value to be converted
+		@throws Exception When value cannot be converted to a std::string
+		*/
+		template < class T >
+			std::string ToString( const T& value ) const
+		{
+			std::stringstream convert;
+			convert << value;
+			if ( convert.fail() )
+			{
+				TICPPTHROW( "Could not convert value to text" );
+			}
+			return convert.str();
+		}
+
+		std::string ToString( const std::string& value ) const
+		{
+			return value;
+		}
+
+		/**
+		Converts a std::string to any class with a proper overload of the >> opertor
+		@param temp			The string to be converted
+		@param out	[OUT]	The container for the returned value
+		@throws Exception When temp cannot be converted to the target type
+		*/
+		template < class T >
+			void FromString( const std::string& temp, T* out ) const
+		{
+			std::istringstream val( temp );
+			val >> *out;
+
+			if ( val.fail() )
+			{
+				TICPPTHROW( "Could not convert \"" << temp << "\" to target type" );
+			}
+		}
+
+		/**
+		Specialization for std::string
+		*/
+		void FromString( const std::string& temp, std::string* out ) const
+		{
+			*out = temp;
+		}
+
+		/**
+		Return the position, in the original source file, of this node or attribute.
+		Wrapper around TiXmlBase::Row()
+		*/
+		int Row() const
+		{
+			return GetBasePointer()->Row();
+		}
+
+		/**
+		Return the position, in the original source file, of this node or attribute.
+		Wrapper around TiXmlBase::Row()
+		*/
+		int Column() const
+		{
+			return GetBasePointer()->Column();
+		}
+
+		/**
+		Compare internal TiXml pointers to determine is both are wrappers around the same node
+		*/
+		bool operator == ( const Base& rhs ) const
+		{
+			return ( GetBasePointer() == rhs.GetBasePointer() );
+		}
+		
+		/**
+		Compare internal TiXml pointers to determine is both are wrappers around the same node
+		*/
+		bool operator != ( const Base& rhs ) const
+		{
+			return ( GetBasePointer() != rhs.GetBasePointer() );
+		}
+		
+		/**
+		Builds detailed error string using TiXmlDocument::Error() and others
+		*/
+		std::string BuildDetailedErrorString() const
+		{
+			std::ostringstream full_message;
+			#ifndef TICPP_NO_RTTI
+			TiXmlNode* node = dynamic_cast< TiXmlNode* >( GetBasePointer() );
+			if ( node != 0 )
+			{
+				TiXmlDocument* doc = node->GetDocument();
+				if ( doc != 0 )
+				{
+					if ( doc->Error() )
+					{
+						full_message 	<< "\nDescription: " << doc->ErrorDesc()
+										<< "\nFile: " << (strlen( doc->Value() ) > 0 ? doc->Value() : "<unnamed-file>") 
+										<< "\nLine: " << doc->ErrorRow() 
+										<< "\nColumn: " << doc->ErrorCol();
+					}
+				}
+			}
+			#endif
+			return full_message.str();
+		}
+
+		/**
+		Destructor
+		*/
+		virtual ~Base()
+		{
+		}
+
+	protected:
+		mutable TiCppRCImp* m_impRC;	/**< Holds status of internal TiXmlPointer - use this to determine if object has been deleted already */
+
+		/**
+		@internal
+		Updates the pointer to the reference counter to point at the counter in the new node.
+
+		@param node TiXmlBase containing the new reference counter
+		*/
+		void SetImpRC( TiXmlBase* node )
+		{
+			m_impRC = node->m_tiRC;
+		}
+
+		void ValidatePointer() const
+		{
+			if ( m_impRC->IsNull() )
+			{
+				TICPPTHROW( "Internal TiXml Pointer is NULL" );
+			}
+		}		
+
+		/**
+		@internal
+		Get internal TiXmlBase*
+		*/
+		virtual TiXmlBase* GetBasePointer() const = 0;
+	};
+
+	/**
+	Wrapper around TiXmlAttribute
+	*/
+	class Attribute : public Base
+	{
+	private:
+		TiXmlAttribute* m_tiXmlPointer;
+		TiXmlBase* GetBasePointer() const
+		{
+			ValidatePointer();
+			return m_tiXmlPointer;
+		}
+
+	public:
+		/**
+		Construct an empty attribute.
+		*/
+		Attribute();
+
+		/**
+		Construct an attribute with @a name and @a value
+
+		@param name The name of the attribute
+		@param value The value of the attribute
+		*/
+		Attribute( const std::string& name, const std::string& value );
+
+		/**
+		@internal
+		Construct an attribute with the internal pointer
+
+		@param attribute The internal pointer
+		*/
+		Attribute( TiXmlAttribute* attribute );
+
+		/**
+		Get the value of this attribute
+		Uses Base::FromString to convert TiXmlAttribute::ValueStr from a std::string,
+		and puts it in the passed pointer.
+
+		@param value [OUT] A pointer to fill with the value
+		*/
+		template < class T >
+			void GetValue( T* value ) const
+		{
+			ValidatePointer();
+			FromString( m_tiXmlPointer->ValueStr(), value );
+		}
+
+		/**
+		Get the value of this attribute.
+		Simple wrapper for TiXmlAttribute::ValueStr.
+
+		@see GetValue
+		*/
+		std::string Value() const;
+
+		/**
+		Set the value of this node.
+		Uses Base::ToString to convert value to a std::string, then calls TiXmlAttribute::SetValue.
+
+		@param value The value to set
+		*/
+		template < class T >
+			void SetValue( const T& value )
+		{
+			ValidatePointer();
+			m_tiXmlPointer->SetValue( ToString( value ) );
+		}
+
+		/**
+		Get the value of this attribute
+		Uses Base::FromString to convert TiXmlAttribute::Name from a std::string,
+		and puts it in the passed pointer.
+
+		@param name [OUT] A pointer to fill with the name
+		*/
+		template < class T >
+			void GetName( T* name ) const
+		{
+			ValidatePointer();
+			FromString( m_tiXmlPointer->Name(), name );
+		}
+
+		/**
+		Get the value of this attribute.
+		Simple wrapper for TiXmlAttribute::Name.
+
+		@see GetName
+		*/
+		std::string Name() const;
+
+		/**
+		Set the value of this attribute.
+		Uses Base::ToString to convert @a name to a std::string, then calls TiXmlAttribute::SetName.
+
+		@param name The name to set
+		*/
+		template < class T >
+			void SetName( const T& name )
+		{
+			ValidatePointer();
+			m_tiXmlPointer->SetName( ToString( name ) );
+		}
+
+		/**
+		@internal
+		Updates the reference count for the old and new pointers.
+		*/
+		void operator=( const Attribute& copy );
+
+		/**
+		@internal
+		Updates the reference count for the old and new pointers.
+		*/
+		Attribute( const Attribute& copy );
+
+		/*
+		Decrements reference count.
+		*/
+		~Attribute();
+
+		/**
+		Get the next sibling attribute in the DOM.
+		*/
+		Attribute* Next( bool throwIfNoAttribute = true ) const;
+
+		/**
+		Get the previous sibling attribute in the DOM.
+		*/
+		Attribute* Previous( bool throwIfNoAttribute = true ) const;
+
+		/**
+		@internal
+		Just for Iterator<>
+
+		@param next [OUT] The pointer to the next valid attribute
+		@return true if there is a next attribute, false if not
+		*/
+		void IterateNext( const std::string&, Attribute** next ) const;
+
+		/**
+		@internal
+		Just for Iterator<>
+
+		@param previous [OUT] The pointer to the previous valid attribute
+		@return true if there is a previous attribute, false if not
+		*/
+		void IteratePrevious( const std::string&, Attribute** previous ) const;
+
+		/**
+		All TinyXml classes can print themselves to a filestream.
+		*/
+		virtual void Print( FILE* file, int depth ) const;
+
+	private:
+
+		/**
+		@internal
+		Sets the internal pointer.
+		Saves a copy of the pointer to the RC object.
+
+		@param newPointer TiXmlAttribute* to set.
+		*/
+		void SetTiXmlPointer( TiXmlAttribute* newPointer );
+	};
+
+	/**
+	Wrapper around TiXmlNode
+	*/
+	class Node : public Base
+	{
+	public:
+
+		/**
+		Get the value of this node
+		Uses Base::FromString to convert TiXmlNode::ValueStr from a std::string,
+		and puts it in the passed pointer.
+
+		@param value [OUT] A pointer to fill with the value
+		*/
+		template < class T >
+			void GetValue( T* value) const
+		{
+			FromString( GetTiXmlPointer()->ValueStr(), value );
+		}
+
+		/**
+		Get the value of this node.
+		Simple wrapper for TiXmlNode::ValueStr.
+
+		@see GetValue
+		*/
+		std::string Value() const;
+
+		/**
+		Set the value of this node.
+		Uses Base::ToString to convert value to a std::string, then calls TiXmlNode::SetValue.
+
+		@param value The value to set
+		*/
+		template < class T >
+			void SetValue( const T& value )
+		{
+			GetTiXmlPointer()->SetValue( ToString( value ) );
+		}
+
+		/**
+		Clear all Nodes below this.
+		Simple wrapper for TiXmlNode::Clear.
+		*/
+		void Clear();
+
+		/**
+		The Parent of this Node.
+		Simple wrapper for TiXmlNode::Parent.
+
+		@param throwIfNoParent [DEF] If true, throws when Parent = NULL.
+		@return The parent of this node, NULL if there is no Parent.
+		@throws Exception When throwIfNoParent is true, and TiXmlNode::Parent returns Null.
+		*/
+		Node* Parent( bool throwIfNoParent = true ) const;
+
+		/**
+		The first child of this node.
+
+		@param throwIfNoChildren [DEF] If true, will throw an exception if there are no children.
+		@return Pointer to child, Null if no children and 'throwIfNoChildren' is false.
+		@throws Exception When throwIfNoChildren is true, and TiXmlNode::FirstChild returns Null.
+
+		@see TiXmlNode::FirstChild
+		*/
+		Node* FirstChild( bool throwIfNoChildren = true ) const;
+
+		/**
+		@internal
+		The first child of this node with the matching @a value.
+
+		@overload
+		@param value				Value to match.
+		@param throwIfNoChildren	[DEF] If true, will throw an exception if there are no children.
+
+		@see FirstChild( bool throwIfNoChildren = true )
+		*/
+		Node* FirstChild( const char* value, bool throwIfNoChildren = true ) const;
+
+		/**
+		The first child of this node with the matching @a value.
+
+		@overload
+		@param value				Value to match.
+		@param throwIfNoChildren	[DEF] If true, will throw an exception if there are no children.
+
+		@see FirstChild( const char* value, bool throwIfNoChildren = true )
+		*/
+		Node* FirstChild( const std::string& value, bool throwIfNoChildren = true ) const;
+
+		/**
+		The last child of this node.
+
+		@param throwIfNoChildren [DEF] If true, will throw an exception if there are no children.
+		@return Pointer to child, Null if no children and 'throwIfNoChildren' is false.
+		@throws Exception When throwIfNoChildren is true, and TiXmlNode::LastChild returns Null.
+
+		@see TiXmlNode::LastChild
+		*/
+		Node* LastChild( bool throwIfNoChildren = true ) const;
+
+		/**
+		@internal
+		The last child of this node with the matching @a value.
+
+		@overload
+		@param value				Value to match.
+		@param throwIfNoChildren	[DEF] If true, will throw an exception if there are no children.
+
+		@see LastChild( bool throwIfNoChildren = true )
+		*/
+		Node* LastChild( const char* value, bool throwIfNoChildren = true ) const;
+
+		/**
+		The last child of this node with the matching @a value.
+
+		@overload
+		@param value				Value to match.
+		@param throwIfNoChildren	[DEF] If true, will throw an exception if there are no children.
+
+		@see LastChild( const char* value, bool throwIfNoChildren = true )
+		*/
+		Node* LastChild( const std::string& value, bool throwIfNoChildren = true ) const;
+
+		/**
+		An alternate way to walk the children of a node.
+		Simple wrapper for TiXmlNode::IterateChildren.
+
+		@param previous The previous Node* that was returned from IterateChildren.
+		@return NULL When there are no more children.
+		*/
+		Node* IterateChildren( Node* previous ) const;
+
+		/**
+		This flavor of IterateChildren searches for children with a particular @a value.
+		Simple wrapper for TiXmlNode::IterateChildren.
+
+		@param value	The value you want to search for.
+		@param previous The previous Node* that was returned from IterateChildren.
+		@return NULL When there are no more children.
+		*/
+		Node* IterateChildren( const std::string& value, Node* previous ) const;
+
+		/**
+		Adds a child past the LastChild.
+		Throws if you try to insert a document.
+
+		@note This takes a copy of @a addThis so it is not as efficiant as LinkEndChild.
+		@param addThis Node to insert.
+		@throws Exception When TiXmlNode::InsertEndChild returns Null
+
+		@see LinkEndChild
+		@see TiXmlNode::InsertEndChild
+		*/
+		Node* InsertEndChild( Node& addThis );
+
+		/**
+		Adds a child past the LastChild.
+		Throws if you try to link a document.
+
+		@param childNode Node to link.
+		@throws Exception When TiXmlNode::LinkEndChild returns Null.
+
+		@see InsertEndChild
+		@see TiXmlNode::LinkEndChild
+		*/
+		Node* LinkEndChild( Node* childNode );
+
+		/**
+		Adds a child before the specified child.
+		Throws if you try to insert a document.
+
+		@param beforeThis	Node that will have @a addThis linked before.
+		@param addThis		Node to insert before.
+		@throws Exception When TiXmlNode::InsertBeforeChild returns Null.
+
+		@see InsertAfterChild
+		@see TiXmlNode::InsertBeforeChild
+		*/
+		Node* InsertBeforeChild( Node* beforeThis, Node& addThis );
+
+		/**
+		Adds a child after the specified child.
+		Throws if you try to insert a document.
+
+		@param afterThis	Node that will have @a addThis linked after.
+		@param addThis		Node to insert after.
+		@throws Exception When TiXmlNode::InsertAfterChild returns Null.
+
+		@see InsertBeforeChild
+		@see TiXmlNode::InsertAfterChild
+		*/
+		Node* InsertAfterChild( Node* afterThis, Node& addThis );
+
+		/**
+		Replace a child of this node.
+		Throws if you try to replace with a document.
+
+		@param replaceThis	Node to replace.
+		@param withThis		Node that is replacing @a replaceThis.
+		@throws Exception When TiXmlNode::ReplaceChild returns Null.
+
+		@see TiXmlNode::ReplaceChild
+		*/
+		Node* ReplaceChild( Node* replaceThis, Node& withThis );
+
+		/**
+		Delete a child of this node.
+
+		@param removeThis Node to delete.
+		@throws Exception When removeThis is not a child of this Node.
+
+		@see TiXmlNode::RemoveChild
+		*/
+		void RemoveChild( Node* removeThis );
+
+		/**
+		Navigate to a sibling node.
+		Wrapper around TiXmlNode::PreviousSibling.
+
+		@param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
+		@return Pointer to sibling, Null if no siblings and 'throwIfNoSiblings' is false.
+		@throws Exception When TiXmlNode::PreviousSibling returns Null and 'throwIfNoSiblings' is true.
+		*/
+		Node* PreviousSibling( bool throwIfNoSiblings = true ) const;
+
+		/**
+		Navigate to a sibling node with the given @a value.
+
+		@overload
+		@param value The value of the node to look for.
+		@param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
+
+		@see PreviousSibling( bool throwIfNoSiblings )
+		*/
+		Node* PreviousSibling( const std::string& value, bool throwIfNoSiblings = true ) const;
+
+		/**
+		@internal
+		Navigate to a sibling node with the given @a value.
+
+		@overload
+		@param value The value of the node to look for.
+		@param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
+
+		@see PreviousSibling( const std::string& value, bool throwIfNoSiblings )
+		*/
+		Node* PreviousSibling( const char* value, bool throwIfNoSiblings = true ) const;
+
+		/**
+		Navigate to a sibling node.
+		Wrapper around TiXmlNode::NextSibling.
+
+		@param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
+		@return Pointer to sibling, Null if no siblings and 'throwIfNoSiblings' is false.
+		@throws Exception When TiXmlNode::NextSibling returns Null and 'throwIfNoSiblings' is true.
+		*/
+		Node* NextSibling( bool throwIfNoSiblings = true ) const;
+
+		/**
+		Navigate to a sibling node with the given @a value.
+
+		@overload
+		@param value The value of the node to look for.
+		@param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
+
+		@see NextSibling( bool throwIfNoSiblings )
+		*/
+		Node* NextSibling( const std::string& value, bool throwIfNoSiblings = true ) const;
+
+		/**
+		@internal
+		Navigate to a sibling node with the given @a value.
+
+		@overload
+		@param value The value of the node to look for.
+		@param throwIfNoSiblings [DEF] If true, will throw an exception if there are no siblings.
+
+		@see NextSibling( const std::string& value, bool throwIfNoSiblings )
+		*/
+		Node* NextSibling( const char* value, bool throwIfNoSiblings = true ) const;
+
+		/**
+		@internal
+		Just for Iterator<>
+
+		@param value The value of nodes to iterate through
+		@param next [OUT] The pointer to the first valid node
+		*/
+		template < class T >
+			void IterateFirst( const std::string& value, T** first ) const
+		{
+			*first = 0;
+			for( Node* child = FirstChild( value, false ); child; child = child->NextSibling( value, false ) )
+			{
+				*first = dynamic_cast< T* >( child );
+				if ( 0 != *first )
+				{
+					return;
+				}
+			}
+		}
+
+		virtual	void IterateFirst( const std::string&, Attribute** ) const
+		{
+			TICPPTHROW( "Attributes can only be iterated with Elements." )
+		}
+
+		/**
+		@internal
+		Just for Iterator<>
+
+		@param value The value of nodes to iterate through
+		@param next [OUT] The pointer to the next valid node
+		*/
+		template < class T >
+			void IterateNext( const std::string& value, T** next ) const
+		{
+			Node* sibling = NextSibling( value, false );
+			*next = dynamic_cast< T* >( sibling );
+
+			while ( ( 0 != sibling ) && ( 0 == *next ) )
+			{
+				sibling = sibling->NextSibling( value, false );
+				*next = dynamic_cast< T* >( sibling );
+			}
+		}
+
+		/**
+		@internal
+		Just for Iterator<>
+
+		@param value The value of nodes to iterate through
+		@param previous [OUT] The pointer to the previous valid node
+		*/
+		template < class T >
+			void IteratePrevious( const std::string& value, T** previous  ) const
+		{
+			Node* sibling = PreviousSibling( value, false );
+			*previous = dynamic_cast< T* >( sibling );
+
+			while ( ( 0 != sibling ) && ( 0 == *previous ) )
+			{
+				sibling = sibling->PreviousSibling( value, false );
+				*previous = dynamic_cast< T* >( sibling );
+			}
+		}
+
+		/**
+		Navigate to a sibling element.
+		Wrapper around TiXmlNode::NextSibling.
+
+		@param throwIfNoSiblings [DEF] If true, will throw an exception if there are no sibling element.
+		@return Pointer to sibling, Null if no siblings and 'throwIfNoSiblings' is false.
+		@throws Exception When TiXmlNode::NextSibling returns Null and 'throwIfNoSiblings' is true.
+		*/
+		Element* NextSiblingElement( bool throwIfNoSiblings = true ) const;
+
+		/**
+		Navigate to a sibling element with the given @a value.
+
+		@overload
+		@param value The value of the element to look for.
+		@param throwIfNoSiblings [DEF] If true, will throw an exception if there are no sibling elements.
+		@see NextSiblingElement( bool throwIfNoSiblings )
+		*/
+		Element* NextSiblingElement( const std::string& value, bool throwIfNoSiblings = true ) const;
+
+		/**
+		@internal
+		Navigate to a sibling element with the given @a value.
+
+		@overload
+		@param value The value of the element to look for.
+		@param throwIfNoSiblings [DEF] If true, will throw an exception if there are no sibling elements.
+
+		@see NextSiblingElement( const std::string& value, bool throwIfNoSiblings )
+		*/
+		Element* NextSiblingElement( const char* value, bool throwIfNoSiblings = true ) const;
+
+		/**
+		The first child element of this node.
+
+		@param throwIfNoChildren [DEF] If true, will throw an exception if there are no element children.
+		@return Pointer to child, Null if no element children and 'throwIfNoChildren' is false.
+		@throws Exception When throwIfNoChildren is true, and TiXmlNode::FirstChildElement returns Null.
+
+		@see TiXmlNode::FirstChildElement
+		*/
+		Element* FirstChildElement( bool throwIfNoChildren = true ) const;
+
+		/**
+		@internal
+		The first child element of this node with the matching @a value.
+
+		@overload
+		@param value Value to match.
+		@param throwIfNoChildren [DEF] If true, will throw an exception if there are no element children.
+
+		@see FirstChildElement( bool throwIfNoChildren = true )
+		*/
+		Element* FirstChildElement( const char* value, bool throwIfNoChildren = true ) const;
+
+		/**
+		The first child element of this node with the matching @a value.
+
+		@overload
+		@param value Value to match.
+		@param throwIfNoChildren [DEF] If true, will throw an exception if there are no element children.
+
+		@see FirstChildElement( const char* value, bool throwIfNoChildren = true )
+		*/
+		Element* FirstChildElement( const std::string& value, bool throwIfNoChildren = true ) const;
+
+		/**
+		Query the type (as TiXmlNode::NodeType ) of this node.
+		*/
+		int Type() const;
+
+		/**
+		Return a pointer to the Document this node lives in.
+
+		@param throwIfNoDocument [DEF] If true, will throw an exception if this node is not linked under a Document.
+		@return A pointer to the Document this node lives in, NULL if not linked under a Document, and 'throwIfNoDocument' is false.
+		@throws Exception When this node is not linked under a Document and 'throwIfNoDocument' is true.
+		*/
+		Document* GetDocument( bool throwIfNoDocument = true ) const;
+
+		/**
+		Check if this node has no children.
+
+		@return true if this node has no children.
+		*/
+		bool NoChildren() const;
+
+		#ifndef TICPP_NO_RTTI
+		/**
+		Pointer conversion ( NOT OBJECT CONVERSION ) - replaces TiXmlNode::ToElement, TiXmlNode::ToDocument, TiXmlNode::ToComment, etc.
+
+		@throws Exception When the target is not an object of class T
+		@warning Some ancient compilers do not support explicit specification of member template arguments, which this depends on ( e.g. VC6 ).
+		*/
+		template < class T >
+			T* To() const
+		{
+			T* pointer = dynamic_cast< T* >( this );
+			if ( 0 == pointer )
+			{
+				std::string thisType = typeid( this ).name();
+				std::string targetType = typeid( T ).name();
+				std::string thatType = typeid( *this ).name();
+				TICPPTHROW( "The " << thisType.substr( 6 ) << " could not be casted to a " << targetType.substr( 6 )
+					<< " *, because the target object is not a " << targetType.substr( 6 ) << ". (It is a " << thatType.substr( 6 ) << ")" );
+			}
+			return pointer;
+		}
+		#endif
+
+		/**
+		Pointer conversion - replaces TiXmlNode::ToDocument.
+
+		@throws Exception When this node is not a Document.
+		*/
+		Document* ToDocument() const;
+
+		/**
+		Pointer conversion - replaces TiXmlNode::ToElement.
+
+		@throws Exception When this node is not a Element.
+		*/
+		Element* ToElement() const;
+
+		/**
+		Pointer conversion - replaces TiXmlNode::ToComment.
+
+		@throws Exception When this node is not a Comment.
+		*/
+		Comment* ToComment() const;
+
+		/**
+		Pointer conversion - replaces TiXmlNode::ToText.
+
+		@throws Exception When this node is not a Text.
+		*/
+		Text* ToText() const;
+
+		/**
+		Pointer conversion - replaces TiXmlNode::ToDeclaration.
+
+		@throws Exception When this node is not a Declaration.
+		*/
+		Declaration* ToDeclaration() const;
+
+		/**
+		Pointer conversion - replaces TiXmlNode::ToStylesheetReference.
+
+		@throws Exception When this node is not a StylesheetReference.
+		*/
+		StylesheetReference* ToStylesheetReference() const;
+
+		/**
+		Create an exact duplicate of this node and return it.
+
+		@note Using auto_ptr to manage the memory declared on the heap by TiXmlNode::Clone.
+		@code
+		// Now using clone
+		ticpp::Document doc( "C:\\Test.xml" );
+		ticpp::Node* sectionToClone;
+		sectionToClone = doc.FirstChild( "settings" );
+		std::auto_ptr< ticpp::Node > clonedNode = sectionToClone->Clone();
+		// Now you can use the clone.
+		ticpp::Node* node2 = clonedNode->FirstChildElement()->FirstChild();
+		...
+		// After the variable clonedNode goes out of scope it will automatically be cleaned up.
+		@endcode
+		@return Pointer the duplicate node.
+		*/
+		std::auto_ptr< Node > Clone() const;
+
+		/**
+		Accept a hierchical visit the nodes in the TinyXML DOM.
+		@return The boolean returned by the visitor.
+		*/
+		bool Accept( TiXmlVisitor* visitor ) const;
+
+		/**
+ 		Stream input operator.
+ 		*/
+ 		friend std::istream& operator >>( std::istream& in, Node& base )
+ 		{
+ 			in >> *base.GetTiXmlPointer();
+ 			return in;
+ 		}
+
+ 		/**
+ 		Stream output operator.
+ 		*/
+ 		friend std::ostream& operator <<( std::ostream& out, const Node& base )
+ 		{
+ 			out << *base.GetTiXmlPointer();
+ 			return out;
+ 		}
+
+	protected:
+		/**
+		@internal
+		Allows NodeImp to use Node*'s.
+		*/
+		virtual TiXmlNode* GetTiXmlPointer() const = 0;
+
+		TiXmlBase* GetBasePointer() const
+		{
+			return GetTiXmlPointer();
+		}
+
+		/**
+		@internal
+		Constructs the correct child of Node, based on the Type of the TiXmlNode*.
+		*/
+		Node* NodeFactory( TiXmlNode* tiXmlNode, bool throwIfNull = true, bool rememberSpawnedWrapper = true ) const;
+
+	};
+
+	/** Iterator for conveniently stepping through Nodes and Attributes.
+	TinyXML++ introduces iterators:
+	@code
+	ticpp::Iterator< ticpp::Node > child;
+	for ( child = child.begin( parent ); child != child.end(); child++ )
+	@endcode
+
+	Iterators have the added advantage of filtering by type:
+	@code
+	// Only iterates through Comment nodes
+	ticpp::Iterator< ticpp::Comment > child;
+	for ( child = child.begin( parent ); child != child.end(); child++ )
+	@endcode
+
+	@code
+	// Only iterates through Element nodes with value "ElementValue"
+	ticpp::Iterator< ticpp::Element > child( "ElementValue" );
+	for ( child = child.begin( parent ); child != child.end(); child++ )
+	@endcode
+
+	Finally, Iterators also work with Attributes
+	@code
+	ticpp::Iterator< ticpp::Attribute > attribute;
+	for ( attribute = attribute.begin( element ); attribute != attribute.end(); attribute++ )
+	@endcode
+	*/
+	template < class T = Node >
+		class Iterator
+	{
+	private:
+		T* m_p;					/**< Internal Pointer */
+		std::string m_value;	/**< Value for NextSibling  calls */
+
+	public:
+
+		/**
+		For for loop comparisons.
+		@param parent The parent of the nodes to iterate.
+		@return The first child of type T.
+		@code
+		ticpp::Iterator< ticpp::Node > child;
+		for ( child = child.begin( parent ); child != child.end(); child++ )
+		@endcode
+		*/
+		T* begin( const Node* parent ) const
+		{
+			T* pointer;
+			parent->IterateFirst( m_value, &pointer );
+			return pointer;
+		}
+
+		/**
+		For for loop comparisons.
+		@return NULL
+		@code
+		ticpp::Iterator< ticpp::Node > child;
+		for ( child = child.begin( parent ); child != child.end(); child++ )
+		@endcode
+		*/
+		T* end() const
+		{
+			return 0;
+		}
+
+		/** Constructor.
+		@param value If not empty, this iterator will only visit nodes with matching value.
+		@code
+		// Only iterates through Element nodes with value "ElementValue"
+		ticpp::Iterator< ticpp::Element > child( "ElementValue" );
+		for ( child = child.begin( parent ); child != child.end(); child++ )
+		@endcode
+		*/
+		Iterator( const std::string& value = "" )
+			: m_p( 0 ), m_value( value )
+		{
+		}
+
+		/// Constructor
+		Iterator( T* node, const std::string& value = "" )
+			: m_p( node ), m_value( value )
+		{
+		}
+
+		/// Constructor
+		Iterator( const Iterator& it )
+			: m_p( it.m_p ), m_value( it.m_value )
+		{
+		}
+
+		/**
+		Gets internal pointer.
+		@return The internal pointer.
+		*/
+		T* Get() const
+		{
+			return m_p;
+		}
+
+		/** Sets internal pointer */
+		Iterator& operator=( const Iterator& it )
+		{
+			m_p = it.m_p;
+			m_value = it.m_value;
+			return *this;
+		}
+
+		/** Sets internal pointer */
+		Iterator& operator=( T* p )
+		{
+			m_p = p;
+			return *this;
+		}
+
+		/** Sets internal pointer to the Next Sibling, or Iterator::END, if there are no more siblings */
+		Iterator& operator++()
+		{
+			m_p->IterateNext( m_value, &m_p );
+			return *this;
+		}
+
+		/** Sets internal pointer to the Next Sibling, or Iterator::END, if there are no more siblings */
+		Iterator operator++(int)
+		{
+			Iterator tmp(*this);
+			++(*this);
+			return tmp;
+		}
+
+		/** Sets internal pointer to the Previous Sibling, or Iterator::END, if there are no prior siblings */
+		Iterator& operator--()
+		{
+			m_p->IteratePrevious( m_value, &m_p );
+			return *this;
+		}
+
+		/** Sets internal pointer to the Previous Sibling, or Iterator::END, if there are no prior siblings */
+		Iterator operator--(int)
+		{			
+			Iterator tmp(*this);
+			--(*this);
+			return tmp;
+		}
+
+		/** Compares internal pointer */
+		bool operator!=( const T* p ) const
+		{
+			if ( m_p == p )
+			{
+				return false;
+			}
+			if ( 0 == m_p || 0 == p )
+			{
+				return true;
+			}
+			return *m_p != *p;
+		}
+
+		/** Compares internal pointer */
+		bool operator!=( const Iterator& it ) const
+		{
+			return operator!=( it.m_p );
+		}
+
+		/** Compares internal pointer* */
+		bool operator==( T* p ) const
+		{
+			if ( m_p == p )
+			{
+				return true;
+			}
+			if ( 0 == m_p || 0 == p )
+			{
+				return false;
+			}
+			return *m_p == *p;
+		}
+
+		/** Compares internal pointer */
+		bool operator==( const Iterator& it ) const
+		{
+			return operator==( it.m_p );
+		}
+
+		/** So Iterator behaves like a STL iterator */
+		T* operator->() const
+		{
+			return m_p;
+		}
+
+		/** So Iterator behaves like a STL iterator */
+		T& operator*() const
+		{
+			return *m_p;
+		}
+	};
+
+	/** Implementation of Node wrapper */
+	template < class T >
+		class NodeImp : public Node
+	{
+	protected:
+
+		T* m_tiXmlPointer;		/**< Internal pointer to the TiXml Class which is being wrapped */
+
+    public:
+		/**
+		@internal
+		Gets the internal TinyXML pointer.
+
+		@returns The internal TiXmlNode*.
+		*/
+		TiXmlNode* GetTiXmlPointer() const
+		{
+			ValidatePointer();
+			return m_tiXmlPointer;
+		}
+    protected:
+
+		/**
+		@internal
+		Sets the internal pointer.
+		Saves a copy of the pointer to the RC object.
+
+		@param newPointer TiXmlNode* to set.
+		*/
+		void SetTiXmlPointer( T* newPointer )
+		{
+			m_tiXmlPointer = newPointer;
+			SetImpRC( newPointer );
+		}
+
+		/**
+		@internal
+		Constructor used by child classes.
+		*/
+		NodeImp( T* tiXmlPointer )
+		{
+			// Check for NULL pointers
+			if ( 0 == tiXmlPointer )
+			{
+				#ifdef TICPP_NO_RTTI
+					TICPPTHROW( "Can not create TinyXML objext" );
+				#else
+					TICPPTHROW( "Can not create a " << typeid( T ).name() );
+				#endif
+			}
+			SetTiXmlPointer( tiXmlPointer );
+			m_impRC->IncRef();
+		}
+
+		/**
+		@internal
+		Updates the reference count for the old and new pointers.
+		In addition, the spawnedWrappers must be cleared out before a new TiXml object is loaded in.
+		*/
+		virtual void operator=( const NodeImp<T>& copy )
+		{
+			// Dropping the reference to the old object
+			this->m_impRC->DecRef();
+
+			// Pointing to the new Object
+			SetTiXmlPointer( copy.m_tiXmlPointer );
+
+			// The internal tixml pointer changed in the above line
+			this->m_impRC->IncRef();
+		}
+
+		/**
+		@internal
+		Updates the reference count for the old and new pointers.
+		In addition, the spawnedWrappers must be cleared out before a new TiXml object is loaded in
+		*/
+		NodeImp( const NodeImp<T>& copy ) : Node( copy )
+		{
+			// Pointing to the new Object
+			SetTiXmlPointer( copy.m_tiXmlPointer );
+
+			// The internal tixml pointer changed in the above line
+			this->m_impRC->IncRef();
+		}
+
+	public:
+
+		/*
+		Deletes the spawned wrapper objects.
+		Decrements reference count.
+		*/
+		virtual ~NodeImp()
+		{
+			m_impRC->DecRef();
+		}
+	};
+
+	/** Wrapper around TiXmlComment */
+	class Comment : public NodeImp< TiXmlComment >
+	{
+	public:
+
+		/**
+		Constructor.
+		*/
+		Comment();
+
+		/**
+		Constructor.
+		*/
+		Comment( TiXmlComment* comment );
+
+		/**
+		Constructor.
+		*/
+		Comment( const std::string& comment );
+	};
+
+	/** Wrapper around TiXmlText */
+	class Text : public NodeImp< TiXmlText >
+	{
+	public:
+
+		/**
+		Constructor.
+		*/
+		Text();
+
+		/**
+		Constructor.
+		@overload
+		*/
+		Text( TiXmlText* text );
+
+		/**
+		Constructor.
+		@overload
+		*/
+		Text( const std::string& value );
+
+		/**
+		Streams value into a string and creates a Text with it.
+		Uses ToString to covert the parameter to a string.
+
+		@param value The value of the Text node.
+		@throws Exception
+
+		@see TiXmlText
+        */
+		template < class T >
+			Text( const T& value )
+				: NodeImp< TiXmlText >( new TiXmlText( ToString( value ) ) )
+		{
+			m_impRC->InitRef();
+		}
+	};
+
+	/** Wrapper around TiXmlDocument */
+	class Document : public NodeImp< TiXmlDocument >
+	{
+	public:
+		/**
+		Default	Constructor.
+		Create an empty document, that has no name.
+		*/
+		Document();
+
+		/**
+		Constructor.
+		*/
+		Document( TiXmlDocument* document );
+
+		/**
+		Constructor.
+		*/
+		Document( const char* documentName );
+
+		/**
+		Constructor.
+		Create a document with a name. The name of the document is also the filename of the xml.
+
+		@param documentName Name to set in the Document.
+		*/
+		Document( const std::string& documentName );
+
+		/**
+		Load a file using the current document value. Throws if load is unsuccessful.
+
+		@param encoding Sets the documents encoding.
+		@see TiXmlEncoding
+		@throws Exception
+		*/
+		void LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+
+		/**
+		Save a file using the current document value. Throws if it can't save the file.
+
+		@throws Exception
+		*/
+		void SaveFile() const;
+
+		/**
+		Load a file using the given filename. Throws if load is unsuccessful.
+
+		@param filename File to load.
+		@param encoding Sets the documents encoding.
+		@see TiXmlEncoding
+		@throws Exception
+		*/
+		void LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+
+		/**
+		@copydoc Document::LoadFile( const std::string&, TiXmlEncoding )
+		*/
+		void LoadFile( const char* filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+
+		/**
+		Save a file using the given filename. Throws if it can't save the file.
+
+		@param filename File to save.
+		@throws Exception
+		*/
+		void SaveFile( const std::string& filename ) const;
+
+		/**
+		Parse the given xml data.
+
+		@param xml Xml to parse.
+		@param throwIfParseError [DEF] If true, throws when there is a parse error.
+		@param encoding Sets the documents encoding.
+		@throws Exception
+		*/
+		void Parse( const std::string& xml, bool throwIfParseError = true, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	};
+
+	/** Wrapper around TiXmlElement */
+	class Element : public NodeImp< TiXmlElement >
+	{
+	public:
+		/**
+		Default Constructor.
+		*/
+		Element();
+
+		/**
+		Default	Constructor. Initializes all the variables.
+		@param value The value of the element.
+		*/
+		Element( const std::string& value );
+
+		/**
+		Default	Constructor. Initializes all the variables.
+		@param value The value of the element.
+		*/
+		Element( const char* value );
+
+		/**
+		Constructor.
+		*/
+		Element( TiXmlElement* element );
+
+		/**
+		Constructor that allows you to set the element text
+		@param value The value of the element.
+		@param text The text to set.
+		*/
+		template < class T >
+			Element( const std::string& value, const T& text )
+			: NodeImp< TiXmlElement >( new TiXmlElement( value ) )
+		{
+			m_impRC->InitRef();
+			SetText( text );
+		}
+
+		/**
+		Access the first attribute in this element.
+
+		@param throwIfNoAttributes [DEF] If true, throws when there are no attributes
+		@return The first attribute, NULL if there are none and @a throwIfNoAttributes is true
+		*/
+		Attribute* FirstAttribute( bool throwIfNoAttributes = true ) const;
+
+		/**
+		Access the last attribute in this element.
+
+		@param throwIfNoAttributes [DEF] If true, throws when there are no attributes
+		@return The last attribute, NULL if there are none and @a throwIfNoAttributes is true
+		*/
+		Attribute* LastAttribute( bool throwIfNoAttributes = true ) const;
+
+		/**
+		@internal
+		Just for Iterator<>
+
+		@param value The value of nodes to iterate through
+		@param next [OUT] The pointer to the first valid node
+		*/
+		void IterateFirst( const std::string&, Attribute** first ) const
+		{
+			*first = 0;
+			for( Attribute* child = FirstAttribute( false ); child; child = child->Next( false ) )
+			{
+				*first = dynamic_cast< Attribute* >( child );
+				if ( 0 != *first )
+				{
+					return;
+				}
+			}
+		}
+
+		/**
+		Sets an attribute of name to a given value.
+		The attribute will be created if it does not exist, or changed if it does.
+		Uses ToString to convert the @a value to a string, so there is no need to use any other SetAttribute methods.
+
+		@see GetAttribute
+		*/
+		template < class T >
+			void SetAttribute ( const std::string& name, const T& value )
+		{
+			ValidatePointer();
+			m_tiXmlPointer->SetAttribute( name, ToString( value ) );
+		}
+
+		/**
+		Gets the text of an Element.
+
+		@param throwIfNotFound	[DEF]	If true, will throw an exception if there is no text in this element
+		@note This only works if the Text is the FirstChild node
+		@throws Exception When there is no text and throwIfNotFound is true
+
+		@see GetText( T* value, bool throwIfNotFound = false )
+		@see GetTextOrDefault
+		@see GetTextOrDefault( T* value, const DefaultT& defaultValue )
+		@see TiXmlElement::GetText
+		*/
+		std::string GetText( bool throwIfNotFound = true ) const
+		{
+			// Get the element's text value as a std::string
+			std::string temp;
+			if ( !GetTextImp( &temp ) )
+			{
+				if ( throwIfNotFound )
+				{
+					TICPPTHROW( "Text does not exists in the current element" );
+				}
+			}
+
+			return temp;
+		}
+
+		/**
+		Gets the text of an Element, if it doesn't exist it will return the defaultValue.
+
+		@param defaultValue			What to put in 'value' if there is no text in this element
+		@note This only works if the Text is the FirstChild node
+
+		@see GetText
+		@see GetText( T* value, bool throwIfNotFound = false )
+		@see GetTextOrDefault( T* value, const DefaultT& defaultValue )
+		@see TiXmlElement::GetText
+		*/
+		std::string GetTextOrDefault( const std::string& defaultValue ) const
+		{
+			// Get the element's text value as a std::string
+			std::string temp;
+			if ( !GetTextImp( &temp ) )
+			{
+				return defaultValue;
+			}
+
+			return temp;
+		}
+
+		/**
+		Gets the text value of an Element, if it doesn't exist it will return the defaultValue.
+		Uses FromString to convert the string to the type of choice
+
+		@param value		[OUT]	The container for the returned value
+		@param defaultValue			What to put in 'value' if there is no text in this element
+		@note This is different than GetText() in that it will covert the text to what ever type you want.
+		@note This only works if the Text is the FirstChild node
+
+		@see GetText
+		@see GetText( T* value, bool throwIfNotFound = false )
+		@see GetTextOrDefault( const std::string& defaultValue )
+		@see TiXmlElement::GetText
+		*/
+		template < class T, class DefaultT >
+			void GetTextOrDefault( T* value, const DefaultT& defaultValue ) const
+		{
+			// Get the element's text value as a std::string
+			std::string temp;
+			if ( !GetTextImp( &temp ) )
+			{
+				// The text value does not exist - set value to the default
+				*value = defaultValue;
+				return;
+			}
+
+			// Stream the value from the string to T
+			FromString( temp, value );
+		}
+
+		/**
+		Gets the text of an Element.
+		Uses FromString to convert the string to the type of choice.
+
+		@param value			[OUT]	The container for the returned value
+		@param throwIfNotFound	[DEF]	If true, will throw an exception if there is no text in this element
+		@note This is different than GetText() in that it will covert the text to what ever type you want
+		@note This only works if the Text is the FirstChild node
+		@throws Exception When there is no text and throwIfNotFound is true
+
+		@see GetText
+		@see GetTextOrDefault
+		@see GetTextOrDefault( T* value, const DefaultT& defaultValue )
+		@see TiXmlElement::GetText
+		*/
+		template< class T >
+			void GetText( T* value, bool throwIfNotFound = true ) const
+		{
+			// Get the element's text value as a std::string
+			std::string temp;
+			if ( !GetTextImp( &temp ) )
+			{
+				if ( throwIfNotFound )
+				{
+					TICPPTHROW( "Text does not exists in the current element" );
+				}
+				else
+				{
+					return;
+				}
+			}
+
+			// Stream the value from the string to T
+			FromString( temp, value );
+		}
+
+		/**
+		Convenience function to set the text of an element.
+		Creates a Text node and inserts it as the first child.
+		Uses ToString to convert the parameter to a string.
+
+		@param value The text to set.
+		*/
+		template < class T >
+			void SetText( const T& value )
+		{
+			ValidatePointer();
+			std::string temp = ToString( value );
+
+			if ( m_tiXmlPointer->NoChildren() )
+			{
+				m_tiXmlPointer->LinkEndChild( new TiXmlText( temp ) );
+			}
+			else
+			{
+				if ( 0 == m_tiXmlPointer->GetText() )
+				{
+					m_tiXmlPointer->InsertBeforeChild( m_tiXmlPointer->FirstChild(), TiXmlText( temp ) );
+				}
+				else
+				{
+					// There already is text, so change it
+					m_tiXmlPointer->FirstChild()->SetValue( temp );
+				}
+			}
+		}
+
+		/**
+		Gets an attribute of @a name from an element, if it doesn't exist it will return the defaultValue.
+		Uses FromString to convert the string to the type of choice.
+
+		@param name			The name of the attribute you are querying.
+		@param value		[OUT] The container for the returned value.
+		@param defaultValue	What to put in @a value if there is no attribute in this element.
+		@throws Exception
+
+		@see GetAttribute
+		*/
+		template < class T, class DefaulT >
+			void GetAttributeOrDefault( const std::string& name, T* value, const DefaulT& defaultValue ) const
+		{
+			// Get the attribute's value as a std::string
+			std::string temp;
+			if ( !GetAttributeImp( name, &temp ) )
+			{
+				// The attribute does not exist - set value to the default
+				*value = defaultValue;
+				return;
+			}
+
+			// Stream the value from the string to T
+			FromString( temp, value );
+		}
+
+		/**
+		Gets an attribute of @a name from an element, if it doesn't exist it will return the defaultValue.
+
+		@param name			The name of the attribute you are querying.
+		@param defaultValue	What to put in @a value if there is no attribute in this element.
+
+		@see GetAttribute
+		*/
+		std::string GetAttributeOrDefault( const std::string& name, const std::string& defaultValue ) const;
+
+		/**
+		Returns an attribute of @a name from an element.
+		Uses FromString to convert the string to the type of choice.
+
+		@param name				The name of the attribute you are querying.
+		@param throwIfNotFound	[DEF]	If true, will throw an exception if the attribute doesn't exist
+		@throws Exception When the attribute doesn't exist and throwIfNotFound is true
+		@see GetAttributeOrDefault
+		*/
+		template < class T >
+			T GetAttribute( const std::string& name, bool throwIfNotFound = true ) const
+		{
+			// Get the attribute's value as a std::string
+			std::string temp;
+			T value;
+			if ( !GetAttributeImp( name, &temp ) )
+			{
+				if ( throwIfNotFound )
+				{
+					TICPPTHROW( "Attribute does not exist" );
+				}
+			}
+			else
+			{
+				// Stream the value from the string to T
+				FromString( temp, &value );
+			}
+
+			return value;
+		}
+
+		/**
+		Gets an attribute of @a name from an element.
+		Uses FromString to convert the string to the type of choice.
+
+		@param name				The name of the attribute you are querying.
+		@param value			[OUT]	The container for the returned value
+		@param throwIfNotFound	[DEF]	If true, will throw an exception if the attribute doesn't exist
+		@throws Exception When the attribute doesn't exist and throwIfNotFound is true
+
+		@see GetAttributeOrDefault
+		*/
+		template< class T >
+			void GetAttribute( const std::string& name, T* value, bool throwIfNotFound = true ) const
+		{
+			// Get the attribute's value as a std::string
+			std::string temp;
+			if ( !GetAttributeImp( name, &temp ) )
+			{
+				if ( throwIfNotFound )
+				{
+					TICPPTHROW( "Attribute does not exist" );
+				}
+				else
+				{
+					return;
+				}
+			}
+
+			// Stream the value from the string to T
+			FromString( temp, value );
+		}
+
+		/**
+		Gets an attribute of @a name from an element.
+		Returns an empty string if the attribute does not exist.
+
+		@param name	The name of the attribute you are querying.
+		@return The value of the attribute, or an empty string if it does not exist.
+
+		@see GetAttributeOrDefault
+		*/
+		std::string GetAttribute( const std::string& name ) const;
+
+		/**
+		Returns true, if attribute exists
+
+		@param name The name of the attribute you are checking.
+		@return Existence of attribute
+		*/
+		bool HasAttribute( const std::string& name ) const;
+
+		/**
+		Removes attribute from element.
+
+		@param name The name of the attribute to remove.
+		*/
+		void RemoveAttribute( const std::string& name );
+
+	private:
+
+		/**
+		@internal
+		Implimentation of the GetAttribute and GetAttributeOrDefault template methods.
+		*/
+		bool GetAttributeImp( const std::string& name, std::string* value ) const;
+
+		/**
+		@internal
+		Implimentation of the GetText, GetTextOrDefault, GetTextValue, and GetTextValueOrDefault template methods.
+		*/
+		bool GetTextImp( std::string* value ) const;
+	};
+
+	/** Wrapper around TiXmlDeclaration */
+	class Declaration : public NodeImp< TiXmlDeclaration >
+	{
+	public:
+		/**
+		Default	Constructor. Construct an empty declaration.
+		*/
+		Declaration();
+
+		/**
+		Constructor.
+		*/
+		Declaration( TiXmlDeclaration* declaration );
+
+		/**
+		Constructor.
+		*/
+		Declaration( const std::string& version, const std::string& encoding, const std::string& standalone );
+
+		/**
+		Version. Will return an empty string if none was found.
+		*/
+		std::string Version() const;
+
+		/**
+		Encoding. Will return an empty string if none was found.
+		*/
+		std::string Encoding() const;
+
+		/**
+		StandAlone. Is this a standalone document?
+		*/
+		std::string Standalone() const;
+	};
+
+	/** Wrapper around TiXmlStylesheetReference */
+	class StylesheetReference : public NodeImp< TiXmlStylesheetReference >
+	{
+	public:
+		/**
+		Default	Constructor. Construct an empty declaration.
+		*/
+		StylesheetReference();
+
+		/**
+		Constructor.
+		*/
+		StylesheetReference( TiXmlStylesheetReference* stylesheetReference );
+
+		/**
+		Constructor.
+		*/
+		StylesheetReference( const std::string& type, const std::string& href );
+
+		/**
+		Type. Will return an empty string if none was found.
+		*/
+		std::string Type() const;
+
+		/**
+		Href. Will return an empty string if none was found.
+		*/
+		std::string Href() const;
+	};
+}
+
+#endif	// TICPP_INCLUDED
+
+#endif // TIXML_USE_TICPP
Index: /code/branches/rocket2/src/external/tinyxml/ticpprc.h
===================================================================
--- /code/branches/rocket2/src/external/tinyxml/ticpprc.h	(revision 6952)
+++ /code/branches/rocket2/src/external/tinyxml/ticpprc.h	(revision 6952)
@@ -0,0 +1,122 @@
+/*
+http://code.google.com/p/ticpp/
+Copyright (c) 2006 Ryan Pusztai, Ryan Mulder
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#ifdef TIXML_USE_TICPP
+
+#ifndef TICPPRC_INCLUDED
+#define TICPPRC_INCLUDED
+
+#include <vector>
+
+// Forward declare ticpp::Node, so it can be made a friend of TiCppRC
+namespace ticpp
+{
+	class Base;
+}
+
+// Forward declare TiCppRCImp so TiCppRC can hold a pointer to it
+class TiCppRCImp;
+
+/**
+Base class for reference counting functionality
+*/
+class TiCppRC
+{
+	// Allow ticpp::Node to directly modify reference count
+	friend class ticpp::Base;
+
+private:
+
+	TiCppRCImp* m_tiRC; /**< Pointer to reference counter */
+
+public:
+
+	/**
+	Constructor
+	Spawns new reference counter with a pointer to this
+	*/
+	TiCppRC();
+
+	/**
+	Destructor
+	Nullifies the pointer to this held by the reference counter
+	Decrements reference count
+	*/
+	virtual ~TiCppRC();
+	
+	std::vector< ticpp::Base* > m_spawnedWrappers; /**< Remember all wrappers that we've created with 'new' - ( e.g. NodeFactory, FirstChildElement, etc. )*/
+
+	/**
+	Delete all container objects we've spawned with 'new'.
+	*/
+	void DeleteSpawnedWrappers();
+};
+
+class TiCppRCImp
+{
+private:
+
+	int m_count;		/**< Holds reference count to me, and to the node I point to */
+
+	TiCppRC* m_tiCppRC;	/**< Holds pointer to an object inheriting TiCppRC */
+
+public:
+
+	/**
+	Initializes m_tiCppRC pointer, and set reference count to 1
+	*/
+	TiCppRCImp( TiCppRC* tiCppRC );
+
+	/**
+	Allows the TiCppRC object to set the pointer to itself ( m_tiCppRc ) to NULL when the TiCppRC object is deleted
+	*/
+	void Nullify();
+
+	/**
+	Increment Reference Count
+	*/
+	void IncRef();
+
+	/**
+	Decrement Reference Count
+	*/
+	void DecRef();
+
+	/**
+	Set Reference Count to 1 - dangerous! - Use only if you are sure of the consequences
+	*/
+	void InitRef();
+
+	/**
+	Get internal pointer to the TiCppRC object - not reference counted, use at your own risk
+	*/
+	TiCppRC* Get();
+
+	/**
+	Returns state of internal pointer - will be null if the object was deleted
+	*/
+	bool IsNull();
+};
+
+#endif // TICPP_INCLUDED
+
+#endif // TIXML_USE_TICPP
Index: /code/branches/rocket2/src/external/tinyxml/tinystr.cpp
===================================================================
--- /code/branches/rocket2/src/external/tinyxml/tinystr.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/tinyxml/tinystr.cpp	(revision 6952)
@@ -0,0 +1,116 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original file by Yves Berquin.
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+/*
+ * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005.
+ */
+
+
+#ifndef TIXML_USE_STL
+
+#include "tinystr.h"
+
+// Error value for find primitive
+const TiXmlString::size_type TiXmlString::npos = static_cast< TiXmlString::size_type >(-1);
+
+
+// Null rep.
+TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, { '\0' } };
+
+
+void TiXmlString::reserve (size_type cap)
+{
+	if (cap > capacity())
+	{
+		TiXmlString tmp;
+		tmp.init(length(), cap);
+		memcpy(tmp.start(), data(), length());
+		swap(tmp);
+	}
+}
+
+
+TiXmlString& TiXmlString::assign(const char* str, size_type len)
+{
+	size_type cap = capacity();
+	if (len > cap || cap > 3*(len + 8))
+	{
+		TiXmlString tmp;
+		tmp.init(len);
+		memcpy(tmp.start(), str, len);
+		swap(tmp);
+	}
+	else
+	{
+		memmove(start(), str, len);
+		set_size(len);
+	}
+	return *this;
+}
+
+
+TiXmlString& TiXmlString::append(const char* str, size_type len)
+{
+	size_type newsize = length() + len;
+	if (newsize > capacity())
+	{
+		reserve (newsize + capacity());
+	}
+	memmove(finish(), str, len);
+	set_size(newsize);
+	return *this;
+}
+
+
+TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
+{
+	TiXmlString tmp;
+	tmp.reserve(a.length() + b.length());
+	tmp += a;
+	tmp += b;
+	return tmp;
+}
+
+TiXmlString operator + (const TiXmlString & a, const char* b)
+{
+	TiXmlString tmp;
+	TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
+	tmp.reserve(a.length() + b_len);
+	tmp += a;
+	tmp.append(b, b_len);
+	return tmp;
+}
+
+TiXmlString operator + (const char* a, const TiXmlString & b)
+{
+	TiXmlString tmp;
+	TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
+	tmp.reserve(a_len + b.length());
+	tmp.append(a, a_len);
+	tmp += b;
+	return tmp;
+}
+
+
+#endif	// TIXML_USE_STL
Index: /code/branches/rocket2/src/external/tinyxml/tinystr.h
===================================================================
--- /code/branches/rocket2/src/external/tinyxml/tinystr.h	(revision 6952)
+++ /code/branches/rocket2/src/external/tinyxml/tinystr.h	(revision 6952)
@@ -0,0 +1,319 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original file by Yves Berquin.
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+/*
+ * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005.
+ *
+ * - completely rewritten. compact, clean, and fast implementation.
+ * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems)
+ * - fixed reserve() to work as per specification.
+ * - fixed buggy compares operator==(), operator<(), and operator>()
+ * - fixed operator+=() to take a const ref argument, following spec.
+ * - added "copy" constructor with length, and most compare operators.
+ * - added swap(), clear(), size(), capacity(), operator+().
+ */
+
+#ifndef TIXML_USE_STL
+
+#ifndef TIXML_STRING_INCLUDED
+#define TIXML_STRING_INCLUDED
+
+#include <assert.h>
+#include <string.h>
+
+/*	The support for explicit isn't that universal, and it isn't really
+	required - it is used to check that the TiXmlString class isn't incorrectly
+	used. Be nice to old compilers and macro it here:
+*/
+#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
+	// Microsoft visual studio, version 6 and higher.
+	#define TIXML_EXPLICIT explicit
+#elif defined(__GNUC__) && (__GNUC__ >= 3 )
+	// GCC version 3 and higher.s
+	#define TIXML_EXPLICIT explicit
+#else
+	#define TIXML_EXPLICIT
+#endif
+
+
+/*
+   TiXmlString is an emulation of a subset of the std::string template.
+   Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
+   Only the member functions relevant to the TinyXML project have been implemented.
+   The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
+   a string and there's no more room, we allocate a buffer twice as big as we need.
+*/
+class TiXmlString
+{
+  public :
+	// The size type used
+  	typedef size_t size_type;
+
+	// Error value for find primitive
+	static const size_type npos; // = -1;
+
+
+	// TiXmlString empty constructor
+	TiXmlString () : rep_(&nullrep_)
+	{
+	}
+
+	// TiXmlString copy constructor
+	TiXmlString ( const TiXmlString & copy) : rep_(0)
+	{
+		init(copy.length());
+		memcpy(start(), copy.data(), length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TIXML_EXPLICIT TiXmlString ( const char * copy) : rep_(0)
+	{
+		init( static_cast<size_type>( strlen(copy) ));
+		memcpy(start(), copy, length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TIXML_EXPLICIT TiXmlString ( const char * str, size_type len) : rep_(0)
+	{
+		init(len);
+		memcpy(start(), str, len);
+	}
+
+	// TiXmlString destructor
+	~TiXmlString ()
+	{
+		quit();
+	}
+
+	// = operator
+	TiXmlString& operator = (const char * copy)
+	{
+		return assign( copy, (size_type)strlen(copy));
+	}
+
+	// = operator
+	TiXmlString& operator = (const TiXmlString & copy)
+	{
+		return assign(copy.start(), copy.length());
+	}
+
+
+	// += operator. Maps to append
+	TiXmlString& operator += (const char * suffix)
+	{
+		return append(suffix, static_cast<size_type>( strlen(suffix) ));
+	}
+
+	// += operator. Maps to append
+	TiXmlString& operator += (char single)
+	{
+		return append(&single, 1);
+	}
+
+	// += operator. Maps to append
+	TiXmlString& operator += (const TiXmlString & suffix)
+	{
+		return append(suffix.data(), suffix.length());
+	}
+
+
+	// Convert a TiXmlString into a null-terminated char *
+	const char * c_str () const { return rep_->str; }
+
+	// Convert a TiXmlString into a char * (need not be null terminated).
+	const char * data () const { return rep_->str; }
+
+	// Return the length of a TiXmlString
+	size_type length () const { return rep_->size; }
+
+	// Alias for length()
+	size_type size () const { return rep_->size; }
+
+	// Checks if a TiXmlString is empty
+	bool empty () const { return rep_->size == 0; }
+
+	// Return capacity of string
+	size_type capacity () const { return rep_->capacity; }
+
+
+	// single char extraction
+	const char& at (size_type index) const
+	{
+		assert( index < length() );
+		return rep_->str[ index ];
+	}
+
+	// [] operator
+	char& operator [] (size_type index) const
+	{
+		assert( index < length() );
+		return rep_->str[ index ];
+	}
+
+	// find a char in a string. Return TiXmlString::npos if not found
+	size_type find (char lookup) const
+	{
+		return find(lookup, 0);
+	}
+
+	// find a char in a string from an offset. Return TiXmlString::npos if not found
+	size_type find (char tofind, size_type offset) const
+	{
+		if (offset >= length()) return npos;
+
+		for (const char* p = c_str() + offset; *p != '\0'; ++p)
+		{
+		   if (*p == tofind) return static_cast< size_type >( p - c_str() );
+		}
+		return npos;
+	}
+
+	void clear ()
+	{
+		//Lee:
+		//The original was just too strange, though correct:
+		//	TiXmlString().swap(*this);
+		//Instead use the quit & re-init:
+		quit();
+		init(0,0);
+	}
+
+	/*	Function to reserve a big amount of data when we know we'll need it. Be aware that this
+		function DOES NOT clear the content of the TiXmlString if any exists.
+	*/
+	void reserve (size_type cap);
+
+	TiXmlString& assign (const char* str, size_type len);
+
+	TiXmlString& append (const char* str, size_type len);
+
+	void swap (TiXmlString& other)
+	{
+		Rep* r = rep_;
+		rep_ = other.rep_;
+		other.rep_ = r;
+	}
+
+  private:
+
+	void init(size_type sz) { init(sz, sz); }
+	void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
+	char* start() const { return rep_->str; }
+	char* finish() const { return rep_->str + rep_->size; }
+
+	struct Rep
+	{
+		size_type size, capacity;
+		char str[1];
+	};
+
+	void init(size_type sz, size_type cap)
+	{
+		if (cap)
+		{
+			// Lee: the original form:
+			//	rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
+			// doesn't work in some cases of new being overloaded. Switching
+			// to the normal allocation, although use an 'int' for systems
+			// that are overly picky about structure alignment.
+			const size_type bytesNeeded = sizeof(Rep) + cap;
+			const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); 
+			rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
+
+			rep_->str[ rep_->size = sz ] = '\0';
+			rep_->capacity = cap;
+		}
+		else
+		{
+			rep_ = &nullrep_;
+		}
+	}
+
+	void quit()
+	{
+		if (rep_ != &nullrep_)
+		{
+			// The rep_ is really an array of ints. (see the allocator, above).
+			// Cast it back before delete, so the compiler won't incorrectly call destructors.
+			delete [] ( reinterpret_cast<int*>( rep_ ) );
+		}
+	}
+
+	Rep * rep_;
+	static Rep nullrep_;
+
+} ;
+
+
+inline bool operator == (const TiXmlString & a, const TiXmlString & b)
+{
+	return    ( a.length() == b.length() )				// optimization on some platforms
+	       && ( strcmp(a.c_str(), b.c_str()) == 0 );	// actual compare
+}
+inline bool operator < (const TiXmlString & a, const TiXmlString & b)
+{
+	return strcmp(a.c_str(), b.c_str()) < 0;
+}
+
+inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
+inline bool operator >  (const TiXmlString & a, const TiXmlString & b) { return b < a; }
+inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
+inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
+
+inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
+inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
+inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
+inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
+
+TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
+TiXmlString operator + (const TiXmlString & a, const char* b);
+TiXmlString operator + (const char* a, const TiXmlString & b);
+
+
+/*
+   TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
+   Only the operators that we need for TinyXML have been developped.
+*/
+class TiXmlOutStream : public TiXmlString
+{
+public :
+
+	// TiXmlOutStream << operator.
+	TiXmlOutStream & operator << (const TiXmlString & in)
+	{
+		*this += in;
+		return *this;
+	}
+
+	// TiXmlOutStream << operator.
+	TiXmlOutStream & operator << (const char * in)
+	{
+		*this += in;
+		return *this;
+	}
+
+} ;
+
+#endif	// TIXML_STRING_INCLUDED
+#endif	// TIXML_USE_STL
Index: /code/branches/rocket2/src/external/tinyxml/tinyxml.cpp
===================================================================
--- /code/branches/rocket2/src/external/tinyxml/tinyxml.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/tinyxml/tinyxml.cpp	(revision 6952)
@@ -0,0 +1,1969 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.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 "tinyxml.h"
+
+#include <ctype.h>
+
+#ifdef TIXML_USE_STL
+#include <sstream>
+#include <iostream>
+#endif
+
+
+bool TiXmlBase::condenseWhiteSpace = true;
+
+// Microsoft compiler security
+FILE* TiXmlFOpen( const char* filename, const char* mode )
+{
+	#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
+		FILE* fp = 0;
+		errno_t err = fopen_s( &fp, filename, mode );
+		if ( !err && fp )
+			return fp;
+		return 0;
+	#else
+		return fopen( filename, mode );
+	#endif
+}
+
+void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
+{
+	int i=0;
+
+	while( i<(int)str.length() )
+	{
+		unsigned char c = (unsigned char) str[i];
+
+		if (    c == '&'
+		     && i < ( (int)str.length() - 2 )
+			 && str[i+1] == '#'
+			 && str[i+2] == 'x' )
+		{
+			// Hexadecimal character reference.
+			// Pass through unchanged.
+			// &#xA9;	-- copyright symbol, for example.
+			//
+			// The -1 is a bug fix from Rob Laveaux. It keeps
+			// an overflow from happening if there is no ';'.
+			// There are actually 2 ways to exit this loop -
+			// while fails (error case) and break (semicolon found).
+			// However, there is no mechanism (currently) for
+			// this function to return an error.
+			while ( i<(int)str.length()-1 )
+			{
+				outString->append( str.c_str() + i, 1 );
+				++i;
+				if ( str[i] == ';' )
+					break;
+			}
+		}
+		else if ( c == '&' )
+		{
+			outString->append( entity[0].str, entity[0].strLength );
+			++i;
+		}
+		else if ( c == '<' )
+		{
+			outString->append( entity[1].str, entity[1].strLength );
+			++i;
+		}
+		else if ( c == '>' )
+		{
+			outString->append( entity[2].str, entity[2].strLength );
+			++i;
+		}
+		else if ( c == '\"' )
+		{
+			outString->append( entity[3].str, entity[3].strLength );
+			++i;
+		}
+		else if ( c == '\'' )
+		{
+			outString->append( entity[4].str, entity[4].strLength );
+			++i;
+		}
+		else if ( c < 32 )
+		{
+			// Easy pass at non-alpha/numeric/symbol
+			// Below 32 is symbolic.
+			char buf[ 32 ];
+
+			#if defined(TIXML_SNPRINTF)
+				TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
+			#else
+				sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
+			#endif
+
+			//*ME:	warning C4267: convert 'size_t' to 'int'
+			//*ME:	Int-Cast to make compiler happy ...
+			outString->append( buf, (int)strlen( buf ) );
+			++i;
+		}
+		else
+		{
+			//char realc = (char) c;
+			//outString->append( &realc, 1 );
+			*outString += (char) c;	// somewhat more efficient function call.
+			++i;
+		}
+	}
+}
+
+
+TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
+{
+	parent = 0;
+	type = _type;
+	firstChild = 0;
+	lastChild = 0;
+	prev = 0;
+	next = 0;
+}
+
+
+TiXmlNode::~TiXmlNode()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}
+}
+
+
+void TiXmlNode::CopyTo( TiXmlNode* target ) const
+{
+	target->SetValue (value.c_str() );
+	target->userData = userData;
+}
+
+
+void TiXmlNode::Clear()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}
+
+	firstChild = 0;
+	lastChild = 0;
+}
+
+
+TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
+{
+	assert( node->parent == 0 || node->parent == this );
+	assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
+
+	if ( node->Type() == TiXmlNode::DOCUMENT )
+	{
+		delete node;
+		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	node->parent = this;
+
+	node->prev = lastChild;
+	node->next = 0;
+
+	if ( lastChild )
+		lastChild->next = node;
+	else
+		firstChild = node;			// it was an empty list.
+
+	lastChild = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
+{
+	if ( addThis.Type() == TiXmlNode::DOCUMENT )
+	{
+		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+
+	return LinkEndChild( node );
+}
+
+
+TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
+{
+	if ( !beforeThis || beforeThis->parent != this ) {
+		return 0;
+	}
+	if ( addThis.Type() == TiXmlNode::DOCUMENT )
+	{
+		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->next = beforeThis;
+	node->prev = beforeThis->prev;
+	if ( beforeThis->prev )
+	{
+		beforeThis->prev->next = node;
+	}
+	else
+	{
+		assert( firstChild == beforeThis );
+		firstChild = node;
+	}
+	beforeThis->prev = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
+{
+	if ( !afterThis || afterThis->parent != this ) {
+		return 0;
+	}
+	if ( addThis.Type() == TiXmlNode::DOCUMENT )
+	{
+		if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->prev = afterThis;
+	node->next = afterThis->next;
+	if ( afterThis->next )
+	{
+		afterThis->next->prev = node;
+	}
+	else
+	{
+		assert( lastChild == afterThis );
+		lastChild = node;
+	}
+	afterThis->next = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
+{
+	if ( replaceThis->parent != this )
+		return 0;
+
+	TiXmlNode* node = withThis.Clone();
+	if ( !node )
+		return 0;
+
+	node->next = replaceThis->next;
+	node->prev = replaceThis->prev;
+
+	if ( replaceThis->next )
+		replaceThis->next->prev = node;
+	else
+		lastChild = node;
+
+	if ( replaceThis->prev )
+		replaceThis->prev->next = node;
+	else
+		firstChild = node;
+
+	delete replaceThis;
+	node->parent = this;
+	return node;
+}
+
+
+bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
+{
+	if ( removeThis->parent != this )
+	{
+		assert( 0 );
+		return false;
+	}
+
+	if ( removeThis->next )
+		removeThis->next->prev = removeThis->prev;
+	else
+		lastChild = removeThis->prev;
+
+	if ( removeThis->prev )
+		removeThis->prev->next = removeThis->next;
+	else
+		firstChild = removeThis->next;
+
+	delete removeThis;
+	return true;
+}
+
+const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = firstChild; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = lastChild; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild();
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling();
+	}
+}
+
+
+const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild( val );
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling( val );
+	}
+}
+
+
+const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = next; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = prev; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+void TiXmlElement::RemoveAttribute( const char * name )
+{
+    #ifdef TIXML_USE_STL
+	TIXML_STRING str( name );
+	TiXmlAttribute* node = attributeSet.Find( str );
+	#else
+	TiXmlAttribute* node = attributeSet.Find( name );
+	#endif
+	if ( node )
+	{
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+const TiXmlElement* TiXmlNode::FirstChildElement() const
+{
+	const TiXmlNode* node;
+
+	for (	node = FirstChild();
+			node;
+			node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
+{
+	const TiXmlNode* node;
+
+	for (	node = FirstChild( _value );
+			node;
+			node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::NextSiblingElement() const
+{
+	const TiXmlNode* node;
+
+	for (	node = NextSibling();
+			node;
+			node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
+{
+	const TiXmlNode* node;
+
+	for (	node = NextSibling( _value );
+			node;
+			node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlDocument* TiXmlNode::GetDocument() const
+{
+	const TiXmlNode* node;
+
+	for( node = this; node; node = node->parent )
+	{
+		if ( node->ToDocument() )
+			return node->ToDocument();
+	}
+	return 0;
+}
+
+
+TiXmlElement::TiXmlElement (const char * _value)
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlElement::TiXmlElement( const std::string& _value )
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+#endif
+
+
+TiXmlElement::TiXmlElement( const TiXmlElement& copy)
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	copy.CopyTo( this );
+}
+
+
+void TiXmlElement::operator=( const TiXmlElement& base )
+{
+	ClearThis();
+	base.CopyTo( this );
+}
+
+
+TiXmlElement::~TiXmlElement()
+{
+	ClearThis();
+}
+
+
+void TiXmlElement::ClearThis()
+{
+	Clear();
+	while( attributeSet.First() )
+	{
+		TiXmlAttribute* node = attributeSet.First();
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+
+const char* TiXmlElement::Attribute( const char* name ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+		return node->Value();
+	return 0;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+		return &node->ValueStr();
+	return 0;
+}
+#endif
+
+
+const char* TiXmlElement::Attribute( const char* name, int* i ) const
+{
+	const char* s = Attribute( name );
+	if ( i )
+	{
+		if ( s ) {
+			*i = atoi( s );
+		}
+		else {
+			*i = 0;
+		}
+	}
+	return s;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
+{
+	const std::string* s = Attribute( name );
+	if ( i )
+	{
+		if ( s ) {
+			*i = atoi( s->c_str() );
+		}
+		else {
+			*i = 0;
+		}
+	}
+	return s;
+}
+#endif
+
+
+const char* TiXmlElement::Attribute( const char* name, double* d ) const
+{
+	const char* s = Attribute( name );
+	if ( d )
+	{
+		if ( s ) {
+			*d = atof( s );
+		}
+		else {
+			*d = 0;
+		}
+	}
+	return s;
+}
+
+
+#ifdef TIXML_USE_STL
+const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
+{
+	const std::string* s = Attribute( name );
+	if ( d )
+	{
+		if ( s ) {
+			*d = atof( s->c_str() );
+		}
+		else {
+			*d = 0;
+		}
+	}
+	return s;
+}
+#endif
+
+
+int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+	return node->QueryIntValue( ival );
+}
+
+
+#ifdef TIXML_USE_STL
+int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+	return node->QueryIntValue( ival );
+}
+#endif
+
+
+int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+	return node->QueryDoubleValue( dval );
+}
+
+
+#ifdef TIXML_USE_STL
+int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+	return node->QueryDoubleValue( dval );
+}
+#endif
+
+
+void TiXmlElement::SetAttribute( const char * name, int val )
+{
+	char buf[64];
+	#if defined(TIXML_SNPRINTF)
+		TIXML_SNPRINTF( buf, sizeof(buf), "%d", val );
+	#else
+		sprintf( buf, "%d", val );
+	#endif
+	SetAttribute( name, buf );
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetAttribute( const std::string& name, int val )
+{
+   std::ostringstream oss;
+   oss << val;
+   SetAttribute( name, oss.str() );
+}
+#endif
+
+
+void TiXmlElement::SetDoubleAttribute( const char * name, double val )
+{
+	char buf[256];
+	#if defined(TIXML_SNPRINTF)
+		TIXML_SNPRINTF( buf, sizeof(buf), "%f", val );
+	#else
+		sprintf( buf, "%f", val );
+	#endif
+	SetAttribute( name, buf );
+}
+
+
+void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
+{
+    #ifdef TIXML_USE_STL
+	TIXML_STRING _name( cname );
+	TIXML_STRING _value( cvalue );
+	#else
+	const char* _name = cname;
+	const char* _value = cvalue;
+	#endif
+
+	TiXmlAttribute* node = attributeSet.Find( _name );
+	if ( node )
+	{
+		node->SetValue( _value );
+		return;
+	}
+
+	TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue );
+	if ( attrib )
+	{
+		attributeSet.Add( attrib );
+	}
+	else
+	{
+		TiXmlDocument* document = GetDocument();
+		if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+	}
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value )
+{
+	TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+	{
+		node->SetValue( _value );
+		return;
+	}
+
+	TiXmlAttribute* attrib = new TiXmlAttribute( name, _value );
+	if ( attrib )
+	{
+		attributeSet.Add( attrib );
+	}
+	else
+	{
+		TiXmlDocument* document = GetDocument();
+		if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+	}
+}
+#endif
+
+
+void TiXmlElement::Print( FILE* cfile, int depth ) const
+{
+	int i;
+	assert( cfile );
+	for ( i=0; i<depth; i++ ) {
+		fprintf( cfile, "    " );
+	}
+
+	fprintf( cfile, "<%s", value.c_str() );
+
+	const TiXmlAttribute* attrib;
+	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
+	{
+		fprintf( cfile, " " );
+		attrib->Print( cfile, depth );
+	}
+
+	// There are 3 different formatting approaches:
+	// 1) An element without children is printed as a <foo /> node
+	// 2) An element with only a text child is printed as <foo> text </foo>
+	// 3) An element with children is printed on multiple lines.
+	TiXmlNode* node;
+	if ( !firstChild )
+	{
+		fprintf( cfile, " />" );
+	}
+	else if ( firstChild == lastChild && firstChild->ToText() )
+	{
+		fprintf( cfile, ">" );
+		firstChild->Print( cfile, depth + 1 );
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+	else
+	{
+		fprintf( cfile, ">" );
+
+		for ( node = firstChild; node; node=node->NextSibling() )
+		{
+			if ( !node->ToText() )
+			{
+				fprintf( cfile, "\n" );
+			}
+			node->Print( cfile, depth+1 );
+		}
+		fprintf( cfile, "\n" );
+		for( i=0; i<depth; ++i ) {
+			fprintf( cfile, "    " );
+		}
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+}
+
+
+void TiXmlElement::CopyTo( TiXmlElement* target ) const
+{
+	// superclass:
+	TiXmlNode::CopyTo( target );
+
+	// Element class:
+	// Clone the attributes, then clone the children.
+	const TiXmlAttribute* attribute = 0;
+	for(	attribute = attributeSet.First();
+	attribute;
+	attribute = attribute->Next() )
+	{
+		target->SetAttribute( attribute->Name(), attribute->Value() );
+	}
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		target->LinkEndChild( node->Clone() );
+	}
+}
+
+bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
+{
+	if ( visitor->VisitEnter( *this, attributeSet.First() ) )
+	{
+		for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+		{
+			if ( !node->Accept( visitor ) )
+				break;
+		}
+	}
+	return visitor->VisitExit( *this );
+}
+
+
+TiXmlNode* TiXmlElement::Clone() const
+{
+	TiXmlElement* clone = new TiXmlElement( Value() );
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+const char* TiXmlElement::GetText() const
+{
+	const TiXmlNode* child = this->FirstChild();
+	if ( child ) {
+		const TiXmlText* childText = child->ToText();
+		if ( childText ) {
+			return childText->Value();
+		}
+	}
+	return 0;
+}
+
+
+TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	ClearError();
+}
+
+TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	value = documentName;
+	ClearError();
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+    value = documentName;
+	ClearError();
+}
+#endif
+
+
+TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+void TiXmlDocument::operator=( const TiXmlDocument& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+}
+
+
+bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
+{
+	// See STL_STRING_BUG below.
+	//StringToBuffer buf( value );
+
+	return LoadFile( Value(), encoding );
+}
+
+
+bool TiXmlDocument::SaveFile() const
+{
+	// See STL_STRING_BUG below.
+//	StringToBuffer buf( value );
+//
+//	if ( buf.buffer && SaveFile( buf.buffer ) )
+//		return true;
+//
+//	return false;
+	return SaveFile( Value() );
+}
+
+bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
+{
+	// There was a really terrifying little bug here. The code:
+	//		value = filename
+	// in the STL case, cause the assignment method of the std::string to
+	// be called. What is strange, is that the std::string had the same
+	// address as it's c_str() method, and so bad things happen. Looks
+	// like a bug in the Microsoft STL implementation.
+	// Add an extra string to avoid the crash.
+	TIXML_STRING filename( _filename );
+	value = filename;
+
+	// reading in binary mode so that tinyxml can normalize the EOL
+	FILE* file = TiXmlFOpen( value.c_str (), "rb" );
+
+	if ( file )
+	{
+		bool result = LoadFile( file, encoding );
+		fclose( file );
+		return result;
+	}
+	else
+	{
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+}
+
+bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
+{
+	if ( !file )
+	{
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	// Delete the existing data:
+	Clear();
+	location.Clear();
+
+	// Get the file size, so we can pre-allocate the string. HUGE speed impact.
+	long length = 0;
+	fseek( file, 0, SEEK_END );
+	length = ftell( file );
+	fseek( file, 0, SEEK_SET );
+
+	// Strange case, but good to handle up front.
+	if ( length <= 0 )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	// If we have a file, assume it is all one big XML file, and read it in.
+	// The document parser may decide the document ends sooner than the entire file, however.
+	TIXML_STRING data;
+	data.reserve( length );
+
+	// Subtle bug here. TinyXml did use fgets. But from the XML spec:
+	// 2.11 End-of-Line Handling
+	// <snip>
+	// <quote>
+	// ...the XML processor MUST behave as if it normalized all line breaks in external
+	// parsed entities (including the document entity) on input, before parsing, by translating
+	// both the two-character sequence #xD #xA and any #xD that is not followed by #xA to
+	// a single #xA character.
+	// </quote>
+	//
+	// It is not clear fgets does that, and certainly isn't clear it works cross platform.
+	// Generally, you expect fgets to translate from the convention of the OS to the c/unix
+	// convention, and not work generally.
+
+	/*
+	while( fgets( buf, sizeof(buf), file ) )
+	{
+		data += buf;
+	}
+	*/
+
+	char* buf = new char[ length+1 ];
+	buf[0] = 0;
+
+	if ( fread( buf, length, 1, file ) != 1 ) {
+		delete [] buf;
+		SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return false;
+	}
+
+	const char* lastPos = buf;
+	const char* p = buf;
+
+	buf[length] = 0;
+	while( *p ) {
+		assert( p < (buf+length) );
+		if ( *p == 0xa ) {
+			// Newline character. No special rules for this. Append all the characters
+			// since the last string, and include the newline.
+			data.append( lastPos, (p-lastPos+1) );	// append, include the newline
+			++p;									// move past the newline
+			lastPos = p;							// and point to the new buffer (may be 0)
+			assert( p <= (buf+length) );
+		}
+		else if ( *p == 0xd ) {
+			// Carriage return. Append what we have so far, then
+			// handle moving forward in the buffer.
+			if ( (p-lastPos) > 0 ) {
+				data.append( lastPos, p-lastPos );	// do not add the CR
+			}
+			data += (char)0xa;						// a proper newline
+
+			if ( *(p+1) == 0xa ) {
+				// Carriage return - new line sequence
+				p += 2;
+				lastPos = p;
+				assert( p <= (buf+length) );
+			}
+			else {
+				// it was followed by something else...that is presumably characters again.
+				++p;
+				lastPos = p;
+				assert( p <= (buf+length) );
+			}
+		}
+		else {
+			++p;
+		}
+	}
+	// Handle any left over characters.
+	if ( p-lastPos ) {
+		data.append( lastPos, p-lastPos );
+	}
+	delete [] buf;
+	buf = 0;
+
+	Parse( data.c_str(), 0, encoding );
+
+	if (  Error() )
+        return false;
+    else
+		return true;
+}
+
+
+bool TiXmlDocument::SaveFile( const char * filename ) const
+{
+	// The old c stuff lives on...
+	FILE* fp = TiXmlFOpen( filename, "w" );
+	if ( fp )
+	{
+		bool result = SaveFile( fp );
+		fclose( fp );
+		return result;
+	}
+	return false;
+}
+
+
+bool TiXmlDocument::SaveFile( FILE* fp ) const
+{
+	if ( useMicrosoftBOM )
+	{
+		const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+		const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+		const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+		fputc( TIXML_UTF_LEAD_0, fp );
+		fputc( TIXML_UTF_LEAD_1, fp );
+		fputc( TIXML_UTF_LEAD_2, fp );
+	}
+	Print( fp, 0 );
+	return (ferror(fp) == 0);
+}
+
+
+void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->error = error;
+	target->errorId = errorId;
+	target->errorDesc = errorDesc;
+	target->tabsize = tabsize;
+	target->errorLocation = errorLocation;
+	target->useMicrosoftBOM = useMicrosoftBOM;
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		target->LinkEndChild( node->Clone() );
+	}
+}
+
+
+TiXmlNode* TiXmlDocument::Clone() const
+{
+	TiXmlDocument* clone = new TiXmlDocument();
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlDocument::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+	{
+		node->Print( cfile, depth );
+		fprintf( cfile, "\n" );
+	}
+}
+
+
+bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
+{
+	if ( visitor->VisitEnter( *this ) )
+	{
+		for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
+		{
+			if ( !node->Accept( visitor ) )
+				break;
+		}
+	}
+	return visitor->VisitExit( *this );
+}
+
+
+const TiXmlAttribute* TiXmlAttribute::Next() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+
+/*
+TiXmlAttribute* TiXmlAttribute::Next()
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+*/
+
+const TiXmlAttribute* TiXmlAttribute::Previous() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+
+/*
+TiXmlAttribute* TiXmlAttribute::Previous()
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+*/
+
+void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
+{
+	TIXML_STRING n, v;
+
+	EncodeString( name, &n );
+	EncodeString( value, &v );
+
+	if (value.find ('\"') == TIXML_STRING::npos) {
+		if ( cfile ) {
+		fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
+		}
+		if ( str ) {
+			(*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
+		}
+	}
+	else {
+		if ( cfile ) {
+		fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
+		}
+		if ( str ) {
+			(*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
+		}
+	}
+}
+
+
+int TiXmlAttribute::QueryIntValue( int* ival ) const
+{
+	if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+int TiXmlAttribute::QueryDoubleValue( double* dval ) const
+{
+	if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+void TiXmlAttribute::SetIntValue( int _value )
+{
+	char buf [64];
+	#if defined(TIXML_SNPRINTF)
+		TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
+	#else
+		sprintf (buf, "%d", _value);
+	#endif
+	SetValue (buf);
+}
+
+void TiXmlAttribute::SetDoubleValue( double _value )
+{
+	char buf [256];
+	#if defined(TIXML_SNPRINTF)
+		TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value);
+	#else
+		sprintf (buf, "%lf", _value);
+	#endif
+	SetValue (buf);
+}
+
+int TiXmlAttribute::IntValue() const
+{
+	return atoi (value.c_str ());
+}
+
+double  TiXmlAttribute::DoubleValue() const
+{
+	return atof (value.c_str ());
+}
+
+
+TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+void TiXmlComment::operator=( const TiXmlComment& base )
+{
+	Clear();
+	base.CopyTo( this );
+}
+
+
+void TiXmlComment::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	for ( int i=0; i<depth; i++ )
+	{
+		fprintf( cfile,  "    " );
+	}
+	fprintf( cfile, "<!--%s-->", value.c_str() );
+}
+
+
+void TiXmlComment::CopyTo( TiXmlComment* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlComment::Clone() const
+{
+	TiXmlComment* clone = new TiXmlComment();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlText::Print( FILE* cfile, int depth ) const
+{
+	assert( cfile );
+	if ( cdata )
+	{
+		int i;
+		fprintf( cfile, "\n" );
+		for ( i=0; i<depth; i++ ) {
+			fprintf( cfile, "    " );
+		}
+		fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() );	// unformatted output
+	}
+	else
+	{
+		TIXML_STRING buffer;
+		EncodeString( value, &buffer );
+		fprintf( cfile, "%s", buffer.c_str() );
+	}
+}
+
+
+void TiXmlText::CopyTo( TiXmlText* target ) const
+{
+	TiXmlNode::CopyTo( target );
+	target->cdata = cdata;
+}
+
+
+bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlText::Clone() const
+{
+	TiXmlText* clone = 0;
+	clone = new TiXmlText( "" );
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+TiXmlDeclaration::TiXmlDeclaration( const char * _version,
+									const char * _encoding,
+									const char * _standalone )
+	: TiXmlNode( TiXmlNode::DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDeclaration::TiXmlDeclaration(	const std::string& _version,
+									const std::string& _encoding,
+									const std::string& _standalone )
+	: TiXmlNode( TiXmlNode::DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+#endif
+
+
+TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
+	: TiXmlNode( TiXmlNode::DECLARATION )
+{
+	copy.CopyTo( this );
+}
+
+
+void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+}
+
+
+void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
+{
+	if ( cfile ) fprintf( cfile, "<?xml " );
+	if ( str )	 (*str) += "<?xml ";
+
+	if ( !version.empty() ) {
+		if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
+		if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
+	}
+	if ( !encoding.empty() ) {
+		if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
+		if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
+	}
+	if ( !standalone.empty() ) {
+		if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
+		if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
+	}
+	if ( cfile ) fprintf( cfile, "?>" );
+	if ( str )	 (*str) += "?>";
+}
+
+
+void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->version = version;
+	target->encoding = encoding;
+	target->standalone = standalone;
+}
+
+
+bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlDeclaration::Clone() const
+{
+	TiXmlDeclaration* clone = new TiXmlDeclaration();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+TiXmlStylesheetReference::TiXmlStylesheetReference( const char * _type,
+													const char * _href )
+	: TiXmlNode( TiXmlNode::STYLESHEETREFERENCE )
+{
+	type = _type;
+	href = _href;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlStylesheetReference::TiXmlStylesheetReference(	const std::string& _type,
+													const std::string& _href )
+	: TiXmlNode( TiXmlNode::STYLESHEETREFERENCE )
+{
+	type = _type;
+	href = _href;
+}
+#endif
+
+
+TiXmlStylesheetReference::TiXmlStylesheetReference( const TiXmlStylesheetReference& copy )
+	: TiXmlNode( TiXmlNode::STYLESHEETREFERENCE )
+{
+	copy.CopyTo( this );
+}
+
+
+void TiXmlStylesheetReference::operator=( const TiXmlStylesheetReference& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+}
+
+
+void TiXmlStylesheetReference::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
+{
+	if ( cfile ) fprintf( cfile, "<?xml-stylesheet " );
+	if ( str )	 (*str) += "<?xml-stylesheet ";
+
+	if ( !type.empty() ) {
+		if ( cfile ) fprintf (cfile, "type=\"%s\" ", type.c_str ());
+		if ( str ) { (*str) += "type=\""; (*str) += type; (*str) += "\" "; }
+	}
+	if ( !href.empty() ) {
+		if ( cfile ) fprintf (cfile, "href=\"%s\" ", href.c_str ());
+		if ( str ) { (*str) += "href=\""; (*str) += href; (*str) += "\" "; }
+	}
+	if ( cfile ) fprintf (cfile, "?>");
+	if ( str )	 (*str) += "?>";
+}
+
+void TiXmlStylesheetReference::CopyTo( TiXmlStylesheetReference* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->type = type;
+	target->href = href;
+}
+
+bool TiXmlStylesheetReference::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+TiXmlNode* TiXmlStylesheetReference::Clone() const
+{
+	TiXmlStylesheetReference* clone = new TiXmlStylesheetReference();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlUnknown::Print( FILE* cfile, int depth ) const
+{
+	for ( int i=0; i<depth; i++ )
+		fprintf( cfile, "    " );
+	fprintf( cfile, "<%s>", value.c_str() );
+}
+
+
+void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
+{
+	return visitor->Visit( *this );
+}
+
+
+TiXmlNode* TiXmlUnknown::Clone() const
+{
+	TiXmlUnknown* clone = new TiXmlUnknown();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+TiXmlAttributeSet::TiXmlAttributeSet()
+{
+	sentinel.next = &sentinel;
+	sentinel.prev = &sentinel;
+}
+
+
+TiXmlAttributeSet::~TiXmlAttributeSet()
+{
+	assert( sentinel.next == &sentinel );
+	assert( sentinel.prev == &sentinel );
+}
+
+
+void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
+{
+    #ifdef TIXML_USE_STL
+	assert( !Find( TIXML_STRING( addMe->Name() ) ) );	// Shouldn't be multiply adding to the set.
+	#else
+	assert( !Find( addMe->Name() ) );	// Shouldn't be multiply adding to the set.
+	#endif
+
+	addMe->next = &sentinel;
+	addMe->prev = sentinel.prev;
+
+	sentinel.prev->next = addMe;
+	sentinel.prev      = addMe;
+}
+
+void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
+{
+	TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node == removeMe )
+		{
+			node->prev->next = node->next;
+			node->next->prev = node->prev;
+			node->next = 0;
+			node->prev = 0;
+			return;
+		}
+	}
+	assert( 0 );		// we tried to remove a non-linked attribute.
+}
+
+
+#ifdef TIXML_USE_STL
+const TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
+{
+	for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node->name == name )
+			return node;
+	}
+	return 0;
+}
+
+/*
+TiXmlAttribute*	TiXmlAttributeSet::Find( const std::string& name )
+{
+	for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node->name == name )
+			return node;
+	}
+	return 0;
+}
+*/
+#endif
+
+
+const TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
+{
+	for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( strcmp( node->name.c_str(), name ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+/*
+TiXmlAttribute*	TiXmlAttributeSet::Find( const char* name )
+{
+	for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( strcmp( node->name.c_str(), name ) == 0 )
+			return node;
+	}
+	return 0;
+}
+*/
+
+#ifdef TIXML_USE_STL
+std::istream& operator>> (std::istream & in, TiXmlNode & base)
+{
+	TIXML_STRING tag;
+	tag.reserve( 8 * 1000 );
+	base.StreamIn( &in, &tag );
+
+	base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
+	return in;
+}
+#endif
+
+
+#ifdef TIXML_USE_STL
+std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
+{
+	TiXmlPrinter printer;
+	printer.SetStreamPrinting();
+	base.Accept( &printer );
+	out << printer.Str();
+
+	return out;
+}
+
+
+std::string& operator<< (std::string& out, const TiXmlNode& base )
+{
+	TiXmlPrinter printer;
+	printer.SetStreamPrinting();
+	base.Accept( &printer );
+	out.append( printer.Str() );
+
+	return out;
+}
+#endif
+
+
+TiXmlHandle TiXmlHandle::FirstChild() const
+{
+	if ( node )
+	{
+		TiXmlNode* child = node->FirstChild();
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
+{
+	if ( node )
+	{
+		TiXmlNode* child = node->FirstChild( value );
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement() const
+{
+	if ( node )
+	{
+		TiXmlElement* child = node->FirstChildElement();
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
+{
+	if ( node )
+	{
+		TiXmlElement* child = node->FirstChildElement( value );
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::Child( int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlNode* child = node->FirstChild();
+		for (	i=0;
+				child && i<count;
+				child = child->NextSibling(), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlNode* child = node->FirstChild( value );
+		for (	i=0;
+				child && i<count;
+				child = child->NextSibling( value ), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement( int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlElement* child = node->FirstChildElement();
+		for (	i=0;
+				child && i<count;
+				child = child->NextSiblingElement(), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlElement* child = node->FirstChildElement( value );
+		for (	i=0;
+				child && i<count;
+				child = child->NextSiblingElement( value ), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
+{
+	return true;
+}
+
+bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
+{
+	return true;
+}
+
+bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
+{
+	DoIndent();
+	buffer += "<";
+	buffer += element.Value();
+
+	for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
+	{
+		buffer += " ";
+		attrib->Print( 0, 0, &buffer );
+	}
+
+	if ( !element.FirstChild() )
+	{
+		buffer += " />";
+		DoLineBreak();
+	}
+	else
+	{
+		buffer += ">";
+		if (    element.FirstChild()->ToText()
+			  && element.LastChild() == element.FirstChild()
+			  && element.FirstChild()->ToText()->CDATA() == false )
+		{
+			simpleTextPrint = true;
+			// no DoLineBreak()!
+		}
+		else
+		{
+			DoLineBreak();
+		}
+	}
+	++depth;
+	return true;
+}
+
+
+bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
+{
+	--depth;
+	if ( !element.FirstChild() )
+	{
+		// nothing.
+	}
+	else
+	{
+		if ( simpleTextPrint )
+		{
+			simpleTextPrint = false;
+		}
+		else
+		{
+			DoIndent();
+		}
+		buffer += "</";
+		buffer += element.Value();
+		buffer += ">";
+		DoLineBreak();
+	}
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlText& text )
+{
+	if ( text.CDATA() )
+	{
+		DoIndent();
+		buffer += "<![CDATA[";
+		buffer += text.Value();
+		buffer += "]]>";
+		DoLineBreak();
+	}
+	else if ( simpleTextPrint )
+	{
+		TIXML_STRING str;
+		TiXmlBase::EncodeString( text.ValueTStr(), &str );
+		buffer += str;
+	}
+	else
+	{
+		DoIndent();
+		TIXML_STRING str;
+		TiXmlBase::EncodeString( text.ValueTStr(), &str );
+		buffer += str;
+		DoLineBreak();
+	}
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
+{
+	DoIndent();
+	declaration.Print( 0, 0, &buffer );
+	DoLineBreak();
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlComment& comment )
+{
+	DoIndent();
+	buffer += "<!--";
+	buffer += comment.Value();
+	buffer += "-->";
+	DoLineBreak();
+	return true;
+}
+
+
+bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
+{
+	DoIndent();
+	buffer += "<";
+	buffer += unknown.Value();
+	buffer += ">";
+	DoLineBreak();
+	return true;
+}
+
+bool TiXmlPrinter::Visit( const TiXmlStylesheetReference& stylesheet )
+{
+	    DoIndent();
+	    stylesheet.Print( 0, 0, &buffer );
+	    DoLineBreak();
+	    return true;
+}
Index: /code/branches/rocket2/src/external/tinyxml/tinyxml.h
===================================================================
--- /code/branches/rocket2/src/external/tinyxml/tinyxml.h	(revision 6952)
+++ /code/branches/rocket2/src/external/tinyxml/tinyxml.h	(revision 6952)
@@ -0,0 +1,1884 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.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 TINYXML_INCLUDED
+#define TINYXML_INCLUDED
+
+#ifdef _MSC_VER
+#pragma warning( push )
+#pragma warning( disable : 4530 )
+#pragma warning( disable : 4786 )
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+// Help out windows:
+#if defined( _DEBUG ) && !defined( DEBUG )
+#define DEBUG
+#endif
+
+#ifdef TIXML_USE_TICPP
+	#ifndef TIXML_USE_STL
+		#define TIXML_USE_STL
+	#endif
+#endif
+
+#ifdef TIXML_USE_STL
+	#include <string>
+ 	#include <iostream>
+	#include <sstream>
+	#define TIXML_STRING		std::string
+#else
+	#include "tinystr.h"
+	#define TIXML_STRING		TiXmlString
+#endif
+
+// Deprecated library function hell. Compilers want to use the
+// new safe versions. This probably doesn't fully address the problem,
+// but it gets closer. There are too many compilers for me to fully
+// test. If you get compilation troubles, undefine TIXML_SAFE
+#define TIXML_SAFE
+
+#ifdef TIXML_SAFE
+	#if defined(_MSC_VER) && (_MSC_VER >= 1400 )
+		// Microsoft visual studio, version 2005 and higher.
+		#define TIXML_SNPRINTF _snprintf_s
+		#define TIXML_SNSCANF  _snscanf_s
+		#define TIXML_SSCANF   sscanf_s
+	#elif defined(_MSC_VER) && (_MSC_VER >= 1200 )
+		// Microsoft visual studio, version 6 and higher.
+		//#pragma message( "Using _sn* functions." )
+		#define TIXML_SNPRINTF _snprintf
+		#define TIXML_SNSCANF  _snscanf
+		#define TIXML_SSCANF   sscanf
+	#elif defined(__GNUC__) && (__GNUC__ >= 3 )
+		// GCC version 3 and higher.s
+		//#warning( "Using sn* functions." )
+		#define TIXML_SNPRINTF snprintf
+		#define TIXML_SNSCANF  snscanf
+		#define TIXML_SSCANF   sscanf
+	#else
+		#define TIXML_SSCANF   sscanf
+	#endif
+#endif
+
+class TiXmlDocument;
+class TiXmlElement;
+class TiXmlComment;
+class TiXmlUnknown;
+class TiXmlAttribute;
+class TiXmlText;
+class TiXmlDeclaration;
+class TiXmlStylesheetReference;
+class TiXmlParsingData;
+
+const int TIXML_MAJOR_VERSION = 2;
+const int TIXML_MINOR_VERSION = 5;
+const int TIXML_PATCH_VERSION = 3;
+
+/*	Internal structure for tracking location of items
+	in the XML file.
+*/
+struct TiXmlCursor
+{
+	TiXmlCursor()		{ Clear(); }
+	void Clear()		{ row = col = -1; }
+
+	int row;	// 0 based.
+	int col;	// 0 based.
+};
+
+
+/**
+	If you call the Accept() method, it requires being passed a TiXmlVisitor
+	class to handle callbacks. For nodes that contain other nodes (Document, Element)
+	you will get called with a VisitEnter/VisitExit pair. Nodes that are always leaves
+	are simple called with Visit().
+
+	If you return 'true' from a Visit method, recursive parsing will continue. If you return
+	false, <b>no children of this node or its sibilings</b> will be Visited.
+
+	All flavors of Visit methods have a default implementation that returns 'true' (continue
+	visiting). You need to only override methods that are interesting to you.
+
+	Generally Accept() is called on the TiXmlDocument, although all nodes suppert Visiting.
+
+	You should never change the document from a callback.
+
+	@sa TiXmlNode::Accept()
+*/
+class TiXmlVisitor
+{
+public:
+	virtual ~TiXmlVisitor() {}
+
+	/// Visit a document.
+	virtual bool VisitEnter( const TiXmlDocument& /*doc*/ )			{ return true; }
+	/// Visit a document.
+	virtual bool VisitExit( const TiXmlDocument& /*doc*/ )			{ return true; }
+
+	/// Visit an element.
+	virtual bool VisitEnter( const TiXmlElement& /*element*/, const TiXmlAttribute* /*firstAttribute*/ )	{ return true; }
+	/// Visit an element.
+	virtual bool VisitExit( const TiXmlElement& /*element*/ )		{ return true; }
+
+	/// Visit a declaration
+	virtual bool Visit( const TiXmlDeclaration& /*declaration*/ )	{ return true; }
+	/// Visit a stylesheet reference
+	virtual bool Visit( const TiXmlStylesheetReference& /*stylesheet*/ )	{ return true; }
+	/// Visit a text node
+	virtual bool Visit( const TiXmlText& /*text*/ )					{ return true; }
+	/// Visit a comment node
+	virtual bool Visit( const TiXmlComment& /*comment*/ )			{ return true; }
+	/// Visit an unknow node
+	virtual bool Visit( const TiXmlUnknown& /*unknown*/ )			{ return true; }
+};
+
+// Only used by Attribute::Query functions
+enum
+{
+	TIXML_SUCCESS,
+	TIXML_NO_ATTRIBUTE,
+	TIXML_WRONG_TYPE
+};
+
+
+// Used by the parsing routines.
+enum TiXmlEncoding
+{
+	TIXML_ENCODING_UNKNOWN,
+	TIXML_ENCODING_UTF8,
+	TIXML_ENCODING_LEGACY
+};
+
+const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
+
+/** TiXmlBase is a base class for every class in TinyXml.
+	It does little except to establish that TinyXml classes
+	can be printed and provide some utility functions.
+
+	In XML, the document and elements can contain
+	other elements and other types of nodes.
+
+	@verbatim
+	A Document can contain:	Element	(container or leaf)
+							Comment (leaf)
+							Unknown (leaf)
+							Declaration( leaf )
+
+	An Element can contain:	Element (container or leaf)
+							Text	(leaf)
+							Attributes (not on tree)
+							Comment (leaf)
+							Unknown (leaf)
+
+	A Decleration contains: Attributes (not on tree)
+	@endverbatim
+*/
+#ifdef TIXML_USE_TICPP
+#include "ticpprc.h"
+class TiXmlBase : public TiCppRC
+#else
+class TiXmlBase
+#endif
+{
+	friend class TiXmlNode;
+	friend class TiXmlElement;
+	friend class TiXmlDocument;
+
+public:
+	TiXmlBase()	:	userData(0)		{}
+	virtual ~TiXmlBase()			{}
+
+	/**	All TinyXml classes can print themselves to a filestream
+		or the string class (TiXmlString in non-STL mode, std::string
+		in STL mode.) Either or both cfile and str can be null.
+
+		This is a formatted print, and will insert
+		tabs and newlines.
+
+		(For an unformatted stream, use the << operator.)
+	*/
+	virtual void Print( FILE* cfile, int depth ) const = 0;
+
+	/**	The world does not agree on whether white space should be kept or
+		not. In order to make everyone happy, these global, static functions
+		are provided to set whether or not TinyXml will condense all white space
+		into a single space or not. The default is to condense. Note changing this
+		value is not thread safe.
+	*/
+	static void SetCondenseWhiteSpace( bool condense )		{ condenseWhiteSpace = condense; }
+
+	/// Return the current white space setting.
+	static bool IsWhiteSpaceCondensed()						{ return condenseWhiteSpace; }
+
+	/** Return the position, in the original source file, of this node or attribute.
+		The row and column are 1-based. (That is the first row and first column is
+		1,1). If the returns values are 0 or less, then the parser does not have
+		a row and column value.
+
+		Generally, the row and column value will be set when the TiXmlDocument::Load(),
+		TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
+		when the DOM was created from operator>>.
+
+		The values reflect the initial load. Once the DOM is modified programmatically
+		(by adding or changing nodes and attributes) the new values will NOT update to
+		reflect changes in the document.
+
+		There is a minor performance cost to computing the row and column. Computation
+		can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
+
+		@sa TiXmlDocument::SetTabSize()
+	*/
+	int Row() const			{ return location.row + 1; }
+	int Column() const		{ return location.col + 1; }	///< See Row()
+
+	void  SetUserData( void* user )			{ userData = user; }	///< Set a pointer to arbitrary user data.
+	void* GetUserData()						{ return userData; }	///< Get a pointer to arbitrary user data.
+	const void* GetUserData() const 		{ return userData; }	///< Get a pointer to arbitrary user data.
+
+	// Table that returs, for a given lead byte, the total number of bytes
+	// in the UTF-8 sequence.
+	static const int utf8ByteTable[256];
+
+	virtual const char* Parse(	const char* p,
+								TiXmlParsingData* data,
+								TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
+
+	/** Expands entities in a string. Note this should not contian the tag's '<', '>', etc,
+		or they will be transformed into entities!
+	*/
+	static void EncodeString( const TIXML_STRING& str, TIXML_STRING* out );
+
+	enum
+	{
+		TIXML_NO_ERROR = 0,
+		TIXML_ERROR,
+		TIXML_ERROR_OPENING_FILE,
+		TIXML_ERROR_OUT_OF_MEMORY,
+		TIXML_ERROR_PARSING_ELEMENT,
+		TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
+		TIXML_ERROR_READING_ELEMENT_VALUE,
+		TIXML_ERROR_READING_ATTRIBUTES,
+		TIXML_ERROR_PARSING_EMPTY,
+		TIXML_ERROR_READING_END_TAG,
+		TIXML_ERROR_PARSING_UNKNOWN,
+		TIXML_ERROR_PARSING_COMMENT,
+		TIXML_ERROR_PARSING_DECLARATION,
+		TIXML_ERROR_DOCUMENT_EMPTY,
+		TIXML_ERROR_EMBEDDED_NULL,
+		TIXML_ERROR_PARSING_CDATA,
+		TIXML_ERROR_DOCUMENT_TOP_ONLY,
+
+		TIXML_ERROR_STRING_COUNT
+	};
+
+protected:
+
+	static const char* SkipWhiteSpace( const char*, TiXmlEncoding encoding );
+	inline static bool IsWhiteSpace( char c )
+	{
+		return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' );
+	}
+	inline static bool IsWhiteSpace( int c )
+	{
+		if ( c < 256 )
+			return IsWhiteSpace( (char) c );
+		return false;	// Again, only truly correct for English/Latin...but usually works.
+	}
+
+	#ifdef TIXML_USE_STL
+	static bool	StreamWhiteSpace( std::istream * in, TIXML_STRING * tag );
+	static bool StreamTo( std::istream * in, int character, TIXML_STRING * tag );
+	#endif
+
+	/*	Reads an XML name into the string provided. Returns
+		a pointer just past the last character of the name,
+		or 0 if the function has an error.
+	*/
+	static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
+
+	/*	Reads text. Returns a pointer past the given end tag.
+		Wickedly complex options, but it keeps the (sensitive) code in one place.
+	*/
+	static const char* ReadText(	const char* in,				// where to start
+									TIXML_STRING* text,			// the string read
+									bool ignoreWhiteSpace,		// whether to keep the white space
+									const char* endTag,			// what ends this text
+									bool ignoreCase,			// whether to ignore case in the end tag
+									TiXmlEncoding encoding );	// the current encoding
+
+	// If an entity has been found, transform it into a character.
+	static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
+
+	// Get a character, while interpreting entities.
+	// The length can be from 0 to 4 bytes.
+	inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
+	{
+		assert( p );
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			*length = utf8ByteTable[ *((const unsigned char*)p) ];
+			assert( *length >= 0 && *length < 5 );
+		}
+		else
+		{
+			*length = 1;
+		}
+
+		if ( *length == 1 )
+		{
+			if ( *p == '&' )
+				return GetEntity( p, _value, length, encoding );
+			*_value = *p;
+			return p+1;
+		}
+		else if ( *length )
+		{
+			//strncpy( _value, p, *length );	// lots of compilers don't like this function (unsafe),
+												// and the null terminator isn't needed
+			for( int i=0; p[i] && i<*length; ++i ) {
+				_value[i] = p[i];
+			}
+			return p + (*length);
+		}
+		else
+		{
+			// Not valid text.
+			return 0;
+		}
+	}
+
+	// Return true if the next characters in the stream are any of the endTag sequences.
+	// Ignore case only works for english, and should only be relied on when comparing
+	// to English words: StringEqual( p, "version", true ) is fine.
+	static bool StringEqual(	const char* p,
+								const char* endTag,
+								bool ignoreCase,
+								TiXmlEncoding encoding );
+
+	static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
+
+	TiXmlCursor location;
+
+    /// Field containing a generic user pointer
+	void*			userData;
+
+	// None of these methods are reliable for any language except English.
+	// Good for approximation, not great for accuracy.
+	static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
+	static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
+	inline static int ToLower( int v, TiXmlEncoding encoding )
+	{
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			if ( v < 128 ) return tolower( v );
+			return v;
+		}
+		else
+		{
+			return tolower( v );
+		}
+	}
+	static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
+
+private:
+	TiXmlBase( const TiXmlBase& );				// not implemented.
+	void operator=( const TiXmlBase& base );	// not allowed.
+
+	struct Entity
+	{
+		const char*     str;
+		unsigned int	strLength;
+		char		    chr;
+	};
+	enum
+	{
+		NUM_ENTITY = 5,
+		MAX_ENTITY_LENGTH = 6
+
+	};
+	static Entity entity[ NUM_ENTITY ];
+	static bool condenseWhiteSpace;
+};
+
+
+/** The parent class for everything in the Document Object Model.
+	(Except for attributes).
+	Nodes have siblings, a parent, and children. A node can be
+	in a document, or stand on its own. The type of a TiXmlNode
+	can be queried, and it can be cast to its more defined type.
+*/
+class TiXmlNode : public TiXmlBase
+{
+	friend class TiXmlDocument;
+	friend class TiXmlElement;
+
+public:
+	#ifdef TIXML_USE_STL
+
+	    /** An input stream operator, for every class. Tolerant of newlines and
+		    formatting, but doesn't expect them.
+	    */
+	    friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
+
+	    /** An output stream operator, for every class. Note that this outputs
+		    without any newlines or formatting, as opposed to Print(), which
+		    includes tabs and new lines.
+
+		    The operator<< and operator>> are not completely symmetric. Writing
+		    a node to a stream is very well defined. You'll get a nice stream
+		    of output, without any extra whitespace or newlines.
+
+		    But reading is not as well defined. (As it always is.) If you create
+		    a TiXmlElement (for example) and read that from an input stream,
+		    the text needs to define an element or junk will result. This is
+		    true of all input streams, but it's worth keeping in mind.
+
+		    A TiXmlDocument will read nodes until it reads a root element, and
+			all the children of that root element.
+	    */
+	    friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
+
+		/// Appends the XML node or attribute to a std::string.
+		friend std::string& operator<< (std::string& out, const TiXmlNode& base );
+
+	#endif
+
+	/** The types of XML nodes supported by TinyXml. (All the
+			unsupported types are picked up by UNKNOWN.)
+	*/
+	enum NodeType
+	{
+		DOCUMENT,
+		ELEMENT,
+		COMMENT,
+		UNKNOWN,
+		TEXT,
+		DECLARATION,
+		STYLESHEETREFERENCE,
+		TYPECOUNT
+	};
+
+	virtual ~TiXmlNode();
+
+	/** The meaning of 'value' changes for the specific type of
+		TiXmlNode.
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+
+		The subclasses will wrap this function.
+	*/
+	const char *Value() const { return value.c_str (); }
+
+    #ifdef TIXML_USE_STL
+	/** Return Value() as a std::string. If you only use STL,
+	    this is more efficient than calling Value().
+		Only available in STL mode.
+	*/
+	const std::string& ValueStr() const { return value; }
+	#endif
+
+	const TIXML_STRING& ValueTStr() const { return value; }
+
+	/** Changes the value of the node. Defined as:
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+	*/
+	void SetValue(const char * _value) { value = _value;}
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetValue( const std::string& _value )	{ value = _value; }
+	#endif
+
+	/// Delete all the children of this node. Does not affect 'this'.
+	void Clear();
+
+	/// One step up the DOM.
+	TiXmlNode* Parent()							{ return parent; }
+	const TiXmlNode* Parent() const				{ return parent; }
+
+	const TiXmlNode* FirstChild()	const		{ return firstChild; }	///< The first child of this node. Will be null if there are no children.
+	TiXmlNode* FirstChild()						{ return firstChild; }
+	const TiXmlNode* FirstChild( const char * value ) const;			///< The first child of this node with the matching 'value'. Will be null if none found.
+	/// The first child of this node with the matching 'value'. Will be null if none found.
+	TiXmlNode* FirstChild( const char * _value ) {
+		// Call through to the const version - safe since nothing is changed. Exiting syntax: cast this to a const (always safe)
+		// call the method, cast the return back to non-const.
+		return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->FirstChild( _value ));
+	}
+	const TiXmlNode* LastChild() const	{ return lastChild; }		/// The last child of this node. Will be null if there are no children.
+	TiXmlNode* LastChild()	{ return lastChild; }
+
+	const TiXmlNode* LastChild( const char * value ) const;			/// The last child of this node matching 'value'. Will be null if there are no children.
+	TiXmlNode* LastChild( const char * _value ) {
+		return const_cast< TiXmlNode* > ((const_cast< const TiXmlNode* >(this))->LastChild( _value ));
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* FirstChild( const std::string& _value ) const	{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* FirstChild( const std::string& _value )				{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
+	const TiXmlNode* LastChild( const std::string& _value ) const	{	return LastChild (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* LastChild( const std::string& _value )				{	return LastChild (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** An alternate way to walk the children of a node.
+		One way to iterate over nodes is:
+		@verbatim
+			for( child = parent->FirstChild(); child; child = child->NextSibling() )
+		@endverbatim
+
+		IterateChildren does the same thing with the syntax:
+		@verbatim
+			child = 0;
+			while( child = parent->IterateChildren( child ) )
+		@endverbatim
+
+		IterateChildren takes the previous child as input and finds
+		the next one. If the previous child is null, it returns the
+		first. IterateChildren will return null when done.
+	*/
+	const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
+	TiXmlNode* IterateChildren( const TiXmlNode* previous ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( previous ) );
+	}
+
+	/// This flavor of IterateChildren searches for children with a particular 'value'
+	const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
+	TiXmlNode* IterateChildren( const char * _value, const TiXmlNode* previous ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->IterateChildren( _value, previous ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const	{	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
+	TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) {	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
+	#endif
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
+
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+
+		NOTE: the node to be added is passed by pointer, and will be
+		henceforth owned (and deleted) by tinyXml. This method is efficient
+		and avoids an extra copy, but should be used with care as it
+		uses a different memory model than the other insert functions.
+
+		@sa InsertEndChild
+	*/
+	TiXmlNode* LinkEndChild( TiXmlNode* addThis );
+
+	/** Add a new node related to this. Adds a child before the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
+
+	/** Add a new node related to this. Adds a child after the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
+
+	/** Replace a child of this node.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
+
+	/// Delete a child of this node.
+	bool RemoveChild( TiXmlNode* removeThis );
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* PreviousSibling() const			{ return prev; }
+	TiXmlNode* PreviousSibling()						{ return prev; }
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* PreviousSibling( const char * ) const;
+	TiXmlNode* PreviousSibling( const char *_prev ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->PreviousSibling( _prev ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* PreviousSibling( const std::string& _value ) const	{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* PreviousSibling( const std::string& _value ) 			{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
+	const TiXmlNode* NextSibling( const std::string& _value) const		{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* NextSibling( const std::string& _value) 					{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* NextSibling() const				{ return next; }
+	TiXmlNode* NextSibling()							{ return next; }
+
+	/// Navigate to a sibling node with the given 'value'.
+	const TiXmlNode* NextSibling( const char * ) const;
+	TiXmlNode* NextSibling( const char* _next ) {
+		return const_cast< TiXmlNode* >( (const_cast< const TiXmlNode* >(this))->NextSibling( _next ) );
+	}
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	const TiXmlElement* NextSiblingElement() const;
+	TiXmlElement* NextSiblingElement() {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement() );
+	}
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	const TiXmlElement* NextSiblingElement( const char * ) const;
+	TiXmlElement* NextSiblingElement( const char *_next ) {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->NextSiblingElement( _next ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlElement* NextSiblingElement( const std::string& _value) const	{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
+	TiXmlElement* NextSiblingElement( const std::string& _value)				{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement()	const;
+	TiXmlElement* FirstChildElement() {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement() );
+	}
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement( const char * _value ) const;
+	TiXmlElement* FirstChildElement( const char * _value ) {
+		return const_cast< TiXmlElement* >( (const_cast< const TiXmlNode* >(this))->FirstChildElement( _value ) );
+	}
+
+    #ifdef TIXML_USE_STL
+	const TiXmlElement* FirstChildElement( const std::string& _value ) const	{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
+	TiXmlElement* FirstChildElement( const std::string& _value )				{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** Query the type (as an enumerated value, above) of this node.
+		The possible types are: DOCUMENT, ELEMENT, COMMENT,
+								UNKNOWN, TEXT, and DECLARATION.
+	*/
+	int Type() const	{ return type; }
+
+	/** Return a pointer to the Document this node lives in.
+		Returns null if not in a document.
+	*/
+	const TiXmlDocument* GetDocument() const;
+	TiXmlDocument* GetDocument() {
+		return const_cast< TiXmlDocument* >( (const_cast< const TiXmlNode* >(this))->GetDocument() );
+	}
+
+	/// Returns true if this node has no children.
+	bool NoChildren() const						{ return !firstChild; }
+
+	virtual const TiXmlDocument*    ToDocument()    const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlElement*     ToElement()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlComment*     ToComment()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlUnknown*     ToUnknown()     const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlText*        ToText()        const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlDeclaration* ToDeclaration() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual const TiXmlStylesheetReference* ToStylesheetReference() const { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+
+	virtual TiXmlDocument*          ToDocument()    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlElement*           ToElement()	    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlComment*           ToComment()     { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlUnknown*           ToUnknown()	    { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlText*	            ToText()        { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlDeclaration*       ToDeclaration() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+	virtual TiXmlStylesheetReference*       ToStylesheetReference() { return 0; } ///< Cast to a more defined type. Will return null if not of the requested type.
+
+	/** Create an exact duplicate of this node and return it. The memory must be deleted
+		by the caller.
+	*/
+	virtual TiXmlNode* Clone() const = 0;
+
+	/** Accept a hierchical visit the nodes in the TinyXML DOM. Every node in the
+		XML tree will be conditionally visited and the host will be called back
+		via the TiXmlVisitor interface.
+
+		This is essentially a SAX interface for TinyXML. (Note however it doesn't re-parse
+		the XML for the callbacks, so the performance of TinyXML is unchanged by using this
+		interface versus any other.)
+
+		The interface has been based on ideas from:
+
+		- http://www.saxproject.org/
+		- http://c2.com/cgi/wiki?HierarchicalVisitorPattern
+
+		Which are both good references for "visiting".
+
+		An example of using Accept():
+		@verbatim
+		TiXmlPrinter printer;
+		tinyxmlDoc.Accept( &printer );
+		const char* xmlcstr = printer.CStr();
+		@endverbatim
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const = 0;
+
+protected:
+	TiXmlNode( NodeType _type );
+
+	// Copy to the allocated object. Shared functionality between Clone, Copy constructor,
+	// and the assignment operator.
+	void CopyTo( TiXmlNode* target ) const;
+
+	#ifdef TIXML_USE_STL
+	    // The real work of the input operator.
+	virtual void StreamIn( std::istream* in, TIXML_STRING* tag ) = 0;
+	#endif
+
+	// Figure out what is at *p, and parse it. Returns null if it is not an xml node.
+	TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
+
+	TiXmlNode*		parent;
+	NodeType		type;
+
+	TiXmlNode*		firstChild;
+	TiXmlNode*		lastChild;
+
+	TIXML_STRING	value;
+
+	TiXmlNode*		prev;
+	TiXmlNode*		next;
+
+private:
+	TiXmlNode( const TiXmlNode& );				// not implemented.
+	void operator=( const TiXmlNode& base );	// not allowed.
+};
+
+
+/** An attribute is a name-value pair. Elements have an arbitrary
+	number of attributes, each with a unique name.
+
+	@note The attributes are not TiXmlNodes, since they are not
+		  part of the tinyXML document object model. There are other
+		  suggested ways to look at this problem.
+*/
+class TiXmlAttribute : public TiXmlBase
+{
+	friend class TiXmlAttributeSet;
+
+public:
+	/// Construct an empty attribute.
+	TiXmlAttribute() : TiXmlBase()
+	{
+		document = 0;
+		prev = next = 0;
+	}
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlAttribute( const std::string& _name, const std::string& _value )
+	{
+		name = _name;
+		value = _value;
+		document = 0;
+		prev = next = 0;
+	}
+	#endif
+
+	/// Construct an attribute with a name and value.
+	TiXmlAttribute( const char * _name, const char * _value )
+	{
+		name = _name;
+		value = _value;
+		document = 0;
+		prev = next = 0;
+	}
+
+	const char*		Name()  const		{ return name.c_str(); }		///< Return the name of this attribute.
+	const char*		Value() const		{ return value.c_str(); }		///< Return the value of this attribute.
+	#ifdef TIXML_USE_STL
+	const std::string& ValueStr() const	{ return value; }				///< Return the value of this attribute.
+	#endif
+	int				IntValue() const;									///< Return the value of this attribute, converted to an integer.
+	double			DoubleValue() const;								///< Return the value of this attribute, converted to a double.
+
+	// Get the tinyxml string representation
+	const TIXML_STRING& NameTStr() const { return name; }
+
+	/** QueryIntValue examines the value string. It is an alternative to the
+		IntValue() method with richer error checking.
+		If the value is an integer, it is stored in 'value' and
+		the call returns TIXML_SUCCESS. If it is not
+		an integer, it returns TIXML_WRONG_TYPE.
+
+		A specialized but useful call. Note that for success it returns 0,
+		which is the opposite of almost all other TinyXml calls.
+	*/
+	int QueryIntValue( int* _value ) const;
+	/// QueryDoubleValue examines the value string. See QueryIntValue().
+	int QueryDoubleValue( double* _value ) const;
+
+	void SetName( const char* _name )	{ name = _name; }				///< Set the name of this attribute.
+	void SetValue( const char* _value )	{ value = _value; }				///< Set the value.
+
+	void SetIntValue( int _value );										///< Set the value from an integer.
+	void SetDoubleValue( double _value );								///< Set the value from a double.
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetName( const std::string& _name )	{ name = _name; }
+	/// STL std::string form.
+	void SetValue( const std::string& _value )	{ value = _value; }
+	#endif
+
+	/// Get the next sibling attribute in the DOM. Returns null at end.
+	const TiXmlAttribute* Next() const;
+	TiXmlAttribute* Next() {
+		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Next() );
+	}
+
+	/// Get the previous sibling attribute in the DOM. Returns null at beginning.
+	const TiXmlAttribute* Previous() const;
+	TiXmlAttribute* Previous() {
+		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttribute* >(this))->Previous() );
+	}
+
+	bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
+	bool operator<( const TiXmlAttribute& rhs )	 const { return name < rhs.name; }
+	bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
+
+	/*	Attribute parsing starts: first letter of the name
+						 returns: the next char after the value end quote
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	// Prints this Attribute to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const {
+		Print( cfile, depth, 0 );
+	}
+	void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+
+	// [internal use]
+	// Set the document pointer so the attribute can report errors.
+	void SetDocument( TiXmlDocument* doc )	{ document = doc; }
+
+private:
+	TiXmlAttribute( const TiXmlAttribute& );				// not implemented.
+	void operator=( const TiXmlAttribute& base );	// not allowed.
+
+	TiXmlDocument*	document;	// A pointer back to a document, for error reporting.
+	TIXML_STRING name;
+	TIXML_STRING value;
+	TiXmlAttribute*	prev;
+	TiXmlAttribute*	next;
+};
+
+
+/*	A class used to manage a group of attributes.
+	It is only used internally, both by the ELEMENT and the DECLARATION.
+
+	The set can be changed transparent to the Element and Declaration
+	classes that use it, but NOT transparent to the Attribute
+	which has to implement a next() and previous() method. Which makes
+	it a bit problematic and prevents the use of STL.
+
+	This version is implemented with circular lists because:
+		- I like circular lists
+		- it demonstrates some independence from the (typical) doubly linked list.
+*/
+class TiXmlAttributeSet
+{
+public:
+	TiXmlAttributeSet();
+	~TiXmlAttributeSet();
+
+	void Add( TiXmlAttribute* attribute );
+	void Remove( TiXmlAttribute* attribute );
+
+	const TiXmlAttribute* First()	const	{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	TiXmlAttribute* First()					{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	const TiXmlAttribute* Last() const		{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+	TiXmlAttribute* Last()					{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+
+	const TiXmlAttribute*	Find( const char* _name ) const;
+	TiXmlAttribute*	Find( const char* _name ) {
+		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
+	}
+	#ifdef TIXML_USE_STL
+	const TiXmlAttribute*	Find( const std::string& _name ) const;
+	TiXmlAttribute*	Find( const std::string& _name ) {
+		return const_cast< TiXmlAttribute* >( (const_cast< const TiXmlAttributeSet* >(this))->Find( _name ) );
+	}
+
+	#endif
+
+private:
+	//*ME:	Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
+	//*ME:	this class must be also use a hidden/disabled copy-constructor !!!
+	TiXmlAttributeSet( const TiXmlAttributeSet& );	// not allowed
+	void operator=( const TiXmlAttributeSet& );	// not allowed (as TiXmlAttribute)
+
+	TiXmlAttribute sentinel;
+};
+
+
+/** The element is a container class. It has a value, the element name,
+	and can contain other elements, text, comments, and unknowns.
+	Elements also contain an arbitrary number of attributes.
+*/
+class TiXmlElement : public TiXmlNode
+{
+public:
+	/// Construct an element.
+	TiXmlElement (const char * in_value);
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlElement( const std::string& _value );
+	#endif
+
+	TiXmlElement( const TiXmlElement& );
+
+	void operator=( const TiXmlElement& base );
+
+	virtual ~TiXmlElement();
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+	*/
+	const char* Attribute( const char* name ) const;
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an integer,
+		the integer value will be put in the return 'i', if 'i'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, int* i ) const;
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an double,
+		the double value will be put in the return 'd', if 'd'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, double* d ) const;
+
+	/** QueryIntAttribute examines the attribute - it is an alternative to the
+		Attribute() method with richer error checking.
+		If the attribute is an integer, it is stored in 'value' and
+		the call returns TIXML_SUCCESS. If it is not
+		an integer, it returns TIXML_WRONG_TYPE. If the attribute
+		does not exist, then TIXML_NO_ATTRIBUTE is returned.
+	*/
+	int QueryIntAttribute( const char* name, int* _value ) const;
+	/// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
+	int QueryDoubleAttribute( const char* name, double* _value ) const;
+	/// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
+	int QueryFloatAttribute( const char* name, float* _value ) const {
+		double d;
+		int result = QueryDoubleAttribute( name, &d );
+		if ( result == TIXML_SUCCESS ) {
+			*_value = (float)d;
+		}
+		return result;
+	}
+
+    #ifdef TIXML_USE_STL
+	/** Template form of the attribute query which will try to read the
+		attribute into the specified type. Very easy, very powerful, but
+		be careful to make sure to call this with the correct type.
+
+		NOTE: This method doesn't work correctly for 'string' types.
+
+		@return TIXML_SUCCESS, TIXML_WRONG_TYPE, or TIXML_NO_ATTRIBUTE
+	*/
+	template< typename T > int QueryValueAttribute( const std::string& name, T* outValue ) const
+	{
+		const TiXmlAttribute* node = attributeSet.Find( name );
+		if ( !node )
+			return TIXML_NO_ATTRIBUTE;
+
+		std::stringstream sstream( node->ValueStr() );
+		sstream >> *outValue;
+		if ( !sstream.fail() )
+			return TIXML_SUCCESS;
+		return TIXML_WRONG_TYPE;
+	}
+	/*
+	 This is - in theory - a bug fix for "QueryValueAtribute returns truncated std::string"
+	 but template specialization is hard to get working cross-compiler. Leaving the bug for now.
+
+	// The above will fail for std::string because the space character is used as a seperator.
+	// Specialize for strings. Bug [ 1695429 ] QueryValueAtribute returns truncated std::string
+	template<> int QueryValueAttribute( const std::string& name, std::string* outValue ) const
+	{
+		const TiXmlAttribute* node = attributeSet.Find( name );
+		if ( !node )
+			return TIXML_NO_ATTRIBUTE;
+		*outValue = node->ValueStr();
+		return TIXML_SUCCESS;
+	}
+	*/
+	#endif
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char* name, const char * _value );
+
+    #ifdef TIXML_USE_STL
+	const std::string* Attribute( const std::string& name ) const;
+	const std::string* Attribute( const std::string& name, int* i ) const;
+	const std::string* Attribute( const std::string& name, double* d ) const;
+	int QueryIntAttribute( const std::string& name, int* _value ) const;
+	int QueryDoubleAttribute( const std::string& name, double* _value ) const;
+
+	/// STL std::string form.
+	void SetAttribute( const std::string& name, const std::string& _value );
+	///< STL std::string form.
+	void SetAttribute( const std::string& name, int _value );
+	#endif
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char * name, int value );
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetDoubleAttribute( const char * name, double value );
+
+	/** Deletes an attribute with the given name.
+	*/
+	void RemoveAttribute( const char * name );
+    #ifdef TIXML_USE_STL
+	void RemoveAttribute( const std::string& name )	{	RemoveAttribute (name.c_str ());	}	///< STL std::string form.
+	#endif
+
+	const TiXmlAttribute* FirstAttribute() const	{ return attributeSet.First(); }		///< Access the first attribute in this element.
+	TiXmlAttribute* FirstAttribute() 				{ return attributeSet.First(); }
+	const TiXmlAttribute* LastAttribute()	const 	{ return attributeSet.Last(); }		///< Access the last attribute in this element.
+	TiXmlAttribute* LastAttribute()					{ return attributeSet.Last(); }
+
+	/** Convenience function for easy access to the text inside an element. Although easy
+		and concise, GetText() is limited compared to getting the TiXmlText child
+		and accessing it directly.
+
+		If the first child of 'this' is a TiXmlText, the GetText()
+		returns the character string of the Text node, else null is returned.
+
+		This is a convenient method for getting the text of simple contained text:
+		@verbatim
+		<foo>This is text</foo>
+		const char* str = fooElement->GetText();
+		@endverbatim
+
+		'str' will be a pointer to "This is text".
+
+		Note that this function can be misleading. If the element foo was created from
+		this XML:
+		@verbatim
+		<foo><b>This is text</b></foo>
+		@endverbatim
+
+		then the value of str would be null. The first child node isn't a text node, it is
+		another element. From this XML:
+		@verbatim
+		<foo>This is <b>text</b></foo>
+		@endverbatim
+		GetText() will return "This is ".
+
+		WARNING: GetText() accesses a child node - don't become confused with the
+				 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are
+				 safe type casts on the referenced node.
+	*/
+	const char* GetText() const;
+
+	/// Creates a new Element and returns it - the returned element is a copy.
+	virtual TiXmlNode* Clone() const;
+	// Print the Element to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/*	Attribtue parsing starts: next char past '<'
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlElement*     ToElement()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlElement*           ToElement()	          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children.
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+
+	void CopyTo( TiXmlElement* target ) const;
+	void ClearThis();	// like clear, but initializes 'this' object as well
+
+	// Used to be public [internal use]
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+	/*	[internal use]
+		Reads the "value" of the element -- another element, or text.
+		This should terminate with the current end tag.
+	*/
+	const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+private:
+
+	TiXmlAttributeSet attributeSet;
+};
+
+
+/**	An XML comment.
+*/
+class TiXmlComment : public TiXmlNode
+{
+public:
+	/// Constructs an empty comment.
+	TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
+	/// Construct a comment from text.
+	TiXmlComment( const char* _value ) : TiXmlNode( TiXmlNode::COMMENT ) {
+		SetValue( _value );
+	}
+	TiXmlComment( const TiXmlComment& );
+	void operator=( const TiXmlComment& base );
+
+	virtual ~TiXmlComment()	{}
+
+	/// Returns a copy of this Comment.
+	virtual TiXmlNode* Clone() const;
+	// Write this Comment to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/*	Attribtue parsing starts: at the ! of the !--
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlComment*  ToComment() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlComment*  ToComment() { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children.
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+	void CopyTo( TiXmlComment* target ) const;
+
+	// used to be public
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+//	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+
+private:
+
+};
+
+
+/** XML text. A text node can have 2 ways to output the next. "normal" output
+	and CDATA. It will default to the mode it was parsed from the XML file and
+	you generally want to leave it alone, but you can change the output mode with
+	SetCDATA() and query it with CDATA().
+*/
+class TiXmlText : public TiXmlNode
+{
+	friend class TiXmlElement;
+public:
+	/** Constructor for text element. By default, it is treated as
+		normal, encoded text. If you want it be output as a CDATA text
+		element, set the parameter _cdata to 'true'
+	*/
+	TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	virtual ~TiXmlText() {}
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	#endif
+
+	TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )	{ copy.CopyTo( this ); }
+	void operator=( const TiXmlText& base )							 	{ base.CopyTo( this ); }
+
+	// Write this text object to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/// Queries whether this represents text using a CDATA section.
+	bool CDATA() const				{ return cdata; }
+	/// Turns on or off a CDATA representation of text.
+	void SetCDATA( bool _cdata )	{ cdata = _cdata; }
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlText* ToText() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlText*       ToText()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children.
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected :
+	///  [internal use] Creates a new Element and returns it.
+	virtual TiXmlNode* Clone() const;
+	void CopyTo( TiXmlText* target ) const;
+
+	bool Blank() const;	// returns true if all white space and new lines
+	// [internal use]
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	bool cdata;			// true if this should be input and output as a CDATA style text element
+};
+
+
+/** In correct XML the declaration is the first entry in the file.
+	@verbatim
+		<?xml version="1.0" standalone="yes"?>
+	@endverbatim
+
+	TinyXml will happily read or write files without a declaration,
+	however. There are 3 possible attributes to the declaration:
+	version, encoding, and standalone.
+
+	Note: In this version of the code, the attributes are
+	handled as special cases, not generic attributes, simply
+	because there can only be at most 3 and they are always the same.
+*/
+class TiXmlDeclaration : public TiXmlNode
+{
+public:
+	/// Construct an empty declaration.
+	TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
+
+#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDeclaration(	const std::string& _version,
+						const std::string& _encoding,
+						const std::string& _standalone );
+#endif
+
+	/// Construct.
+	TiXmlDeclaration(	const char* _version,
+						const char* _encoding,
+						const char* _standalone );
+
+	TiXmlDeclaration( const TiXmlDeclaration& copy );
+	void operator=( const TiXmlDeclaration& copy );
+
+	virtual ~TiXmlDeclaration()	{}
+
+	/// Version. Will return an empty string if none was found.
+	const char *Version() const			{ return version.c_str (); }
+	/// Encoding. Will return an empty string if none was found.
+	const char *Encoding() const		{ return encoding.c_str (); }
+	/// Is this a standalone document?
+	const char *Standalone() const		{ return standalone.c_str (); }
+
+	/// Creates a copy of this Declaration and returns it.
+	virtual TiXmlNode* Clone() const;
+	// Print this declaration to a FILE stream.
+	virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+	virtual void Print( FILE* cfile, int depth ) const {
+		Print( cfile, depth, 0 );
+	}
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlDeclaration* ToDeclaration() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlDeclaration*       ToDeclaration()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children.
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+	void CopyTo( TiXmlDeclaration* target ) const;
+	// used to be public
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+
+	TIXML_STRING version;
+	TIXML_STRING encoding;
+	TIXML_STRING standalone;
+};
+
+/** A stylesheet reference looks like this:
+	@verbatim
+		<?xml-stylesheet type="text/xsl" href="style.xsl"?>
+	@endverbatim
+
+	Note: In this version of the code, the attributes are
+	handled as special cases, not generic attributes, simply
+	because there can only be at most 2 and they are always the same.
+*/
+class TiXmlStylesheetReference : public TiXmlNode
+{
+public:
+	/// Construct an empty declaration.
+	TiXmlStylesheetReference()   : TiXmlNode( TiXmlNode::STYLESHEETREFERENCE ) {}
+
+#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlStylesheetReference(	const std::string& _type,
+								const std::string& _href );
+#endif
+
+	/// Construct.
+	TiXmlStylesheetReference(	const char* _type,
+								const char* _href );
+
+	TiXmlStylesheetReference( const TiXmlStylesheetReference& copy );
+	void operator=( const TiXmlStylesheetReference& copy );
+
+	virtual ~TiXmlStylesheetReference()	{}
+
+	/// Type. Will return an empty string if none was found.
+	const char *Type() const { return type.c_str (); }
+	/// Href. Will return an empty string if none was found.
+	const char *Href() const		{ return href.c_str (); }
+
+	/// Creates a copy of this StylesheetReference and returns it.
+	virtual TiXmlNode* Clone() const;
+	// Print this declaration to a FILE stream.
+	virtual void Print( FILE* cfile, int depth, TIXML_STRING* str ) const;
+	virtual void Print( FILE* cfile, int depth ) const {
+		Print( cfile, depth, 0 );
+	}
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlStylesheetReference* ToStylesheetReference() const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlStylesheetReference*       ToStylesheetReference()       { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children.
+	*/
+	virtual bool Accept( TiXmlVisitor* visitor ) const;
+
+protected:
+	void CopyTo( TiXmlStylesheetReference* target ) const;
+	// used to be public
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+
+	TIXML_STRING type;
+	TIXML_STRING href;
+};
+
+/** Any tag that tinyXml doesn't recognize is saved as an
+	unknown. It is a tag of text, but should not be modified.
+	It will be written back to the XML, unchanged, when the file
+	is saved.
+
+	DTD tags get thrown into TiXmlUnknowns.
+*/
+class TiXmlUnknown : public TiXmlNode
+{
+public:
+	TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN )	{}
+	virtual ~TiXmlUnknown() {}
+
+	TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )		{ copy.CopyTo( this ); }
+	void operator=( const TiXmlUnknown& copy )										{ copy.CopyTo( this ); }
+
+	/// Creates a copy of this Unknown and returns it.
+	virtual TiXmlNode* Clone() const;
+	// Print this Unknown to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	virtual const TiXmlUnknown*     ToUnknown()     const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlUnknown*           ToUnknown()	    { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children.
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected:
+	void CopyTo( TiXmlUnknown* target ) const;
+
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+
+};
+
+
+/** Always the top level node. A document binds together all the
+	XML pieces. It can be saved, loaded, and printed to the screen.
+	The 'value' of a document node is the xml file name.
+*/
+class TiXmlDocument : public TiXmlNode
+{
+public:
+	/// Create an empty document, that has no name.
+	TiXmlDocument();
+	/// Create a document with a name. The name of the document is also the filename of the xml.
+	TiXmlDocument( const char * documentName );
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDocument( const std::string& documentName );
+	#endif
+
+	TiXmlDocument( const TiXmlDocument& copy );
+	void operator=( const TiXmlDocument& copy );
+
+	virtual ~TiXmlDocument() {}
+
+	/** Load a file using the current document value.
+		Returns true if successful. Will delete any existing
+		document data before loading.
+	*/
+	bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the current document value. Returns true if successful.
+	bool SaveFile() const;
+	/// Load a file using the given filename. Returns true if successful.
+	bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the given filename. Returns true if successful.
+	bool SaveFile( const char * filename ) const;
+	/** Load a file using the given FILE*. Returns true if successful. Note that this method
+		doesn't stream - the entire object pointed at by the FILE*
+		will be interpreted as an XML file. TinyXML doesn't stream in XML from the current
+		file location. Streaming may be added in the future.
+	*/
+	bool LoadFile( FILE*, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the given FILE*. Returns true if successful.
+	bool SaveFile( FILE* ) const;
+
+	#ifdef TIXML_USE_STL
+	bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )			///< STL std::string version.
+	{
+//		StringToBuffer f( filename );
+//		return ( f.buffer && LoadFile( f.buffer, encoding ));
+		return LoadFile( filename.c_str(), encoding );
+	}
+	bool SaveFile( const std::string& filename ) const		///< STL std::string version.
+	{
+//		StringToBuffer f( filename );
+//		return ( f.buffer && SaveFile( f.buffer ));
+		return SaveFile( filename.c_str() );
+	}
+	#endif
+
+	/** Parse the given null terminated block of xml data. Passing in an encoding to this
+		method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
+		to use that encoding, regardless of what TinyXml might otherwise try to detect.
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+
+	/** Get the root element -- the only top level element -- of the document.
+		In well formed XML, there should only be one. TinyXml is tolerant of
+		multiple elements at the document level.
+	*/
+	const TiXmlElement* RootElement() const		{ return FirstChildElement(); }
+	TiXmlElement* RootElement()					{ return FirstChildElement(); }
+
+	/** If an error occurs, Error will be set to true. Also,
+		- The ErrorId() will contain the integer identifier of the error (not generally useful)
+		- The ErrorDesc() method will return the name of the error. (very useful)
+		- The ErrorRow() and ErrorCol() will return the location of the error (if known)
+	*/
+	bool Error() const						{ return error; }
+
+	/// Contains a textual (english) description of the error if one occurs.
+	const char * ErrorDesc() const	{ return errorDesc.c_str (); }
+
+	/** Generally, you probably want the error string ( ErrorDesc() ). But if you
+		prefer the ErrorId, this function will fetch it.
+	*/
+	int ErrorId()	const				{ return errorId; }
+
+	/** Returns the location (if known) of the error. The first column is column 1,
+		and the first row is row 1. A value of 0 means the row and column wasn't applicable
+		(memory errors, for example, have no row/column) or the parser lost the error. (An
+		error in the error reporting, in that case.)
+
+		@sa SetTabSize, Row, Column
+	*/
+	int ErrorRow() const	{ return errorLocation.row+1; }
+	int ErrorCol() const	{ return errorLocation.col+1; }	///< The column where the error occured. See ErrorRow()
+
+	/** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
+		to report the correct values for row and column. It does not change the output
+		or input in any way.
+
+		By calling this method, with a tab size
+		greater than 0, the row and column of each node and attribute is stored
+		when the file is loaded. Very useful for tracking the DOM back in to
+		the source file.
+
+		The tab size is required for calculating the location of nodes. If not
+		set, the default of 4 is used. The tabsize is set per document. Setting
+		the tabsize to 0 disables row/column tracking.
+
+		Note that row and column tracking is not supported when using operator>>.
+
+		The tab size needs to be enabled before the parse or load. Correct usage:
+		@verbatim
+		TiXmlDocument doc;
+		doc.SetTabSize( 8 );
+		doc.Load( "myfile.xml" );
+		@endverbatim
+
+		@sa Row, Column
+	*/
+	void SetTabSize( int _tabsize )		{ tabsize = _tabsize; }
+
+	int TabSize() const	{ return tabsize; }
+
+	/** If you have handled the error, it can be reset with this call. The error
+		state is automatically cleared if you Parse a new XML block.
+	*/
+	void ClearError()						{	error = false;
+												errorId = 0;
+												errorDesc = "";
+												errorLocation.row = errorLocation.col = 0;
+												//errorLocation.last = 0;
+											}
+
+	/** Write the document to standard out using formatted printing ("pretty print"). */
+	void Print() const						{ Print( stdout, 0 ); }
+
+	/* Write the document to a string using formatted printing ("pretty print"). This
+		will allocate a character array (new char[]) and return it as a pointer. The
+		calling code pust call delete[] on the return char* to avoid a memory leak.
+	*/
+	//char* PrintToMemory() const;
+
+	/// Print this Document to a FILE stream.
+	virtual void Print( FILE* cfile, int depth = 0 ) const;
+	// [internal use]
+	void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+	virtual const TiXmlDocument*    ToDocument()    const { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+	virtual TiXmlDocument*          ToDocument()          { return this; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Walk the XML tree visiting this node and all of its children.
+	*/
+	virtual bool Accept( TiXmlVisitor* content ) const;
+
+protected :
+	// [internal use]
+	virtual TiXmlNode* Clone() const;
+	#ifdef TIXML_USE_STL
+	virtual void StreamIn( std::istream * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	void CopyTo( TiXmlDocument* target ) const;
+
+	bool error;
+	int  errorId;
+	TIXML_STRING errorDesc;
+	int tabsize;
+	TiXmlCursor errorLocation;
+	bool useMicrosoftBOM;		// the UTF-8 BOM were found when read. Note this, and try to write.
+};
+
+
+/**
+	A TiXmlHandle is a class that wraps a node pointer with null checks; this is
+	an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
+	DOM structure. It is a separate utility class.
+
+	Take an example:
+	@verbatim
+	<Document>
+		<Element attributeA = "valueA">
+			<Child attributeB = "value1" />
+			<Child attributeB = "value2" />
+		</Element>
+	<Document>
+	@endverbatim
+
+	Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very
+	easy to write a *lot* of code that looks like:
+
+	@verbatim
+	TiXmlElement* root = document.FirstChildElement( "Document" );
+	if ( root )
+	{
+		TiXmlElement* element = root->FirstChildElement( "Element" );
+		if ( element )
+		{
+			TiXmlElement* child = element->FirstChildElement( "Child" );
+			if ( child )
+			{
+				TiXmlElement* child2 = child->NextSiblingElement( "Child" );
+				if ( child2 )
+				{
+					// Finally do something useful.
+	@endverbatim
+
+	And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
+	of such code. A TiXmlHandle checks for null	pointers so it is perfectly safe
+	and correct to use:
+
+	@verbatim
+	TiXmlHandle docHandle( &document );
+	TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
+	if ( child2 )
+	{
+		// do something useful
+	@endverbatim
+
+	Which is MUCH more concise and useful.
+
+	It is also safe to copy handles - internally they are nothing more than node pointers.
+	@verbatim
+	TiXmlHandle handleCopy = handle;
+	@endverbatim
+
+	What they should not be used for is iteration:
+
+	@verbatim
+	int i=0;
+	while ( true )
+	{
+		TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).ToElement();
+		if ( !child )
+			break;
+		// do something
+		++i;
+	}
+	@endverbatim
+
+	It seems reasonable, but it is in fact two embedded while loops. The Child method is
+	a linear walk to find the element, so this code would iterate much more than it needs
+	to. Instead, prefer:
+
+	@verbatim
+	TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).ToElement();
+
+	for( child; child; child=child->NextSiblingElement() )
+	{
+		// do something
+	}
+	@endverbatim
+*/
+class TiXmlHandle
+{
+public:
+	/// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
+	TiXmlHandle( TiXmlNode* _node )					{ this->node = _node; }
+	/// Copy constructor
+	TiXmlHandle( const TiXmlHandle& ref )			{ this->node = ref.node; }
+	TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
+
+	/// Return a handle to the first child node.
+	TiXmlHandle FirstChild() const;
+	/// Return a handle to the first child node with the given name.
+	TiXmlHandle FirstChild( const char * value ) const;
+	/// Return a handle to the first child element.
+	TiXmlHandle FirstChildElement() const;
+	/// Return a handle to the first child element with the given name.
+	TiXmlHandle FirstChildElement( const char * value ) const;
+
+	/** Return a handle to the "index" child with the given name.
+		The first child is 0, the second 1, etc.
+	*/
+	TiXmlHandle Child( const char* value, int index ) const;
+	/** Return a handle to the "index" child.
+		The first child is 0, the second 1, etc.
+	*/
+	TiXmlHandle Child( int index ) const;
+	/** Return a handle to the "index" child element with the given name.
+		The first child element is 0, the second 1, etc. Note that only TiXmlElements
+		are indexed: other types are not counted.
+	*/
+	TiXmlHandle ChildElement( const char* value, int index ) const;
+	/** Return a handle to the "index" child element.
+		The first child element is 0, the second 1, etc. Note that only TiXmlElements
+		are indexed: other types are not counted.
+	*/
+	TiXmlHandle ChildElement( int index ) const;
+
+	#ifdef TIXML_USE_STL
+	TiXmlHandle FirstChild( const std::string& _value ) const				{ return FirstChild( _value.c_str() ); }
+	TiXmlHandle FirstChildElement( const std::string& _value ) const		{ return FirstChildElement( _value.c_str() ); }
+
+	TiXmlHandle Child( const std::string& _value, int index ) const			{ return Child( _value.c_str(), index ); }
+	TiXmlHandle ChildElement( const std::string& _value, int index ) const	{ return ChildElement( _value.c_str(), index ); }
+	#endif
+
+	/** Return the handle as a TiXmlNode. This may return null.
+	*/
+	TiXmlNode* ToNode() const			{ return node; }
+	/** Return the handle as a TiXmlElement. This may return null.
+	*/
+	TiXmlElement* ToElement() const		{ return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
+	/**	Return the handle as a TiXmlText. This may return null.
+	*/
+	TiXmlText* ToText() const			{ return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
+	/** Return the handle as a TiXmlUnknown. This may return null.
+	*/
+	TiXmlUnknown* ToUnknown() const		{ return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
+
+	/** @deprecated use ToNode.
+		Return the handle as a TiXmlNode. This may return null.
+	*/
+	TiXmlNode* Node() const			{ return ToNode(); }
+	/** @deprecated use ToElement.
+		Return the handle as a TiXmlElement. This may return null.
+	*/
+	TiXmlElement* Element() const	{ return ToElement(); }
+	/**	@deprecated use ToText()
+		Return the handle as a TiXmlText. This may return null.
+	*/
+	TiXmlText* Text() const			{ return ToText(); }
+	/** @deprecated use ToUnknown()
+		Return the handle as a TiXmlUnknown. This may return null.
+	*/
+	TiXmlUnknown* Unknown() const	{ return ToUnknown(); }
+
+private:
+	TiXmlNode* node;
+};
+
+
+/** Print to memory functionality. The TiXmlPrinter is useful when you need to:
+
+	-# Print to memory (especially in non-STL mode)
+	-# Control formatting (line endings, etc.)
+
+	When constructed, the TiXmlPrinter is in its default "pretty printing" mode.
+	Before calling Accept() you can call methods to control the printing
+	of the XML document. After TiXmlNode::Accept() is called, the printed document can
+	be accessed via the CStr(), Str(), and Size() methods.
+
+	TiXmlPrinter uses the Visitor API.
+	@verbatim
+	TiXmlPrinter printer;
+	printer.SetIndent( "\t" );
+
+	doc.Accept( &printer );
+	fprintf( stdout, "%s", printer.CStr() );
+	@endverbatim
+*/
+class TiXmlPrinter : public TiXmlVisitor
+{
+public:
+	TiXmlPrinter() : depth( 0 ), simpleTextPrint( false ),
+					 buffer(), indent( "    " ), lineBreak( "\n" ) {}
+
+	virtual bool VisitEnter( const TiXmlDocument& doc );
+	virtual bool VisitExit( const TiXmlDocument& doc );
+
+	virtual bool VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute );
+	virtual bool VisitExit( const TiXmlElement& element );
+
+	virtual bool Visit( const TiXmlDeclaration& declaration );
+	virtual bool Visit( const TiXmlText& text );
+	virtual bool Visit( const TiXmlComment& comment );
+	virtual bool Visit( const TiXmlUnknown& unknown );
+	virtual bool Visit( const TiXmlStylesheetReference& stylesheet );
+
+	/** Set the indent characters for printing. By default 4 spaces
+		but tab (\t) is also useful, or null/empty string for no indentation.
+	*/
+	void SetIndent( const char* _indent )			{ indent = _indent ? _indent : "" ; }
+	/// Query the indention string.
+	const char* Indent()							{ return indent.c_str(); }
+	/** Set the line breaking string. By default set to newline (\n).
+		Some operating systems prefer other characters, or can be
+		set to the null/empty string for no indenation.
+	*/
+	void SetLineBreak( const char* _lineBreak )		{ lineBreak = _lineBreak ? _lineBreak : ""; }
+	/// Query the current line breaking string.
+	const char* LineBreak()							{ return lineBreak.c_str(); }
+
+	/** Switch over to "stream printing" which is the most dense formatting without
+		linebreaks. Common when the XML is needed for network transmission.
+	*/
+	void SetStreamPrinting()						{ indent = "";
+													  lineBreak = "";
+													}
+	/// Return the result.
+	const char* CStr()								{ return buffer.c_str(); }
+	/// Return the length of the result string.
+	size_t Size()									{ return buffer.size(); }
+
+	#ifdef TIXML_USE_STL
+	/// Return the result.
+	const std::string& Str()						{ return buffer; }
+	#endif
+
+private:
+	void DoIndent()	{
+		for( int i=0; i<depth; ++i )
+			buffer += indent;
+	}
+	void DoLineBreak() {
+		buffer += lineBreak;
+	}
+
+	int depth;
+	bool simpleTextPrint;
+	TIXML_STRING buffer;
+	TIXML_STRING indent;
+	TIXML_STRING lineBreak;
+};
+
+
+#ifdef _MSC_VER
+#pragma warning( pop )
+#endif
+
+#endif
+
Index: /code/branches/rocket2/src/external/tinyxml/tinyxmlerror.cpp
===================================================================
--- /code/branches/rocket2/src/external/tinyxml/tinyxmlerror.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/tinyxml/tinyxmlerror.cpp	(revision 6952)
@@ -0,0 +1,53 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.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 "tinyxml.h"
+
+// The goal of the seperate error file is to make the first
+// step towards localization. tinyxml (currently) only supports
+// english error messages, but the could now be translated.
+//
+// It also cleans up the code a bit.
+//
+
+const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] =
+{
+	"No error",
+	"Error",
+	"Failed to open file",
+	"Memory allocation failed.",
+	"Error parsing Element.",
+	"Failed to read Element name",
+	"Error reading Element value.",
+	"Error reading Attributes.",
+	"Error: empty tag.",
+	"Error reading end tag.",
+	"Error parsing Unknown.",
+	"Error parsing Comment.",
+	"Error parsing Declaration.",
+	"Error document empty.",
+	"Error null (0) or unexpected EOF found in input stream.",
+	"Error parsing CDATA.",
+	"Error when TiXmlDocument added to document, because TiXmlDocument can only be at the root.",
+};
Index: /code/branches/rocket2/src/external/tinyxml/tinyxmlparser.cpp
===================================================================
--- /code/branches/rocket2/src/external/tinyxml/tinyxmlparser.cpp	(revision 6952)
+++ /code/branches/rocket2/src/external/tinyxml/tinyxmlparser.cpp	(revision 6952)
@@ -0,0 +1,1722 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.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 <ctype.h>
+#include <stddef.h>
+
+#include "tinyxml.h"
+
+//#define DEBUG_PARSER
+#if defined( DEBUG_PARSER )
+#	if defined( DEBUG ) && defined( _MSC_VER )
+#		include <windows.h>
+#		define TIXML_LOG OutputDebugString
+#	else
+#		define TIXML_LOG printf
+#	endif
+#endif
+
+// Note tha "PutString" hardcodes the same list. This
+// is less flexible than it appears. Changing the entries
+// or order will break putstring.
+TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] =
+{
+	{ "&amp;",  5, '&' },
+	{ "&lt;",   4, '<' },
+	{ "&gt;",   4, '>' },
+	{ "&quot;", 6, '\"' },
+	{ "&apos;", 6, '\'' }
+};
+
+// Bunch of unicode info at:
+//		http://www.unicode.org/faq/utf_bom.html
+// Including the basic of this table, which determines the #bytes in the
+// sequence from the lead byte. 1 placed for invalid sequences --
+// although the result will be junk, pass it through as much as possible.
+// Beware of the non-characters in UTF-8:
+//				ef bb bf (Microsoft "lead bytes")
+//				ef bf be
+//				ef bf bf
+
+const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+const int TiXmlBase::utf8ByteTable[256] =
+{
+	//	0	1	2	3	4	5	6	7	8	9	a	b	c	d	e	f
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x00
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x10
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x20
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x30
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x40
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x50
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x60
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x70	End of ASCII range
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x80 0x80 to 0xc1 invalid
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x90
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xa0
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xb0
+		1,	1,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xc0 0xc2 to 0xdf 2 byte
+		2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xd0
+		3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	// 0xe0 0xe0 to 0xef 3 byte
+		4,	4,	4,	4,	4,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1	// 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
+};
+
+
+void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
+{
+	const unsigned long BYTE_MASK = 0xBF;
+	const unsigned long BYTE_MARK = 0x80;
+	const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+	if (input < 0x80)
+		*length = 1;
+	else if ( input < 0x800 )
+		*length = 2;
+	else if ( input < 0x10000 )
+		*length = 3;
+	else if ( input < 0x200000 )
+		*length = 4;
+	else
+		{ *length = 0; return; }	// This code won't covert this correctly anyway.
+
+	output += *length;
+
+	// Scary scary fall throughs.
+	switch (*length)
+	{
+		case 4:
+			--output;
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK);
+			input >>= 6;
+		case 3:
+			--output;
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK);
+			input >>= 6;
+		case 2:
+			--output;
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK);
+			input >>= 6;
+		case 1:
+			--output;
+			*output = (char)(input | FIRST_BYTE_MARK[*length]);
+	}
+}
+
+
+/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
+{
+	// This will only work for low-ascii, everything else is assumed to be a valid
+	// letter. I'm not sure this is the best approach, but it is quite tricky trying
+	// to figure out alhabetical vs. not across encoding. So take a very
+	// conservative approach.
+
+//	if ( encoding == TIXML_ENCODING_UTF8 )
+//	{
+		if ( anyByte < 127 )
+			return isalpha( anyByte );
+		else
+			return 1;	// What else to do? The unicode set is huge...get the english ones right.
+//	}
+//	else
+//	{
+//		return isalpha( anyByte );
+//	}
+}
+
+
+/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
+{
+	// This will only work for low-ascii, everything else is assumed to be a valid
+	// letter. I'm not sure this is the best approach, but it is quite tricky trying
+	// to figure out alhabetical vs. not across encoding. So take a very
+	// conservative approach.
+
+//	if ( encoding == TIXML_ENCODING_UTF8 )
+//	{
+		if ( anyByte < 127 )
+			return isalnum( anyByte );
+		else
+			return 1;	// What else to do? The unicode set is huge...get the english ones right.
+//	}
+//	else
+//	{
+//		return isalnum( anyByte );
+//	}
+}
+
+
+class TiXmlParsingData
+{
+	friend class TiXmlDocument;
+  public:
+	void Stamp( const char* now, TiXmlEncoding encoding );
+
+	const TiXmlCursor& Cursor()	{ return cursor; }
+
+  private:
+	// Only used by the document!
+	TiXmlParsingData( const char* start, int _tabsize, int row, int col )
+	{
+		assert( start );
+		stamp = start;
+		tabsize = _tabsize;
+		cursor.row = row;
+		cursor.col = col;
+	}
+
+	TiXmlCursor		cursor;
+	const char*		stamp;
+	int				tabsize;
+};
+
+
+void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
+{
+	assert( now );
+
+	// Do nothing if the tabsize is 0.
+	if ( tabsize < 1 )
+	{
+		return;
+	}
+
+	// Get the current row, column.
+	int row = cursor.row;
+	int col = cursor.col;
+	const char* p = stamp;
+	assert( p );
+
+	while ( p < now )
+	{
+		// Treat p as unsigned, so we have a happy compiler.
+		const unsigned char* pU = (const unsigned char*)p;
+
+		// Code contributed by Fletcher Dunn: (modified by lee)
+		switch (*pU) {
+			case 0:
+				// We *should* never get here, but in case we do, don't
+				// advance past the terminating null character, ever
+				return;
+
+			case '\r':
+				// bump down to the next line
+				++row;
+				col = 0;
+				// Eat the character
+				++p;
+
+				// Check for \r\n sequence, and treat this as a single character
+				if (*p == '\n') {
+					++p;
+				}
+				break;
+
+			case '\n':
+				// bump down to the next line
+				++row;
+				col = 0;
+
+				// Eat the character
+				++p;
+
+				// Check for \n\r sequence, and treat this as a single
+				// character.  (Yes, this bizarre thing does occur still
+				// on some arcane platforms...)
+				if (*p == '\r') {
+					++p;
+				}
+				break;
+
+			case '\t':
+				// Eat the character
+				++p;
+
+				// Skip to next tab stop
+				col = (col / tabsize + 1) * tabsize;
+				break;
+
+			case TIXML_UTF_LEAD_0:
+				if ( encoding == TIXML_ENCODING_UTF8 )
+				{
+					if ( *(p+1) && *(p+2) )
+					{
+						// In these cases, don't advance the column. These are
+						// 0-width spaces.
+						if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
+							p += 3;
+						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
+							p += 3;
+						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
+							p += 3;
+						else
+							{ p +=3; ++col; }	// A normal character.
+					}
+				}
+				else
+				{
+					++p;
+					++col;
+				}
+				break;
+
+			default:
+				if ( encoding == TIXML_ENCODING_UTF8 )
+				{
+					// Eat the 1 to 4 byte utf8 character.
+					int step = TiXmlBase::utf8ByteTable[*((const unsigned char*)p)];
+					if ( step == 0 )
+						step = 1;		// Error case from bad encoding, but handle gracefully.
+					p += step;
+
+					// Just advance one column, of course.
+					++col;
+				}
+				else
+				{
+					++p;
+					++col;
+				}
+				break;
+		}
+	}
+	cursor.row = row;
+	cursor.col = col;
+	assert( cursor.row >= -1 );
+	assert( cursor.col >= -1 );
+	stamp = p;
+	assert( stamp );
+}
+
+
+const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
+{
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+	if ( encoding == TIXML_ENCODING_UTF8 )
+	{
+		while ( *p )
+		{
+			const unsigned char* pU = (const unsigned char*)p;
+
+			// Skip the stupid Microsoft UTF-8 Byte order marks
+			if (	*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==TIXML_UTF_LEAD_1
+				 && *(pU+2)==TIXML_UTF_LEAD_2 )
+			{
+				p += 3;
+				continue;
+			}
+			else if(*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==0xbfU
+				 && *(pU+2)==0xbeU )
+			{
+				p += 3;
+				continue;
+			}
+			else if(*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==0xbfU
+				 && *(pU+2)==0xbfU )
+			{
+				p += 3;
+				continue;
+			}
+
+			if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' )		// Still using old rules for white space.
+				++p;
+			else
+				break;
+		}
+	}
+	else
+	{
+		while ( ( *p && IsWhiteSpace( *p ) ) || *p == '\n' || *p =='\r' )
+			++p;
+	}
+
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+/*static*/ bool TiXmlBase::StreamWhiteSpace( std::istream * in, TIXML_STRING * tag )
+{
+	for( ;; )
+	{
+		if ( !in->good() ) return false;
+
+		int c = in->peek();
+		// At this scope, we can't get to a document. So fail silently.
+		if ( !IsWhiteSpace( c ) || c <= 0 )
+			return true;
+
+		*tag += (char) in->get();
+	}
+}
+
+/*static*/ bool TiXmlBase::StreamTo( std::istream * in, int character, TIXML_STRING * tag )
+{
+	//assert( character > 0 && character < 128 );	// else it won't work in utf-8
+	while ( in->good() )
+	{
+		int c = in->peek();
+		if ( c == character )
+			return true;
+		if ( c <= 0 )		// Silent failure: can't get document at this scope
+			return false;
+
+		in->get();
+		*tag += (char) c;
+	}
+	return false;
+}
+#endif
+
+// One of TinyXML's more performance demanding functions. Try to keep the memory overhead down. The
+// "assign" optimization removes over 10% of the execution time.
+//
+const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
+{
+	// Oddly, not supported on some comilers,
+	//name->clear();
+	// So use this:
+	*name = "";
+	assert( p );
+
+	// Names start with letters or underscores.
+	// Of course, in unicode, tinyxml has no idea what a letter *is*. The
+	// algorithm is generous.
+	//
+	// After that, they can be letters, underscores, numbers,
+	// hyphens, or colons. (Colons are valid ony for namespaces,
+	// but tinyxml can't tell namespaces from names.)
+	if (    p && *p
+		 && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
+	{
+		const char* start = p;
+		while(		p && *p
+				&&	(		IsAlphaNum( (unsigned char ) *p, encoding )
+						 || *p == '_'
+						 || *p == '-'
+						 || *p == '.'
+						 || *p == ':' ) )
+		{
+			//(*name) += *p; // expensive
+			++p;
+		}
+		if ( p-start > 0 ) {
+			name->assign( start, p-start );
+		}
+		return p;
+	}
+	return 0;
+}
+
+const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding )
+{
+	// Presume an entity, and pull it out.
+    TIXML_STRING ent;
+	int i;
+	*length = 0;
+
+	if ( *(p+1) && *(p+1) == '#' && *(p+2) )
+	{
+		unsigned long ucs = 0;
+		ptrdiff_t delta = 0;
+		unsigned mult = 1;
+
+		if ( *(p+2) == 'x' )
+		{
+			// Hexadecimal.
+			if ( !*(p+3) ) return 0;
+
+			const char* q = p+3;
+			q = strchr( q, ';' );
+
+			if ( !q || !*q ) return 0;
+
+			delta = q-p;
+			--q;
+
+			while ( *q != 'x' )
+			{
+				if ( *q >= '0' && *q <= '9' )
+					ucs += mult * (*q - '0');
+				else if ( *q >= 'a' && *q <= 'f' )
+					ucs += mult * (*q - 'a' + 10);
+				else if ( *q >= 'A' && *q <= 'F' )
+					ucs += mult * (*q - 'A' + 10 );
+				else
+					return 0;
+				mult *= 16;
+				--q;
+			}
+		}
+		else
+		{
+			// Decimal.
+			if ( !*(p+2) ) return 0;
+
+			const char* q = p+2;
+			q = strchr( q, ';' );
+
+			if ( !q || !*q ) return 0;
+
+			delta = q-p;
+			--q;
+
+			while ( *q != '#' )
+			{
+				if ( *q >= '0' && *q <= '9' )
+					ucs += mult * (*q - '0');
+				else
+					return 0;
+				mult *= 10;
+				--q;
+			}
+		}
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			// convert the UCS to UTF-8
+			ConvertUTF32ToUTF8( ucs, value, length );
+		}
+		else
+		{
+			*value = (char)ucs;
+			*length = 1;
+		}
+		return p + delta + 1;
+	}
+
+	// Now try to match it.
+	for( i=0; i<NUM_ENTITY; ++i )
+	{
+		if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 )
+		{
+			assert( strlen( entity[i].str ) == entity[i].strLength );
+			*value = entity[i].chr;
+			*length = 1;
+			return ( p + entity[i].strLength );
+		}
+	}
+
+	// So it wasn't an entity, its unrecognized, or something like that.
+	*value = *p;	// Don't put back the last one, since we return it!
+	//*length = 1;	// Leave unrecognized entities - this doesn't really work.
+					// Just writes strange XML.
+	return p+1;
+}
+
+
+bool TiXmlBase::StringEqual( const char* p,
+							 const char* tag,
+							 bool ignoreCase,
+							 TiXmlEncoding encoding )
+{
+	assert( p );
+	assert( tag );
+	if ( !p || !*p )
+	{
+		assert( 0 );
+		return false;
+	}
+
+	const char* q = p;
+
+	if ( ignoreCase )
+	{
+		while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) )
+		{
+			++q;
+			++tag;
+		}
+
+		if ( *tag == 0 )
+			return true;
+	}
+	else
+	{
+		while ( *q && *tag && *q == *tag )
+		{
+			++q;
+			++tag;
+		}
+
+		if ( *tag == 0 )		// Have we found the end of the tag, and everything equal?
+			return true;
+	}
+	return false;
+}
+
+const char* TiXmlBase::ReadText(	const char* p,
+									TIXML_STRING * text,
+									bool trimWhiteSpace,
+									const char* endTag,
+									bool caseInsensitive,
+									TiXmlEncoding encoding )
+{
+    *text = "";
+	if (    !trimWhiteSpace			// certain tags always keep whitespace
+		 || !condenseWhiteSpace )	// if true, whitespace is always kept
+	{
+		// Keep all the white space.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive, encoding )
+			  )
+		{
+			int len;
+			char cArr[4] = { 0, 0, 0, 0 };
+			p = GetChar( p, cArr, &len, encoding );
+			text->append( cArr, len );
+		}
+	}
+	else
+	{
+		bool whitespace = false;
+
+		// Remove leading white space:
+		p = SkipWhiteSpace( p, encoding );
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive, encoding ) )
+		{
+			if ( *p == '\r' || *p == '\n' )
+			{
+				whitespace = true;
+				++p;
+			}
+			else if ( IsWhiteSpace( *p ) )
+			{
+				whitespace = true;
+				++p;
+			}
+			else
+			{
+				// If we've found whitespace, add it before the
+				// new character. Any whitespace just becomes a space.
+				if ( whitespace )
+				{
+					(*text) += ' ';
+					whitespace = false;
+				}
+				int len;
+				char cArr[4] = { 0, 0, 0, 0 };
+				p = GetChar( p, cArr, &len, encoding );
+				if ( len == 1 )
+					(*text) += cArr[0];	// more efficient
+				else
+					text->append( cArr, len );
+			}
+		}
+	}
+	if ( p )
+		p += strlen( endTag );
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlDocument::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	// The basic issue with a document is that we don't know what we're
+	// streaming. Read something presumed to be a tag (and hope), then
+	// identify it, and call the appropriate stream method on the tag.
+	//
+	// This "pre-streaming" will never read the closing ">" so the
+	// sub-tag can orient itself.
+
+	if ( !StreamTo( in, '<', tag ) )
+	{
+		SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return;
+	}
+
+	while ( in->good() )
+	{
+		int tagIndex = (int) tag->length();
+		while ( in->good() && in->peek() != '>' )
+		{
+			int c = in->get();
+			if ( c <= 0 )
+			{
+				SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+				break;
+			}
+			(*tag) += (char) c;
+		}
+
+		if ( in->good() )
+		{
+			// We now have something we presume to be a node of
+			// some sort. Identify it, and call the node to
+			// continue streaming.
+			TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING );
+
+			if ( node )
+			{
+				node->StreamIn( in, tag );
+				bool isElement = node->ToElement() != 0;
+				delete node;
+				node = 0;
+
+				// If this is the root element, we're done. Parsing will be
+				// done by the >> operator.
+				if ( isElement )
+				{
+					return;
+				}
+			}
+			else
+			{
+				SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+				return;
+			}
+		}
+	}
+	// We should have returned sooner.
+	SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+}
+
+#endif
+
+const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding )
+{
+	ClearError();
+
+	// Parse away, at the document level. Since a document
+	// contains nothing but other tags, most of what happens
+	// here is skipping white space.
+	if ( !p || !*p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	// Note that, for a document, this needs to come
+	// before the while space skip, so that parsing
+	// starts from the pointer we are given.
+	location.Clear();
+	if ( prevData )
+	{
+		location.row = prevData->cursor.row;
+		location.col = prevData->cursor.col;
+	}
+	else
+	{
+		location.row = 0;
+		location.col = 0;
+	}
+	TiXmlParsingData data( p, TabSize(), location.row, location.col );
+	location = data.Cursor();
+
+	if ( encoding == TIXML_ENCODING_UNKNOWN )
+	{
+		// Check for the Microsoft UTF-8 lead bytes.
+		const unsigned char* pU = (const unsigned char*)p;
+		if (	*(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0
+			 && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1
+			 && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 )
+		{
+			encoding = TIXML_ENCODING_UTF8;
+			useMicrosoftBOM = true;
+		}
+	}
+
+    p = SkipWhiteSpace( p, encoding );
+	if ( !p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	while ( p && *p )
+	{
+		TiXmlNode* node = Identify( p, encoding );
+		if ( node )
+		{
+			p = node->Parse( p, &data, encoding );
+			LinkEndChild( node );
+		}
+		else
+		{
+			break;
+		}
+
+		// Did we get encoding info?
+		if (    encoding == TIXML_ENCODING_UNKNOWN
+			 && node->ToDeclaration() )
+		{
+			TiXmlDeclaration* dec = node->ToDeclaration();
+			const char* enc = dec->Encoding();
+			assert( enc );
+
+			if ( *enc == 0 )
+				encoding = TIXML_ENCODING_UTF8;
+			else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) )
+				encoding = TIXML_ENCODING_UTF8;
+			else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
+				encoding = TIXML_ENCODING_UTF8;	// incorrect, but be nice
+			else
+				encoding = TIXML_ENCODING_LEGACY;
+		}
+
+		p = SkipWhiteSpace( p, encoding );
+	}
+
+	// Was this empty?
+	if ( !firstChild ) {
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding );
+		return 0;
+	}
+
+	// All is well.
+	return p;
+}
+
+void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	// The first error in a chain is more accurate - don't set again!
+	if ( error )
+		return;
+
+	assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
+	error   = true;
+	errorId = err;
+	errorDesc = errorString[ errorId ];
+
+	errorLocation.Clear();
+	if ( pError && data )
+	{
+		data->Stamp( pError, encoding );
+		errorLocation = data->Cursor();
+	}
+}
+
+
+TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
+{
+	TiXmlNode* returnNode = 0;
+
+	p = SkipWhiteSpace( p, encoding );
+	if( !p || !*p || *p != '<' )
+	{
+		return 0;
+	}
+
+	TiXmlDocument* doc = GetDocument();
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+
+	// What is this thing?
+	// - Elements start with a letter or underscore, but xml is reserved.
+	// - Comments: <!--
+	// - Decleration: <?xml
+	// - StylesheetReference <?xml-stylesheet
+	// - Everthing else is unknown to tinyxml.
+	//
+
+	const char* xmlHeader = { "<?xml" };
+	const char* xmlSSHeader = { "<?xml-stylesheet" };
+	const char* commentHeader = { "<!--" };
+	const char* dtdHeader = { "<!" };
+	const char* cdataHeader = { "<![CDATA[" };
+
+	if ( StringEqual( p, xmlSSHeader, true, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Stylesheet Reference\n" );
+		#endif
+		returnNode = new TiXmlStylesheetReference();
+	}
+	else if ( StringEqual( p, xmlHeader, true, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Declaration\n" );
+		#endif
+		returnNode = new TiXmlDeclaration();
+	}
+	else if ( StringEqual( p, commentHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Comment\n" );
+		#endif
+		returnNode = new TiXmlComment();
+	}
+	else if ( StringEqual( p, cdataHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing CDATA\n" );
+		#endif
+		TiXmlText* text = new TiXmlText( "" );
+		text->SetCDATA( true );
+		returnNode = text;
+	}
+	else if ( StringEqual( p, dtdHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown(1)\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+	else if (    IsAlpha( *(p+1), encoding )
+			  || *(p+1) == '_' )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Element\n" );
+		#endif
+		returnNode = new TiXmlElement( "" );
+	}
+	else
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown(2)\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+
+	if ( returnNode )
+	{
+		// Set the parent, so it can report errors
+		returnNode->parent = this;
+	}
+	else
+	{
+		if ( doc )
+			doc->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+	}
+	return returnNode;
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlElement::StreamIn (std::istream * in, TIXML_STRING * tag)
+{
+	// We're called with some amount of pre-parsing. That is, some of "this"
+	// element is in "tag". Go ahead and stream to the closing ">"
+	while( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c ;
+
+		if ( c == '>' )
+			break;
+	}
+
+	if ( tag->length() < 3 ) return;
+
+	// Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
+	// If not, identify and stream.
+
+	if (    tag->at( tag->length() - 1 ) == '>'
+		 && tag->at( tag->length() - 2 ) == '/' )
+	{
+		// All good!
+		return;
+	}
+	else if ( tag->at( tag->length() - 1 ) == '>' )
+	{
+		// There is more. Could be:
+		//		text
+		//		cdata text (which looks like another node)
+		//		closing tag
+		//		another node.
+		for ( ;; )
+		{
+			StreamWhiteSpace( in, tag );
+
+			// Do we have text?
+			if ( in->good() && in->peek() != '<' )
+			{
+				// Yep, text.
+				TiXmlText text( "" );
+				text.StreamIn( in, tag );
+
+				// What follows text is a closing tag or another node.
+				// Go around again and figure it out.
+				continue;
+			}
+
+			// We now have either a closing tag...or another node.
+			// We should be at a "<", regardless.
+			if ( !in->good() ) return;
+			assert( in->peek() == '<' );
+			int tagIndex = (int) tag->length();
+
+			bool closingTag = false;
+			bool firstCharFound = false;
+
+			for( ;; )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->peek();
+				if ( c <= 0 )
+				{
+					TiXmlDocument* document = GetDocument();
+					if ( document )
+						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+					return;
+				}
+
+				if ( c == '>' )
+					break;
+
+				*tag += (char) c;
+				in->get();
+
+				// Early out if we find the CDATA id.
+				if ( c == '[' && tag->size() >= 9 )
+				{
+					size_t len = tag->size();
+					const char* start = tag->c_str() + len - 9;
+					if ( strcmp( start, "<![CDATA[" ) == 0 ) {
+						assert( !closingTag );
+						break;
+					}
+				}
+
+				if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
+				{
+					firstCharFound = true;
+					if ( c == '/' )
+						closingTag = true;
+				}
+			}
+			// If it was a closing tag, then read in the closing '>' to clean up the input stream.
+			// If it was not, the streaming will be done by the tag.
+			if ( closingTag )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->get();
+				if ( c <= 0 )
+				{
+					TiXmlDocument* document = GetDocument();
+					if ( document )
+						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+					return;
+				}
+				assert( c == '>' );
+				*tag += (char) c;
+
+				// We are done, once we've found our closing tag.
+				return;
+			}
+			else
+			{
+				// If not a closing tag, id it, and stream.
+				const char* tagloc = tag->c_str() + tagIndex;
+				TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING );
+				if ( !node )
+					return;
+				node->StreamIn( in, tag );
+				delete node;
+				node = 0;
+
+				// No return: go around from the beginning: text, closing tag, or node.
+			}
+		}
+	}
+}
+#endif
+
+const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	TiXmlDocument* document = GetDocument();
+
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding );
+		return 0;
+	}
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+
+	if ( *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding );
+		return 0;
+	}
+
+	p = SkipWhiteSpace( p+1, encoding );
+
+	// Read the name.
+	const char* pErr = p;
+
+    p = ReadName( p, &value, encoding );
+	if ( !p || !*p )
+	{
+		if ( document )	document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding );
+		return 0;
+	}
+
+    TIXML_STRING endTag ("</");
+	endTag += value;
+	endTag += ">";
+
+	// Check for and read attributes. Also look for an empty
+	// tag or an end tag.
+	while ( p && *p )
+	{
+		pErr = p;
+		p = SkipWhiteSpace( p, encoding );
+		if ( !p || !*p )
+		{
+			if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+			return 0;
+		}
+		if ( *p == '/' )
+		{
+			++p;
+			// Empty tag.
+			if ( *p  != '>' )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );
+				return 0;
+			}
+			return (p+1);
+		}
+		else if ( *p == '>' )
+		{
+			// Done with attributes (if there were any.)
+			// Read the value -- which can include other
+			// elements -- read the end tag, and return.
+			++p;
+			p = ReadValue( p, data, encoding );		// Note this is an Element method, and will set the error if one happens.
+			if ( !p || !*p ) {
+				// We were looking for the end tag, but found nothing.
+				// Fix for [ 1663758 ] Failure to report error on bad XML
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+
+			// We should find the end tag now
+			if ( StringEqual( p, endTag.c_str(), false, encoding ) )
+			{
+				p += endTag.length();
+				return p;
+			}
+			else
+			{
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+		}
+		else
+		{
+			// Try to read an attribute:
+			TiXmlAttribute* attrib = new TiXmlAttribute();
+			if ( !attrib )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding );
+				return 0;
+			}
+
+			attrib->SetDocument( document );
+			pErr = p;
+			p = attrib->Parse( p, data, encoding );
+
+			if ( !p || !*p )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
+				delete attrib;
+				return 0;
+			}
+
+			// Handle the strange case of double attributes:
+			#ifdef TIXML_USE_STL
+			TiXmlAttribute* node = attributeSet.Find( attrib->NameTStr() );
+			#else
+			TiXmlAttribute* node = attributeSet.Find( attrib->Name() );
+			#endif
+			if ( node )
+			{
+				node->SetValue( attrib->Value() );
+				delete attrib;
+				return 0;
+			}
+
+			attributeSet.Add( attrib );
+		}
+	}
+	return p;
+}
+
+
+const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+
+	// Read in text and elements in any order.
+	const char* pWithWhiteSpace = p;
+	p = SkipWhiteSpace( p, encoding );
+
+	while ( p && *p )
+	{
+		if ( *p != '<' )
+		{
+			// Take what we have, make a text element.
+			TiXmlText* textNode = new TiXmlText( "" );
+
+			if ( !textNode )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, encoding );
+				    return 0;
+			}
+
+			if ( TiXmlBase::IsWhiteSpaceCondensed() )
+			{
+				p = textNode->Parse( p, data, encoding );
+			}
+			else
+			{
+				// Special case: we want to keep the white space
+				// so that leading spaces aren't removed.
+				p = textNode->Parse( pWithWhiteSpace, data, encoding );
+			}
+
+			if ( !textNode->Blank() )
+				LinkEndChild( textNode );
+			else
+				delete textNode;
+		}
+		else
+		{
+			// We hit a '<'
+			// Have we hit a new element or an end tag? This could also be
+			// a TiXmlText in the "CDATA" style.
+			if ( StringEqual( p, "</", false, encoding ) )
+			{
+				return p;
+			}
+			else
+			{
+				TiXmlNode* node = Identify( p, encoding );
+				if ( node )
+				{
+					p = node->Parse( p, data, encoding );
+					LinkEndChild( node );
+				}
+				else
+				{
+					return 0;
+				}
+			}
+		}
+		pWithWhiteSpace = p;
+		p = SkipWhiteSpace( p, encoding );
+	}
+
+	if ( !p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding );
+	}
+	return p;
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlUnknown::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	if ( !p || !*p || *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding );
+		return 0;
+	}
+	++p;
+    value = "";
+
+	while ( p && *p && *p != '>' )
+	{
+		value += *p;
+		++p;
+	}
+
+	if ( !p )
+	{
+		if ( document )	document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding );
+	}
+	if ( *p == '>' )
+		return p+1;
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlComment::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+
+		(*tag) += (char) c;
+
+		if ( c == '>'
+			 && tag->at( tag->length() - 2 ) == '-'
+			 && tag->at( tag->length() - 3 ) == '-' )
+		{
+			// All is well.
+			return;
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+	value = "";
+
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	const char* startTag = "<!--";
+	const char* endTag   = "-->";
+
+	if ( !StringEqual( p, startTag, false, encoding ) )
+	{
+		document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
+		return 0;
+	}
+	p += strlen( startTag );
+
+	// [ 1475201 ] TinyXML parses entities in comments
+	// Oops - ReadText doesn't work, because we don't want to parse the entities.
+	// p = ReadText( p, &value, false, endTag, false, encoding );
+	//
+	// from the XML spec:
+	/*
+	 [Definition: Comments may appear anywhere in a document outside other markup; in addition,
+	              they may appear within the document type declaration at places allowed by the grammar.
+				  They are not part of the document's character data; an XML processor MAY, but need not,
+				  make it possible for an application to retrieve the text of comments. For compatibility,
+				  the string "--" (double-hyphen) MUST NOT occur within comments.] Parameter entity
+				  references MUST NOT be recognized within comments.
+
+				  An example of a comment:
+
+				  <!-- declarations for <head> & <body> -->
+	*/
+
+    value = "";
+	// Keep all the white space.
+	while (	p && *p && !StringEqual( p, endTag, false, encoding ) )
+	{
+		value.append( p, 1 );
+		++p;
+	}
+	if ( p )
+		p += strlen( endTag );
+
+	return p;
+}
+
+
+const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p ) return 0;
+
+//	int tabsize = 4;
+//	if ( document )
+//		tabsize = document->TabSize();
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	// Read the name, the '=' and the value.
+	const char* pErr = p;
+	p = ReadName( p, &name, encoding );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+		return 0;
+	}
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p || *p != '=' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+		return 0;
+	}
+
+	++p;	// skip '='
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+		return 0;
+	}
+
+	const char* end;
+	const char SINGLE_QUOTE = '\'';
+	const char DOUBLE_QUOTE = '\"';
+
+	if ( *p == SINGLE_QUOTE )
+	{
+		++p;
+		end = "\'";		// single quote in string
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else if ( *p == DOUBLE_QUOTE )
+	{
+		++p;
+		end = "\"";		// double quote in string
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else
+	{
+		// All attribute values should be in single or double quotes.
+		// But this is such a common error that the parser will try
+		// its best, even without them.
+		value = "";
+		while (    p && *p											// existence
+				&& !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r'	// whitespace
+				&& *p != '/' && *p != '>' )							// tag end
+		{
+			if ( *p == SINGLE_QUOTE || *p == DOUBLE_QUOTE ) {
+				// [ 1451649 ] Attribute values with trailing quotes not handled correctly
+				// We did not have an opening quote but seem to have a
+				// closing one. Give up and throw an error.
+				if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+				return 0;
+			}
+			value += *p;
+			++p;
+		}
+	}
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlText::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->peek();
+		if ( !cdata && (c == '<' ) )
+		{
+			return;
+		}
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+
+		(*tag) += (char) c;
+		in->get();	// "commits" the peek made above
+
+		if ( cdata && c == '>' && tag->size() >= 3 ) {
+			size_t len = tag->size();
+			if ( (*tag)[len-2] == ']' && (*tag)[len-3] == ']' ) {
+				// terminator of cdata.
+				return;
+			}
+		}
+	}
+}
+#endif
+
+const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	value = "";
+	TiXmlDocument* document = GetDocument();
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+
+	const char* const startTag = "<![CDATA[";
+	const char* const endTag   = "]]>";
+
+	if ( cdata || StringEqual( p, startTag, false, encoding ) )
+	{
+		cdata = true;
+
+		if ( !StringEqual( p, startTag, false, encoding ) )
+		{
+			document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding );
+			return 0;
+		}
+		p += strlen( startTag );
+
+		// Keep all the white space, ignore the encoding, etc.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, false, encoding )
+			  )
+		{
+			value += *p;
+			++p;
+		}
+
+		TIXML_STRING dummy;
+		p = ReadText( p, &dummy, false, endTag, false, encoding );
+		return p;
+	}
+	else
+	{
+		bool ignoreWhite = true;
+
+		const char* end = "<";
+		p = ReadText( p, &value, ignoreWhite, end, false, encoding );
+		if ( p )
+			return p-1;	// don't truncate the '<'
+		return 0;
+	}
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlDeclaration::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;
+		}
+	}
+}
+#endif
+
+const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding )
+{
+	p = SkipWhiteSpace( p, _encoding );
+	// Find the beginning, find the end, and look for
+	// the stuff in-between.
+	TiXmlDocument* document = GetDocument();
+	if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding );
+		return 0;
+	}
+	if ( data )
+	{
+		data->Stamp( p, _encoding );
+		location = data->Cursor();
+	}
+	p += 5;
+
+	version = "";
+	encoding = "";
+	standalone = "";
+
+	while ( p && *p )
+	{
+		if ( *p == '>' )
+		{
+			++p;
+			return p;
+		}
+
+		p = SkipWhiteSpace( p, _encoding );
+		if ( StringEqual( p, "version", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );
+			version = attrib.Value();
+		}
+		else if ( StringEqual( p, "encoding", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );
+			encoding = attrib.Value();
+		}
+		else if ( StringEqual( p, "standalone", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );
+			standalone = attrib.Value();
+		}
+		else
+		{
+			// Read over whatever it is.
+			while( p && *p && *p != '>' && !IsWhiteSpace( *p ) )
+				++p;
+		}
+	}
+	return 0;
+}
+
+bool TiXmlText::Blank() const
+{
+	for ( unsigned i=0; i<value.length(); i++ )
+		if ( !IsWhiteSpace( value[i] ) )
+			return false;
+	return true;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlStylesheetReference::StreamIn( std::istream * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;
+		}
+	}
+}
+#endif
+
+const char* TiXmlStylesheetReference::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding )
+{
+	p = SkipWhiteSpace( p, _encoding );
+	// Find the beginning, find the end, and look for
+	// the stuff in-between.
+	TiXmlDocument* document = GetDocument();
+	if ( !p || !*p || !StringEqual( p, "<?xml-stylesheet", true, _encoding ) )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding );
+		return 0;
+	}
+	if ( data )
+	{
+		data->Stamp( p, _encoding );
+		location = data->Cursor();
+	}
+	p += 5;
+
+	type = "";
+	href = "";
+
+	while ( p && *p )
+	{
+		if ( *p == '>' )
+		{
+			++p;
+			return p;
+		}
+
+		p = SkipWhiteSpace( p, _encoding );
+		if ( StringEqual( p, "type", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );
+			type = attrib.Value();
+		}
+		else if ( StringEqual( p, "href", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );
+			href = attrib.Value();
+		}
+		else
+		{
+			// Read over whatever it is.
+			while( p && *p && *p != '>' && !IsWhiteSpace( *p ) )
+				++p;
+		}
+	}
+	return 0;
+}
Index: /code/branches/rocket2/src/external/tolua/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/external/tolua/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,88 @@
+ #
+ #             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.
+ #
+
+################### Tolua++ library ###################
+
+SET_SOURCE_FILES(TOLUA++_FILES
+  tolua_event.h
+  tolua++.h
+COMPILATION_BEGIN ToluaCompilation.c
+  tolua_event.c
+  tolua_is.c
+  tolua_map.c
+  tolua_push.c
+  tolua_to.c
+COMPILATION_END
+)
+
+ORXONOX_ADD_LIBRARY(tolua++_orxonox
+  ORXONOX_EXTERNAL
+  DEFINE_SYMBOL
+    "TOLUA_SHARED_BUILD"
+  VERSION
+    1.0.92
+  LINK_LIBRARIES
+    ${LUA_LIBRARIES}
+  SOURCE_FILES
+    ${TOLUA++_FILES}
+)
+
+
+################## Tolua++ generator ##################
+
+ORXONOX_ADD_EXECUTABLE(tolua++app_orxonox
+  ORXONOX_EXTERNAL
+  VERSION
+    1.0.92
+  NO_INSTALL
+  LINK_LIBRARIES
+    ${LUA_LIBRARIES}
+  SOURCE_FILES
+    tolua.c
+)
+
+# Set some variables to the cache in order to use them in the TOLUA macro
+SET(TOLUA_PARSER_SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/all-${LUA_VERSION}.lua" CACHE INTERNAL "")
+SET(TOLUA_PARSER_DEPENDENCIES
+  tolua++app_orxonox
+  ${CMAKE_CURRENT_SOURCE_DIR}/all-${LUA_VERSION}.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/compat-5.1.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/compat.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/basic.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/feature.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/verbatim.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/code.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/typedef.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/container.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/package.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/module.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/namespace.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/define.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/enumerate.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/declaration.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/variable.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/array.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/function.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/operator.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/class.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/clean.lua
+  ${CMAKE_CURRENT_SOURCE_DIR}/lua/doit.lua
+
+  CACHE INTERNAL ""
+)
Index: /code/branches/rocket2/src/external/tolua/MANUAL
===================================================================
--- /code/branches/rocket2/src/external/tolua/MANUAL	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/MANUAL	(revision 6952)
@@ -0,0 +1,58 @@
+This tolua++ is modified with support for exception handling, and more will
+likely come over time.
+
+So to avoid forgetting how it works and what's new, all added features will
+be documented in full in this file:
+
+***********************
+* Exception handling: *
+***********************
+A new function modifier 'tolua_throws' has been added. It goes the same place
+as 'tolua_outside' etc. - so before the function name and return type.
+
+Two "types" of exceptions are supported internally, but they can be customized
+by making the tolua++ binary execute a Lua script before parsing with the '-L'
+command line option.
+Look in '../LuaScriptModule/package/exceptions.lua' to see the format. It's
+fairly simple and gives you alot of control.
+
+You always have 'std::exception' and 'any' (which means ...) available.
+
+This first example would be valid in a .pkg file for tolua++, and would ensure
+that any exceptions based on 'std::exception' thrown by the real C++ function
+would result in return value of 'nil' in Lua:
+
+	tolua_throws|std::exception,nil| void I_Throw:StdException();
+
+Inside the pipes the exception name follow by return values (or actions) are
+listed. The syntax is like so:
+
+	tolua_throws|<exceptionName>[,<ret1>[,<ret2> ... [, <retN>]]]|[<exceptionName>...|]
+
+The return values can by any of the following:
+* nil
+* message (the exception message, or 'Unknown' if not possible.
+* true
+* false
+* error (can only be used alone, will contain the exception is possible)
+
+In case no return values are specified, it will default to: 'nil, message'.
+
+Example 1: 
+----------
+Returns 'nil, false' for all exceptions:
+
+	tolua_throws|any,nil,false|
+
+Example 2:
+----------
+Returns 'nil, message' if a 'std::exception' is thrown:
+
+	tolua_throws|std::exception,nil,message|
+
+Example 3:
+----------
+If a CEGUI::Exception is thrown, return 'nil, message'.
+If any other kind of exception is thrown abort (error).
+
+	tolua_throws|CEGUI::Exception|any,error|
Index: /code/branches/rocket2/src/external/tolua/README
===================================================================
--- /code/branches/rocket2/src/external/tolua/README	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/README	(revision 6952)
@@ -0,0 +1,32 @@
+This is tolua++-1.0
+
+* What is tolua++?
+  tolua++ is an extension of toLua, a tool to integrate C/C++ code with
+  Lua. tolua++ includes new features oriented to c++, such as class
+  templates.
+
+  tolua is a tool that greatly simplifies the integration of C/C++ code 
+  with Lua. Based on a "cleaned" header file, tolua automatically generates 
+  the binding code to access C/C++ features from Lua. Using Lua-5.0 API and
+  metamethod facilities, the current version automatically maps C/C++ 
+  constants, external variables, functions, namespace, classes, and methods 
+  to Lua. It also provides facilities to create Lua modules.
+
+* Availability
+  tolua is freely available; you can redistribute it and/or modify it.
+  The software provided hereunder is on an "as is" basis, and
+  the author has no obligation to provide maintenance, support, 
+  updates, enhancements, or modifications.
+
+  tolua can be downloaded from the sites below:
+            http://www.codenix.com/~tolua/
+            http://www.codenix.com/~tolua/tolua++-1.0.tar.bz2
+
+* Installation
+  See INSTALL.
+
+* Contacting the author
+  tolua has been designed and implemented by Waldemar Celes.
+  tolua++ is maintained by Ariel Manzur.
+  Send your comments, bug reports and anything else to 
+  tolua@codenix.com
Index: /code/branches/rocket2/src/external/tolua/VERSION
===================================================================
--- /code/branches/rocket2/src/external/tolua/VERSION	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/VERSION	(revision 6952)
@@ -0,0 +1,9 @@
+Tolua++ v1.0.92 with changes:
+
+- Exception handling by CEGUI team
+- Corrected all indentation by Orxonox
+- Added more command line arguments by Orxonox
+- Several small changes considering the output files by Orxonox
+
+The changes to the C source files are stored in changes_orxonox.diff
+
Index: /code/branches/rocket2/src/external/tolua/all-5.0.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/all-5.0.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/all-5.0.lua	(revision 6952)
@@ -0,0 +1,28 @@
+dofile(path.."lua/compat.lua")
+dofile(path.."lua/basic.lua")
+dofile(path.."lua/feature.lua")
+dofile(path.."lua/verbatim.lua")
+dofile(path.."lua/code.lua")
+dofile(path.."lua/typedef.lua")
+dofile(path.."lua/container.lua")
+dofile(path.."lua/package.lua")
+dofile(path.."lua/module.lua")
+dofile(path.."lua/namespace.lua")
+dofile(path.."lua/define.lua")
+dofile(path.."lua/enumerate.lua")
+dofile(path.."lua/declaration.lua")
+dofile(path.."lua/variable.lua")
+dofile(path.."lua/array.lua")
+dofile(path.."lua/function.lua")
+dofile(path.."lua/operator.lua")
+dofile(path.."lua/class.lua")
+dofile(path.."lua/clean.lua")
+--dofile(path.."lua/custom.lua")
+dofile(path.."lua/doit.lua")
+
+local err,msg = xpcall(doit, debug.traceback)
+if not err then
+--print("**** msg is "..tostring(msg))
+ local _,_,label,msg = strfind(msg,"(.-:.-:%s*)(.*)")
+ tolua_error(msg,label)
+end
Index: /code/branches/rocket2/src/external/tolua/all-5.1.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/all-5.1.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/all-5.1.lua	(revision 6952)
@@ -0,0 +1,29 @@
+dofile(path.."lua/compat-5.1.lua")
+dofile(path.."lua/compat.lua")
+dofile(path.."lua/basic.lua")
+dofile(path.."lua/feature.lua")
+dofile(path.."lua/verbatim.lua")
+dofile(path.."lua/code.lua")
+dofile(path.."lua/typedef.lua")
+dofile(path.."lua/container.lua")
+dofile(path.."lua/package.lua")
+dofile(path.."lua/module.lua")
+dofile(path.."lua/namespace.lua")
+dofile(path.."lua/define.lua")
+dofile(path.."lua/enumerate.lua")
+dofile(path.."lua/declaration.lua")
+dofile(path.."lua/variable.lua")
+dofile(path.."lua/array.lua")
+dofile(path.."lua/function.lua")
+dofile(path.."lua/operator.lua")
+dofile(path.."lua/class.lua")
+dofile(path.."lua/clean.lua")
+--dofile(path.."lua/custom.lua")
+dofile(path.."lua/doit.lua")
+
+local err,msg = xpcall(doit, debug.traceback)
+if not err then
+--print("**** msg is "..tostring(msg))
+ local _,_,label,msg = strfind(msg,"(.-:.-:%s*)(.*)")
+ tolua_error(msg,label)
+end
Index: /code/branches/rocket2/src/external/tolua/changes_orxonox.diff
===================================================================
--- /code/branches/rocket2/src/external/tolua/changes_orxonox.diff	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/changes_orxonox.diff	(revision 6952)
@@ -0,0 +1,182 @@
+diff -ruN tolua/tolua++.h tolua2/tolua++.h
+--- tolua/tolua++.h	Wed Jan 28 21:51:38 2009
++++ tolua2/tolua++.h	Sat Jan 10 14:48:44 2009
+@@ -16,9 +16,34 @@
+ #ifndef TOLUA_H
+ #define TOLUA_H
+ 
++/* original code */
++/*
+ #ifndef TOLUA_API
+ #define TOLUA_API extern
+ #endif
++*/
++
++/********************************
++******* ORXONOX CHANGES *********
++********************************/
++
++#if (defined( __WIN32__ ) || defined( _WIN32 )) && !defined( TOLUA_STATIC_BUILD )
++#  ifdef TOLUA_SHARED_BUILD
++#    define TOLUA_API __declspec(dllexport)
++#  else
++#    if defined( __MINGW32__ )
++#      define TOLUA_API
++#    else
++#      define TOLUA_API __declspec(dllimport)
++#    endif
++#  endif
++#else
++#  define TOLUA_API extern
++#endif
++
++/********************************
++****** END ORXONOX CHANGES ******
++********************************/
+ 
+ #define TOLUA_VERSION "tolua++-1.0.92"
+ 
+diff -ruN tolua/tolua.c tolua2/tolua.c
+--- tolua/tolua.c	Wed Jan 28 21:51:00 2009
++++ tolua2/tolua.c	Sat Jan 10 14:48:45 2009
+@@ -4,6 +4,8 @@
+ ** TeCGraf/PUC-Rio
+ ** Aug 2003
+ ** $Id:$
++** Extension by Orxonox (Reto Grieder) to support working directory
++** and direct usage of lua files. (2008)
+ */
+ 
+ /* This code is free software; you can redistribute it and/or modify it.
+@@ -33,6 +35,8 @@
+          "  -o  file : set output file; default is stdout.\n"
+          "  -H  file : create include file.\n"
+          "  -n  name : set package name; default is input file root name.\n"
++         "  -w  directory : set working directory; default is location of package file.\n"
++         "  -s  file : specify source lua code for the parser; all.lua is default.\n"
+          "  -p       : parse only.\n"
+          "  -P       : parse and print structure information (for debug).\n"
+          "  -S       : disable support for c++ strings.\n"
+@@ -64,12 +68,12 @@
+ }
+ 
+ static void add_extra (lua_State* L, char* value) {
+-	int len;
+-	lua_getglobal(L, "_extra_parameters");
+-	len = luaL_getn(L, -1);
+-	lua_pushstring(L, value);
+-	lua_rawseti(L, -2, len+1);
+-	lua_pop(L, 1);
++ int len;
++ lua_getglobal(L, "_extra_parameters");
++ len = luaL_getn(L, -1);
++ lua_pushstring(L, value);
++ lua_rawseti(L, -2, len+1);
++ lua_pop(L, 1);
+ };
+ 
+ static void error (char* o)
+@@ -81,6 +85,9 @@
+ 
+ int main (int argc, char* argv[])
+ {
++ char* working_directory = "";
++ char* lua_source = "";
++
+  #ifdef LUA_VERSION_NUM /* lua 5.1 */
+  lua_State* L = luaL_newstate();
+  luaL_openlibs(L);
+@@ -97,6 +104,7 @@
+  lua_pushstring(L,TOLUA_VERSION); lua_setglobal(L,"TOLUA_VERSION");
+  lua_pushstring(L,LUA_VERSION); lua_setglobal(L,"TOLUA_LUA_VERSION");
+ 
++
+  if (argc==1)
+  {
+   help();
+@@ -124,6 +132,14 @@
+      case 'o': setfield(L,t,"o",argv[++i]); break;
+      case 'n': setfield(L,t,"n",argv[++i]); break;
+      case 'H': setfield(L,t,"H",argv[++i]); break;
++     case 'w':
++      working_directory = argv[++i];
++      setfield(L,t,"w",argv[i]);
++      break;
++     case 's':
++      lua_source = argv[++i];
++      setfield(L,t,"s",argv[i]);
++      break;
+      case 'S': setfield(L,t,"S",""); break;
+      case '1': setfield(L,t,"1",""); break;
+      case 'L': setfield(L,t,"L",argv[++i]); break;
+@@ -143,25 +159,53 @@
+   }
+   lua_pop(L,1);
+  }
+-/* #define TOLUA_SCRIPT_RUN */
+-#ifndef TOLUA_SCRIPT_RUN
++
+  {
+-  int tolua_tolua_open (lua_State* L);
+-  tolua_tolua_open(L);
+- }
++  char path[BUFSIZ];
++  char file[BUFSIZ];
++  path[0] = '\0';
++  file[0] = '\0';
++
++  if (strlen(lua_source) > 0 &&
++      lua_source[0] != '/' &&
++      lua_source[0] != '\\' &&
++      strlen(lua_source) > 1 &&
++      lua_source[1] != ':')
++  {
++   /* Relative path, prefix working directory */
++   strcpy(path, working_directory);
++   /* Make sure there is '\\' or '/' at the end of the path */
++   if (strlen(path) > 0)
++   {
++    char last = path[strlen(path) - 1];
++    if (last != '\\' && last != '/')
++     strcat(path, "/");
++   }
++  }
++
++  strcat(path, lua_source);
++
++  /* Extract the full path */
++  {
++   char* p;
++   p = strrchr(path, '/');
++   if (p == NULL)
++    p = strrchr(path, '\\');
++   p = (p == NULL) ? path : p + 1;
++   strcpy(file, p);
++   *p = '\0';
++  }
++  if (strlen(file) == 0)
++   strcpy(file, "all.lua");
++
++  lua_pushstring(L, path);
++  lua_setglobal(L, "path");
++  strcat(path, file);
++#ifdef LUA_VERSION_NUM /* lua 5.1 */
++  luaL_dofile(L, path);
+ #else
+- {
+-  char* p;
+-  char  path[BUFSIZ];
+-  strcpy(path,argv[0]);
+-  p = strrchr(path,'/');
+-  if (p==NULL) p = strrchr(path,'\\');
+-  p = (p==NULL) ? path : p+1;
+-  sprintf(p,"%s","../src/bin/lua/");
+-  lua_pushstring(L,path); lua_setglobal(L,"path");
+-		strcat(path,"all.lua");
+-  lua_dofile(L,path);
+- }
++  lua_dofile(L, path);
+ #endif
++ }
+  return 0;
+ }
Index: /code/branches/rocket2/src/external/tolua/lua/array.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/array.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/array.lua	(revision 6952)
@@ -0,0 +1,226 @@
+-- tolua: array class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1999
+-- $Id: array.lua,v 1.1 2000/11/06 22:03:57 celes Exp $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+-- Array class
+-- Represents a extern array variable or a public member of a class.
+-- Stores all fields present in a declaration.
+classArray = {
+}
+classArray.__index = classArray
+setmetatable(classArray,classDeclaration)
+
+-- Print method
+function classArray:print (ident,close)
+    print(ident.."Array{")
+    print(ident.." mod  = '"..self.mod.."',")
+    print(ident.." type = '"..self.type.."',")
+    print(ident.." ptr  = '"..self.ptr.."',")
+    print(ident.." name = '"..self.name.."',")
+    print(ident.." def  = '"..self.def.."',")
+    print(ident.." dim  = '"..self.dim.."',")
+    print(ident.." ret  = '"..self.ret.."',")
+    print(ident.."}"..close)
+end
+
+-- check if it is a variable
+function classArray:isvariable ()
+    return true
+end
+
+
+-- get variable value
+function classArray:getvalue (class,static)
+    if class and static then
+        return class..'::'..self.name..'[tolua_index]'
+    elseif class then
+        return 'self->'..self.name..'[tolua_index]'
+    else
+        return self.name..'[tolua_index]'
+    end
+end
+
+-- Write binding functions
+function classArray:supcode ()
+    local class = self:inclass()
+
+    -- get function ------------------------------------------------
+    if class then
+        output("/* get function:",self.name," of class ",class," */")
+    else
+        output("/* get function:",self.name," */")
+    end
+    self.cgetname = self:cfuncname("tolua_get")
+    output("#ifndef TOLUA_DISABLE_"..self.cgetname)
+    output("\nstatic int",self.cgetname,"(lua_State* tolua_S)")
+    output("{")
+    output(" int tolua_index;")
+
+    -- declare self, if the case
+    local _,_,static = strfind(self.mod,'^%s*(static)')
+    if class and static==nil then
+        output(' ',self.parent.type,'*','self;')
+        output(' lua_pushstring(tolua_S,".self");')
+        output(' lua_rawget(tolua_S,1);')
+        output(' self = ')
+        output('(',self.parent.type,'*) ')
+        output('lua_touserdata(tolua_S,-1);')
+    elseif static then
+        _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
+    end
+
+    -- check index
+    output('#ifndef TOLUA_RELEASE\n')
+    output(' {')
+    output('  tolua_Error tolua_err;')
+    output('  if (!tolua_isnumber(tolua_S,2,0,&tolua_err))')
+    output('   tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);')
+    output(' }')
+    output('#endif\n')
+    if flags['1'] then -- for compatibility with tolua5 ?
+        output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0)-1;')
+    else
+        output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0);')
+    end
+    output('#ifndef TOLUA_RELEASE\n')
+    if self.dim and self.dim ~= '' then
+        output(' if (tolua_index<0 || tolua_index>='..self.dim..')')
+    else
+        output(' if (tolua_index<0)')
+    end
+    output('  tolua_error(tolua_S,"array indexing out of range.",NULL);')
+    output('#endif\n')
+
+    -- return value
+    local t,ct = isbasic(self.type)
+    if t then
+        output(' tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static)..');')
+    else
+        t = self.type
+        if self.ptr == '&' or self.ptr == '' then
+            output(' tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static)..',"',t,'");')
+        else
+            output(' tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static)..',"',t,'");')
+        end
+    end
+    output(' return 1;')
+    output('}')
+    output('#endif //#ifndef TOLUA_DISABLE\n')
+    output('\n')
+
+    -- set function ------------------------------------------------
+    if not strfind(self.type,'const') then
+        if class then
+            output("/* set function:",self.name," of class ",class," */")
+        else
+            output("/* set function:",self.name," */")
+        end
+        self.csetname = self:cfuncname("tolua_set")
+        output("#ifndef TOLUA_DISABLE_"..self.csetname)
+        output("\nstatic int",self.csetname,"(lua_State* tolua_S)")
+        output("{")
+
+        -- declare index
+        output(' int tolua_index;')
+
+        -- declare self, if the case
+        local _,_,static = strfind(self.mod,'^%s*(static)')
+        if class and static==nil then
+            output(' ',self.parent.type,'*','self;')
+            output(' lua_pushstring(tolua_S,".self");')
+            output(' lua_rawget(tolua_S,1);')
+            output(' self = ')
+            output('(',self.parent.type,'*) ')
+            output('lua_touserdata(tolua_S,-1);')
+        elseif static then
+            _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
+        end
+
+        -- check index
+        output('#ifndef TOLUA_RELEASE\n')
+        output(' {')
+        output('  tolua_Error tolua_err;')
+        output('  if (!tolua_isnumber(tolua_S,2,0,&tolua_err))')
+        output('   tolua_error(tolua_S,"#vinvalid type in array indexing.",&tolua_err);')
+        output(' }')
+        output('#endif\n')
+
+        if flags['1'] then -- for compatibility with tolua5 ?
+            output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0)-1;')
+        else
+            output(' tolua_index = (int)tolua_tonumber(tolua_S,2,0);')
+        end
+
+        output('#ifndef TOLUA_RELEASE\n')
+        if self.dim and self.dim ~= '' then
+            output(' if (tolua_index<0 || tolua_index>='..self.dim..')')
+        else
+            output(' if (tolua_index<0)')
+        end
+        output('  tolua_error(tolua_S,"array indexing out of range.",NULL);')
+        output('#endif\n')
+
+        -- assign value
+        local ptr = ''
+        if self.ptr~='' then ptr = '*' end
+            output(' ')
+        if class and static then
+            output(class..'::'..self.name..'[tolua_index]')
+        elseif class then
+            output('self->'..self.name..'[tolua_index]')
+        else
+            output(self.name..'[tolua_index]')
+        end
+        local t = isbasic(self.type)
+        output(' = ')
+        if not t and ptr=='' then output('*') end
+        output('((',self.mod,self.type)
+        if not t then
+            output('*')
+        end
+        output(') ')
+        local def = 0
+        if self.def ~= '' then def = self.def end
+        if t then
+            output('tolua_to'..t,'(tolua_S,3,',def,'));')
+        else
+            output('tolua_tousertype(tolua_S,3,',def,'));')
+        end
+        output(' return 0;')
+        output('}')
+        output('#endif //#ifndef TOLUA_DISABLE\n')
+        output('\n')
+    end
+end
+
+function classArray:register (pre)
+    pre = pre or ''
+    if self.csetname then
+        output(pre..'tolua_array(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');')
+    else
+        output(pre..'tolua_array(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);')
+    end
+end
+
+-- Internal constructor
+function _Array (t)
+    setmetatable(t,classArray)
+    append(t)
+    return t
+end
+
+-- Constructor
+-- Expects a string representing the variable declaration.
+function Array (s)
+    return _Array (Declaration(s,'var'))
+end
+
+
Index: /code/branches/rocket2/src/external/tolua/lua/basic.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/basic.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/basic.lua	(revision 6952)
@@ -0,0 +1,356 @@
+-- tolua: basic utility functions
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- Last update: Apr 2003
+-- $Id: $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+-- Basic C types and their corresponding Lua types
+-- All occurrences of "char*" will be replaced by "_cstring",
+-- and all occurrences of "void*" will be replaced by "_userdata"
+_basic = {
+    ['void'] = '',
+    ['char'] = 'number',
+    ['int'] = 'number',
+    ['short'] = 'number',
+    ['long'] = 'number',
+    ['unsigned'] = 'number',
+    ['float'] = 'number',
+    ['double'] = 'number',
+    ['_cstring'] = 'string',
+    ['_userdata'] = 'userdata',
+    ['char*'] = 'string',
+    ['void*'] = 'userdata',
+    ['bool'] = 'boolean',
+    ['lua_Object'] = 'value',
+    ['LUA_VALUE'] = 'value',    -- for compatibility with tolua 4.0
+    ['lua_State*'] = 'state',
+    ['_lstate'] = 'state',
+    ['lua_Function'] = 'value',
+}
+
+_basic_ctype = {
+    number = "lua_Number",
+    string = "const char*",
+    userdata = "void*",
+    boolean = "bool",
+    value = "int",
+    state = "lua_State*",
+}
+
+-- functions the are used to do a 'raw push' of basic types
+_basic_raw_push = {}
+
+-- List of user defined types
+-- Each type corresponds to a variable name that stores its tag value.
+_usertype = {}
+
+-- List of types that have to be collected
+_collect = {}
+
+-- List of types
+_global_types = {n=0}
+_global_types_hash = {}
+
+-- list of classes
+_global_classes = {}
+
+-- List of enum constants
+_global_enums = {}
+
+-- List of auto renaming
+_renaming = {}
+function appendrenaming (s)
+    local b,e,old,new = strfind(s,"%s*(.-)%s*@%s*(.-)%s*$")
+    if not b then
+        error("#Invalid renaming syntax; it should be of the form: pattern@pattern")
+    end
+    tinsert(_renaming,{old=old, new=new})
+end
+
+function applyrenaming (s)
+    for i=1,getn(_renaming) do
+        local m,n = gsub(s,_renaming[i].old,_renaming[i].new)
+        if n ~= 0 then
+            return m
+        end
+    end
+    return nil
+end
+
+-- Error handler
+function tolua_error (s,f)
+    if _curr_code then
+        print("***curr code for error is "..tostring(_curr_code))
+        print(debug.traceback())
+    end
+    local out = _OUTPUT
+    _OUTPUT = _STDERR
+    if strsub(s,1,1) == '#' then
+        write("\n** tolua: "..strsub(s,2)..".\n\n")
+        if _curr_code then
+            local _,_,s = strfind(_curr_code,"^%s*(.-\n)") -- extract first line
+            if s==nil then s = _curr_code end
+            s = gsub(s,"_userdata","void*") -- return with 'void*'
+            s = gsub(s,"_cstring","char*")  -- return with 'char*'
+            s = gsub(s,"_lstate","lua_State*")  -- return with 'lua_State*'
+            write("Code being processed:\n"..s.."\n")
+        end
+    else
+        if not f then f = "(f is nil)" end
+        print("\n** tolua internal error: "..f..s..".\n\n")
+        return
+    end
+    _OUTPUT = out
+end
+
+function warning (msg)
+    local out = _OUTPUT
+    _OUTPUT = _STDERR
+    write("\n** tolua warning: "..msg..".\n\n")
+    _OUTPUT = out
+end
+
+-- register an user defined type: returns full type
+function regtype (t)
+    --if isbasic(t) then
+    --    return t
+    --end
+    local ft = findtype(t)
+
+    if not _usertype[ft] then
+        return appendusertype(t)
+    end
+    return ft
+end
+
+-- return type name: returns full type
+function typevar(type)
+    if type == '' or type == 'void' then
+        return type
+    else
+        local ft = findtype(type)
+        if ft then
+            return ft
+        end
+        _usertype[type] = type
+        return type
+    end
+end
+
+-- check if basic type
+function isbasic (type)
+    local t = gsub(type,'const ','')
+    local m,t = applytypedef('', t)
+    local b = _basic[t]
+    if b then
+        return b,_basic_ctype[b]
+    end
+    return nil
+end
+
+-- split string using a token
+function split (s,t)
+    local l = {n=0}
+    local f = function (s)
+        l.n = l.n + 1
+        l[l.n] = s
+        return ""
+    end
+    local p = "%s*(.-)%s*"..t.."%s*"
+    s = gsub(s,"^%s+","")
+    s = gsub(s,"%s+$","")
+    s = gsub(s,p,f)
+    l.n = l.n + 1
+    l[l.n] = gsub(s,"(%s%s*)$","")
+    return l
+end
+
+-- splits a string using a pattern, considering the spacial cases of C code (templates, function parameters, etc)
+-- pattern can't contain the '^' (as used to identify the begining of the line)
+-- also strips whitespace
+function split_c_tokens(s, pat)
+
+    s = string.gsub(s, "^%s*", "")
+    s = string.gsub(s, "%s*$", "")
+
+    local token_begin = 1
+    local token_end = 1
+    local ofs = 1
+    local ret = {n=0}
+
+    function add_token(ofs)
+
+        local t = string.sub(s, token_begin, ofs)
+        t = string.gsub(t, "^%s*", "")
+        t = string.gsub(t, "%s*$", "")
+        ret.n = ret.n + 1
+        ret[ret.n] = t
+    end
+
+    while ofs <= string.len(s) do
+
+        local sub = string.sub(s, ofs, -1)
+        local b,e = string.find(sub, "^"..pat)
+        if b then
+            add_token(ofs-1)
+            ofs = ofs+e
+            token_begin = ofs
+        else
+            local char = string.sub(s, ofs, ofs)
+            if char == "(" or char == "<" then
+
+                local block
+                if char == "(" then block = "^%b()" end
+                if char == "<" then block = "^%b<>" end
+
+                b,e = string.find(sub, block)
+                if not b then
+                    -- unterminated block?
+                    ofs = ofs+1
+                else
+                    ofs = ofs + e
+                end
+
+            else
+                ofs = ofs+1
+            end
+        end
+
+    end
+    add_token(ofs)
+    --if ret.n == 0 then
+
+    --    ret.n=1
+    --    ret[1] = ""
+    --end
+
+    return ret
+
+end
+
+-- concatenate strings of a table
+function concat (t,f,l,jstr)
+    jstr = jstr or " "
+    local s = ''
+    local i=f
+    while i<=l do
+        s = s..t[i]
+        i = i+1
+        if i <= l then s = s..jstr end
+    end
+    return s
+end
+
+-- concatenate all parameters, following output rules
+function concatparam (line, ...)
+    local i=1
+    while i<=arg.n do
+        if _cont and not strfind(_cont,'[%(,"]') and
+            strfind(arg[i],"^[%a_~]") then
+            line = line .. ' '
+        end
+        line = line .. arg[i]
+        if arg[i] ~= '' then
+            _cont = strsub(arg[i],-1,-1)
+        end
+        i = i+1
+    end
+    if strfind(arg[arg.n],"[%/%)%;%{%}]$") then
+        _cont=nil line = line .. '\n'
+    end
+    return line
+end
+
+-- output line
+function output (...)
+    local i=1
+    while i<=arg.n do
+        if _cont and not strfind(_cont,'[%(,"]') and
+            strfind(arg[i],"^[%a_~]") then
+            write(' ')
+        end
+        write(arg[i])
+        if arg[i] ~= '' then
+            _cont = strsub(arg[i],-1,-1)
+        end
+        i = i+1
+    end
+    if strfind(arg[arg.n],"[%/%)%;%{%}]$") then
+        _cont=nil write('\n')
+    end
+end
+
+function get_property_methods(ptype, name)
+
+    if get_property_methods_hook and get_property_methods_hook(ptype,name) then
+        return get_property_methods_hook(ptype, name)
+    end
+
+    if ptype == "default" then -- get_name, set_name
+        return "get_"..name, "set_"..name
+    end
+
+    if ptype == "qt" then -- name, setName
+        return name, "set"..string.upper(string.sub(name, 1, 1))..string.sub(name, 2, -1)
+    end
+
+    if ptype == "overload" then -- name, name
+        return name,name
+    end
+
+    return nil
+end
+
+-------------- the hooks
+
+-- called right after processing the $[ichl]file directives,
+-- right before processing anything else
+-- takes the package object as the parameter
+function preprocess_hook(p)
+    -- p.code has all the input code from the pkg
+end
+
+
+-- called for every $ifile directive
+-- takes a table with a string called 'code' inside, the filename, and any extra arguments
+-- passed to $ifile. no return value
+function include_file_hook(t, filename, ...)
+
+end
+
+-- called after processing anything that's not code (like '$renaming', comments, etc)
+-- and right before parsing the actual code.
+-- takes the Package object with all the code on the 'code' key. no return value
+function preparse_hook(package)
+
+end
+
+
+-- called after writing all the output.
+-- takes the Package object
+function post_output_hook(package)
+
+end
+
+
+-- called from 'get_property_methods' to get the methods to retrieve a property
+-- according to its type
+function get_property_methods_hook(property_type, name)
+
+end
+
+-- called from ClassContainer:doparse with the string being parsed
+-- return nil, or a substring
+function parser_hook(s)
+
+    return nil
+end
+
+
Index: /code/branches/rocket2/src/external/tolua/lua/class.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/class.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/class.lua	(revision 6952)
@@ -0,0 +1,220 @@
+-- tolua: class class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- $Id: $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+-- Class class
+-- Represents a class definition.
+-- Stores the following fields:
+--    name = class name
+--    base = class base, if any (only single inheritance is supported)
+--    {i}  = list of members
+classClass = {
+    classtype = 'class',
+    name = '',
+    base = '',
+    type = '',
+    btype = '',
+    ctype = '',
+}
+classClass.__index = classClass
+setmetatable(classClass,classContainer)
+
+
+-- register class
+function classClass:register (pre)
+    if not self:check_public_access() then
+        return
+    end
+
+    pre = pre or ''
+    push(self)
+    if _collect[self.type] then
+        output(pre,'#ifdef __cplusplus\n')
+        output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",'.._collect[self.type]..');')
+        output(pre,'#else\n')
+        output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",NULL);')
+        output(pre,'#endif\n')
+    else
+        output(pre..'tolua_cclass(tolua_S,"'..self.lname..'","'..self.type..'","'..self.btype..'",NULL);')
+    end
+    if self.extra_bases then
+        for k,base in ipairs(self.extra_bases) do
+            -- not now
+            --output(pre..' tolua_addbase(tolua_S, "'..self.type..'", "'..base..'");')
+        end
+    end
+    output(pre..'tolua_beginmodule(tolua_S,"'..self.lname..'");')
+    local i=1
+    while self[i] do
+        self[i]:register(pre..' ')
+        i = i+1
+    end
+    output(pre..'tolua_endmodule(tolua_S);')
+    pop()
+end
+
+-- return collection requirement
+function classClass:requirecollection (t)
+    if self.flags.protected_destructor then
+        return false
+    end
+    push(self)
+    local r = false
+    local i=1
+    while self[i] do
+        r = self[i]:requirecollection(t) or r
+        i = i+1
+    end
+    pop()
+    -- only class that exports destructor can be appropriately collected
+    -- classes that export constructors need to have a collector (overrided by -D flag on command line)
+    if self._delete or ((not flags['D']) and self._new) then
+        --t[self.type] = "tolua_collect_" .. gsub(self.type,"::","_")
+        t[self.type] = "tolua_collect_" .. clean_template(self.type)
+        r = true
+    end
+    return r
+end
+
+-- output tags
+function classClass:decltype ()
+    push(self)
+    self.type = regtype(self.original_name or self.name)
+    self.btype = typevar(self.base)
+    self.ctype = 'const '..self.type
+    if self.extra_bases then
+        for i=1,table.getn(self.extra_bases) do
+            self.extra_bases[i] = typevar(self.extra_bases[i])
+        end
+    end
+    local i=1
+    while self[i] do
+        self[i]:decltype()
+        i = i+1
+    end
+    pop()
+end
+
+
+-- Print method
+function classClass:print (ident,close)
+    print(ident.."Class{")
+    print(ident.." name = '"..self.name.."',")
+    print(ident.." base = '"..self.base.."';")
+    print(ident.." lname = '"..self.lname.."',")
+    print(ident.." type = '"..self.type.."',")
+    print(ident.." btype = '"..self.btype.."',")
+    print(ident.." ctype = '"..self.ctype.."',")
+    local i=1
+    while self[i] do
+        self[i]:print(ident.." ",",")
+        i = i+1
+    end
+    print(ident.."}"..close)
+end
+
+function classClass:set_protected_destructor(p)
+self.flags.protected_destructor = self.flags.protected_destructor or p
+end
+
+-- Internal constructor
+function _Class (t)
+    setmetatable(t,classClass)
+    t:buildnames()
+    append(t)
+    return t
+end
+
+-- Constructor
+-- Expects the name, the base (array) and the body of the class.
+function Class (n,p,b)
+
+    if table.getn(p) > 1 then
+        b = string.sub(b, 1, -2)
+        for i=2,table.getn(p),1 do
+            b = b.."\n tolua_inherits "..p[i].." __"..p[i].."__;\n"
+        end
+        b = b.."\n}"
+    end
+
+    -- check for template
+    b = string.gsub(b, "^{%s*TEMPLATE_BIND", "{\nTOLUA_TEMPLATE_BIND")
+    local t,_,T,I = string.find(b, "^{%s*TOLUA_TEMPLATE_BIND%s*%(+%s*\"?([^\",]*)\"?%s*,%s*([^%)]*)%s*%)+")
+    if t then
+
+        -- remove quotes
+        I = string.gsub(I, "\"", "")
+        T = string.gsub(T, "\"", "")
+        -- get type list
+        local types = split_c_tokens(I, ",")
+        -- remove TEMPLATE_BIND line
+        local bs = string.gsub(b, "^{%s*TOLUA_TEMPLATE_BIND[^\n]*\n", "{\n")
+
+        -- replace
+        for i =1 , types.n do
+
+            local Tl = split(T, " ")
+            local Il = split_c_tokens(types[i], " ")
+            local bI = bs
+            local pI = {}
+            for j = 1,Tl.n do
+                Tl[j] = findtype(Tl[j]) or Tl[j]
+                bI = string.gsub(bI, "([^_%w])"..Tl[j].."([^_%w])", "%1"..Il[j].."%2")
+                if p then
+                    for i=1,table.getn(p) do
+                        pI[i] = string.gsub(p[i], "([^_%w]?)"..Tl[j].."([^_%w]?)", "%1"..Il[j].."%2")
+                    end
+                end
+            end
+            --local append = "<"..string.gsub(types[i], "%s+", ",")..">"
+            local append = "<"..concat(Il, 1, table.getn(Il), ",")..">"
+            append = string.gsub(append, "%s*,%s*", ",")
+            append = string.gsub(append, ">>", "> >")
+            for i=1,table.getn(pI) do
+                --pI[i] = string.gsub(pI[i], ">>", "> >")
+                pI[i] = resolve_template_types(pI[i])
+            end
+            bI = string.gsub(bI, ">>", "> >")
+            Class(n..append, pI, bI)
+        end
+        return
+    end
+
+    local mbase
+
+    if p then
+        mbase = table.remove(p, 1)
+        if not p[1] then p = nil end
+    end
+
+    mbase = mbase and resolve_template_types(mbase)
+
+    local c
+    local oname = string.gsub(n, "@.*$", "")
+    oname = getnamespace(classContainer.curr)..oname
+
+    if _global_classes[oname] then
+        c = _global_classes[oname]
+        if mbase and ((not c.base) or c.base == "") then
+            c.base = mbase
+        end
+    else
+        c = _Class(_Container{name=n, base=mbase, extra_bases=p})
+
+        local ft = getnamespace(c.parent)..c.original_name
+        append_global_type(ft, c)
+    end
+
+    push(c)
+    c:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces
+    pop()
+end
+
Index: /code/branches/rocket2/src/external/tolua/lua/clean.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/clean.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/clean.lua	(revision 6952)
@@ -0,0 +1,79 @@
+-- mark up comments and strings
+STR1 = "\001"
+STR2 = "\002"
+STR3 = "\003"
+STR4 = "\004"
+REM  = "\005"
+ANY  = "([\001-\005])"
+ESC1 = "\006"
+ESC2 = "\007"
+
+MASK = { -- the substitution order is important
+    {ESC1, "\\'"},
+    {ESC2, '\\"'},
+    {STR1, "'"},
+    {STR2, '"'},
+    {STR3, "%[%["},
+    {STR4, "%]%]"},
+    {REM , "%-%-"},
+}
+
+function mask (s)
+    for i = 1,getn(MASK)  do
+        s = gsub(s,MASK[i][2],MASK[i][1])
+    end
+    return s
+end
+
+function unmask (s)
+    for i = 1,getn(MASK)  do
+        s = gsub(s,MASK[i][1],MASK[i][2])
+    end
+    return s
+end
+
+function clean (s)
+    -- check for compilation error
+    local code = "return function ()\n" .. s .. "\n end"
+    if not dostring(code) then
+        return nil
+    end
+
+    if flags['C'] then
+        return s
+    end
+
+    local S = "" -- saved string
+
+    s = mask(s)
+
+    -- remove blanks and comments
+    while 1 do
+        local b,e,d = strfind(s,ANY)
+        if b then
+            S = S..strsub(s,1,b-1)
+            s = strsub(s,b+1)
+            if d==STR1 or d==STR2 then
+                e = strfind(s,d)
+                S = S ..d..strsub(s,1,e)
+                s = strsub(s,e+1)
+            elseif d==STR3 then
+                e = strfind(s,STR4)
+                S = S..d..strsub(s,1,e)
+                s = strsub(s,e+1)
+            elseif d==REM then
+                s = gsub(s,"[^\n]*(\n?)","%1",1)
+            end
+        else
+            S = S..s
+            break
+        end
+    end
+    -- eliminate unecessary spaces
+    S = gsub(S,"[ \t]+"," ")
+    S = gsub(S,"[ \t]*\n[ \t]*","\n")
+    S = gsub(S,"\n+","\n")
+    S = unmask(S)
+    return S
+end
+
Index: /code/branches/rocket2/src/external/tolua/lua/code.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/code.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/code.lua	(revision 6952)
@@ -0,0 +1,100 @@
+-- tolua: code class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1999
+-- $Id: $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+-- global
+code_n = 1
+
+-- Code class
+-- Represents Lua code to be compiled and included
+-- in the initialization function.
+-- The following fields are stored:
+--   text = text code
+classCode = {
+    text = '',
+}
+classCode.__index = classCode
+setmetatable(classCode,classFeature)
+
+-- register code
+function classCode:register (pre)
+    pre = pre or ''
+    -- clean Lua code
+    local s = clean(self.text)
+    if not s then
+        --print(self.text)
+        error("parser error in embedded code")
+    end
+
+    -- get first line
+    local _, _, first_line=string.find(self.text, "^([^\n\r]*)")
+    if string.find(first_line, "^%s*%-%-") then
+        if string.find(first_line, "^%-%-##") then
+            first_line = string.gsub(first_line, "^%-%-##", "")
+            if flags['C'] then
+                s = string.gsub(s, "^%-%-##[^\n\r]*\n", "")
+            end
+        end
+    else
+        first_line = ""
+    end
+
+    -- convert to C
+    output('\n'..pre..'{ /* begin embedded lua code */\n')
+    output(pre..' int top = lua_gettop(tolua_S);')
+    output(pre..' static unsigned char B[] = {\n   ')
+    local t={n=0}
+    local b = gsub(s, '(.)',
+        function (c)
+            local e = ''
+            t.n=t.n+1
+            if t.n==15 then
+             t.n=0 e='\n'..pre..'  '
+            end
+            return format('%3u,%s',strbyte(c),e)
+        end
+    )
+    output(b..strbyte(" "))
+    output('\n'..pre..' };\n')
+    if first_line and first_line ~= "" then
+        output(pre..' tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua embedded: '..first_line..'");')
+    else
+        output(pre..' tolua_dobuffer(tolua_S,(char*)B,sizeof(B),"tolua: embedded Lua code '..code_n..'");')
+    end
+    output(pre..' lua_settop(tolua_S, top);')
+    output(pre..'} /* end of embedded lua code */\n\n')
+    code_n = code_n +1
+end
+
+
+-- Print method
+function classCode:print (ident,close)
+    print(ident.."Code{")
+    print(ident.." text = [["..self.text.."]],")
+    print(ident.."}"..close)
+end
+
+
+-- Internal constructor
+function _Code (t)
+    setmetatable(t,classCode)
+    append(t)
+    return t
+end
+
+-- Constructor
+-- Expects a string representing the code text
+function Code (l)
+    return _Code {
+        text = l
+    }
+end
+
+
Index: /code/branches/rocket2/src/external/tolua/lua/compat-5.1.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/compat-5.1.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/compat-5.1.lua	(revision 6952)
@@ -0,0 +1,52 @@
+if string.find(_VERSION, "5%.0") then
+    return
+end
+
+-- "loadfile"
+local function pp_dofile(path)
+    local loaded = false
+    local getfile = function()
+
+        if loaded then
+            return
+        else
+            local file,err = io.open(path)
+            if not file then
+                error("error loading file "..path..": "..err)
+            end
+            local ret = file:read("*a")
+            file:close()
+
+            ret = string.gsub(ret, "%.%.%.%s*%)", "...) local arg = {n=select('#', ...), ...};")
+
+            loaded = true
+            return ret
+        end
+    end
+
+    local f = load(getfile, path)
+    return f()
+end
+
+old_dofile = dofile
+dofile = pp_dofile
+
+
+-- string.gsub
+--[[
+local ogsub = string.gsub
+local function compgsub(a,b,c,d)
+    if type(c) == "function" then
+        local oc = c
+        c = function (...) return oc(...) or '' end
+    end
+    return ogsub(a,b,c,d)
+end
+string.repl = ogsub
+--]]
+
+--string.gsub = compgsub
+
+
+
+
Index: /code/branches/rocket2/src/external/tolua/lua/compat.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/compat.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/compat.lua	(revision 6952)
@@ -0,0 +1,193 @@
+-------------------------------------------------------------------
+-- Real globals
+-- _ALERT
+-- _ERRORMESSAGE
+-- _VERSION
+-- _G
+-- assert
+-- error
+-- metatable
+-- next
+-- print
+-- require
+-- tonumber
+-- tostring
+-- type
+-- unpack
+
+-------------------------------------------------------------------
+-- collectgarbage
+-- gcinfo
+
+-- globals
+
+-- call   -> protect(f, err)
+-- loadfile
+-- loadstring
+
+-- rawget
+-- rawset
+
+-- getargs = Main.getargs ??
+
+rawtype = type
+
+function do_ (f, err)
+    if not f then print(err); return end
+    local a,b = pcall(f)
+    if not a then print(b); return nil
+    else return b or true
+    end
+end
+
+function dostring(s) return do_(loadstring(s)) end
+-- function dofile(s) return do_(loadfile(s)) end
+
+-------------------------------------------------------------------
+-- Table library
+local tab = table
+foreach = tab.foreach
+foreachi = tab.foreachi
+getn = tab.getn
+tinsert = tab.insert
+tremove = tab.remove
+sort = tab.sort
+
+-------------------------------------------------------------------
+-- Debug library
+local dbg = debug
+getinfo = dbg.getinfo
+getlocal = dbg.getlocal
+setcallhook = function () error"`setcallhook' is deprecated" end
+setlinehook = function () error"`setlinehook' is deprecated" end
+setlocal = dbg.setlocal
+
+-------------------------------------------------------------------
+-- math library
+local math = math
+abs = math.abs
+acos = function (x) return math.deg(math.acos(x)) end
+asin = function (x) return math.deg(math.asin(x)) end
+atan = function (x) return math.deg(math.atan(x)) end
+atan2 = function (x,y) return math.deg(math.atan2(x,y)) end
+ceil = math.ceil
+cos = function (x) return math.cos(math.rad(x)) end
+deg = math.deg
+exp = math.exp
+floor = math.floor
+frexp = math.frexp
+ldexp = math.ldexp
+log = math.log
+log10 = math.log10
+max = math.max
+min = math.min
+mod = math.mod
+PI = math.pi
+--??? pow = math.pow  
+rad = math.rad
+random = math.random
+randomseed = math.randomseed
+sin = function (x) return math.sin(math.rad(x)) end
+sqrt = math.sqrt
+tan = function (x) return math.tan(math.rad(x)) end
+
+-------------------------------------------------------------------
+-- string library
+local str = string
+strbyte = str.byte
+strchar = str.char
+strfind = str.find
+format = str.format
+gsub = str.gsub
+strlen = str.len
+strlower = str.lower
+strrep = str.rep
+strsub = str.sub
+strupper = str.upper
+
+-------------------------------------------------------------------
+-- os library
+clock = os.clock
+date = os.date
+difftime = os.difftime
+execute = os.execute --?
+exit = os.exit
+getenv = os.getenv
+remove = os.remove
+rename = os.rename
+setlocale = os.setlocale
+time = os.time
+tmpname = os.tmpname
+
+-------------------------------------------------------------------
+-- compatibility only
+getglobal = function (n) return _G[n] end
+setglobal = function (n,v) _G[n] = v end
+
+-------------------------------------------------------------------
+
+local io, tab = io, table
+
+-- IO library (files)
+_STDIN = io.stdin
+_STDERR = io.stderr
+_STDOUT = io.stdout
+_INPUT = io.stdin
+_OUTPUT = io.stdout
+seek = io.stdin.seek   -- sick ;-)
+tmpfile = io.tmpfile
+closefile = io.close
+openfile = io.open
+
+function flush (f)
+    if f then f:flush()
+    else _OUTPUT:flush()
+    end
+end
+
+function readfrom (name)
+    if name == nil then
+        local f, err, cod = io.close(_INPUT)
+        _INPUT = io.stdin
+        return f, err, cod
+    else
+        local f, err, cod = io.open(name, "r")
+        _INPUT = f or _INPUT
+        return f, err, cod
+    end
+end
+
+function writeto (name)
+    if name == nil then
+        local f, err, cod = io.close(_OUTPUT)
+        _OUTPUT = io.stdout
+        return f, err, cod
+    else
+        local f, err, cod = io.open(name, "w")
+        _OUTPUT = f or _OUTPUT
+        return f, err, cod
+    end
+end
+
+function appendto (name)
+    local f, err, cod = io.open(name, "a")
+    _OUTPUT = f or _OUTPUT
+    return f, err, cod
+end
+
+function read (...)
+    local f = _INPUT
+    if rawtype(arg[1]) == 'userdata' then
+        f = tab.remove(arg, 1)
+    end
+    return f:read(unpack(arg))
+end
+
+function write (...)
+    local f = _OUTPUT
+    if rawtype(arg[1]) == 'userdata' then
+        f = tab.remove(arg, 1)
+    end
+    return f:write(unpack(arg))
+end
+
Index: /code/branches/rocket2/src/external/tolua/lua/container.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/container.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/container.lua	(revision 6952)
@@ -0,0 +1,770 @@
+-- tolua: container abstract class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- $Id: $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+-- table to store namespaced typedefs/enums in global scope
+global_typedefs = {}
+global_enums = {}
+
+-- Container class
+-- Represents a container of features to be bound
+-- to lua.
+classContainer =
+{
+    curr = nil,
+}
+classContainer.__index = classContainer
+setmetatable(classContainer,classFeature)
+
+-- output tags
+function classContainer:decltype ()
+    push(self)
+    local i=1
+    while self[i] do
+        self[i]:decltype()
+        i = i+1
+    end
+    pop()
+end
+
+
+-- write support code
+function classContainer:supcode ()
+
+    if not self:check_public_access() then
+        return
+    end
+
+    push(self)
+    local i=1
+    while self[i] do
+        if self[i]:check_public_access() then
+            self[i]:supcode()
+        end
+        i = i+1
+    end
+    pop()
+end
+
+function classContainer:hasvar ()
+    local i=1
+    while self[i] do
+        if self[i]:isvariable() then
+            return 1
+        end
+        i = i+1
+    end
+    return 0
+end
+
+-- Internal container constructor
+function _Container (self)
+    setmetatable(self,classContainer)
+    self.n = 0
+    self.typedefs = {tolua_n=0}
+    self.usertypes = {}
+    self.enums = {tolua_n=0}
+    self.lnames = {}
+    return self
+end
+
+-- push container
+function push (t)
+    t.prox = classContainer.curr
+    classContainer.curr = t
+end
+
+-- pop container
+function pop ()
+    --print("name",classContainer.curr.name)
+    --foreach(classContainer.curr.usertypes,print)
+    --print("______________")
+    classContainer.curr = classContainer.curr.prox
+end
+
+-- get current namespace
+function getcurrnamespace ()
+    return getnamespace(classContainer.curr)
+end
+
+-- append to current container
+function append (t)
+    return classContainer.curr:append(t)
+end
+
+-- append typedef to current container
+function appendtypedef (t)
+    return classContainer.curr:appendtypedef(t)
+end
+
+-- append usertype to current container
+function appendusertype (t)
+    return classContainer.curr:appendusertype(t)
+end
+
+-- append enum to current container
+function appendenum (t)
+    return classContainer.curr:appendenum(t)
+end
+
+-- substitute typedef
+function applytypedef (mod,type)
+    return classContainer.curr:applytypedef(mod,type)
+end
+
+-- check if is type
+function findtype (type)
+    local t = classContainer.curr:findtype(type)
+    return t
+end
+
+-- check if is typedef
+function istypedef (type)
+    return classContainer.curr:istypedef(type)
+end
+
+-- get fulltype (with namespace)
+function fulltype (t)
+    local curr =  classContainer.curr
+    while curr do
+        if curr then
+            if curr.typedefs and curr.typedefs[t] then
+                return curr.typedefs[t]
+            elseif curr.usertypes and curr.usertypes[t] then
+                return curr.usertypes[t]
+            end
+        end
+        curr = curr.prox
+    end
+    return t
+end
+
+-- checks if it requires collection
+function classContainer:requirecollection (t)
+    push(self)
+    local i=1
+    local r = false
+    while self[i] do
+        r = self[i]:requirecollection(t) or r
+        i = i+1
+    end
+    pop()
+    return r
+end
+
+
+-- get namesapce
+function getnamespace (curr)
+    local namespace = ''
+    while curr do
+        if curr and
+            ( curr.classtype == 'class' or curr.classtype == 'namespace')
+        then
+            namespace = (curr.original_name or curr.name) .. '::' .. namespace
+            --namespace = curr.name .. '::' .. namespace
+        end
+        curr = curr.prox
+    end
+    return namespace
+end
+
+-- get namespace (only namespace)
+function getonlynamespace ()
+    local curr = classContainer.curr
+    local namespace = ''
+    while curr do
+        if curr.classtype == 'class' then
+            return namespace
+        elseif curr.classtype == 'namespace' then
+            namespace = curr.name .. '::' .. namespace
+        end
+        curr = curr.prox
+    end
+    return namespace
+end
+
+-- check if is enum
+function isenum (type)
+    return classContainer.curr:isenum(type)
+end
+
+-- append feature to container
+function classContainer:append (t)
+    self.n = self.n + 1
+    self[self.n] = t
+    t.parent = self
+end
+
+-- append typedef
+function classContainer:appendtypedef (t)
+    local namespace = getnamespace(classContainer.curr)
+    self.typedefs.tolua_n = self.typedefs.tolua_n + 1
+    self.typedefs[self.typedefs.tolua_n] = t
+    self.typedefs[t.utype] = namespace .. t.utype
+    global_typedefs[namespace..t.utype] = t
+    t.ftype = findtype(t.type) or t.type
+    --print("appending typedef "..t.utype.." as "..namespace..t.utype.." with ftype "..t.ftype)
+    append_global_type(namespace..t.utype)
+    if t.ftype and isenum(t.ftype) then
+        global_enums[namespace..t.utype] = true
+    end
+end
+
+-- append usertype: return full type
+function classContainer:appendusertype (t)
+    local container
+    if t == (self.original_name or self.name) then
+        container = self.prox
+    else
+        container = self
+    end
+    local ft = getnamespace(container) .. t
+    container.usertypes[t] = ft
+    _usertype[ft] = ft
+    return ft
+end
+
+-- append enum
+function classContainer:appendenum (t)
+    local namespace = getnamespace(classContainer.curr)
+    self.enums.tolua_n = self.enums.tolua_n + 1
+    self.enums[self.enums.tolua_n] = t
+    global_enums[namespace..t.name] = t
+end
+
+-- determine lua function name overload
+function classContainer:overload (lname)
+    if not self.lnames[lname] then
+        self.lnames[lname] = 0
+    else
+        self.lnames[lname] = self.lnames[lname] + 1
+    end
+    return format("%02d",self.lnames[lname])
+end
+
+-- applies typedef: returns the 'the facto' modifier and type
+function classContainer:applytypedef (mod,type)
+    if global_typedefs[type] then
+        --print("found typedef "..global_typedefs[type].type)
+        local mod1, type1 = global_typedefs[type].mod, global_typedefs[type].ftype
+        local mod2, type2 = applytypedef(mod.." "..mod1, type1)
+        --return mod2 .. ' ' .. mod1, type2
+        return mod2, type2
+    end
+    do return mod,type end
+end
+
+-- check if it is a typedef
+function classContainer:istypedef (type)
+    local env = self
+    while env do
+        if env.typedefs then
+            local i=1
+            while env.typedefs[i] do
+                if env.typedefs[i].utype == type then
+                    return type
+                end
+                i = i+1
+            end
+        end
+        env = env.parent
+    end
+    return nil
+end
+
+function find_enum_var(var)
+
+    if tonumber(var) then return var end
+
+    local c = classContainer.curr
+    while c do
+        local ns = getnamespace(c)
+        for k,v in pairs(_global_enums) do
+            if match_type(var, v, ns) then
+                return v
+            end
+        end
+        if c.base and c.base ~= '' then
+            c = _global_classes[c:findtype(c.base)]
+        else
+            c = nil
+        end
+    end
+
+    return var
+end
+
+-- check if is a registered type: return full type or nil
+function classContainer:findtype (t)
+
+    t = string.gsub(t, "=.*", "")
+    if _basic[t] then
+     return t
+    end
+
+    local _,_,em = string.find(t, "([&%*])%s*$")
+    t = string.gsub(t, "%s*([&%*])%s*$", "")
+    p = self
+    while p and type(p)=='table' do
+        local st = getnamespace(p)
+
+        for i=_global_types.n,1,-1 do -- in reverse order
+
+            if match_type(t, _global_types[i], st) then
+                return _global_types[i]..(em or "")
+            end
+        end
+        if p.base and p.base ~= '' and p.base ~= t then
+            --print("type is "..t..", p is "..p.base.." self.type is "..self.type.." self.name is "..self.name)
+            p = _global_classes[p:findtype(p.base)]
+        else
+            p = nil
+        end
+    end
+
+    return nil
+end
+
+function append_global_type(t, class)
+    _global_types.n = _global_types.n +1
+    _global_types[_global_types.n] = t
+    _global_types_hash[t] = 1
+    if class then append_class_type(t, class) end
+end
+
+function append_class_type(t,class)
+    if _global_classes[t] then
+        class.flags = _global_classes[t].flags
+        class.lnames = _global_classes[t].lnames
+        if _global_classes[t].base and (_global_classes[t].base ~= '') then
+            class.base = _global_classes[t].base or class.base
+        end
+    end
+    _global_classes[t] = class
+    class.flags = class.flags or {}
+end
+
+function match_type(childtype, regtype, st)
+--print("findtype "..childtype..", "..regtype..", "..st)
+    local b,e = string.find(regtype, childtype, -string.len(childtype), true)
+    if b then
+
+        if e == string.len(regtype) and
+                (b == 1 or (string.sub(regtype, b-1, b-1) == ':' and
+                string.sub(regtype, 1, b-1) == string.sub(st, 1, b-1))) then
+            return true
+        end
+    end
+
+    return false
+end
+
+function findtype_on_childs(self, t)
+
+    local tchild
+    if self.classtype == 'class' or self.classtype == 'namespace' then
+        for k,v in ipairs(self) do
+            if v.classtype == 'class' or v.classtype == 'namespace' then
+                if v.typedefs and v.typedefs[t] then
+                 return v.typedefs[t]
+                elseif v.usertypes and v.usertypes[t] then
+                 return v.usertypes[t]
+                end
+                tchild = findtype_on_childs(v, t)
+                if tchild then return tchild end
+            end
+        end
+    end
+    return nil
+
+end
+
+function classContainer:isenum (type)
+    if global_enums[type] then
+        return type
+    else
+        return false
+    end
+
+    local basetype = gsub(type,"^.*::","")
+    local env = self
+    while env do
+        if env.enums then
+            local i=1
+            while env.enums[i] do
+                if env.enums[i].name == basetype then
+                    return true
+                end
+                i = i+1
+            end
+        end
+        env = env.parent
+    end
+    return false
+end
+
+methodisvirtual = false -- a global
+
+-- parse chunk
+function classContainer:doparse (s)
+    --print ("parse "..s)
+
+    -- try the parser hook
+    do
+        local sub = parser_hook(s)
+        if sub then
+            return sub
+        end
+    end
+
+    -- try the null statement
+    do
+        local b,e,code = string.find(s, "^%s*;")
+        if b then
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try empty verbatim line
+    do
+        local b,e,code = string.find(s, "^%s*$\n")
+        if b then
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try Lua code
+    do
+        local b,e,code = strfind(s,"^%s*(%b\1\2)")
+        if b then
+            Code(strsub(code,2,-2))
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try C code
+    do
+        local b,e,code = strfind(s,"^%s*(%b\3\4)")
+        if b then
+            code = '{'..strsub(code,2,-2)..'\n}\n'
+            Verbatim(code,'r')        -- verbatim code for 'r'egister fragment
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try C code for preamble section
+    do
+        local b,e,code = string.find(s, "^%s*(%b\5\6)")
+        if b then
+            code = string.sub(code, 2, -2).."\n"
+            Verbatim(code, '')
+            return string.sub(s, e+1)
+        end
+    end
+
+    -- try default_property directive
+    do
+        local b,e,ptype = strfind(s, "^%s*TOLUA_PROPERTY_TYPE%s*%(+%s*([^%)%s]*)%s*%)+%s*;?")
+        if b then
+            if not ptype or ptype == "" then
+                ptype = "default"
+            end
+            self:set_property_type(ptype)
+            return strsub(s, e+1)
+        end
+    end
+
+    -- try protected_destructor directive
+    do
+        local b,e = string.find(s, "^%s*TOLUA_PROTECTED_DESTRUCTOR%s*;?")
+        if b then
+            if self.set_protected_destructor then
+                self:set_protected_destructor(true)
+            end
+            return strsub(s, e+1)
+        end
+    end
+
+    -- try 'extern' keyword
+    do
+        local b,e = string.find(s, "^%s*extern%s+")
+        if b then
+            -- do nothing
+            return strsub(s, e+1)
+        end
+    end
+
+    -- try 'virtual' keyworkd
+    do
+        local b,e = string.find(s, "^%s*virtual%s+")
+        if b then
+            methodisvirtual = true
+            return strsub(s, e+1)
+        end
+    end
+
+    -- try labels (public, private, etc)
+    do
+        local b,e = string.find(s, "^%s*%w*%s*:[^:]")
+        if b then
+            return strsub(s, e) -- preserve the [^:]
+        end
+    end
+
+    -- try module
+    do
+        local b,e,name,body = strfind(s,"^%s*module%s%s*([_%w][_%w]*)%s*(%b{})%s*")
+        if b then
+            _curr_code = strsub(s,b,e)
+            Module(name,body)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try namesapce
+    do
+        local b,e,name,body = strfind(s,"^%s*namespace%s%s*([_%w][_%w]*)%s*(%b{})%s*;?")
+        if b then
+            _curr_code = strsub(s,b,e)
+            Namespace(name,body)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try define
+    do
+        local b,e,name = strfind(s,"^%s*#define%s%s*([^%s]*)[^\n]*\n%s*")
+        if b then
+            _curr_code = strsub(s,b,e)
+            Define(name)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try enumerates
+
+    do
+        local b,e,name,body,varname = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*([^%s;]*)%s*;?%s*")
+        if b then
+            --error("#Sorry, declaration of enums and variables on the same statement is not supported.\nDeclare your variable separately (example: '"..name.." "..varname..";')")
+            _curr_code = strsub(s,b,e)
+            Enumerate(name,body,varname)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- do
+    --    local b,e,name,body = strfind(s,"^%s*enum%s+(%S*)%s*(%b{})%s*;?%s*")
+    --    if b then
+    --        _curr_code = strsub(s,b,e)
+    --        Enumerate(name,body)
+    --        return strsub(s,e+1)
+    --    end
+    -- end
+
+    do
+        local b,e,body,name = strfind(s,"^%s*typedef%s+enum[^{]*(%b{})%s*([%w_][^%s]*)%s*;%s*")
+        if b then
+        _curr_code = strsub(s,b,e)
+        Enumerate(name,body)
+        return strsub(s,e+1)
+        end
+    end
+
+    -- try operator
+    do
+        local b,e,decl,kind,arg,const = strfind(s,"^%s*([_%w][_%w%s%*&:<>,]-%s+operator)%s*([^%s][^%s]*)%s*(%b())%s*(c?o?n?s?t?)%s*;%s*")
+        if not b then
+            -- try inline
+            b,e,decl,kind,arg,const = strfind(s,"^%s*([_%w][_%w%s%*&:<>,]-%s+operator)%s*([^%s][^%s]*)%s*(%b())%s*(c?o?n?s?t?)[%s\n]*%b{}%s*;?%s*")
+        end
+        if not b then
+            -- try cast operator
+            b,e,decl,kind,arg,const = strfind(s, "^%s*(operator)%s+([%w_:%d<>%*%&%s]+)%s*(%b())%s*(c?o?n?s?t?)");
+            if b then
+                local _,ie = string.find(s, "^%s*%b{}", e+1)
+                if ie then
+                    e = ie
+                end
+            end
+        end
+        if b then
+            _curr_code = strsub(s,b,e)
+            Operator(decl,kind,arg,const)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try function
+    do
+        --local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w])%s*(%b())%s*(c?o?n?s?t?)%s*=?%s*0?%s*;%s*")
+        local b,e,decl,arg,const,virt = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)%s*(=?%s*0?)%s*;%s*")
+        if not b then
+            -- try function with template
+            b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w]%b<>)%s*(%b())%s*(c?o?n?s?t?)%s*=?%s*0?%s*;%s*")
+        end
+        if not b then
+            -- try a single letter function name
+            b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?)%s*;%s*")
+        end
+        if b then
+            if virt and string.find(virt, "[=0]") then
+                if self.flags then
+                    self.flags.pure_virtual = true
+                end
+            end
+            _curr_code = strsub(s,b,e)
+            Function(decl,arg,const)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try inline function
+    do
+        local b,e,decl,arg,const = strfind(s,"^%s*([^%(\n]+)%s*(%b())%s*(c?o?n?s?t?)[^;{]*%b{}%s*;?%s*")
+        --local b,e,decl,arg,const = strfind(s,"^%s*([~_%w][_@%w%s%*&:<>]*[_%w>])%s*(%b())%s*(c?o?n?s?t?)[^;]*%b{}%s*;?%s*")
+        if not b then
+            -- try a single letter function name
+            b,e,decl,arg,const = strfind(s,"^%s*([_%w])%s*(%b())%s*(c?o?n?s?t?).-%b{}%s*;?%s*")
+        end
+        if b then
+            _curr_code = strsub(s,b,e)
+            Function(decl,arg,const)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try class
+    do
+        local b,e,name,base,body
+        base = '' body = ''
+        b,e,name = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*;")  -- dummy class
+        if not b then
+            b,e,name = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*;")    -- dummy struct
+            if not b then
+                b,e,name,base,body = strfind(s,"^%s*class%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
+                if not b then
+                    b,e,name,base,body = strfind(s,"^%s*struct%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
+                    if not b then
+                        b,e,name,base,body = strfind(s,"^%s*union%s*([_%w][_%w@]*)%s*(.-)%s*(%b{})%s*;%s*")
+                        if not b then
+                            base = ''
+                            b,e,body,name = strfind(s,"^%s*typedef%s%s*struct%s%s*[_%w]*%s*(%b{})%s*([_%w][_%w@]*)%s*;%s*")
+                        end
+                    end
+                end
+            end
+        end
+        if b then
+            if base ~= '' then
+                base = string.gsub(base, "^%s*:%s*", "")
+                base = string.gsub(base, "%s*public%s*", "")
+                base = split(base, ",")
+                --local b,e
+                --b,e,base = strfind(base,".-([_%w][_%w<>,:]*)$")
+            else
+                base = {}
+            end
+            _curr_code = strsub(s,b,e)
+            Class(name,base,body)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try typedef
+    do
+        local b,e,types = strfind(s,"^%s*typedef%s%s*(.-)%s*;%s*")
+        if b then
+            _curr_code = strsub(s,b,e)
+            Typedef(types)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try variable
+    do
+        local b,e,decl = strfind(s,"^%s*([_%w][_@%s%w%d%*&:<>,]*[_%w%d])%s*;%s*")
+        if b then
+            _curr_code = strsub(s,b,e)
+
+            local list = split_c_tokens(decl, ",")
+            Variable(list[1])
+            if list.n > 1 then
+                local _,_,type = strfind(list[1], "(.-)%s+([^%s]*)$");
+
+                local i =2;
+                while list[i] do
+                    Variable(type.." "..list[i])
+                    i=i+1
+                end
+            end
+            --Variable(decl)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try string
+    do
+        local b,e,decl = strfind(s,"^%s*([_%w]?[_%s%w%d]-char%s+[_@%w%d]*%s*%[%s*%S+%s*%])%s*;%s*")
+        if b then
+            _curr_code = strsub(s,b,e)
+            Variable(decl)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- try array
+    do
+        local b,e,decl = strfind(s,"^%s*([_%w][][_@%s%w%d%*&:]*[]_%w%d])%s*;%s*")
+        if b then
+            _curr_code = strsub(s,b,e)
+            Array(decl)
+            return strsub(s,e+1)
+        end
+    end
+
+    -- no matching
+    if gsub(s,"%s%s*","") ~= "" then
+        _curr_code = s
+        error("#parse error")
+    else
+        return ""
+    end
+
+end
+
+function classContainer:parse (s)
+
+    self.curr_member_access = nil
+
+    while s ~= '' do
+        s = self:doparse(s)
+        methodisvirtual = false
+    end
+end
+
+
+-- property types
+
+function get_property_type()
+
+    return classContainer.curr:get_property_type()
+end
+
+function classContainer:set_property_type(ptype)
+    ptype = string.gsub(ptype, "^%s*", "")
+    ptype = string.gsub(ptype, "%s*$", "")
+
+    self.property_type = ptype
+end
+
+function classContainer:get_property_type()
+    return self.property_type or (self.parent and self.parent:get_property_type()) or "default"
+end
Index: /code/branches/rocket2/src/external/tolua/lua/custom.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/custom.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/custom.lua	(revision 6952)
@@ -0,0 +1,45 @@
+
+function extract_code(fn,s)
+    local code = ""
+    if fn then
+        code = '\n$#include "'..fn..'"\n'
+    end
+    s= "\n" .. s .. "\n" -- add blank lines as sentinels
+    local _,e,c,t = strfind(s, "\n([^\n]-)SCRIPT_([%w_]*)[^\n]*\n")
+    while e do
+        t = strlower(t)
+        if t == "bind_begin" then
+            _,e,c = strfind(s,"(.-)\n[^\n]*SCRIPT_BIND_END[^\n]*\n",e)
+            if not e then
+             tolua_error("Unbalanced 'SCRIPT_BIND_BEGIN' directive in header file")
+            end
+        end
+        if t == "bind_class" or t == "bind_block" then
+            local b
+            _,e,c,b = string.find(s, "([^{]-)(%b{})", e)
+            c = c..'{\n'..extract_code(nil, b)..'\n};\n'
+        end
+        code = code .. c .. "\n"
+     _,e,c,t = strfind(s, "\n([^\n]-)SCRIPT_([%w_]*)[^\n]*\n",e)
+    end
+    return code
+end
+
+function preprocess_hook(p)
+end
+
+function preparse_hook(p)
+end
+
+function include_file_hook(p, filename)
+    do return end
+--print("FILENAME is "..filename)
+    p.code = string.gsub(p.code, "\n%s*SigC::Signal", "\n\ttolua_readonly SigC::Signal")
+    p.code = string.gsub(p.code, "#ifdef __cplusplus\nextern \"C\" {\n#endif", "")
+    p.code = string.gsub(p.code, "#ifdef __cplusplus\n};?\n#endif", "")
+    p.code = string.gsub(p.code, "DECLSPEC", "")
+    p.code = string.gsub(p.code, "SDLCALL", "")
+    p.code = string.gsub(p.code, "DLLINTERFACE", "")
+    p.code = string.gsub(p.code, "#define[^\n]*_[hH]_?%s*\n", "\n")
+--print("code is "..p.code)
+end
Index: /code/branches/rocket2/src/external/tolua/lua/custom_hide.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/custom_hide.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/custom_hide.lua	(revision 6952)
@@ -0,0 +1,21 @@
+-- extract code with tolua_hide, and also
+function extract_code(fn,s)
+    local code = '\n$#include "'..fn..'"\n'
+    s= "\n" .. s .. "\n" -- add blank lines as sentinels
+    local _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n")
+    while e do
+        t = strlower(t)
+        if t == "begin" then
+            _,e,c = strfind(s,"(.-)\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Ee][Nn][Dd][^\n]*\n",e)
+            if not e then
+             tolua_error("Unbalanced 'tolua_begin' directive in header file")
+            end
+        end
+        c = c.."\n"
+        c = string.gsub(c, "\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[hH][iI][Dd][eE][^\n]*\n", "\n");
+        c = string.gsub(c, "#define[^%(\n]*%(.-\n", "\n")
+        code = code .. c
+     _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n",e)
+    end
+    return code
+end
Index: /code/branches/rocket2/src/external/tolua/lua/declaration.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/declaration.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/declaration.lua	(revision 6952)
@@ -0,0 +1,567 @@
+-- tolua: declaration class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- $Id: $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+-- Declaration class
+-- Represents variable, function, or argument declaration.
+-- Stores the following fields:
+--  mod  = type modifiers
+--  type = type
+--  ptr  = "*" or "&", if representing a pointer or a reference
+--  name = name
+--  dim  = dimension, if a vector
+--  def  = default value, if any (only for arguments)
+--  ret  = "*" or "&", if value is to be returned (only for arguments)
+classDeclaration = {
+    mod = '',
+    type = '',
+    ptr = '',
+    name = '',
+    dim = '',
+    ret = '',
+    def = ''
+}
+classDeclaration.__index = classDeclaration
+setmetatable(classDeclaration,classFeature)
+
+-- Create an unique variable name
+function create_varname ()
+    if not _varnumber then _varnumber = 0 end
+    _varnumber = _varnumber + 1
+    return "tolua_var_".._varnumber
+end
+
+-- Check declaration name
+-- It also identifies default values
+function classDeclaration:checkname ()
+
+    if strsub(self.name,1,1) == '[' and not findtype(self.type) then
+        self.name = self.type..self.name
+        local m = split(self.mod,'%s%s*')
+        self.type = m[m.n]
+        self.mod = concat(m,1,m.n-1)
+    end
+
+    local t = split(self.name,'=')
+    if t.n==2 then
+        self.name = t[1]
+        self.def = find_enum_var(t[t.n])
+    end
+
+    local b,e,d = strfind(self.name,"%[(.-)%]")
+    if b then
+        self.name = strsub(self.name,1,b-1)
+        self.dim = find_enum_var(d)
+    end
+
+
+    if self.type ~= '' and self.type ~= 'void' and self.name == '' then
+        self.name = create_varname()
+    elseif self.kind=='var' then
+        if self.type=='' and self.name~='' then
+            self.type = self.type..self.name
+            self.name = create_varname()
+        elseif findtype(self.name) then
+            if self.type=='' then self.type = self.name
+            else self.type = self.type..' '..self.name end
+            self.name = create_varname()
+        end
+    end
+
+    -- adjust type of string
+    if self.type == 'char' and self.dim ~= '' then
+        self.type = 'char*'
+    end
+
+    if self.kind and self.kind == 'var' then
+        self.name = string.gsub(self.name, ":.*$", "") -- ???
+    end
+end
+
+-- Check declaration type
+-- Substitutes typedef's.
+function classDeclaration:checktype ()
+
+    -- check if there is a pointer to basic type
+    local basic = isbasic(self.type)
+    if self.kind == 'func' and basic=='number' and string.find(self.ptr, "%*") then
+        self.type = '_userdata'
+        self.ptr = ""
+    end
+    if basic and self.ptr~='' then
+        self.ret = self.ptr
+        self.ptr = nil
+        if isbasic(self.type) == 'number' then
+            self.return_userdata = true
+        end
+    end
+
+    -- check if there is array to be returned
+    if self.dim~='' and self.ret~='' then
+        error('#invalid parameter: cannot return an array of values')
+    end
+    -- restore 'void*' and 'string*'
+    if self.type == '_userdata' then self.type = 'void*'
+    elseif self.type == '_cstring' then self.type = 'char*'
+    elseif self.type == '_lstate' then self.type = 'lua_State*'
+    end
+
+    -- resolve types inside the templates
+    if self.type then
+        self.type = resolve_template_types(self.type)
+    end
+
+    --
+    -- -- if returning value, automatically set default value
+    -- if self.ret ~= '' and self.def == '' then
+    --  self.def = '0'
+    -- end
+    --
+
+end
+
+function resolve_template_types(type)
+
+    if isbasic(type) then
+        return type
+    end
+    local b,_,m = string.find(type, "(%b<>)")
+    if b then
+
+        m = split_c_tokens(string.sub(m, 2, -2), ",")
+        for i=1, table.getn(m) do
+            m[i] = string.gsub(m[i],"%s*([%*&])", "%1")
+            m[i] = findtype(m[i]) or m[i]
+            m[i] = resolve_template_types(m[i])
+        end
+
+        local b,i
+        type,b,i = break_template(type)
+        local template_part = "<"..string.gsub(concat(m, 1, m.n), " ", ",")..">"
+        type = rebuild_template(type, b, template_part)
+        type = string.gsub(type, ">>", "> >")
+    end
+    return type
+end
+
+function break_template(s)
+    local b,e,timpl = string.find(s, "(%b<>)")
+    if timpl then
+        s = string.gsub(s, "%b<>", "")
+        return s, b, timpl
+    else
+        return s, 0, nil
+    end
+end
+
+function rebuild_template(s, b, timpl)
+
+    if b == 0 then
+        return s
+    end
+
+    return string.sub(s, 1, b-1)..timpl..string.sub(s, b, -1)
+end
+
+-- Print method
+function classDeclaration:print (ident,close)
+    print(ident.."Declaration{")
+    print(ident.." mod  = '"..self.mod.."',")
+    print(ident.." type = '"..self.type.."',")
+    print(ident.." ptr  = '"..self.ptr.."',")
+    print(ident.." name = '"..self.name.."',")
+    print(ident.." dim  = '"..self.dim.."',")
+    print(ident.." def  = '"..self.def.."',")
+    print(ident.." ret  = '"..self.ret.."',")
+    print(ident.."}"..close)
+end
+
+-- check if array of values are returned to Lua
+function classDeclaration:requirecollection (t)
+ if self.mod ~= 'const' and
+        self.dim and self.dim ~= '' and
+                 not isbasic(self.type) and
+                 self.ptr == '' then
+        local type = gsub(self.type,"%s*const%s+","")
+        t[type] = "tolua_collect_" .. clean_template(type)
+        return true
+    end
+    return false
+end
+
+-- declare tag
+function classDeclaration:decltype ()
+
+    self.type = typevar(self.type)
+    if strfind(self.mod,'const') then
+        self.type = 'const '..self.type
+        self.mod = gsub(self.mod,'const%s*','')
+    end
+end
+
+
+-- output type checking
+function classDeclaration:outchecktype (narg)
+    local def
+    local t = isbasic(self.type)
+    if self.def~='' then
+        def = 1
+    else
+        def = 0
+    end
+    if self.dim ~= '' then
+        --if t=='string' then
+        --    return 'tolua_isstringarray(tolua_S,'..narg..','..def..',&tolua_err)'
+        --else
+        return 'tolua_istable(tolua_S,'..narg..',0,&tolua_err)'
+        --end
+    elseif t then
+        return 'tolua_is'..t..'(tolua_S,'..narg..','..def..',&tolua_err)'
+    else
+        return 'tolua_isusertype(tolua_S,'..narg..',"'..self.type..'",'..def..',&tolua_err)'
+    end
+end
+
+function classDeclaration:builddeclaration (narg, cplusplus)
+    local array = self.dim ~= '' and tonumber(self.dim)==nil
+    local line = ""
+    local ptr = ''
+    local mod
+    local type = self.type
+    if self.dim ~= '' then
+        type = gsub(self.type,'const%s+','')  -- eliminates const modifier for arrays
+    end
+    if self.ptr~='' and not isbasic(type) then ptr = '*' end
+    line = concatparam(line," ",self.mod,type,ptr)
+    if array then
+        line = concatparam(line,'*')
+    end
+    line = concatparam(line,self.name)
+    if self.dim ~= '' then
+        if tonumber(self.dim)~=nil then
+            line = concatparam(line,'[',self.dim,'];')
+        else
+            if cplusplus then
+                line = concatparam(line,' = new',type,ptr,'['..self.dim..'];')
+            else
+                line = concatparam(line,' = (',type,ptr,'*)',
+                'malloc((',self.dim,')*sizeof(',type,ptr,'));')
+            end
+        end
+    else
+    local t = isbasic(type)
+    line = concatparam(line,' = ')
+    if t == 'state' then
+        line = concatparam(line, 'tolua_S;')
+    else
+        --print("t is "..tostring(t)..", ptr is "..tostring(self.ptr))
+        if t == 'number' and string.find(self.ptr, "%*") then
+            t = 'userdata'
+        end
+        if not t and ptr=='' then line = concatparam(line,'*') end
+            line = concatparam(line,'((',self.mod,type)
+            if not t then
+                line = concatparam(line,'*')
+            end
+            line = concatparam(line,') ')
+            if isenum(type) then
+                line = concatparam(line,'(int) ')
+            end
+            local def = 0
+            if self.def ~= '' then
+                def = self.def
+                if (ptr == '' or self.ptr == '&') and not t then
+                    def = "(void*)&(const "..type..")"..def
+                end
+            end
+            if t then
+                line = concatparam(line,'tolua_to'..t,'(tolua_S,',narg,',',def,'));')
+            else
+                line = concatparam(line,'tolua_tousertype(tolua_S,',narg,',',def,'));')
+            end
+        end
+    end
+    return line
+end
+
+-- Declare variable
+function classDeclaration:declare (narg)
+    if self.dim ~= '' and tonumber(self.dim)==nil then
+        output('#ifdef __cplusplus\n')
+        output(self:builddeclaration(narg,true))
+        output('#else\n')
+        output(self:builddeclaration(narg,false))
+        output('#endif\n')
+    else
+        output(self:builddeclaration(narg,false))
+    end
+end
+
+-- Get parameter value
+function classDeclaration:getarray (narg)
+    if self.dim ~= '' then
+        local type = gsub(self.type,'const ','')
+        output('  {')
+        output('#ifndef TOLUA_RELEASE\n')
+        local def; if self.def~='' then def=1 else def=0 end
+        local t = isbasic(type)
+        if (t) then
+            output('   if (!tolua_is'..t..'array(tolua_S,',narg,',',self.dim,',',def,',&tolua_err))')
+        else
+            output('   if (!tolua_isusertypearray(tolua_S,',narg,',"',type,'",',self.dim,',',def,',&tolua_err))')
+        end
+        output('    goto tolua_lerror;')
+        output('   else\n')
+        output('#endif\n')
+        output('   {')
+        output('    int i;')
+        output('    for(i=0; i<'..self.dim..';i++)')
+        local t = isbasic(type)
+        local ptr = ''
+        if self.ptr~='' then ptr = '*' end
+        output('   ',self.name..'[i] = ')
+        if not t and ptr=='' then output('*') end
+        output('((',type)
+        if not t then
+            output('*')
+        end
+        output(') ')
+        local def = 0
+        if self.def ~= '' then def = self.def end
+        if t then
+            output('tolua_tofield'..t..'(tolua_S,',narg,',i+1,',def,'));')
+        else
+            output('tolua_tofieldusertype(tolua_S,',narg,',i+1,',def,'));')
+        end
+        output('   }')
+        output('  }')
+    end
+end
+
+-- Get parameter value
+function classDeclaration:setarray (narg)
+    if not strfind(self.type,'const%s+') and self.dim ~= '' then
+        local type = gsub(self.type,'const ','')
+        output('  {')
+        output('   int i;')
+        output('   for(i=0; i<'..self.dim..';i++)')
+        local t,ct = isbasic(type)
+        if t then
+            output('    tolua_pushfield'..t..'(tolua_S,',narg,',i+1,(',ct,')',self.name,'[i]);')
+        else
+            if self.ptr == '' then
+                output('   {')
+                output('#ifdef __cplusplus\n')
+                output('    void* tolua_obj = new',type,'(',self.name,'[i]);')
+                output('    tolua_pushfieldusertype_and_takeownership(tolua_S,',narg,',i+1,tolua_obj,"',type,'");')
+                output('#else\n')
+                output('    void* tolua_obj = tolua_copy(tolua_S,(void*)&',self.name,'[i],sizeof(',type,'));')
+                output('    tolua_pushfieldusertype(tolua_S,',narg,',i+1,tolua_obj,"',type,'");')
+                output('#endif\n')
+                output('   }')
+            else
+                output('   tolua_pushfieldusertype(tolua_S,',narg,',i+1,(void*)',self.name,'[i],"',type,'");')
+            end
+        end
+        output('  }')
+    end
+end
+
+-- Free dynamically allocated array
+function classDeclaration:freearray ()
+    if self.dim ~= '' and tonumber(self.dim)==nil then
+        output('#ifdef __cplusplus\n')
+        output('  delete []',self.name,';')
+        output('#else\n')
+        output('  free(',self.name,');')
+        output('#endif\n')
+    end
+end
+
+-- Pass parameter
+function classDeclaration:passpar ()
+    if self.ptr=='&' and not isbasic(self.type) then
+        output('*'..self.name)
+    elseif self.ret=='*' then
+        output('&'..self.name)
+    else
+        output(self.name)
+    end
+end
+
+-- Return parameter value
+function classDeclaration:retvalue ()
+    if self.ret ~= '' then
+        local t,ct = isbasic(self.type)
+        if t and t~='' then
+            output('   tolua_push'..t..'(tolua_S,(',ct,')'..self.name..');')
+        else
+            output('   tolua_pushusertype(tolua_S,(void*)'..self.name..',"',self.type,'");')
+        end
+        return 1
+    end
+    return 0
+end
+
+-- Internal constructor
+function _Declaration (t)
+
+    setmetatable(t,classDeclaration)
+    t:buildnames()
+    t:checkname()
+    t:checktype()
+    local ft = findtype(t.type) or t.type
+    if not isenum(ft) then
+        t.mod, t.type = applytypedef(t.mod, ft)
+    end
+
+    if t.kind=="var" and (string.find(t.mod, "tolua_property%s") or string.find(t.mod, "tolua_property$")) then
+        t.mod = string.gsub(t.mod, "tolua_property", "tolua_property__"..get_property_type())
+    end
+
+    return t
+end
+
+-- Constructor
+-- Expects the string declaration.
+-- The kind of declaration can be "var" or "func".
+function Declaration (s,kind,is_parameter)
+
+    -- eliminate spaces if default value is provided
+    s = gsub(s,"%s*=%s*","=")
+    s = gsub(s, "%s*<", "<")
+
+    local defb,tmpdef
+    defb,_,tmpdef = string.find(s, "(=.*)$")
+    if defb then
+        s = string.gsub(s, "=.*$", "")
+    else
+        tmpdef = ''
+    end
+    if kind == "var" then
+        -- check the form: void
+        if s == '' or s == 'void' then
+            return _Declaration{type = 'void', kind = kind, is_parameter = is_parameter}
+        end
+    end
+
+    -- check the form: mod type*& name
+    local t = split_c_tokens(s,'%*%s*&')
+    if t.n == 2 then
+        if kind == 'func' then
+            error("#invalid function return type: "..s)
+        end
+        --local m = split(t[1],'%s%s*')
+        local m = split_c_tokens(t[1],'%s+')
+        return _Declaration {
+            name = t[2]..tmpdef,
+            ptr = '*',
+            ret = '&',
+            --type = rebuild_template(m[m.n], tb, timpl),
+            type = m[m.n],
+            mod = concat(m,1,m.n-1),
+            is_parameter = is_parameter,
+            kind = kind
+        }
+    end
+
+    -- check the form: mod type** name
+    t = split_c_tokens(s,'%*%s*%*')
+    if t.n == 2 then
+        if kind == 'func' then
+            error("#invalid function return type: "..s)
+        end
+        --local m = split(t[1],'%s%s*')
+        local m = split_c_tokens(t[1],'%s+')
+        return _Declaration {
+            name = t[2]..tmpdef,
+            ptr = '*',
+            ret = '*',
+            --type = rebuild_template(m[m.n], tb, timpl),
+            type = m[m.n],
+            mod = concat(m,1,m.n-1),
+            is_parameter = is_parameter,
+            kind = kind
+        }
+    end
+
+    -- check the form: mod type& name
+    t = split_c_tokens(s,'&')
+    if t.n == 2 then
+        --local m = split(t[1],'%s%s*')
+        local m = split_c_tokens(t[1],'%s+')
+        return _Declaration {
+            name = t[2]..tmpdef,
+            ptr = '&',
+            --type = rebuild_template(m[m.n], tb, timpl),
+            type = m[m.n],
+            mod = concat(m,1,m.n-1),
+            is_parameter = is_parameter,
+            kind = kind
+        }
+    end
+
+    -- check the form: mod type* name
+    local s1 = gsub(s,"(%b\[\])",function (n) return gsub(n,'%*','\1') end)
+    t = split_c_tokens(s1,'%*')
+    if t.n == 2 then
+        t[2] = gsub(t[2],'\1','%*') -- restore * in dimension expression
+        --local m = split(t[1],'%s%s*')
+        local m = split_c_tokens(t[1],'%s+')
+        return _Declaration {
+            name = t[2]..tmpdef,
+            ptr = '*',
+            type = m[m.n],
+            --type = rebuild_template(m[m.n], tb, timpl),
+            mod = concat(m,1,m.n-1)   ,
+            is_parameter = is_parameter,
+            kind = kind
+        }
+    end
+
+    if kind == 'var' then
+        -- check the form: mod type name
+        --t = split(s,'%s%s*')
+        t = split_c_tokens(s,'%s+')
+        local v
+        if findtype(t[t.n]) then v = create_varname() else v = t[t.n]; t.n = t.n-1 end
+        return _Declaration {
+            name = v..tmpdef,
+            --type = rebuild_template(t[t.n], tb, timpl),
+            type = t[t.n],
+            mod = concat(t,1,t.n-1),
+            is_parameter = is_parameter,
+            kind = kind
+        }
+
+    else -- kind == "func"
+
+        -- check the form: mod type name
+        --t = split(s,'%s%s*')
+        t = split_c_tokens(s,'%s+')
+        local v = t[t.n]  -- last word is the function name
+        local tp,md
+        if t.n>1 then
+            tp = t[t.n-1]
+            md = concat(t,1,t.n-2)
+        end
+        --if tp then tp = rebuild_template(tp, tb, timpl) end
+        return _Declaration {
+            name = v,
+            type = tp,
+            mod = md,
+            is_parameter = is_parameter,
+            kind = kind
+        }
+    end
+
+end
+
Index: /code/branches/rocket2/src/external/tolua/lua/define.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/define.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/define.lua	(revision 6952)
@@ -0,0 +1,63 @@
+-- tolua: define class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- $Id: define.lua,v 1.2 1999/07/28 22:21:08 celes Exp $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+-- Define class
+-- Represents a numeric const definition
+-- The following filds are stored:
+--   name = constant name
+classDefine = {
+    name = '',
+}
+classDefine.__index = classDefine
+setmetatable(classDefine,classFeature)
+
+-- register define
+function classDefine:register (pre)
+    if not self:check_public_access() then
+        return
+    end
+
+    pre = pre or ''
+    output(pre..'tolua_constant(tolua_S,"'..self.lname..'",'..self.name..');')
+end
+
+-- Print method
+function classDefine:print (ident,close)
+    print(ident.."Define{")
+    print(ident.." name = '"..self.name.."',")
+    print(ident.." lname = '"..self.lname.."',")
+    print(ident.."}"..close)
+end
+
+
+-- Internal constructor
+function _Define (t)
+    setmetatable(t,classDefine)
+    t:buildnames()
+
+    if t.name == '' then
+        error("#invalid define")
+    end
+
+    append(t)
+    return t
+end
+
+-- Constructor
+-- Expects a string representing the constant name
+function Define (n)
+    return _Define {
+        name = n
+    }
+end
+
+
Index: /code/branches/rocket2/src/external/tolua/lua/doit.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/doit.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/doit.lua	(revision 6952)
@@ -0,0 +1,126 @@
+-- Generate binding code
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- Last update: Apr 2003
+-- $Id: $
+
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+function parse_extra()
+
+    for k,v in ipairs(_extra_parameters or {}) do
+        
+        local b,e,name,value = string.find(v, "^([^=])=(.*)$")
+        if b then
+            _extra_parameters[name] = value
+        else
+            _extra_parameters[v] = true
+        end
+    end
+end
+
+function doit ()
+    -- define package name, if not provided
+    if not flags.n then
+        if flags.f then
+            flags.n = gsub(flags.f,"%..*$","")
+            _,_,flags.n = string.find(flags.n, "([^/\\]*)$")
+        else
+            error("#no package name nor input file provided")
+        end
+    end
+
+    -- parse table with extra paramters
+    parse_extra()
+
+    -- get potential working directory
+    if not flags.w then
+        flags.w = ''
+    end
+
+    -- do this after setting the package name
+    if flags.L then
+        if string.sub(flags.L, 1, 1) == '/' or string.sub(flags.L, 1, 1) == '\\' or (string.len(flags.L) > 1 and string.sub(flags.L, 2, 2) == ':') then
+            dofile(flags.L)
+        else
+            dofile(flags.w..'/'..flags.L)
+        end
+    end
+
+    -- add cppstring
+    if not flags.S then
+        _basic['string'] = 'cppstring'
+        _basic['std::string'] = 'cppstring'
+        _basic_ctype.cppstring = 'const char*'
+    end
+
+    -- proccess package
+    local file
+    if flags.f then
+        if string.sub(flags.f, 1, 1) == '/' or string.sub(flags.f, 1, 1) == '\\' or (string.len(flags.f) > 1 and string.sub(flags.f, 2, 2) == ':') then
+            file = flags.f
+        else
+            file = flags.w..'/'..flags.f
+        end
+    else
+        file = flags.f
+    end
+    local p  = Package(flags.n, file)
+
+    if flags.p then
+        return        -- only parse
+    end
+
+    if flags.o then
+        local file
+        if string.sub(flags.o, 1, 1) == '/' or string.sub(flags.o, 1, 1) == '\\' or (string.len(flags.o) > 1 and string.sub(flags.o, 2, 2) == ':') then
+            file = flags.o
+        else
+            file = flags.w..'/'..flags.o
+        end
+        local st,msg = writeto(file)
+        if not st then
+            error('#'..msg)
+        end
+    end
+
+    p:decltype()
+    if flags.P then
+        p:print()
+    else
+        p:preamble()
+        p:supcode()
+        p:register()
+        push(p)
+        post_output_hook(p)
+        pop()
+    end
+
+    if flags.o then
+        writeto()
+    end
+
+    -- write header file
+    if not flags.P then
+        if flags.H then
+            local file
+            if string.sub(flags.H, 1, 1) == '/' or string.sub(flags.H, 1, 1) == '\\' or (string.len(flags.H) > 1 and string.sub(flags.H, 2, 2) == ':') then
+                file = flags.H
+            else
+                file = flags.w..'/'..flags.H
+            end
+            local st,msg = writeto(file)
+            if not st then
+                error('#'..msg)
+            end
+            p:header()
+            writeto()
+        end
+    end
+end
+
Index: /code/branches/rocket2/src/external/tolua/lua/enumerate.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/enumerate.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/enumerate.lua	(revision 6952)
@@ -0,0 +1,95 @@
+-- tolua: enumerate class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- $Id: enumerate.lua,v 1.3 2000/01/24 20:41:15 celes Exp $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+-- Enumerate class
+-- Represents enumeration
+-- The following fields are stored:
+--    {i} = list of constant names
+classEnumerate = {
+}
+classEnumerate.__index = classEnumerate
+setmetatable(classEnumerate,classFeature)
+
+-- register enumeration
+function classEnumerate:register (pre)
+    pre = pre or ''
+    local nspace = getnamespace(classContainer.curr)
+    local i=1
+    while self[i] do
+        output(pre..'tolua_constant(tolua_S,"'..self.lnames[i]..'",'..nspace..self[i]..');')
+        i = i+1
+    end
+end
+
+-- Print method
+function classEnumerate:print (ident,close)
+    print(ident.."Enumerate{")
+    print(ident.." name = "..self.name)
+    local i=1
+    while self[i] do
+        print(ident.." '"..self[i].."'("..self.lnames[i].."),")
+        i = i+1
+    end
+    print(ident.."}"..close)
+end
+
+-- Internal constructor
+function _Enumerate (t,varname)
+    setmetatable(t,classEnumerate)
+    append(t)
+    appendenum(t)
+    if varname and varname ~= "" then
+        if t.name ~= "" then
+            Variable(t.name.." "..varname)
+        else
+            local ns = getcurrnamespace()
+            warning("Variable "..ns..varname.." of type <anonymous enum> is declared as read-only")
+            Variable("tolua_readonly int "..varname)
+        end
+    end
+    return t
+end
+
+-- Constructor
+-- Expects a string representing the enumerate body
+function Enumerate (n,b,varname)
+    b = string.gsub(b, ",[%s\n]*}", "\n}") -- eliminate last ','
+    local t = split(strsub(b,2,-2),',') -- eliminate braces
+    local i = 1
+    local e = {n=0}
+    while t[i] do
+        local tt = split(t[i],'=')  -- discard initial value
+        e.n = e.n + 1
+        e[e.n] = tt[1]
+        i = i+1
+    end
+    -- set lua names
+    i  = 1
+    e.lnames = {}
+    local ns = getcurrnamespace()
+    while e[i] do
+        local t = split(e[i],'@')
+        e[i] = t[1]
+        if not t[2] then
+            t[2] = applyrenaming(t[1])
+        end
+        e.lnames[i] = t[2] or t[1]
+        _global_enums[ ns..e[i] ] = (ns..e[i])
+        i = i+1
+    end
+    e.name = n
+    if n ~= "" then
+        Typedef("int "..n)
+    end
+    return _Enumerate(e, varname)
+end
+
Index: /code/branches/rocket2/src/external/tolua/lua/feature.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/feature.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/feature.lua	(revision 6952)
@@ -0,0 +1,128 @@
+-- tolua: abstract feature class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- $Id: $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+-- Feature class
+-- Represents the base class of all mapped feature.
+classFeature = {
+}
+classFeature.__index = classFeature
+
+-- write support code
+function classFeature:supcode ()
+end
+
+-- output tag
+function classFeature:decltype ()
+end
+
+-- register feature
+function classFeature:register (pre)
+end
+
+-- translate verbatim
+function classFeature:preamble ()
+end
+
+-- check if it is a variable
+function classFeature:isvariable ()
+ return false
+end
+
+-- check if it requires collection
+function classFeature:requirecollection (t)
+    return false
+end
+
+-- build names
+function classFeature:buildnames ()
+    if self.name and self.name~='' then
+        local n = split(self.name,'@')
+        self.name = n[1]
+        if not n[2] then
+            n[2] = applyrenaming(n[1])
+        end
+        self.lname = n[2] or gsub(n[1],"%[.-%]","")
+        self.original_name = self.name
+        self.lname = clean_template(self.lname)
+    end
+    if not self.is_parameter then
+        self.name = getonlynamespace() .. self.name
+    end
+
+    local parent = classContainer.curr
+    if parent then
+        self.access = parent.curr_member_access
+    else
+    end
+end
+
+function classFeature:check_public_access()
+
+    if self.access and self.access ~= 0 then
+        return false
+    end
+
+    local parent = classContainer.curr
+    while parent do
+        if parent.access and parent.access ~= 0 then
+            return false
+        end
+        parent = parent.prox
+    end
+    return true
+end
+
+function clean_template(t)
+
+    return string.gsub(t, "[<>:, %*]", "_")
+end
+
+-- check if feature is inside a container definition
+-- it returns the container class name or nil.
+function classFeature:incontainer (which)
+    if self.parent then
+        local parent = self.parent
+        while parent do
+            if parent.classtype == which then
+                return parent.name
+            end
+            parent = parent.parent
+        end
+    end
+    return nil
+end
+
+function classFeature:inclass ()
+    return self:incontainer('class')
+end
+
+function classFeature:inmodule ()
+    return self:incontainer('module')
+end
+
+function classFeature:innamespace ()
+    return self:incontainer('namespace')
+end
+
+-- return C binding function name based on name
+-- the client specifies a prefix
+function classFeature:cfuncname (n)
+
+    if self.parent then
+        n = self.parent:cfuncname(n)
+    end
+
+    n = string.gsub(n..'_'.. (self.lname or self.name), "[<>:, \.%*&]", "_")
+
+    return n
+end
+
Index: /code/branches/rocket2/src/external/tolua/lua/function.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/function.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/function.lua	(revision 6952)
@@ -0,0 +1,737 @@
+-- tolua: function class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- $Id: function.lua 1597 2008-03-11 22:25:01Z ice-drezday $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+-- CEGUILua mod
+-- exception handling
+-- patch from Tov
+-- modded by Lindquist
+exceptionDefs = exceptionDefs or {}
+exceptionDefs["std::exception"]             = {}
+exceptionDefs["std::exception"]["var"]      = "&e"
+exceptionDefs["std::exception"]["c_str"]    = "e.what()"
+
+exceptionDefs["any"]                        = {}
+exceptionDefs["any"]["var"]                 = ""
+exceptionDefs["any"]["c_str"]               = '"Unknown"'
+
+exceptionMessageBufferSize = 512
+
+function outputExceptionError(f,e,errBuf)
+    -- if the exception is not "..." then use the "c_str" info the get a real exception message
+    local messageC_str = true
+    if e.name == "any" then
+        messageC_str = false
+    end
+
+    -- make a default e.ret if empty
+    if not e.ret or e.ret == "" then
+        e.ret = "nil,message"
+    end
+
+    -- create a default exceptionDef if we dont have one
+    if not exceptionDefs[e.name] then
+        exceptionDefs[e.name] = {}
+        exceptionDefs[e.name].var = "&e"
+        exceptionDefs[e.name].c_str = '"Unknown"'
+    end
+
+    -- print catch header
+    local nameToEcho = e.name
+    if nameToEcho == "any" then
+        nameToEcho = "..."
+    end
+    if e.ret == "nil" then
+        output("catch(",nameToEcho," CEGUIDeadException(",exceptionDefs[e.name].var,"))\n{\n")
+    else
+        output("catch(",nameToEcho,exceptionDefs[e.name].var,")\n{\n")
+    end
+
+    -- if just a nil
+    if e.ret == "nil" then
+        output("return 0;\n")
+    -- if error should be raised
+    elseif string.find(e.ret,"error") then
+        if messageC_str then
+            output("snprintf(errorBuffer,"..exceptionMessageBufferSize..",\"Exception of type '"..e.name.."' was thrown by function '"..f.."'\\nMessage: %s\","..exceptionDefs[e.name].c_str..");\n")
+        else
+            output("snprintf(errorBuffer,"..exceptionMessageBufferSize..",\"Unknown exception thrown by function '"..f.."'\");\n")
+        end
+        output("errorDoIt = true;\n")
+    -- else go through the returns
+    else
+        -- buffer for message
+        if string.find(e.ret,"message") and messageC_str and errBuf == false then
+            output("char errorBuffer["..exceptionMessageBufferSize.."];\n")
+        end
+        local numrets = 0
+        local retpat = "(%w+),?"
+        local i,j,retval = string.find(e.ret,retpat)
+        while i do
+            local code = ""
+
+            -- NIL
+            if retval == "nil" then
+                code = "tolua_pushnil(tolua_S);\n"
+
+            -- MESSAGE
+            elseif retval == "message" then
+                if messageC_str then
+                    code = "snprintf(errorBuffer,"..exceptionMessageBufferSize..",\"Exception of type '"..e.name.."' was thrown by function '"..f.."'\\nMessage: %s\","..exceptionDefs[e.name].c_str..");\ntolua_pushstring(tolua_S,errorBuffer);\n"
+                else
+                    code = "tolua_pushstring(tolua_S,\"Unknown exception thrown by function '"..f.."'\");\n"
+                end
+
+            -- TRUE
+            elseif retval == "true" then
+                code = "tolua_pushboolean(tolua_S, 1);\n"
+
+            -- FALSE
+            elseif retval == "false" then
+                code = "tolua_pushboolean(tolua_S, 0);\n"
+            end
+
+            -- print code for this return value
+            if code ~= "" then
+                output(code)
+                numrets = numrets + 1
+            end
+
+            -- next return value
+            i,j,retval = string.find(e.ret,retpat,j+1)
+        end
+        output("return ",numrets,";\n")
+    end
+
+    -- print catch footer
+    output("}\n")
+end
+
+function outputExceptionCatchBlocks(func,throws,err)
+    for i=1,table.getn(throws) do
+        outputExceptionError(func, throws[i], err)
+    end
+
+    -- if an error should be raised, we do it here
+    if err then
+        output("if (errorDoIt) {\n")
+        output("luaL_error(tolua_S,errorBuffer);\n")
+        output("}\n")
+    end
+end
+
+
+-- Function class
+-- Represents a function or a class method.
+-- The following fields are stored:
+--  mod  = type modifiers
+--  type = type
+--  ptr  = "*" or "&", if representing a pointer or a reference
+--  name = name
+--  lname = lua name
+--  args  = list of argument declarations
+--  const = if it is a method receiving a const "this".
+classFunction = {
+    mod = '',
+    type = '',
+    ptr = '',
+    name = '',
+    args = {n=0},
+    const = '',
+}
+classFunction.__index = classFunction
+setmetatable(classFunction,classFeature)
+
+-- declare tags
+function classFunction:decltype ()
+    self.type = typevar(self.type)
+    if strfind(self.mod,'const') then
+        self.type = 'const '..self.type
+        self.mod = gsub(self.mod,'const','')
+    end
+    local i=1
+    while self.args[i] do
+        self.args[i]:decltype()
+        i = i+1
+    end
+end
+
+
+-- Write binding function
+-- Outputs C/C++ binding function.
+function classFunction:supcode (local_constructor)
+
+    local overload = strsub(self.cname,-2,-1) - 1  -- indicate overloaded func
+    local nret = 0      -- number of returned values
+    local class = self:inclass()
+    local _,_,static = strfind(self.mod,'^%s*(static)')
+    if class then
+
+        if self.name == 'new' and self.parent.flags.pure_virtual then
+            -- no constructor for classes with pure virtual methods
+            return
+        end
+
+        if local_constructor then
+           output("/* method: new_local of class ",class," */")
+       else
+           output("/* method:",self.name," of class ",class," */")
+       end
+    else
+        output("/* function:",self.name," */")
+    end
+
+    if local_constructor then
+        output("#ifndef TOLUA_DISABLE_"..self.cname.."_local")
+        output("\nstatic int",self.cname.."_local","(lua_State* tolua_S)")
+    else
+        output("#ifndef TOLUA_DISABLE_"..self.cname)
+        output("\nstatic int",self.cname,"(lua_State* tolua_S)")
+    end
+    output("{")
+
+    -- check types
+    if overload < 0 then
+        output('#ifndef TOLUA_RELEASE\n')
+    end
+    output(' tolua_Error tolua_err;')
+    output(' if (\n')
+    -- check self
+    local narg
+    if class then narg=2 else narg=1 end
+    if class then
+        local func = 'tolua_isusertype'
+        local type = self.parent.type
+        if self.name=='new' or static~=nil then
+            func = 'tolua_isusertable'
+            type = self.parent.type
+        end
+        if self.const ~= '' then
+            type = "const "..type
+        end
+        output('     !'..func..'(tolua_S,1,"'..type..'",0,&tolua_err) ||\n')
+    end
+    -- check args
+    if self.args[1].type ~= 'void' then
+        local i=1
+        while self.args[i] do
+            local btype = isbasic(self.args[i].type)
+            if btype ~= 'value' and btype ~= 'state' then
+                output('     !'..self.args[i]:outchecktype(narg)..' ||\n')
+            end
+            if btype ~= 'state' then
+                narg = narg+1
+            end
+            i = i+1
+        end
+    end
+    -- check end of list
+    output('     !tolua_isnoobj(tolua_S,'..narg..',&tolua_err)\n )')
+    output('  goto tolua_lerror;')
+
+    output(' else\n')
+    if overload < 0 then
+        output('#endif\n')
+    end
+    output(' {')
+
+    -- declare self, if the case
+    local narg
+    if class then narg=2 else narg=1 end
+    if class and self.name~='new' and static==nil then
+        output(' ',self.const,self.parent.type,'*','self = ')
+        output('(',self.const,self.parent.type,'*) ')
+        output('tolua_tousertype(tolua_S,1,0);')
+    elseif static then
+        _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
+    end
+    -- declare parameters
+    if self.args[1].type ~= 'void' then
+        local i=1
+        while self.args[i] do
+            self.args[i]:declare(narg)
+            if isbasic(self.args[i].type) ~= "state" then
+                narg = narg+1
+            end
+            i = i+1
+        end
+    end
+
+    -- check self
+    if class and self.name~='new' and static==nil then
+        output('#ifndef TOLUA_RELEASE\n')
+        output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'",NULL);');
+        output('#endif\n')
+    end
+
+    -- get array element values
+    if class then narg=2 else narg=1 end
+    if self.args[1].type ~= 'void' then
+        local i=1
+        while self.args[i] do
+            self.args[i]:getarray(narg)
+            narg = narg+1
+            i = i+1
+        end
+    end
+
+    --------------------------------------------------
+    -- CEGUILua mod
+    -- init exception handling
+    local throws = false
+    do
+        local pattern = "tolua_throws|.*|"
+        local i,j = string.find(self.mod, pattern)
+        if i then
+            throws = {}
+            -- ensure table is empty.  Used to be: table.setn(throws,0)
+            for x in pairs(throws) do
+                throws[x] = nil
+            end
+            local excepts = string.sub(self.mod, i+12,j)
+            local epattern = "|.-|"
+            local i,j = string.find(excepts, epattern)
+            while i do
+                local e = string.sub(excepts,i+1,j-1)
+                local _,_,name,rest = string.find(e, "([%w:_]+),?(.*)")
+                table.insert(throws,{name=name, ret=rest})
+                i,j = string.find(excepts, epattern, j)
+            end
+            self.mod = string.gsub(self.mod, pattern, "")
+        end
+    end
+    local exRaiseError = false
+    --------------------------------------------------
+
+    local out = string.find(self.mod, "tolua_outside")
+
+    ---------------
+    -- CEGUILua mod
+    -- remove "tolua_outside" from self.mod
+    if out then
+        self.mod = string.gsub(self.mod, "tolua_outside", "")
+    end
+
+    -- call function
+    if class and self.name=='delete' then
+        output('  delete self;')
+    elseif class and self.name == 'operator&[]' then
+        if flags['1'] then -- for compatibility with tolua5 ?
+            output('  self->operator[](',self.args[1].name,'-1) = ',self.args[2].name,';')
+        else
+            output('  self->operator[](',self.args[1].name,') = ',self.args[2].name,';')
+        end
+    else
+    -- CEGUILua mod begin- throws
+    if throws then
+        for i=1,table.getn(throws) do
+            if string.find(throws[i].ret, "error") then
+                output("char errorBuffer["..exceptionMessageBufferSize.."];\n")
+                output("bool errorDoIt = false;\n")
+                exRaiseError = true
+                break
+            end
+        end
+        output("try\n")
+    end
+    -- CEGUILua mod end - throws
+    output('  {')
+    if self.type ~= '' and self.type ~= 'void' then
+        output('  ',self.mod,self.type,self.ptr,'tolua_ret = ')
+        output('(',self.mod,self.type,self.ptr,') ')
+    else
+        output('  ')
+    end
+    if class and self.name=='new' then
+        output('new',self.type,'(')
+    elseif class and static then
+        if out then
+            output(self.name,'(')
+        else
+            output(class..'::'..self.name,'(')
+        end
+    elseif class then
+        if out then
+            output(self.name,'(')
+        else
+            if self.cast_operator then
+                output('static_cast<',self.mod,self.type,self.ptr,'>(*self')
+            else
+                output('self->'..self.name,'(')
+            end
+        end
+    else
+        output(self.name,'(')
+    end
+
+    if out and not static then
+        output('self')
+        if self.args[1] and self.args[1].name ~= '' then
+            output(',')
+        end
+    end
+    -- write parameters
+    local i=1
+    while self.args[i] do
+        self.args[i]:passpar()
+        i = i+1
+        if self.args[i] then
+            output(',')
+        end
+    end
+
+    if class and self.name == 'operator[]' and flags['1'] then
+        output('-1);')
+    else
+        output(');')
+    end
+
+    -- return values
+    if self.type ~= '' and self.type ~= 'void' then
+        nret = nret + 1
+        local t,ct = isbasic(self.type)
+        if t then
+            if self.cast_operator and _basic_raw_push[t] then
+                output('   ',_basic_raw_push[t],'(tolua_S,(',ct,')tolua_ret);')
+            else
+                output('   tolua_push'..t..'(tolua_S,(',ct,')tolua_ret);')
+            end
+            else
+                t = self.type
+                new_t = string.gsub(t, "const%s+", "")
+                if self.ptr == '' then
+                    output('   {')
+                    output('#ifdef __cplusplus\n')
+                    output('    void* tolua_obj = new',new_t,'(tolua_ret);')
+                    output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
+                    output('#else\n')
+                    output('    void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));')
+                    output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
+                    output('#endif\n')
+                    output('   }')
+                elseif self.ptr == '&' then
+                    output('   tolua_pushusertype(tolua_S,(void*)&tolua_ret,"',t,'");')
+                else
+                    if local_constructor then
+                        output('   tolua_pushusertype_and_takeownership(tolua_S,(void *)tolua_ret,"',t,'");')
+                    else
+                        output('   tolua_pushusertype(tolua_S,(void*)tolua_ret,"',t,'");')
+                    end
+                end
+            end
+        end
+        local i=1
+        while self.args[i] do
+            nret = nret + self.args[i]:retvalue()
+            i = i+1
+        end
+        output('  }')
+
+        ------------------------------------------
+        -- CEGUILua mod
+        -- finish exception handling
+        -- catch
+        if throws then
+            outputExceptionCatchBlocks(self.name, throws, exRaiseError)
+        end
+        ------------------------------------------
+
+        -- set array element values
+        if class then narg=2 else narg=1 end
+        if self.args[1].type ~= 'void' then
+            local i=1
+            while self.args[i] do
+                self.args[i]:setarray(narg)
+                narg = narg+1
+                i = i+1
+            end
+        end
+
+        -- free dynamically allocated array
+        if self.args[1].type ~= 'void' then
+            local i=1
+            while self.args[i] do
+                self.args[i]:freearray()
+                i = i+1
+            end
+        end
+    end
+
+    output(' }')
+    output(' return '..nret..';')
+
+    -- call overloaded function or generate error
+    if overload < 0 then
+
+        output('#ifndef TOLUA_RELEASE\n')
+        output('tolua_lerror:\n')
+        output(' tolua_error(tolua_S,"#ferror in function \''..self.lname..'\'.",&tolua_err);')
+        output(' return 0;')
+        output('#endif\n')
+    else
+        local _local = ""
+        if local_constructor then
+            _local = "_local"
+        end
+        output('tolua_lerror:\n')
+        output(' return '..strsub(self.cname,1,-3)..format("%02d",overload).._local..'(tolua_S);')
+    end
+    output('}')
+    output('#endif //#ifndef TOLUA_DISABLE\n')
+    output('\n')
+
+    -- recursive call to write local constructor
+    if class and self.name=='new' and not local_constructor then
+
+        self:supcode(1)
+    end
+
+end
+
+
+-- register function
+function classFunction:register (pre)
+
+    if not self:check_public_access() then
+        return
+    end
+
+    if self.name == 'new' and self.parent.flags.pure_virtual then
+        -- no constructor for classes with pure virtual methods
+        return
+    end
+
+    output(pre..'tolua_function(tolua_S,"'..self.lname..'",'..self.cname..');')
+    if self.name == 'new' then
+        output(pre..'tolua_function(tolua_S,"new_local",'..self.cname..'_local);')
+        output(pre..'tolua_function(tolua_S,".call",'..self.cname..'_local);')
+        --output(' tolua_set_call_event(tolua_S,'..self.cname..'_local, "'..self.parent.type..'");')
+    end
+end
+
+-- Print method
+function classFunction:print (ident,close)
+    print(ident.."Function{")
+    print(ident.." mod  = '"..self.mod.."',")
+    print(ident.." type = '"..self.type.."',")
+    print(ident.." ptr  = '"..self.ptr.."',")
+    print(ident.." name = '"..self.name.."',")
+    print(ident.." lname = '"..self.lname.."',")
+    print(ident.." const = '"..self.const.."',")
+    print(ident.." cname = '"..self.cname.."',")
+    print(ident.." lname = '"..self.lname.."',")
+    print(ident.." args = {")
+    local i=1
+    while self.args[i] do
+        self.args[i]:print(ident.."  ",",")
+        i = i+1
+    end
+    print(ident.." }")
+    print(ident.."}"..close)
+end
+
+-- check if it returns an object by value
+function classFunction:requirecollection (t)
+    local r = false
+    if self.type ~= '' and not isbasic(self.type) and self.ptr=='' then
+        local type = gsub(self.type,"%s*const%s+","")
+        t[type] = "tolua_collect_" .. clean_template(type)
+        r = true
+    end
+    local i=1
+    while self.args[i] do
+        r = self.args[i]:requirecollection(t) or r
+        i = i+1
+    end
+    return r
+end
+
+-- determine lua function name overload
+function classFunction:overload ()
+    return self.parent:overload(self.lname)
+end
+
+
+function param_object(par) -- returns true if the parameter has an object as its default value
+
+    if not string.find(par, '=') then return false end -- it has no default value
+
+    local _,_,def = string.find(par, "=(.*)$")
+
+    if string.find(par, "|") then -- a list of flags
+
+        return true
+    end
+
+    if string.find(par, "%*") then -- it's a pointer with a default value
+
+        if string.find(par, '=%s*new') then -- it's a pointer with an instance as default parameter.. is that valid?
+            return true
+        end
+        return false -- default value is 'NULL' or something
+    end
+
+
+    if string.find(par, "[%(&]") then
+        return true
+    end -- default value is a constructor call (most likely for a const reference)
+
+    --if string.find(par, "&") then
+
+    --    if string.find(def, ":") or string.find(def, "^%s*new%s+") then
+
+    --        -- it's a reference with default to something like Class::member, or 'new Class'
+    --        return true
+    --    end
+    --end
+
+    return false -- ?
+end
+
+function strip_last_arg(all_args, last_arg) -- strips the default value from the last argument
+
+    local _,_,s_arg = string.find(last_arg, "^([^=]+)")
+    last_arg = string.gsub(last_arg, "([%%%(%)])", "%%%1");
+    all_args = string.gsub(all_args, "%s*,%s*"..last_arg.."%s*%)%s*$", ")")
+    return all_args, s_arg
+end
+
+
+
+-- Internal constructor
+function _Function (t)
+    setmetatable(t,classFunction)
+
+    if t.const ~= 'const' and t.const ~= '' then
+        error("#invalid 'const' specification")
+    end
+
+    append(t)
+    if t:inclass() then
+        --print ('t.name is '..t.name..', parent.name is '..t.parent.name)
+        if string.gsub(t.name, "%b<>", "") == string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then
+            t.name = 'new'
+            t.lname = 'new'
+            t.parent._new = true
+            t.type = t.parent.name
+            t.ptr = '*'
+        elseif string.gsub(t.name, "%b<>", "") == '~'..string.gsub(t.parent.original_name or t.parent.name, "%b<>", "") then
+            t.name = 'delete'
+            t.lname = 'delete'
+            t.parent._delete = true
+        end
+    end
+    t.cname = t:cfuncname("tolua")..t:overload(t)
+    return t
+end
+
+-- Constructor
+-- Expects three strings: one representing the function declaration,
+-- another representing the argument list, and the third representing
+-- the "const" or empty string.
+function Function (d,a,c)
+    --local t = split(strsub(a,2,-2),',') -- eliminate braces
+    --local t = split_params(strsub(a,2,-2))
+
+    if not flags['W'] and string.find(a, "%.%.%.%s*%)") then
+
+        warning("Functions with variable arguments (`...') are not supported. Ignoring "..d..a..c)
+        return nil
+    end
+
+
+    local i=1
+    local l = {n=0}
+
+    a = string.gsub(a, "%s*([%(%)])%s*", "%1")
+    local t,strip,last = strip_pars(strsub(a,2,-2));
+    if strip then
+        --local ns = string.sub(strsub(a,1,-2), 1, -(string.len(last)+1))
+        local ns = join(t, ",", 1, last-1)
+
+        ns = "("..string.gsub(ns, "%s*,%s*$", "")..')'
+        --ns = strip_defaults(ns)
+
+        Function(d, ns, c)
+        for i=1,last do
+            t[i] = string.gsub(t[i], "=.*$", "")
+        end
+    end
+
+    while t[i] do
+        l.n = l.n+1
+        l[l.n] = Declaration(t[i],'var',true)
+        i = i+1
+    end
+    local f = Declaration(d,'func')
+    f.args = l
+    f.const = c
+    return _Function(f)
+end
+
+function join(t, sep, first, last)
+
+    first = first or 1
+    last = last or table.getn(t)
+    local lsep = ""
+    local ret = ""
+    local loop = false
+    for i = first,last do
+
+        ret = ret..lsep..t[i]
+        lsep = sep
+        loop = true
+    end
+    if not loop then
+        return ""
+    end
+
+    return ret
+end
+
+function strip_pars(s)
+
+    local t = split_c_tokens(s, ',')
+    local strip = false
+    local last
+
+    for i=t.n,1,-1 do
+
+        if not strip and param_object(t[i]) then
+            last = i
+            strip = true
+        end
+        --if strip then
+        --    t[i] = string.gsub(t[i], "=.*$", "")
+        --end
+    end
+
+    return t,strip,last
+
+end
+
+function strip_defaults(s)
+
+    s = string.gsub(s, "^%(", "")
+    s = string.gsub(s, "%)$", "")
+
+    local t = split_c_tokens(s, ",")
+    local sep, ret = "",""
+    for i=1,t.n do
+        t[i] = string.gsub(t[i], "=.*$", "")
+        ret = ret..sep..t[i]
+        sep = ","
+    end
+
+    return "("..ret..")"
+end
+
+
Index: /code/branches/rocket2/src/external/tolua/lua/module.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/module.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/module.lua	(revision 6952)
@@ -0,0 +1,68 @@
+-- tolua: module class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- $Id: $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+
+-- Module class
+-- Represents module.
+-- The following fields are stored:
+--    {i} = list of objects in the module.
+classModule = {
+    classtype = 'module'
+}
+classModule.__index = classModule
+setmetatable(classModule,classContainer)
+
+-- register module
+function classModule:register (pre)
+    pre = pre or ''
+    push(self)
+    output(pre..'tolua_module(tolua_S,"'..self.name..'",',self:hasvar(),');')
+    output(pre..'tolua_beginmodule(tolua_S,"'..self.name..'");')
+    local i=1
+    while self[i] do
+        self[i]:register(pre..' ')
+        i = i+1
+    end
+    output(pre..'tolua_endmodule(tolua_S);')
+    pop()
+end
+
+-- Print method
+function classModule:print (ident,close)
+    print(ident.."Module{")
+    print(ident.." name = '"..self.name.."';")
+    local i=1
+    while self[i] do
+        self[i]:print(ident.." ",",")
+        i = i+1
+    end
+    print(ident.."}"..close)
+end
+
+-- Internal constructor
+function _Module (t)
+    setmetatable(t,classModule)
+    append(t)
+    return t
+end
+
+-- Constructor
+-- Expects two string representing the module name and body.
+function Module (n,b)
+    local t = _Module(_Container{name=n})
+    push(t)
+    t:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces
+    pop()
+    return t
+end
+
+
Index: /code/branches/rocket2/src/external/tolua/lua/namespace.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/namespace.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/namespace.lua	(revision 6952)
@@ -0,0 +1,52 @@
+-- tolua: namespace class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 2003
+-- $Id: $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+-- Namespace class
+-- Represents a namesapce definition.
+-- Stores the following fields:
+--    name = class name
+--    {i}  = list of members
+classNamespace = {
+    classtype = 'namespace',
+    name = '',
+}
+classNamespace.__index = classNamespace
+setmetatable(classNamespace,classModule)
+
+-- Print method
+function classNamespace:print (ident,close)
+    print(ident.."Namespace{")
+    print(ident.." name = '"..self.name.."',")
+    local i=1
+    while self[i] do
+        self[i]:print(ident.." ",",")
+        i = i+1
+    end
+    print(ident.."}"..close)
+end
+
+-- Internal constructor
+function _Namespace (t)
+    setmetatable(t,classNamespace)
+    append(t)
+    return t
+end
+
+-- Constructor
+-- Expects the name and the body of the namespace.
+function Namespace (n,b)
+    local c = _Namespace(_Container{name=n})
+    push(c)
+    c:parse(strsub(b,2,strlen(b)-1)) -- eliminate braces
+    pop()
+end
+
Index: /code/branches/rocket2/src/external/tolua/lua/operator.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/operator.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/operator.lua	(revision 6952)
@@ -0,0 +1,215 @@
+-- tolua: operator class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- $Id: $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+-- Operator class
+-- Represents an operator function or a class operator method.
+-- It stores the same fields as functions do plus:
+--  kind = set of character representing the operator (as it appers in C++ code)
+classOperator = {
+    kind = '',
+}
+classOperator.__index = classOperator
+setmetatable(classOperator,classFunction)
+
+-- table to transform operator kind into the appropriate tag method name
+_TM = {
+    ['+'] = 'add',
+    ['-'] = 'sub',
+    ['*'] = 'mul',
+    ['/'] = 'div',
+    ['<'] = 'lt',
+    ['<='] = 'le',
+    ['=='] = 'eq',
+    ['[]'] = 'geti',
+    ['&[]'] = 'seti',
+    --['->'] = 'flechita',
+}
+
+
+-- Print method
+function classOperator:print (ident,close)
+    print(ident.."Operator{")
+    print(ident.." kind  = '"..self.kind.."',")
+    print(ident.." mod  = '"..self.mod.."',")
+    print(ident.." type = '"..self.type.."',")
+    print(ident.." ptr  = '"..self.ptr.."',")
+    print(ident.." name = '"..self.name.."',")
+    print(ident.." const = '"..self.const.."',")
+    print(ident.." cname = '"..self.cname.."',")
+    print(ident.." lname = '"..self.lname.."',")
+    print(ident.." args = {")
+    local i=1
+    while self.args[i] do
+        self.args[i]:print(ident.."  ",",")
+        i = i+1
+    end
+    print(ident.." }")
+    print(ident.."}"..close)
+end
+
+function classOperator:supcode_tmp()
+
+    if not _TM[self.kind] then
+        return classFunction.supcode(self)
+    end
+
+    -- no overload, no parameters, always inclass
+    output("/* method:",self.name," of class ",self:inclass()," */")
+
+    output("#ifndef TOLUA_DISABLE_"..self.cname)
+    output("\nstatic int",self.cname,"(lua_State* tolua_S)")
+
+    if overload < 0 then
+        output('#ifndef TOLUA_RELEASE\n')
+    end
+    output(' tolua_Error tolua_err;')
+    output(' if (\n')
+    -- check self
+    output('     !'..'tolua_isusertype(tolua_S,1,"'..self.parent.type..'",0,&tolua_err) ||\n')
+    output('     !tolua_isnoobj(tolua_S,2,&tolua_err)\n )')
+    output('  goto tolua_lerror;')
+
+    output(' else\n')
+    output('#endif\n') -- tolua_release
+    output(' {')
+
+    -- declare self
+    output(' ',self.const,self.parent.type,'*','self = ')
+    output('(',self.const,self.parent.type,'*) ')
+    output('tolua_tousertype(tolua_S,1,0);')
+
+    -- check self
+    output('#ifndef TOLUA_RELEASE\n')
+    output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in function \''..self.name..'\'",NULL);');
+    output('#endif\n')
+
+    -- cast self
+    output('  ',self.mod,self.type,self.ptr,'tolua_ret = ')
+    output('(',self.mod,self.type,self.ptr,')(*self);')
+
+    -- return value
+    local t,ct = isbasic(self.type)
+    if t then
+        output('   tolua_push'..t..'(tolua_S,(',ct,')tolua_ret);')
+    else
+        t = self.type
+        new_t = string.gsub(t, "const%s+", "")
+        if self.ptr == '' then
+            output('   {')
+            output('#ifdef __cplusplus\n')
+            output('    void* tolua_obj = new',new_t,'(tolua_ret);')
+            output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
+            output('#else\n')
+            output('    void* tolua_obj = tolua_copy(tolua_S,(void*)&tolua_ret,sizeof(',t,'));')
+            output('    tolua_pushusertype_and_takeownership(tolua_S,tolua_obj,"',t,'");')
+            output('#endif\n')
+            output('   }')
+        elseif self.ptr == '&' then
+            output('   tolua_pushusertype(tolua_S,(void*)&tolua_ret,"',t,'");')
+        else
+            if local_constructor then
+                output('   tolua_pushusertype_and_takeownership(tolua_S,(void *)tolua_ret,"',t,'");')
+            else
+                output('   tolua_pushusertype(tolua_S,(void*)tolua_ret,"',t,'");')
+            end
+        end
+    end
+
+    output('  }')
+    output(' return 1;')
+
+    output('#ifndef TOLUA_RELEASE\n')
+    output('tolua_lerror:\n')
+    output(' tolua_error(tolua_S,"#ferror in function \''..self.lname..'\'.",&tolua_err);')
+    output(' return 0;')
+    output('#endif\n')
+
+
+    output('}')
+    output('#endif //#ifndef TOLUA_DISABLE\n')
+    output('\n')
+end
+
+-- Internal constructor
+function _Operator (t)
+    setmetatable(t,classOperator)
+
+    if t.const ~= 'const' and t.const ~= '' then
+        error("#invalid 'const' specification")
+    end
+
+    append(t)
+    if not t:inclass() then
+        error("#operator can only be defined as class member")
+    end
+
+    --t.name = t.name .. "_" .. (_TM[t.kind] or t.kind)
+    t.cname = t:cfuncname("tolua")..t:overload(t)
+    t.name = "operator" .. t.kind  -- set appropriate calling name
+    return t
+end
+
+-- Constructor
+function Operator (d,k,a,c)
+
+    local op_k = string.gsub(k, "^%s*", "")
+    op_k = string.gsub(k, "%s*$", "")
+    --if string.find(k, "^[%w_:%d<>%*%&]+$") then
+    if d == "operator" and k ~= '' then
+
+        d = k.." operator"
+    elseif not _TM[op_k] then
+
+        if flags['W'] then
+            error("tolua: no support for operator" .. f.kind)
+        else
+            warning("No support for operator "..op_k..", ignoring")
+            return nil
+        end
+    end
+
+    local ref = ''
+    local t = split_c_tokens(strsub(a,2,strlen(a)-1),',') -- eliminate braces
+    local i=1
+    local l = {n=0}
+    while t[i] do
+        l.n = l.n+1
+        l[l.n] = Declaration(t[i],'var')
+        i = i+1
+    end
+    if k == '[]' then
+        local _
+        _, _, ref = strfind(d,'(&)')
+        d = gsub(d,'&','')
+    elseif k=='&[]' then
+        l.n = l.n+1
+        l[l.n] = Declaration(d,'var')
+        l[l.n].name = 'tolua_value'
+    end
+    local f = Declaration(d,'func')
+    if k == '[]' and (l[1]==nil or isbasic(l[1].type)~='number') then
+        error('operator[] can only be defined for numeric index.')
+    end
+    f.args = l
+    f.const = c
+    f.kind = op_k
+    f.lname = "."..(_TM[f.kind] or f.kind)
+    if not _TM[f.kind] then
+        f.cast_operator = true
+    end
+    if f.kind == '[]' and ref=='&' and f.const~='const' then
+        Operator(d,'&'..k,a,c)     -- create correspoding set operator
+    end
+    return _Operator(f)
+end
+
+
Index: /code/branches/rocket2/src/external/tolua/lua/package.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/package.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/package.lua	(revision 6952)
@@ -0,0 +1,335 @@
+-- tolua: package class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- $Id: $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+
+-- Package class
+-- Represents the whole package being bound.
+-- The following fields are stored:
+--    {i} = list of objects in the package.
+classPackage = {
+    classtype = 'package'
+}
+classPackage.__index = classPackage
+setmetatable(classPackage,classContainer)
+
+-- Print method
+function classPackage:print ()
+    print("Package: "..self.name)
+    local i=1
+    while self[i] do
+        self[i]:print("","")
+        i = i+1
+    end
+end
+
+function classPackage:preprocess ()
+
+    -- avoid preprocessing embedded Lua code
+    local L = {}
+    self.code = gsub(self.code,"\n%s*%$%[","\1") -- deal with embedded lua code
+    self.code = gsub(self.code,"\n%s*%$%]","\2")
+    self.code = gsub(self.code,"(%b\1\2)", function (c)
+                                               tinsert(L,c)
+                                               return "\n#["..getn(L).."]#"
+                                           end
+    )
+    -- avoid preprocessing embedded C code
+    local C = {}
+    self.code = gsub(self.code,"\n%s*%$%<","\3") -- deal with embedded C code
+    self.code = gsub(self.code,"\n%s*%$%>","\4")
+    self.code = gsub(self.code,"(%b\3\4)", function (c)
+                                               tinsert(C,c)
+                                               return "\n#<"..getn(C)..">#"
+                                           end
+    )
+    -- avoid preprocessing embedded C code
+    self.code = gsub(self.code,"\n%s*%$%{","\5") -- deal with embedded C code
+    self.code = gsub(self.code,"\n%s*%$%}","\6")
+    self.code = gsub(self.code,"(%b\5\6)", function (c)
+                                               tinsert(C,c)
+                                               return "\n#<"..getn(C)..">#"
+                                           end
+    )
+
+    --self.code = gsub(self.code,"\n%s*#[^d][^\n]*\n", "\n\n") -- eliminate preprocessor directives that don't start with 'd'
+    self.code = gsub(self.code,"\n[ \t]*#[ \t]*[^d%<%[]", "\n//") -- eliminate preprocessor directives that don't start with 'd'
+
+    -- avoid preprocessing verbatim lines
+    local V = {}
+    self.code = gsub(self.code,"\n(%s*%$[^%[%]][^\n]*)", function (v)
+                                                             tinsert(V,v)
+                                                             return "\n#"..getn(V).."#"
+                                                         end
+    )
+
+    -- perform global substitution
+
+    self.code = gsub(self.code,"(//[^\n]*)","")     -- eliminate C++ comments
+    self.code = gsub(self.code,"/%*","\1")
+    self.code = gsub(self.code,"%*/","\2")
+    self.code = gsub(self.code,"%b\1\2","")
+    self.code = gsub(self.code,"\1","/%*")
+    self.code = gsub(self.code,"\2","%*/")
+    self.code = gsub(self.code,"%s*@%s*","@") -- eliminate spaces beside @
+    self.code = gsub(self.code,"%s?inline(%s)","%1") -- eliminate 'inline' keyword
+    --self.code = gsub(self.code,"%s?extern(%s)","%1") -- eliminate 'extern' keyword
+    --self.code = gsub(self.code,"%s?virtual(%s)","%1") -- eliminate 'virtual' keyword
+    --self.code = gsub(self.code,"public:","") -- eliminate 'public:' keyword
+    self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*'
+    self.code = gsub(self.code,"([^%w_])void%s*%*","%1_userdata ") -- substitute 'void*'
+    self.code = gsub(self.code,"([^%w_])char%s*%*","%1_cstring ")  -- substitute 'char*'
+    self.code = gsub(self.code,"([^%w_])lua_State%s*%*","%1_lstate ")  -- substitute 'lua_State*'
+
+    -- restore embedded Lua code
+    self.code = gsub(self.code,"%#%[(%d+)%]%#", function (n)
+                                                    return L[tonumber(n)]
+                                                end
+    )
+    -- restore embedded C code
+    self.code = gsub(self.code,"%#%<(%d+)%>%#", function (n)
+                                                    return C[tonumber(n)]
+                                                end
+    )
+    -- restore verbatim lines
+    self.code = gsub(self.code,"%#(%d+)%#", function (n)
+                                                return V[tonumber(n)]
+                                            end
+    )
+
+    self.code = string.gsub(self.code, "\n%s*%$([^\n]+)", function (l)
+                                                              Verbatim(l.."\n")
+                                                              return "\n"
+                                                          end
+    )
+end
+
+-- translate verbatim
+function classPackage:preamble ()
+    output('/*\n')
+    output('** Lua binding: '..self.name..'\n')
+    output('** Generated automatically by '..TOLUA_VERSION..' on '..date()..'.\n')
+    output('*/\n\n')
+
+    output('#ifndef __cplusplus\n')
+    output('#include <stdlib.h>\n')
+    output('#endif\n')
+    output('#include <string.h>\n\n')
+    output('#include <tolua/tolua++.h>\n\n')
+
+    if flags.H then
+        output('#include "'..flags.H..'"\n')
+    end
+
+    local i=1
+    while self[i] do
+        self[i]:preamble()
+        i = i+1
+    end
+
+    if self:requirecollection(_collect) then
+        output('\n')
+        output('/* function to release collected object via destructor */')
+        output('#ifdef __cplusplus\n')
+        for i,v in pairs(_collect) do
+            output('\nstatic int '..v..' (lua_State* tolua_S)')
+            output('{')
+            output(' '..i..'* self = ('..i..'*) tolua_tousertype(tolua_S,1,0);')
+            output('    delete self;')
+            output('    return 0;')
+            output('}')
+        end
+        output('#endif\n\n')
+    end
+
+    output('\n')
+    output('/* function to register type */')
+    output('static void tolua_reg_types (lua_State* tolua_S)')
+    output('{')
+    foreach(_usertype,function(n,v) output(' tolua_usertype(tolua_S,"',v,'");') end)
+    if flags.t then
+        output("#ifndef Mtolua_typeid\n#define Mtolua_typeid(L,TI,T)\n#endif\n")
+        foreach(_usertype,function(n,v) output(' Mtolua_typeid(tolua_S,typeid(',v,'), "',v,'");') end)
+    end
+    output('}')
+    output('\n')
+end
+
+-- register package
+-- write package open function
+function classPackage:register (pre)
+    pre = pre or ''
+    push(self)
+    output(pre.."/* Open function */")
+    output(pre.."int tolua_"..self.name.."_open (lua_State* tolua_S)")
+    output(pre.."{")
+    output(pre.." tolua_open(tolua_S);")
+    output(pre.." tolua_reg_types(tolua_S);")
+    output(pre.." tolua_module(tolua_S,NULL,",self:hasvar(),");")
+    output(pre.." tolua_beginmodule(tolua_S,NULL);")
+    local i=1
+    while self[i] do
+        self[i]:register(pre.."  ")
+        i = i+1
+    end
+    output(pre.." tolua_endmodule(tolua_S);")
+    output(pre.." return 1;")
+    output(pre.."}")
+
+    output("\n\n")
+    output("#if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM >= 501\n");
+    output(pre.."int luaopen_"..self.name.." (lua_State* tolua_S) {")
+    output(pre.." return tolua_"..self.name.."_open(tolua_S);")
+    output(pre.."};")
+    output("#endif\n\n")
+
+    pop()
+end
+
+-- write header file
+function classPackage:header ()
+    output('/*\n') output('** Lua binding: '..self.name..'\n')
+    output('** Generated automatically by '..TOLUA_VERSION..' on '..date()..'.\n')
+    output('*/\n\n')
+
+    if flags.H then
+        output('#include "'..flags.w..'/'..self.name..'Prereqs.h"\n')
+        output('/* Exported function */')
+        output('_'..self.name..'Export')
+        output('int  tolua_'..self.name..'_open (lua_State* tolua_S);')
+        output('\n')
+    end
+end
+
+-- Internal constructor
+function _Package (self)
+    setmetatable(self,classPackage)
+    return self
+end
+
+-- Parse C header file with tolua directives
+-- *** Thanks to Ariel Manzur for fixing bugs in nested directives ***
+function extract_code(fn,s)
+    local code = '\n$#include "'..flags.w..'/'..fn..'"\n'
+    s= "\n" .. s .. "\n" -- add blank lines as sentinels
+
+    -- eliminate export macro problems in class declarations
+    s = gsub(s, ' _%w*Export ', ' ')
+
+    local _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n")
+    while e do
+        t = strlower(t)
+        if t == "begin" then
+            _,e,c = strfind(s,"(.-)\n[^\n]*[Tt][Oo][Ll][Uu][Aa]_[Ee][Nn][Dd][^\n]*\n",e)
+            if not e then
+             tolua_error("Unbalanced 'tolua_begin' directive in header file")
+            end
+        end
+        code = code .. c .. "\n"
+        _,e,c,t = strfind(s, "\n([^\n]-)[Tt][Oo][Ll][Uu][Aa]_([^%s]*)[^\n]*\n",e)
+    end
+    return code
+end
+
+-- Constructor
+-- Expects the package name, the file extension, and the file text.
+function Package (name,fn)
+    local ext = "pkg"
+
+    -- open input file, if any
+    if fn then
+        local file
+        if flags.f then
+            if string.sub(flags.f, 1, 1) == '/' or string.sub(flags.f, 1, 1) == '\\' or (string.len(flags.f) > 1 and string.sub(flags.f, 2, 2) == ':') then
+                file = flags.f
+            else
+                file = flags.w..'/'..flags.f
+            end
+        else
+            file = flags.f
+        end
+        local st, msg = readfrom(file)
+        if not st then
+            error('#'..msg..' path: '..flags.f)
+        end
+        local _; _, _, ext = strfind(fn,".*%.(.*)$")
+    end
+    local code = "\n" .. read('*a')
+    if ext == 'h' or ext == 'hpp' then
+        code = extract_code(fn,code)
+    end
+
+    -- close file
+    if fn then
+        readfrom()
+    end
+
+    -- prepare working directory
+    local current_path
+    if not flags.w and flags.f then
+        current_path = gsub(flags.f, '(/)[^/]*%.?[^/]*$', '%1')
+    elseif flags.w then
+        if not (string.sub(flags.w, string.len(flags.w)) == '/') then
+            current_path = flags.w..'/'
+        else
+            current_path = flags.w
+        end
+    else
+        current_path = ''
+    end
+
+    -- deal with include directive
+    local nsubst
+    repeat
+        code,nsubst = gsub(code,'\n%s*%$(.)file%s*"(.-)"([^\n]*)\n',
+            function (kind,fn,extra)
+                local _, _, ext = strfind(fn,".*%.(.*)$")
+                local fp,msg = openfile(current_path..fn,'r')
+                if not fp then
+                    error('#'..msg..': '..fn)
+                end
+                local s = read(fp,'*a')
+                closefile(fp)
+                if kind == 'c' or kind == 'h' then
+                    return extract_code(fn,s)
+                elseif kind == 'p' then
+                    return "\n\n" .. s
+                elseif kind == 'l' then
+                    return "\n$[--##"..fn.."\n" .. s .. "\n$]\n"
+                elseif kind == 'i' then
+                    local t = {code=s}
+                    extra = string.gsub(extra, "^%s*,%s*", "")
+                    local pars = split_c_tokens(extra, ",")
+                    include_file_hook(t, fn, unpack(pars))
+                    return "\n\n" .. t.code
+                else
+                    error('#Invalid include directive (use $cfile, $pfile, $lfile or $ifile)')
+                end
+            end
+        )
+    until nsubst==0
+
+    -- deal with renaming directive
+    repeat -- I don't know why this is necesary
+        code,nsubst = gsub(code,'\n%s*%$renaming%s*(.-)%s*\n', function (r) appendrenaming(r) return "\n" end)
+    until nsubst == 0
+
+    local t = _Package(_Container{name=name, code=code})
+    push(t)
+    preprocess_hook(t)
+    t:preprocess()
+    preparse_hook(t)
+    t:parse(t.code)
+    pop()
+    return t
+end
+
+
Index: /code/branches/rocket2/src/external/tolua/lua/typedef.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/typedef.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/typedef.lua	(revision 6952)
@@ -0,0 +1,71 @@
+-- tolua: typedef class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- $Id: $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+
+-- Typedef class
+-- Represents a type synonym.
+-- The 'de facto' type replaces the typedef before the
+-- remaining code is parsed.
+-- The following fields are stored:
+--   utype = typedef name
+--   type = 'the facto' type
+--   mod = modifiers to the 'de facto' type
+classTypedef = {
+    utype = '',
+    mod = '',
+    type = ''
+}
+classTypedef.__index = classTypedef
+
+-- Print method
+function classTypedef:print (ident,close)
+    print(ident.."Typedef{")
+    print(ident.." utype = '"..self.utype.."',")
+    print(ident.." mod = '"..self.mod.."',")
+    print(ident.." type = '"..self.type.."',")
+    print(ident.."}"..close)
+end
+
+-- Return it's not a variable
+function classTypedef:isvariable ()
+    return false
+end
+
+-- Internal constructor
+function _Typedef (t)
+    setmetatable(t,classTypedef)
+    t.type = resolve_template_types(t.type)
+    appendtypedef(t)
+    return t
+end
+
+-- Constructor
+-- Expects one string representing the type definition.
+function Typedef (s)
+    if strfind(string.gsub(s, '%b<>', ''),'[%*&]') then
+        tolua_error("#invalid typedef: pointers (and references) are not supported")
+    end
+    local o = {mod = ''}
+    if string.find(s, "[<>]") then
+        _,_,o.type,o.utype = string.find(s, "^%s*([^<>]+%b<>[^%s]*)%s+(.-)$")
+    else
+        local t = split(gsub(s,"%s%s*"," ")," ")
+        o = {
+            utype = t[t.n],
+            type = t[t.n-1],
+            mod = concat(t,1,t.n-2),
+        }
+    end
+    return _Typedef(o)
+end
+
+
Index: /code/branches/rocket2/src/external/tolua/lua/variable.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/variable.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/variable.lua	(revision 6952)
@@ -0,0 +1,295 @@
+-- tolua: variable class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- $Id: $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+-- Variable class
+-- Represents a extern variable or a public member of a class.
+-- Stores all fields present in a declaration.
+classVariable = {
+    _get = {},   -- mapped get functions
+    _set = {},   -- mapped set functions
+}
+classVariable.__index = classVariable
+setmetatable(classVariable,classDeclaration)
+
+-- Print method
+function classVariable:print (ident,close)
+    print(ident.."Variable{")
+    print(ident.." mod  = '"..self.mod.."',")
+    print(ident.." type = '"..self.type.."',")
+    print(ident.." ptr  = '"..self.ptr.."',")
+    print(ident.." name = '"..self.name.."',")
+    if self.dim then print(ident.." dim = '"..self.dim.."',") end
+    print(ident.." def  = '"..self.def.."',")
+    print(ident.." ret  = '"..self.ret.."',")
+    print(ident.."}"..close)
+end
+
+-- Generates C function name
+function classVariable:cfuncname (prefix)
+    local parent = ""
+    local unsigned = ""
+    local ptr = ""
+
+    local p = self:inmodule() or self:innamespace() or self:inclass()
+
+    if p then
+        if self.parent.classtype == 'class' then
+            parent = "_" .. self.parent.type
+        else
+            parent = "_" .. p
+        end
+    end
+
+    if strfind(self.mod,"(unsigned)") then
+        unsigned = "_unsigned"
+    end
+
+    if self.ptr == "*" then ptr = "_ptr"
+    elseif self.ptr == "&" then ptr = "_ref"
+    end
+
+    local name =  prefix .. parent .. unsigned .. "_" .. gsub(self.lname or self.name,".*::","") .. ptr
+
+    name = clean_template(name)
+    return name
+
+end
+
+-- check if it is a variable
+function classVariable:isvariable ()
+    return true
+end
+
+-- get variable value
+function classVariable:getvalue (class,static, prop_get)
+
+    local name
+    if prop_get then
+
+        name = prop_get.."()"
+    else
+        name = self.name
+    end
+
+    if class and static then
+        return self.parent.type..'::'..name
+    elseif class then
+        return 'self->'..name
+    else
+        return name
+    end
+end
+
+-- get variable pointer value
+function classVariable:getpointervalue (class,static)
+    if class and static then
+        return class..'::p'
+    elseif class then
+        return 'self->p'
+    else
+        return 'p'
+    end
+end
+
+-- Write binding functions
+function classVariable:supcode ()
+
+ local class = self:inclass()
+
+    local prop_get,prop_set
+    if string.find(self.mod, 'tolua_property') then
+
+        _,_,type = string.find(self.mod, "tolua_property__([^%s]*)")
+        type = type or "default"
+        prop_get,prop_set = get_property_methods(type, self.name)
+        self.mod = string.gsub(self.mod, "tolua_property[^%s]*", "")
+    end
+
+    -- get function ------------------------------------------------
+    if class then
+        output("/* get function:",self.name," of class ",class," */")
+    else
+        output("/* get function:",self.name," */")
+    end
+    self.cgetname = self:cfuncname("tolua_get")
+    output("#ifndef TOLUA_DISABLE_"..self.cgetname)
+    output("\nstatic int",self.cgetname,"(lua_State* tolua_S)")
+    output("{")
+
+    -- declare self, if the case
+    local _,_,static = strfind(self.mod,'^%s*(static)')
+    if class and static==nil then
+        output(' ',self.parent.type,'*','self = ')
+        output('(',self.parent.type,'*) ')
+        output('tolua_tousertype(tolua_S,1,0);')
+    elseif static then
+        _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
+    end
+
+
+    -- check self value
+    if class and static==nil then
+        output('#ifndef TOLUA_RELEASE\n')
+        output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);');
+        output('#endif\n')
+    end
+
+    -- return value
+    if string.find(self.mod, 'tolua_inherits') then
+        output('#ifdef __cplusplus\n')
+        output('  tolua_pushusertype(tolua_S,(void*)static_cast<'..self.type..'*>(self), "',self.type,'");')
+        output('#else\n')
+        output('  tolua_pushusertype(tolua_S,(void*)(('..self.type..'*)self), "',self.type,'");')
+        output('#endif\n')
+    else
+        local t,ct = isbasic(self.type)
+        if t then
+            output('  tolua_push'..t..'(tolua_S,(',ct,')'..self:getvalue(class,static,prop_get)..');')
+        else
+            t = self.type
+            if self.ptr == '&' or self.ptr == '' then
+                output('  tolua_pushusertype(tolua_S,(void*)&'..self:getvalue(class,static,prop_get)..',"',t,'");')
+            else
+                output('  tolua_pushusertype(tolua_S,(void*)'..self:getvalue(class,static,prop_get)..',"',t,'");')
+            end
+        end
+    end
+    output(' return 1;')
+    output('}')
+    output('#endif //#ifndef TOLUA_DISABLE\n')
+    output('\n')
+
+    -- set function ------------------------------------------------
+    if not (strfind(self.type,'const%s+') or string.find(self.mod, 'tolua_readonly') or string.find(self.mod, 'tolua_inherits'))  then
+    if class then
+        output("/* set function:",self.name," of class ",class," */")
+    else
+        output("/* set function:",self.name," */")
+    end
+    self.csetname = self:cfuncname("tolua_set")
+    output("#ifndef TOLUA_DISABLE_"..self.csetname)
+    output("\nstatic int",self.csetname,"(lua_State* tolua_S)")
+    output("{")
+
+    -- declare self, if the case
+    if class and static==nil then
+        output(' ',self.parent.type,'*','self = ')
+        output('(',self.parent.type,'*) ')
+        output('tolua_tousertype(tolua_S,1,0);')
+        -- check self value
+    end
+    -- check types
+    output('#ifndef TOLUA_RELEASE\n')
+    output('  tolua_Error tolua_err;')
+    if class and static==nil then
+        output('  if (!self) tolua_error(tolua_S,"invalid \'self\' in accessing variable \''..self.name..'\'",NULL);');
+    elseif static then
+        _,_,self.mod = strfind(self.mod,'^%s*static%s%s*(.*)')
+    end
+
+    -- check variable type
+    output('  if (!'..self:outchecktype(2)..')')
+    output('   tolua_error(tolua_S,"#vinvalid type in variable assignment.",&tolua_err);')
+    output('#endif\n')
+
+    -- assign value
+    local def = 0
+    if self.def ~= '' then def = self.def end
+    if self.type == 'char*' and self.dim ~= '' then -- is string
+        output(' strncpy(')
+        if class and static then
+            output(self.parent.type..'::'..self.name)
+            elseif class then
+                output('self->'..self.name)
+            else
+                output(self.name)
+            end
+            output(',tolua_tostring(tolua_S,2,',def,'),',self.dim,'-1);')
+        else
+            local ptr = ''
+            if self.ptr~='' then ptr = '*' end
+            output(' ')
+            local name = prop_set or self.name
+            if class and static then
+                output(self.parent.type..'::'..name)
+            elseif class then
+                output('self->'..name)
+            else
+                output(name)
+            end
+            local t = isbasic(self.type)
+            if prop_set then
+                output('(')
+            else
+                output(' = ')
+            end
+            if not t and ptr=='' then output('*') end
+            output('((',self.mod,self.type)
+            if not t then
+                output('*')
+            end
+            output(') ')
+            if t then
+                if isenum(self.type) then
+                    output('(int) ')
+                end
+                output('tolua_to'..t,'(tolua_S,2,',def,'))')
+            else
+                output('tolua_tousertype(tolua_S,2,',def,'))')
+            end
+            if prop_set then
+                output(")")
+            end
+            output(";")
+        end
+        output(' return 0;')
+        output('}')
+        output('#endif //#ifndef TOLUA_DISABLE\n')
+        output('\n')
+    end
+
+end
+
+function classVariable:register (pre)
+
+    if not self:check_public_access() then
+        return
+    end
+    pre = pre or ''
+    local parent = self:inmodule() or self:innamespace() or self:inclass()
+    if not parent then
+        if classVariable._warning==nil then
+            warning("Mapping variable to global may degrade performance")
+            classVariable._warning = 1
+        end
+    end
+    if self.csetname then
+        output(pre..'tolua_variable(tolua_S,"'..self.lname..'",'..self.cgetname..','..self.csetname..');')
+    else
+        output(pre..'tolua_variable(tolua_S,"'..self.lname..'",'..self.cgetname..',NULL);')
+    end
+end
+
+-- Internal constructor
+function _Variable (t)
+    setmetatable(t,classVariable)
+    append(t)
+    return t
+end
+
+-- Constructor
+-- Expects a string representing the variable declaration.
+function Variable (s)
+    return _Variable (Declaration(s,'var'))
+end
+
+
Index: /code/branches/rocket2/src/external/tolua/lua/verbatim.lua
===================================================================
--- /code/branches/rocket2/src/external/tolua/lua/verbatim.lua	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/lua/verbatim.lua	(revision 6952)
@@ -0,0 +1,78 @@
+-- tolua: verbatim class
+-- Written by Waldemar Celes
+-- TeCGraf/PUC-Rio
+-- Jul 1998
+-- $Id: verbatim.lua,v 1.3 2000/01/24 20:41:16 celes Exp $
+
+-- This code is free software; you can redistribute it and/or modify it.
+-- The software provided hereunder is on an "as is" basis, and
+-- the author has no obligation to provide maintenance, support, updates,
+-- enhancements, or modifications.
+
+
+
+-- Verbatim class
+-- Represents a line translated directed to the binding file.
+-- The following filds are stored:
+--   line = line text
+classVerbatim = {
+    line = '',
+    cond = nil,    -- condition: where to generate the code (s=suport, r=register)
+}
+classVerbatim.__index = classVerbatim
+setmetatable(classVerbatim,classFeature)
+
+-- preamble verbatim
+function classVerbatim:preamble ()
+    if self.cond == '' then
+        write(self.line)
+    end
+end
+
+-- support code
+function classVerbatim:supcode ()
+    if strfind(self.cond,'s') then
+        write(self.line)
+        write('\n')
+    end
+end
+
+-- register code
+function classVerbatim:register (pre)
+    if strfind(self.cond,'r') then
+        write(self.line)
+    end
+end
+
+
+-- Print method
+function classVerbatim:print (ident,close)
+    print(ident.."Verbatim{")
+    print(ident.." line = '"..self.line.."',")
+    print(ident.."}"..close)
+    end
+
+
+-- Internal constructor
+function _Verbatim (t)
+    setmetatable(t,classVerbatim)
+    append(t)
+    return t
+end
+
+-- Constructor
+-- Expects a string representing the text line
+function Verbatim (l,cond)
+    if strsub(l,1,1) == "'" then
+        l = strsub(l,2)
+    elseif strsub(l,1,1) == '$' then
+        cond = 'sr'       -- generates in both suport and register fragments
+        l = strsub(l,2)
+    end
+    return _Verbatim {
+        line = l,
+        cond = cond or '',
+    }
+end
+
+
Index: /code/branches/rocket2/src/external/tolua/tolua++.h
===================================================================
--- /code/branches/rocket2/src/external/tolua/tolua++.h	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/tolua++.h	(revision 6952)
@@ -0,0 +1,182 @@
+/* tolua
+** Support code for Lua bindings.
+** Written by Waldemar Celes
+** TeCGraf/PUC-Rio
+** Apr 2003
+** $Id: $
+*/
+
+/* This code is free software; you can redistribute it and/or modify it.
+** The software provided hereunder is on an "as is" basis, and
+** the author has no obligation to provide maintenance, support, updates,
+** enhancements, or modifications.
+*/
+
+
+#ifndef TOLUA_H
+#define TOLUA_H
+
+/* original code */
+/*
+#ifndef TOLUA_API
+#define TOLUA_API extern
+#endif
+*/
+
+/********************************
+******* ORXONOX CHANGES *********
+********************************/
+
+#if (defined( __WIN32__ ) || defined( _WIN32 )) && !defined( TOLUA_STATIC_BUILD )
+#  ifdef TOLUA_SHARED_BUILD
+#    define TOLUA_API __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define TOLUA_API
+#    else
+#      define TOLUA_API __declspec(dllimport)
+#    endif
+#  endif
+#else
+#  define TOLUA_API extern
+#endif
+
+/********************************
+****** END ORXONOX CHANGES ******
+********************************/
+
+#define TOLUA_VERSION "tolua++-1.0.92"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define tolua_pushcppstring(x,y)	tolua_pushstring(x,y.c_str())
+#define tolua_iscppstring	tolua_isstring
+
+#define tolua_iscppstringarray tolua_isstringarray
+#define tolua_pushfieldcppstring(L,lo,idx,s) tolua_pushfieldstring(L, lo, idx, s.c_str())
+
+#define TEMPLATE_BIND(p)
+#define TOLUA_TEMPLATE_BIND(p)
+#define TOLUA_PROTECTED_DESTRUCTOR
+#define TOLUA_PROPERTY_TYPE(p)
+
+typedef int lua_Object;
+
+#include "lua.h"
+#include "lauxlib.h"
+
+struct tolua_Error
+{
+	int index;
+	int array;
+	const char* type;
+};
+typedef struct tolua_Error tolua_Error;
+
+#define TOLUA_NOPEER	LUA_REGISTRYINDEX /* for lua 5.1 */
+
+TOLUA_API const char* tolua_typename (lua_State* L, int lo);
+TOLUA_API void tolua_error (lua_State* L, char* msg, tolua_Error* err);
+TOLUA_API int tolua_isnoobj (lua_State* L, int lo, tolua_Error* err);
+TOLUA_API int tolua_isvalue (lua_State* L, int lo, int def, tolua_Error* err);
+TOLUA_API int tolua_isboolean (lua_State* L, int lo, int def, tolua_Error* err);
+TOLUA_API int tolua_isnumber (lua_State* L, int lo, int def, tolua_Error* err);
+TOLUA_API int tolua_isstring (lua_State* L, int lo, int def, tolua_Error* err);
+TOLUA_API int tolua_istable (lua_State* L, int lo, int def, tolua_Error* err);
+TOLUA_API int tolua_isusertable (lua_State* L, int lo, const char* type, int def, tolua_Error* err);
+TOLUA_API int tolua_isuserdata (lua_State* L, int lo, int def, tolua_Error* err);
+TOLUA_API int tolua_isusertype (lua_State* L, int lo, const char* type, int def, tolua_Error* err);
+TOLUA_API int tolua_isvaluearray
+ (lua_State* L, int lo, int dim, int def, tolua_Error* err);
+TOLUA_API int tolua_isbooleanarray
+ (lua_State* L, int lo, int dim, int def, tolua_Error* err);
+TOLUA_API int tolua_isnumberarray
+ (lua_State* L, int lo, int dim, int def, tolua_Error* err);
+TOLUA_API int tolua_isstringarray
+ (lua_State* L, int lo, int dim, int def, tolua_Error* err);
+TOLUA_API int tolua_istablearray
+ (lua_State* L, int lo, int dim, int def, tolua_Error* err);
+TOLUA_API int tolua_isuserdataarray
+ (lua_State* L, int lo, int dim, int def, tolua_Error* err);
+TOLUA_API int tolua_isusertypearray
+ (lua_State* L, int lo, const char* type, int dim, int def, tolua_Error* err);
+
+TOLUA_API void tolua_open (lua_State* L);
+
+TOLUA_API void* tolua_copy (lua_State* L, void* value, unsigned int size);
+TOLUA_API int tolua_register_gc (lua_State* L, int lo);
+TOLUA_API int tolua_default_collect (lua_State* tolua_S);
+
+TOLUA_API void tolua_usertype (lua_State* L, char* type);
+TOLUA_API void tolua_beginmodule (lua_State* L, char* name);
+TOLUA_API void tolua_endmodule (lua_State* L);
+TOLUA_API void tolua_module (lua_State* L, char* name, int hasvar);
+TOLUA_API void tolua_class (lua_State* L, char* name, char* base);
+TOLUA_API void tolua_cclass (lua_State* L, char* lname, char* name, char* base, lua_CFunction col);
+TOLUA_API void tolua_function (lua_State* L, char* name, lua_CFunction func);
+TOLUA_API void tolua_constant (lua_State* L, char* name, double value);
+TOLUA_API void tolua_variable (lua_State* L, char* name, lua_CFunction get, lua_CFunction set);
+TOLUA_API void tolua_array (lua_State* L,char* name, lua_CFunction get, lua_CFunction set);
+
+/* TOLUA_API void tolua_set_call_event(lua_State* L, lua_CFunction func, char* type); */
+/* TOLUA_API void tolua_addbase(lua_State* L, char* name, char* base); */
+
+TOLUA_API void tolua_pushvalue (lua_State* L, int lo);
+TOLUA_API void tolua_pushboolean (lua_State* L, int value);
+TOLUA_API void tolua_pushnumber (lua_State* L, double value);
+TOLUA_API void tolua_pushstring (lua_State* L, const char* value);
+TOLUA_API void tolua_pushuserdata (lua_State* L, void* value);
+TOLUA_API void tolua_pushusertype (lua_State* L, void* value, const char* type);
+TOLUA_API void tolua_pushusertype_and_takeownership(lua_State* L, void* value, const char* type);
+TOLUA_API void tolua_pushfieldvalue (lua_State* L, int lo, int index, int v);
+TOLUA_API void tolua_pushfieldboolean (lua_State* L, int lo, int index, int v);
+TOLUA_API void tolua_pushfieldnumber (lua_State* L, int lo, int index, double v);
+TOLUA_API void tolua_pushfieldstring (lua_State* L, int lo, int index, const char* v);
+TOLUA_API void tolua_pushfielduserdata (lua_State* L, int lo, int index, void* v);
+TOLUA_API void tolua_pushfieldusertype (lua_State* L, int lo, int index, void* v, const char* type);
+TOLUA_API void tolua_pushfieldusertype_and_takeownership (lua_State* L, int lo, int index, void* v, const char* type);
+
+TOLUA_API double tolua_tonumber (lua_State* L, int narg, double def);
+TOLUA_API const char* tolua_tostring (lua_State* L, int narg, const char* def);
+TOLUA_API void* tolua_touserdata (lua_State* L, int narg, void* def);
+TOLUA_API void* tolua_tousertype (lua_State* L, int narg, void* def);
+TOLUA_API int tolua_tovalue (lua_State* L, int narg, int def);
+TOLUA_API int tolua_toboolean (lua_State* L, int narg, int def);
+TOLUA_API double tolua_tofieldnumber (lua_State* L, int lo, int index, double def);
+TOLUA_API const char* tolua_tofieldstring (lua_State* L, int lo, int index, const char* def);
+TOLUA_API void* tolua_tofielduserdata (lua_State* L, int lo, int index, void* def);
+TOLUA_API void* tolua_tofieldusertype (lua_State* L, int lo, int index, void* def);
+TOLUA_API int tolua_tofieldvalue (lua_State* L, int lo, int index, int def);
+TOLUA_API int tolua_getfieldboolean (lua_State* L, int lo, int index, int def);
+
+TOLUA_API void tolua_dobuffer(lua_State* L, char* B, unsigned int size, const char* name);
+
+TOLUA_API int class_gc_event (lua_State* L);
+
+#ifdef __cplusplus
+static inline const char* tolua_tocppstring (lua_State* L, int narg, const char* def) {
+
+	const char* s = tolua_tostring(L, narg, def);
+	return s?s:"";
+};
+
+static inline const char* tolua_tofieldcppstring (lua_State* L, int lo, int index, const char* def) {
+
+	const char* s = tolua_tofieldstring(L, lo, index, def);
+	return s?s:"";
+};
+
+#else
+#define tolua_tocppstring tolua_tostring
+#define tolua_tofieldcppstring tolua_tofieldstring
+#endif
+
+TOLUA_API int tolua_fast_isa(lua_State *L, int mt_indexa, int mt_indexb, int super_index);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Index: /code/branches/rocket2/src/external/tolua/tolua.c
===================================================================
--- /code/branches/rocket2/src/external/tolua/tolua.c	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/tolua.c	(revision 6952)
@@ -0,0 +1,211 @@
+/* tolua
+** Support code for Lua bindings.
+** Written by Waldemar Celes
+** TeCGraf/PUC-Rio
+** Aug 2003
+** $Id:$
+** Extension by Orxonox (Reto Grieder) to support working directory
+** and direct usage of lua files. (2008)
+*/
+
+/* This code is free software; you can redistribute it and/or modify it.
+** The software provided hereunder is on an "as is" basis, and
+** the author has no obligation to provide maintenance, support, updates,
+** enhancements, or modifications.
+*/
+
+#include "tolua++.h"
+
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+static void help (void)
+{
+ fprintf(stderr,"\n"
+         "usage: tolua++ [options] input_file\n"
+         "\n"
+         "Command line options are:\n"
+         "  -v       : print version information.\n"
+         "  -o  file : set output file; default is stdout.\n"
+         "  -H  file : create include file.\n"
+         "  -n  name : set package name; default is input file root name.\n"
+         "  -w  directory : set working directory; default is location of package file.\n"
+         "  -s  file : specify source lua code for the parser; all.lua is default.\n"
+         "  -p       : parse only.\n"
+         "  -P       : parse and print structure information (for debug).\n"
+         "  -S       : disable support for c++ strings.\n"
+         "  -1       : substract 1 to operator[] index (for compatibility with tolua5).\n"
+         "  -L  file : run lua file (with dofile()) before doing anything.\n"
+         "  -D       : disable automatic exporting of destructors for classes that have\n"
+         "             constructors (for compatibility with tolua5)\n"
+         "  -W       : disable warnings for unsupported features (for compatibility\n"
+         "             with tolua5)\n"
+         "  -C       : disable cleanup of included lua code (for easier debugging)\n"
+         "  -E  value[=value] : add extra values to the luastate\n"
+         "  -t       : export a list of types asociates with the C++ typeid name\n"
+         "  -h       : print this message.\n"
+         "Should the input file be omitted, stdin is assumed;\n"
+         "in that case, the package name must be explicitly set.\n\n"
+        );
+}
+
+static void version (void)
+{
+ fprintf(stderr, "%s (written by W. Celes, A. Manzur)\n",TOLUA_VERSION);
+}
+
+static void setfield (lua_State* L, int table, char* f, char* v)
+{
+ lua_pushstring(L,f);
+ lua_pushstring(L,v);
+ lua_settable(L,table);
+}
+
+static void add_extra (lua_State* L, char* value) {
+ int len;
+ lua_getglobal(L, "_extra_parameters");
+ len = luaL_getn(L, -1);
+ lua_pushstring(L, value);
+ lua_rawseti(L, -2, len+1);
+ lua_pop(L, 1);
+};
+
+static void error (char* o)
+{
+ fprintf(stderr,"tolua: unknown option '%s'\n",o);
+ help();
+ exit(1);
+}
+
+int main (int argc, char* argv[])
+{
+ char* working_directory = "";
+ char* lua_source = "";
+
+ #ifdef LUA_VERSION_NUM /* lua 5.1 */
+ lua_State* L = luaL_newstate();
+ luaL_openlibs(L);
+ #else
+ lua_State* L = lua_open();
+ luaopen_base(L);
+ luaopen_io(L);
+ luaopen_string(L);
+ luaopen_table(L);
+ luaopen_math(L);
+ luaopen_debug(L);
+ #endif
+
+ lua_pushstring(L,TOLUA_VERSION); lua_setglobal(L,"TOLUA_VERSION");
+ lua_pushstring(L,LUA_VERSION); lua_setglobal(L,"TOLUA_LUA_VERSION");
+
+
+ if (argc==1)
+ {
+  help();
+  return 0;
+ }
+ else
+ {
+  int i, t;
+  lua_newtable(L);
+  lua_setglobal(L, "_extra_parameters");
+  lua_newtable(L);
+  lua_pushvalue(L,-1);
+  lua_setglobal(L,"flags");
+  t = lua_gettop(L);
+  for (i=1; i<argc; ++i)
+  {
+   if (*argv[i] == '-')
+   {
+    switch (argv[i][1])
+    {
+     case 'v': version(); return 0;
+     case 'h': help(); return 0;
+     case 'p': setfield(L,t,"p",""); break;
+     case 'P': setfield(L,t,"P",""); break;
+     case 'o': setfield(L,t,"o",argv[++i]); break;
+     case 'n': setfield(L,t,"n",argv[++i]); break;
+     case 'H': setfield(L,t,"H",argv[++i]); break;
+     case 'w':
+      working_directory = argv[++i];
+      setfield(L,t,"w",argv[i]);
+      break;
+     case 's':
+      lua_source = argv[++i];
+      setfield(L,t,"s",argv[i]);
+      break;
+     case 'S': setfield(L,t,"S",""); break;
+     case '1': setfield(L,t,"1",""); break;
+     case 'L': setfield(L,t,"L",argv[++i]); break;
+     case 'D': setfield(L,t,"D",""); break;
+     case 'W': setfield(L,t,"W",""); break;
+     case 'C': setfield(L,t,"C",""); break;
+     case 'E': add_extra(L,argv[++i]); break;
+     case 't': setfield(L,t,"t",""); break;
+     default: error(argv[i]); break;
+    }
+   }
+   else
+   {
+    setfield(L,t,"f",argv[i]);
+    break;
+   }
+  }
+  lua_pop(L,1);
+ }
+
+ {
+  char path[BUFSIZ];
+  char file[BUFSIZ];
+  path[0] = '\0';
+  file[0] = '\0';
+
+  if (strlen(lua_source) > 0 &&
+      lua_source[0] != '/' &&
+      lua_source[0] != '\\' &&
+      strlen(lua_source) > 1 &&
+      lua_source[1] != ':')
+  {
+   /* Relative path, prefix working directory */
+   strcpy(path, working_directory);
+   /* Make sure there is '\\' or '/' at the end of the path */
+   if (strlen(path) > 0)
+   {
+    char last = path[strlen(path) - 1];
+    if (last != '\\' && last != '/')
+     strcat(path, "/");
+   }
+  }
+
+  strcat(path, lua_source);
+
+  /* Extract the full path */
+  {
+   char* p;
+   p = strrchr(path, '/');
+   if (p == NULL)
+    p = strrchr(path, '\\');
+   p = (p == NULL) ? path : p + 1;
+   strcpy(file, p);
+   *p = '\0';
+  }
+  if (strlen(file) == 0)
+   strcpy(file, "all.lua");
+
+  lua_pushstring(L, path);
+  lua_setglobal(L, "path");
+  strcat(path, file);
+#ifdef LUA_VERSION_NUM /* lua 5.1 */
+  luaL_dofile(L, path);
+#else
+  lua_dofile(L, path);
+#endif
+ }
+ return 0;
+}
Index: /code/branches/rocket2/src/external/tolua/tolua_event.c
===================================================================
--- /code/branches/rocket2/src/external/tolua/tolua_event.c	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/tolua_event.c	(revision 6952)
@@ -0,0 +1,513 @@
+/* tolua: event functions
+** Support code for Lua bindings.
+** Written by Waldemar Celes
+** TeCGraf/PUC-Rio
+** Apr 2003
+** $Id: $
+*/
+
+/* This code is free software; you can redistribute it and/or modify it.
+** The software provided hereunder is on an "as is" basis, and
+** the author has no obligation to provide maintenance, support, updates,
+** enhancements, or modifications.
+*/
+
+#include <stdio.h>
+
+#include "tolua++.h"
+
+/* Store at ubox
+	* It stores, creating the corresponding table if needed,
+	* the pair key/value in the corresponding ubox table
+*/
+static void storeatubox (lua_State* L, int lo)
+{
+	#ifdef LUA_VERSION_NUM
+		lua_getfenv(L, lo);
+		if (lua_rawequal(L, -1, TOLUA_NOPEER)) {
+			lua_pop(L, 1);
+			lua_newtable(L);
+			lua_pushvalue(L, -1);
+			lua_setfenv(L, lo);	/* stack: k,v,table  */
+		};
+		lua_insert(L, -3);
+		lua_settable(L, -3); /* on lua 5.1, we trade the "tolua_peers" lookup for a settable call */
+		lua_pop(L, 1);
+	#else
+	 /* stack: key value (to be stored) */
+		lua_pushstring(L,"tolua_peers");
+		lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: k v ubox */
+		lua_pushvalue(L,lo);
+		lua_rawget(L,-2);                       /* stack: k v ubox ubox[u] */
+		if (!lua_istable(L,-1))
+		{
+			lua_pop(L,1);                          /* stack: k v ubox */
+			lua_newtable(L);                       /* stack: k v ubox table */
+			lua_pushvalue(L,1);
+			lua_pushvalue(L,-2);                   /* stack: k v ubox table u table */
+			lua_rawset(L,-4);                      /* stack: k v ubox ubox[u]=table */
+		}
+		lua_insert(L,-4);                       /* put table before k */
+		lua_pop(L,1);                           /* pop ubox */
+		lua_rawset(L,-3);                       /* store at table */
+		lua_pop(L,1);                           /* pop ubox[u] */
+	#endif
+}
+
+/* Module index function
+*/
+static int module_index_event (lua_State* L)
+{
+	lua_pushstring(L,".get");
+	lua_rawget(L,-3);
+	if (lua_istable(L,-1))
+	{
+		lua_pushvalue(L,2);  /* key */
+		lua_rawget(L,-2);
+		if (lua_iscfunction(L,-1))
+		{
+			lua_call(L,0,1);
+			return 1;
+		}
+		else if (lua_istable(L,-1))
+			return 1;
+	}
+	/* call old index meta event */
+	if (lua_getmetatable(L,1))
+	{
+		lua_pushstring(L,"__index");
+		lua_rawget(L,-2);
+		lua_pushvalue(L,1);
+		lua_pushvalue(L,2);
+		if (lua_isfunction(L,-1))
+		{
+			lua_call(L,2,1);
+			return 1;
+		}
+		else if (lua_istable(L,-1))
+		{
+			lua_gettable(L,-3);
+			return 1;
+		}
+	}
+	lua_pushnil(L);
+	return 1;
+}
+
+/* Module newindex function
+*/
+static int module_newindex_event (lua_State* L)
+{
+	lua_pushstring(L,".set");
+	lua_rawget(L,-4);
+	if (lua_istable(L,-1))
+	{
+		lua_pushvalue(L,2);  /* key */
+		lua_rawget(L,-2);
+		if (lua_iscfunction(L,-1))
+		{
+			lua_pushvalue(L,1); /* only to be compatible with non-static vars */
+			lua_pushvalue(L,3); /* value */
+			lua_call(L,2,0);
+			return 0;
+		}
+	}
+	/* call old newindex meta event */
+	if (lua_getmetatable(L,1) && lua_getmetatable(L,-1))
+	{
+		lua_pushstring(L,"__newindex");
+		lua_rawget(L,-2);
+		if (lua_isfunction(L,-1))
+		{
+		 lua_pushvalue(L,1);
+		 lua_pushvalue(L,2);
+		 lua_pushvalue(L,3);
+			lua_call(L,3,0);
+		}
+	}
+	lua_settop(L,3);
+	lua_rawset(L,-3);
+	return 0;
+}
+
+/* Class index function
+	* If the object is a userdata (ie, an object), it searches the field in
+	* the alternative table stored in the corresponding "ubox" table.
+*/
+static int class_index_event (lua_State* L)
+{
+ int t = lua_type(L,1);
+	if (t == LUA_TUSERDATA)
+	{
+		/* Access alternative table */
+		#ifdef LUA_VERSION_NUM /* new macro on version 5.1 */
+		lua_getfenv(L,1);
+		if (!lua_rawequal(L, -1, TOLUA_NOPEER)) {
+			lua_pushvalue(L, 2); /* key */
+			lua_gettable(L, -2); /* on lua 5.1, we trade the "tolua_peers" lookup for a gettable call */
+			if (!lua_isnil(L, -1))
+				return 1;
+		};
+		#else
+		lua_pushstring(L,"tolua_peers");
+		lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: obj key ubox */
+		lua_pushvalue(L,1);
+		lua_rawget(L,-2);                       /* stack: obj key ubox ubox[u] */
+		if (lua_istable(L,-1))
+		{
+			lua_pushvalue(L,2);  /* key */
+			lua_rawget(L,-2);                      /* stack: obj key ubox ubox[u] value */
+			if (!lua_isnil(L,-1))
+				return 1;
+		}
+		#endif
+		lua_settop(L,2);                        /* stack: obj key */
+		/* Try metatables */
+		lua_pushvalue(L,1);                     /* stack: obj key obj */
+		while (lua_getmetatable(L,-1))
+		{                                       /* stack: obj key obj mt */
+			lua_remove(L,-2);                      /* stack: obj key mt */
+			if (lua_isnumber(L,2))                 /* check if key is a numeric value */
+			{
+				/* try operator[] */
+				lua_pushstring(L,".geti");
+				lua_rawget(L,-2);                      /* stack: obj key mt func */
+				if (lua_isfunction(L,-1))
+				{
+					lua_pushvalue(L,1);
+					lua_pushvalue(L,2);
+					lua_call(L,2,1);
+					return 1;
+				}
+			}
+			else
+			{
+			 lua_pushvalue(L,2);                    /* stack: obj key mt key */
+				lua_rawget(L,-2);                      /* stack: obj key mt value */
+				if (!lua_isnil(L,-1))
+					return 1;
+				else
+					lua_pop(L,1);
+				/* try C/C++ variable */
+				lua_pushstring(L,".get");
+				lua_rawget(L,-2);                      /* stack: obj key mt tget */
+				if (lua_istable(L,-1))
+				{
+					lua_pushvalue(L,2);
+					lua_rawget(L,-2);                      /* stack: obj key mt value */
+					if (lua_iscfunction(L,-1))
+					{
+						lua_pushvalue(L,1);
+						lua_pushvalue(L,2);
+						lua_call(L,2,1);
+						return 1;
+					}
+					else if (lua_istable(L,-1))
+					{
+						/* deal with array: create table to be returned and cache it in ubox */
+						void* u = *((void**)lua_touserdata(L,1));
+						lua_newtable(L);                /* stack: obj key mt value table */
+						lua_pushstring(L,".self");
+						lua_pushlightuserdata(L,u);
+						lua_rawset(L,-3);               /* store usertype in ".self" */
+						lua_insert(L,-2);               /* stack: obj key mt table value */
+						lua_setmetatable(L,-2);         /* set stored value as metatable */
+						lua_pushvalue(L,-1);            /* stack: obj key met table table */
+						lua_pushvalue(L,2);             /* stack: obj key mt table table key */
+						lua_insert(L,-2);               /*  stack: obj key mt table key table */
+						storeatubox(L,1);               /* stack: obj key mt table */
+						return 1;
+					}
+				}
+			}
+			lua_settop(L,3);
+		}
+		lua_pushnil(L);
+		return 1;
+	}
+	else if (t== LUA_TTABLE)
+	{
+		module_index_event(L);
+		return 1;
+	}
+	lua_pushnil(L);
+	return 1;
+}
+
+/* Newindex function
+	* It first searches for a C/C++ varaible to be set.
+	* Then, it either stores it in the alternative ubox table (in the case it is
+	* an object) or in the own table (that represents the class or module).
+*/
+static int class_newindex_event (lua_State* L)
+{
+ int t = lua_type(L,1);
+	if (t == LUA_TUSERDATA)
+	{
+	 /* Try accessing a C/C++ variable to be set */
+		lua_getmetatable(L,1);
+		while (lua_istable(L,-1))                /* stack: t k v mt */
+		{
+			if (lua_isnumber(L,2))                 /* check if key is a numeric value */
+			{
+				/* try operator[] */
+				lua_pushstring(L,".seti");
+				lua_rawget(L,-2);                      /* stack: obj key mt func */
+				if (lua_isfunction(L,-1))
+				{
+					lua_pushvalue(L,1);
+					lua_pushvalue(L,2);
+					lua_pushvalue(L,3);
+					lua_call(L,3,0);
+					return 0;
+				}
+			}
+			else
+			{
+				lua_pushstring(L,".set");
+				lua_rawget(L,-2);                      /* stack: t k v mt tset */
+				if (lua_istable(L,-1))
+				{
+					lua_pushvalue(L,2);
+					lua_rawget(L,-2);                     /* stack: t k v mt tset func */
+					if (lua_iscfunction(L,-1))
+					{
+						lua_pushvalue(L,1);
+						lua_pushvalue(L,3);
+						lua_call(L,2,0);
+						return 0;
+					}
+					lua_pop(L,1);                          /* stack: t k v mt tset */
+				}
+				lua_pop(L,1);                           /* stack: t k v mt */
+				if (!lua_getmetatable(L,-1))            /* stack: t k v mt mt */
+					lua_pushnil(L);
+				lua_remove(L,-2);                       /* stack: t k v mt */
+			}
+		}
+	 lua_settop(L,3);                          /* stack: t k v */
+
+		/* then, store as a new field */
+		storeatubox(L,1);
+	}
+	else if (t== LUA_TTABLE)
+	{
+		module_newindex_event(L);
+	}
+	return 0;
+}
+
+static int class_call_event(lua_State* L) {
+
+	if (lua_istable(L, 1)) {
+		lua_pushstring(L, ".call");
+		lua_rawget(L, 1);
+		if (lua_isfunction(L, -1)) {
+
+			lua_insert(L, 1);
+			lua_call(L, lua_gettop(L)-1, 1);
+
+			return 1;
+		};
+	};
+	tolua_error(L,"Attempt to call a non-callable object.",NULL);
+	return 0;
+};
+
+static int do_operator (lua_State* L, const char* op)
+{
+	if (lua_isuserdata(L,1))
+	{
+		/* Try metatables */
+		lua_pushvalue(L,1);                     /* stack: op1 op2 */
+		while (lua_getmetatable(L,-1))
+		{                                       /* stack: op1 op2 op1 mt */
+			lua_remove(L,-2);                      /* stack: op1 op2 mt */
+			lua_pushstring(L,op);                  /* stack: op1 op2 mt key */
+			lua_rawget(L,-2);                      /* stack: obj key mt func */
+			if (lua_isfunction(L,-1))
+			{
+				lua_pushvalue(L,1);
+				lua_pushvalue(L,2);
+				lua_call(L,2,1);
+				return 1;
+			}
+			lua_settop(L,3);
+		}
+	}
+	tolua_error(L,"Attempt to perform operation on an invalid operand",NULL);
+	return 0;
+}
+
+static int class_add_event (lua_State* L)
+{
+	return do_operator(L,".add");
+}
+
+static int class_sub_event (lua_State* L)
+{
+	return do_operator(L,".sub");
+}
+
+static int class_mul_event (lua_State* L)
+{
+	return do_operator(L,".mul");
+}
+
+static int class_div_event (lua_State* L)
+{
+	return do_operator(L,".div");
+}
+
+static int class_lt_event (lua_State* L)
+{
+	return do_operator(L,".lt");
+}
+
+static int class_le_event (lua_State* L)
+{
+	return do_operator(L,".le");
+}
+
+static int class_eq_event (lua_State* L)
+{
+	return do_operator(L,".eq");
+}
+
+/*
+static int class_gc_event (lua_State* L)
+{
+	void* u = *((void**)lua_touserdata(L,1));
+	fprintf(stderr, "collecting: looking at %p\n", u);
+	lua_pushstring(L,"tolua_gc");
+	lua_rawget(L,LUA_REGISTRYINDEX);
+	lua_pushlightuserdata(L,u);
+	lua_rawget(L,-2);
+	if (lua_isfunction(L,-1))
+	{
+		lua_pushvalue(L,1);
+		lua_call(L,1,0);
+ 		lua_pushlightuserdata(L,u);
+		lua_pushnil(L);
+		lua_rawset(L,-3);
+	}
+	lua_pop(L,2);
+	return 0;
+}
+*/
+TOLUA_API int class_gc_event (lua_State* L)
+{
+	void* u = *((void**)lua_touserdata(L,1));
+	int top;
+	/*fprintf(stderr, "collecting: looking at %p\n", u);*/
+	/*
+	lua_pushstring(L,"tolua_gc");
+	lua_rawget(L,LUA_REGISTRYINDEX);
+	*/
+	lua_pushvalue(L, lua_upvalueindex(1));
+	lua_pushlightuserdata(L,u);
+	lua_rawget(L,-2);            /* stack: gc umt    */
+	lua_getmetatable(L,1);       /* stack: gc umt mt */
+	/*fprintf(stderr, "checking type\n");*/
+	top = lua_gettop(L);
+	if (tolua_fast_isa(L,top,top-1, lua_upvalueindex(2))) /* make sure we collect correct type */
+	{
+		/*fprintf(stderr, "Found type!\n");*/
+		/* get gc function */
+		lua_pushliteral(L,".collector");
+		lua_rawget(L,-2);           /* stack: gc umt mt collector */
+		if (lua_isfunction(L,-1)) {
+			/*fprintf(stderr, "Found .collector!\n");*/
+		}
+		else {
+			lua_pop(L,1);
+			/*fprintf(stderr, "Using default cleanup\n");*/
+			lua_pushcfunction(L,tolua_default_collect);
+		}
+
+		lua_pushvalue(L,1);         /* stack: gc umt mt collector u */
+		lua_call(L,1,0);
+
+		lua_pushlightuserdata(L,u); /* stack: gc umt mt u */
+		lua_pushnil(L);             /* stack: gc umt mt u nil */
+		lua_rawset(L,-5);           /* stack: gc umt mt */
+	}
+	lua_pop(L,3);
+	return 0;
+}
+
+
+/* Register module events
+	* It expects the metatable on the top of the stack
+*/
+TOLUA_API void tolua_moduleevents (lua_State* L)
+{
+	lua_pushstring(L,"__index");
+	lua_pushcfunction(L,module_index_event);
+	lua_rawset(L,-3);
+	lua_pushstring(L,"__newindex");
+	lua_pushcfunction(L,module_newindex_event);
+	lua_rawset(L,-3);
+}
+
+/* Check if the object on the top has a module metatable
+*/
+TOLUA_API int tolua_ismodulemetatable (lua_State* L)
+{
+	int r = 0;
+	if (lua_getmetatable(L,-1))
+	{
+		lua_pushstring(L,"__index");
+		lua_rawget(L,-2);
+		r = (lua_tocfunction(L,-1) == module_index_event);
+		lua_pop(L,2);
+	}
+	return r;
+}
+
+/* Register class events
+	* It expects the metatable on the top of the stack
+*/
+TOLUA_API void tolua_classevents (lua_State* L)
+{
+	lua_pushstring(L,"__index");
+	lua_pushcfunction(L,class_index_event);
+	lua_rawset(L,-3);
+	lua_pushstring(L,"__newindex");
+	lua_pushcfunction(L,class_newindex_event);
+	lua_rawset(L,-3);
+
+	lua_pushstring(L,"__add");
+	lua_pushcfunction(L,class_add_event);
+	lua_rawset(L,-3);
+	lua_pushstring(L,"__sub");
+	lua_pushcfunction(L,class_sub_event);
+	lua_rawset(L,-3);
+	lua_pushstring(L,"__mul");
+	lua_pushcfunction(L,class_mul_event);
+	lua_rawset(L,-3);
+	lua_pushstring(L,"__div");
+	lua_pushcfunction(L,class_div_event);
+	lua_rawset(L,-3);
+
+	lua_pushstring(L,"__lt");
+	lua_pushcfunction(L,class_lt_event);
+	lua_rawset(L,-3);
+	lua_pushstring(L,"__le");
+	lua_pushcfunction(L,class_le_event);
+	lua_rawset(L,-3);
+	lua_pushstring(L,"__eq");
+	lua_pushcfunction(L,class_eq_event);
+	lua_rawset(L,-3);
+
+	lua_pushstring(L,"__call");
+	lua_pushcfunction(L,class_call_event);
+	lua_rawset(L,-3);
+
+	lua_pushstring(L,"__gc");
+	lua_pushstring(L, "tolua_gc_event");
+	lua_rawget(L, LUA_REGISTRYINDEX);
+	/*lua_pushcfunction(L,class_gc_event);*/
+	lua_rawset(L,-3);
+}
+
Index: /code/branches/rocket2/src/external/tolua/tolua_event.h
===================================================================
--- /code/branches/rocket2/src/external/tolua/tolua_event.h	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/tolua_event.h	(revision 6952)
@@ -0,0 +1,24 @@
+/* tolua: event functions
+** Support code for Lua bindings.
+** Written by Waldemar Celes
+** TeCGraf/PUC-Rio
+** Apr 2003
+** $Id: $
+*/
+
+/* This code is free software; you can redistribute it and/or modify it.
+** The software provided hereunder is on an "as is" basis, and
+** the author has no obligation to provide maintenance, support, updates,
+** enhancements, or modifications.
+*/
+
+#ifndef TOLUA_EVENT_H
+#define TOLUA_EVENT_H
+
+#include "tolua++.h"
+
+TOLUA_API void tolua_moduleevents (lua_State* L);
+TOLUA_API int tolua_ismodulemetatable (lua_State* L);
+TOLUA_API void tolua_classevents (lua_State* L);
+
+#endif
Index: /code/branches/rocket2/src/external/tolua/tolua_is.c
===================================================================
--- /code/branches/rocket2/src/external/tolua/tolua_is.c	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/tolua_is.c	(revision 6952)
@@ -0,0 +1,607 @@
+/* tolua: functions to check types.
+** Support code for Lua bindings.
+** Written by Waldemar Celes
+** TeCGraf/PUC-Rio
+** Apr 2003
+** $Id: $
+*/
+
+/* This code is free software; you can redistribute it and/or modify it.
+** The software provided hereunder is on an "as is" basis, and
+** the author has no obligation to provide maintenance, support, updates,
+** enhancements, or modifications.
+*/
+
+#include "tolua++.h"
+#include "lauxlib.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/* a fast check if a is b, without parameter validation
+ i.e. if b is equal to a or a superclass of a. */
+TOLUA_API int tolua_fast_isa(lua_State *L, int mt_indexa, int mt_indexb, int super_index)
+{
+ int result;
+	if (lua_rawequal(L,mt_indexa,mt_indexb))
+		result = 1;
+	else
+	{
+		if (super_index) {
+			lua_pushvalue(L, super_index);
+		} else {
+			lua_pushliteral(L,"tolua_super");
+			lua_rawget(L,LUA_REGISTRYINDEX);  /* stack: super */
+		};
+		lua_pushvalue(L,mt_indexa);       /* stack: super mta */
+		lua_rawget(L,-2);                 /* stack: super super[mta] */
+		lua_pushvalue(L,mt_indexb);       /* stack: super super[mta] mtb */
+		lua_rawget(L,LUA_REGISTRYINDEX);  /* stack: super super[mta] typenameB */
+		lua_rawget(L,-2);                 /* stack: super super[mta] bool */
+		result = lua_toboolean(L,-1);
+		lua_pop(L,3);
+	}
+	return result;
+}
+
+/* Push and returns the corresponding object typename */
+TOLUA_API const char* tolua_typename (lua_State* L, int lo)
+{
+	int tag = lua_type(L,lo);
+ if (tag == LUA_TNONE)
+  lua_pushstring(L,"[no object]");
+ else if (tag != LUA_TUSERDATA && tag != LUA_TTABLE)
+  lua_pushstring(L,lua_typename(L,tag));
+ else if (tag == LUA_TUSERDATA)
+ {
+  if (!lua_getmetatable(L,lo))
+   lua_pushstring(L,lua_typename(L,tag));
+		else
+		{
+		 lua_rawget(L,LUA_REGISTRYINDEX);
+		 if (!lua_isstring(L,-1))
+			{
+		  lua_pop(L,1);
+				lua_pushstring(L,"[undefined]");
+			}
+		}
+	}
+	else  /* is table */
+	{
+		lua_pushvalue(L,lo);
+		lua_rawget(L,LUA_REGISTRYINDEX);
+		if (!lua_isstring(L,-1))
+		{
+			lua_pop(L,1);
+			lua_pushstring(L,"table");
+		}
+		else
+		{
+   lua_pushstring(L,"class ");
+			lua_insert(L,-2);
+			lua_concat(L,2);
+		}
+	}
+	return lua_tostring(L,-1);
+}
+
+TOLUA_API void tolua_error (lua_State* L, char* msg, tolua_Error* err)
+{
+	if (msg[0] == '#')
+	{
+  const char* expected = err->type;
+		const char* provided = tolua_typename(L,err->index);
+  if (msg[1]=='f')
+  {
+   int narg = err->index;
+			if (err->array)
+    luaL_error(L,"%s\n     argument #%d is array of '%s'; array of '%s' expected.\n",
+               msg+2,narg,provided,expected);
+			else
+    luaL_error(L,"%s\n     argument #%d is '%s'; '%s' expected.\n",
+               msg+2,narg,provided,expected);
+  }
+  else if (msg[1]=='v')
+		{
+			if (err->array)
+    luaL_error(L,"%s\n     value is array of '%s'; array of '%s' expected.\n",
+               msg+2,provided,expected);
+			else
+    luaL_error(L,"%s\n     value is '%s'; '%s' expected.\n",
+               msg+2,provided,expected);
+		}
+ }
+ else
+  luaL_error(L,msg);
+}
+
+/* the equivalent of lua_is* for usertable */
+static  int lua_isusertable (lua_State* L, int lo, const char* type)
+{
+	int r = 0;
+	if (lo < 0) lo = lua_gettop(L)+lo+1;
+	lua_pushvalue(L,lo);
+	lua_rawget(L,LUA_REGISTRYINDEX);  /* get registry[t] */
+	if (lua_isstring(L,-1))
+	{
+		r = strcmp(lua_tostring(L,-1),type)==0;
+		if (!r)
+		{
+			/* try const */
+			lua_pushstring(L,"const ");
+			lua_insert(L,-2);
+			lua_concat(L,2);
+			r = lua_isstring(L,-1) && strcmp(lua_tostring(L,-1),type)==0;
+		}
+	}
+	lua_pop(L, 1);
+	return r;
+}
+
+int push_table_instance(lua_State* L, int lo) {
+
+	if (lua_istable(L, lo)) {
+
+		lua_pushstring(L, ".c_instance");
+		lua_gettable(L, lo);
+		if (lua_isuserdata(L, -1)) {
+
+			lua_replace(L, lo);
+			return 1;
+		} else {
+
+			lua_pop(L, 1);
+			return 0;
+		};
+	} else {
+		return 0;
+	};
+
+	return 0;
+};
+
+/* the equivalent of lua_is* for usertype */
+static int lua_isusertype (lua_State* L, int lo, const char* type)
+{
+	if (!lua_isuserdata(L,lo)) {
+		if (!push_table_instance(L, lo)) {
+			return 0;
+		};
+	};
+	{
+		/* check if it is of the same type */
+		int r;
+		const char *tn;
+		if (lua_getmetatable(L,lo))        /* if metatable? */
+		{
+		 lua_rawget(L,LUA_REGISTRYINDEX);  /* get registry[mt] */
+		 tn = lua_tostring(L,-1);
+		 r = tn && (strcmp(tn,type) == 0);
+		 lua_pop(L, 1);
+			if (r)
+			 return 1;
+			else
+			{
+				/* check if it is a specialized class */
+				lua_pushstring(L,"tolua_super");
+				lua_rawget(L,LUA_REGISTRYINDEX); /* get super */
+				lua_getmetatable(L,lo);
+				lua_rawget(L,-2);                /* get super[mt] */
+				if (lua_istable(L,-1))
+				{
+					int b;
+					lua_pushstring(L,type);
+					lua_rawget(L,-2);                /* get super[mt][type] */
+					b = lua_toboolean(L,-1);
+					lua_pop(L,3);
+					if (b)
+					 return 1;
+				}
+			}
+		}
+ }
+	return 0;
+}
+
+TOLUA_API int tolua_isnoobj (lua_State* L, int lo, tolua_Error* err)
+{
+ if (lua_gettop(L)<abs(lo))
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = "[no object]";
+ return 0;
+}
+TOLUA_API int tolua_isvalue (lua_State* L, int lo, int def, tolua_Error* err)
+{
+	if (def || abs(lo)<=lua_gettop(L))  /* any valid index */
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = "value";
+	return 0;
+}
+
+TOLUA_API int tolua_isboolean (lua_State* L, int lo, int def, tolua_Error* err)
+{
+	if (def && lua_gettop(L)<abs(lo))
+		return 1;
+	if (lua_isnil(L,lo) || lua_isboolean(L,lo))
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = "boolean";
+	return 0;
+}
+
+TOLUA_API int tolua_isnumber (lua_State* L, int lo, int def, tolua_Error* err)
+{
+	if (def && lua_gettop(L)<abs(lo))
+		return 1;
+	if (lua_isnumber(L,lo))
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = "number";
+	return 0;
+}
+
+TOLUA_API int tolua_isstring (lua_State* L, int lo, int def, tolua_Error* err)
+{
+	if (def && lua_gettop(L)<abs(lo))
+		return 1;
+ if (lua_isnil(L,lo) || lua_isstring(L,lo))
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = "string";
+	return 0;
+}
+
+TOLUA_API int tolua_istable (lua_State* L, int lo, int def, tolua_Error* err)
+{
+	if (def && lua_gettop(L)<abs(lo))
+		return 1;
+	if (lua_istable(L,lo))
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = "table";
+	return 0;
+}
+
+TOLUA_API int tolua_isusertable (lua_State* L, int lo, const char* type, int def, tolua_Error* err)
+{
+	if (def && lua_gettop(L)<abs(lo))
+		return 1;
+	if (lua_isusertable(L,lo,type))
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = type;
+	return 0;
+}
+
+
+TOLUA_API int tolua_isuserdata (lua_State* L, int lo, int def, tolua_Error* err)
+{
+	if (def && lua_gettop(L)<abs(lo))
+		return 1;
+	if (lua_isnil(L,lo) || lua_isuserdata(L,lo))
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = "userdata";
+	return 0;
+}
+
+TOLUA_API int tolua_isusertype (lua_State* L, int lo, const char* type, int def, tolua_Error* err)
+{
+	if (def && lua_gettop(L)<abs(lo))
+		return 1;
+	if (lua_isnil(L,lo) || lua_isusertype(L,lo,type))
+		return 1;
+	err->index = lo;
+	err->array = 0;
+	err->type = type;
+	return 0;
+}
+
+TOLUA_API int tolua_isvaluearray
+ (lua_State* L, int lo, int dim, int def, tolua_Error* err)
+{
+	if (!tolua_istable(L,lo,def,err))
+		return 0;
+	else
+		return 1;
+}
+
+TOLUA_API int tolua_isbooleanarray
+ (lua_State* L, int lo, int dim, int def, tolua_Error* err)
+{
+	if (!tolua_istable(L,lo,def,err))
+		return 0;
+	else
+	{
+		int i;
+		for (i=1; i<=dim; ++i)
+		{
+			lua_pushnumber(L,i);
+			lua_gettable(L,lo);
+	  if (!(lua_isnil(L,-1) || lua_isboolean(L,-1)) &&
+					  !(def && lua_isnil(L,-1))
+						)
+			{
+				err->index = lo;
+				err->array = 1;
+				err->type = "boolean";
+				return 0;
+			}
+			lua_pop(L,1);
+		}
+ }
+ return 1;
+}
+
+TOLUA_API int tolua_isnumberarray
+ (lua_State* L, int lo, int dim, int def, tolua_Error* err)
+{
+	if (!tolua_istable(L,lo,def,err))
+		return 0;
+	else
+	{
+		int i;
+		for (i=1; i<=dim; ++i)
+		{
+			lua_pushnumber(L,i);
+			lua_gettable(L,lo);
+			if (!lua_isnumber(L,-1) &&
+					  !(def && lua_isnil(L,-1))
+						)
+			{
+				err->index = lo;
+				err->array = 1;
+				err->type = "number";
+				return 0;
+			}
+			lua_pop(L,1);
+		}
+ }
+ return 1;
+}
+
+TOLUA_API int tolua_isstringarray
+ (lua_State* L, int lo, int dim, int def, tolua_Error* err)
+{
+	if (!tolua_istable(L,lo,def,err))
+		return 0;
+	else
+	{
+		int i;
+		for (i=1; i<=dim; ++i)
+		{
+			lua_pushnumber(L,i);
+			lua_gettable(L,lo);
+   if (!(lua_isnil(L,-1) || lua_isstring(L,-1)) &&
+			    !(def && lua_isnil(L,-1))
+						)
+			{
+				err->index = lo;
+				err->array = 1;
+				err->type = "string";
+				return 0;
+			}
+			lua_pop(L,1);
+		}
+ }
+ return 1;
+}
+
+TOLUA_API int tolua_istablearray
+ (lua_State* L, int lo, int dim, int def, tolua_Error* err)
+{
+	if (!tolua_istable(L,lo,def,err))
+		return 0;
+	else
+	{
+		int i;
+		for (i=1; i<=dim; ++i)
+		{
+			lua_pushnumber(L,i);
+			lua_gettable(L,lo);
+	  if (! lua_istable(L,-1) &&
+			    !(def && lua_isnil(L,-1))
+						)
+			{
+				err->index = lo;
+				err->array = 1;
+				err->type = "table";
+				return 0;
+			}
+			lua_pop(L,1);
+		}
+ }
+ return 1;
+}
+
+TOLUA_API int tolua_isuserdataarray
+ (lua_State* L, int lo, int dim, int def, tolua_Error* err)
+{
+	if (!tolua_istable(L,lo,def,err))
+		return 0;
+	else
+	{
+		int i;
+		for (i=1; i<=dim; ++i)
+		{
+			lua_pushnumber(L,i);
+			lua_gettable(L,lo);
+	  if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
+			    !(def && lua_isnil(L,-1))
+						)
+			{
+				err->index = lo;
+				err->array = 1;
+				err->type = "userdata";
+				return 0;
+			}
+			lua_pop(L,1);
+		}
+ }
+ return 1;
+}
+
+TOLUA_API int tolua_isusertypearray
+ (lua_State* L, int lo, const char* type, int dim, int def, tolua_Error* err)
+{
+	if (!tolua_istable(L,lo,def,err))
+		return 0;
+	else
+	{
+		int i;
+		for (i=1; i<=dim; ++i)
+		{
+			lua_pushnumber(L,i);
+			lua_gettable(L,lo);
+	  if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
+			    !(def && lua_isnil(L,-1))
+						)
+			{
+				err->index = lo;
+				err->type = type;
+				err->array = 1;
+				return 0;
+			}
+			lua_pop(L,1);
+		}
+ }
+ return 1;
+}
+
+#if 0
+int tolua_isbooleanfield
+ (lua_State* L, int lo, int i, int def, tolua_Error* err)
+{
+	lua_pushnumber(L,i);
+	lua_gettable(L,lo);
+	if (!(lua_isnil(L,-1) || lua_isboolean(L,-1)) &&
+			  !(def && lua_isnil(L,-1))
+				)
+	{
+		err->index = lo;
+		err->array = 1;
+		err->type = "boolean";
+		return 0;
+	}
+	lua_pop(L,1);
+ return 1;
+}
+
+int tolua_isnumberfield
+ (lua_State* L, int lo, int i, int def, tolua_Error* err)
+{
+	lua_pushnumber(L,i);
+	lua_gettable(L,lo);
+	if (!lua_isnumber(L,-1) &&
+			  !(def && lua_isnil(L,-1))
+				)
+	{
+		err->index = lo;
+		err->array = 1;
+		err->type = "number";
+		return 0;
+	}
+	lua_pop(L,1);
+ return 1;
+}
+
+int tolua_isstringfield
+ (lua_State* L, int lo, int i, int def, tolua_Error* err)
+{
+	lua_pushnumber(L,i);
+	lua_gettable(L,lo);
+ if (!(lua_isnil(L,-1) || lua_isstring(L,-1)) &&
+	    !(def && lua_isnil(L,-1))
+				)
+	{
+		err->index = lo;
+		err->array = 1;
+		err->type = "string";
+		return 0;
+	}
+	lua_pop(L,1);
+ return 1;
+}
+
+int tolua_istablefield
+ (lua_State* L, int lo, int i, int def, tolua_Error* err)
+{
+	lua_pushnumber(L,i+1);
+	lua_gettable(L,lo);
+	if (! lua_istable(L,-1) &&
+	    !(def && lua_isnil(L,-1))
+				)
+	{
+		err->index = lo;
+		err->array = 1;
+		err->type = "table";
+		return 0;
+	}
+	lua_pop(L,1);
+}
+
+int tolua_isusertablefield
+ (lua_State* L, int lo, const char* type, int i, int def, tolua_Error* err)
+{
+	lua_pushnumber(L,i);
+	lua_gettable(L,lo);
+	if (! lua_isusertable(L,-1,type) &&
+	    !(def && lua_isnil(L,-1))
+				)
+	{
+		err->index = lo;
+		err->array = 1;
+		err->type = type;
+		return 0;
+	}
+	lua_pop(L,1);
+ return 1;
+}
+
+int tolua_isuserdatafield
+ (lua_State* L, int lo, int i, int def, tolua_Error* err)
+{
+	lua_pushnumber(L,i);
+	lua_gettable(L,lo);
+	if (!(lua_isnil(L,-1) || lua_isuserdata(L,-1)) &&
+	    !(def && lua_isnil(L,-1))
+				)
+	{
+		err->index = lo;
+		err->array = 1;
+		err->type = "userdata";
+		return 0;
+	}
+	lua_pop(L,1);
+ return 1;
+}
+
+int tolua_isusertypefield
+ (lua_State* L, int lo, const char* type, int i, int def, tolua_Error* err)
+{
+	lua_pushnumber(L,i);
+	lua_gettable(L,lo);
+	if (!(lua_isnil(L,-1) || lua_isusertype(L,-1,type)) &&
+	    !(def && lua_isnil(L,-1))
+				)
+	{
+		err->index = lo;
+		err->type = type;
+		err->array = 1;
+		return 0;
+	}
+	lua_pop(L,1);
+ return 1;
+}
+
+#endif
Index: /code/branches/rocket2/src/external/tolua/tolua_map.c
===================================================================
--- /code/branches/rocket2/src/external/tolua/tolua_map.c	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/tolua_map.c	(revision 6952)
@@ -0,0 +1,704 @@
+/* tolua: functions to map features
+** Support code for Lua bindings.
+** Written by Waldemar Celes
+** TeCGraf/PUC-Rio
+** Apr 2003
+** $Id: $
+*/
+
+/* This code is free software; you can redistribute it and/or modify it.
+** The software provided hereunder is on an "as is" basis, and
+** the author has no obligation to provide maintenance, support, updates,
+** enhancements, or modifications.
+*/
+
+#include "tolua++.h"
+#include "tolua_event.h"
+#include "lauxlib.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+/* Create metatable
+	* Create and register new metatable
+*/
+static int tolua_newmetatable (lua_State* L, char* name)
+{
+	int r = luaL_newmetatable(L,name);
+
+	#ifdef LUA_VERSION_NUM /* only lua 5.1 */
+	if (r) {
+		lua_pushvalue(L, -1);
+		lua_pushstring(L, name);
+		lua_settable(L, LUA_REGISTRYINDEX); /* reg[mt] = type_name */
+	};
+	#endif
+
+	if (r)
+		tolua_classevents(L); /* set meta events */
+	lua_pop(L,1);
+	return r;
+}
+
+/* Map super classes
+	* It sets 'name' as being also a 'base', mapping all super classes of 'base' in 'name'
+*/
+static void mapsuper (lua_State* L, const char* name, const char* base)
+{
+	/* push registry.super */
+ lua_pushstring(L,"tolua_super");
+ lua_rawget(L,LUA_REGISTRYINDEX);    /* stack: super */
+	luaL_getmetatable(L,name);          /* stack: super mt */
+ lua_rawget(L,-2);                   /* stack: super table */
+	if (lua_isnil(L,-1))
+	{
+	 /* create table */
+		lua_pop(L,1);
+	 lua_newtable(L);                    /* stack: super table */
+	 luaL_getmetatable(L,name);          /* stack: super table mt */
+		lua_pushvalue(L,-2);                /* stack: super table mt table */
+		lua_rawset(L,-4);                   /* stack: super table */
+	}
+
+	/* set base as super class */
+	lua_pushstring(L,base);
+	lua_pushboolean(L,1);
+	lua_rawset(L,-3);                    /* stack: super table */
+
+	/* set all super class of base as super class of name */
+	luaL_getmetatable(L,base);          /* stack: super table base_mt */
+	lua_rawget(L,-3);                   /* stack: super table base_table */
+	if (lua_istable(L,-1))
+	{
+		/* traverse base table */
+		lua_pushnil(L);  /* first key */
+		while (lua_next(L,-2) != 0)
+		{
+			/* stack: ... base_table key value */
+			lua_pushvalue(L,-2);    /* stack: ... base_table key value key */
+			lua_insert(L,-2);       /* stack: ... base_table key key value */
+			lua_rawset(L,-5);       /* stack: ... base_table key */
+		}
+	}
+	lua_pop(L,3);                       /* stack: <empty> */
+}
+
+/* creates a 'tolua_ubox' table for base clases, and
+// expects the metatable and base metatable on the stack */
+static void set_ubox(lua_State* L) {
+
+	/* mt basemt */
+	if (!lua_isnil(L, -1)) {
+		lua_pushstring(L, "tolua_ubox");
+		lua_rawget(L,-2);
+	} else {
+		lua_pushnil(L);
+	};
+	/* mt basemt base_ubox */
+	if (!lua_isnil(L,-1)) {
+		lua_pushstring(L, "tolua_ubox");
+		lua_insert(L, -2);
+		/* mt basemt key ubox */
+		lua_rawset(L,-4);
+		/* (mt with ubox) basemt */
+	} else {
+		/* mt basemt nil */
+		lua_pop(L, 1);
+		lua_pushstring(L,"tolua_ubox"); lua_newtable(L);
+		/* make weak value metatable for ubox table to allow userdata to be
+		garbage-collected */
+		lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "v"); lua_rawset(L, -3);               /* stack: string ubox mt */
+		lua_setmetatable(L, -2);  /* stack:mt basemt string ubox */
+		lua_rawset(L,-4);
+	};
+
+};
+
+/* Map inheritance
+	* It sets 'name' as derived from 'base' by setting 'base' as metatable of 'name'
+*/
+static void mapinheritance (lua_State* L, const char* name, const char* base)
+{
+	/* set metatable inheritance */
+	luaL_getmetatable(L,name);
+
+	if (base && *base)
+		luaL_getmetatable(L,base);
+	else {
+
+		if (lua_getmetatable(L, -1)) { /* already has a mt, we don't overwrite it */
+			lua_pop(L, 2);
+			return;
+		};
+		luaL_getmetatable(L,"tolua_commonclass");
+	};
+
+	set_ubox(L);
+
+	lua_setmetatable(L,-2);
+	lua_pop(L,1);
+}
+
+/* Object type
+*/
+static int tolua_bnd_type (lua_State* L)
+{
+	tolua_typename(L,lua_gettop(L));
+	return 1;
+}
+
+/* Take ownership
+*/
+static int tolua_bnd_takeownership (lua_State* L)
+{
+	int success = 0;
+	if (lua_isuserdata(L,1))
+	{
+		if (lua_getmetatable(L,1))        /* if metatable? */
+		{
+			lua_pop(L,1);             /* clear metatable off stack */
+			/* force garbage collection to avoid C to reuse a to-be-collected address */
+			#ifdef LUA_VERSION_NUM
+			lua_gc(L, LUA_GCCOLLECT, 0);
+			#else
+			lua_setgcthreshold(L,0);
+			#endif
+
+			success = tolua_register_gc(L,1);
+		}
+	}
+	lua_pushboolean(L,success!=0);
+	return 1;
+}
+
+/* Release ownership
+*/
+static int tolua_bnd_releaseownership (lua_State* L)
+{
+	int done = 0;
+	if (lua_isuserdata(L,1))
+	{
+		void* u = *((void**)lua_touserdata(L,1));
+		/* force garbage collection to avoid releasing a to-be-collected address */
+		#ifdef LUA_VERSION_NUM
+		lua_gc(L, LUA_GCCOLLECT, 0);
+		#else
+		lua_setgcthreshold(L,0);
+		#endif
+		lua_pushstring(L,"tolua_gc");
+		lua_rawget(L,LUA_REGISTRYINDEX);
+		lua_pushlightuserdata(L,u);
+		lua_rawget(L,-2);
+		lua_getmetatable(L,1);
+		if (lua_rawequal(L,-1,-2))  /* check that we are releasing the correct type */
+		{
+			lua_pushlightuserdata(L,u);
+			lua_pushnil(L);
+			lua_rawset(L,-5);
+			done = 1;
+		}
+	}
+	lua_pushboolean(L,done!=0);
+	return 1;
+}
+
+/* Type casting
+*/
+static int tolua_bnd_cast (lua_State* L)
+{
+
+/* // old code
+        void* v = tolua_tousertype(L,1,NULL);
+        const char* s = tolua_tostring(L,2,NULL);
+        if (v && s)
+         tolua_pushusertype(L,v,s);
+        else
+         lua_pushnil(L);
+        return 1;
+*/
+
+	void* v;
+	const char* s;
+	if (lua_islightuserdata(L, 1)) {
+		v = tolua_touserdata(L, 1, NULL);
+	} else {
+		v = tolua_tousertype(L, 1, 0);
+	};
+
+	s = tolua_tostring(L,2,NULL);
+	if (v && s)
+	 tolua_pushusertype(L,v,s);
+	else
+	 lua_pushnil(L);
+	return 1;
+}
+
+/* Inheritance
+*/
+static int tolua_bnd_inherit (lua_State* L) {
+
+	/* stack: lua object, c object */
+	lua_pushstring(L, ".c_instance");
+	lua_pushvalue(L, -2);
+	lua_rawset(L, -4);
+	/* l_obj[".c_instance"] = c_obj */
+
+	return 0;
+};
+
+#ifdef LUA_VERSION_NUM /* lua 5.1 */
+static int tolua_bnd_setpeer(lua_State* L) {
+
+	/* stack: userdata, table */
+	if (!lua_isuserdata(L, -2)) {
+		lua_pushstring(L, "Invalid argument #1 to setpeer: userdata expected.");
+		lua_error(L);
+	};
+	
+	if (lua_isnil(L, -1)) {
+
+		lua_pop(L, 1);
+		lua_pushvalue(L, TOLUA_NOPEER);
+	};
+	lua_setfenv(L, -2);
+
+	return 0;
+};
+
+static int tolua_bnd_getpeer(lua_State* L) {
+
+	/* stack: userdata */
+	lua_getfenv(L, -1);
+	if (lua_rawequal(L, -1, TOLUA_NOPEER)) {
+		lua_pop(L, 1);
+		lua_pushnil(L);
+	};
+	return 1;
+};
+#endif
+
+/* static int class_gc_event (lua_State* L); */
+
+TOLUA_API void tolua_open (lua_State* L)
+{
+ int top = lua_gettop(L);
+ lua_pushstring(L,"tolua_opened");
+ lua_rawget(L,LUA_REGISTRYINDEX);
+ if (!lua_isboolean(L,-1))
+ {
+  lua_pushstring(L,"tolua_opened"); lua_pushboolean(L,1); lua_rawset(L,LUA_REGISTRYINDEX);
+
+  #ifndef LUA_VERSION_NUM /* only prior to lua 5.1 */
+  /* create peer object table */
+  lua_pushstring(L, "tolua_peers"); lua_newtable(L);
+  /* make weak key metatable for peers indexed by userdata object */
+  lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "k"); lua_rawset(L, -3);                /* stack: string peers mt */
+  lua_setmetatable(L, -2);   /* stack: string peers */
+  lua_rawset(L,LUA_REGISTRYINDEX);
+  #endif
+
+  /* create object ptr -> udata mapping table */
+  lua_pushstring(L,"tolua_ubox"); lua_newtable(L);
+  /* make weak value metatable for ubox table to allow userdata to be
+     garbage-collected */
+  lua_newtable(L); lua_pushliteral(L, "__mode"); lua_pushliteral(L, "v"); lua_rawset(L, -3);               /* stack: string ubox mt */
+  lua_setmetatable(L, -2);  /* stack: string ubox */
+  lua_rawset(L,LUA_REGISTRYINDEX);
+
+  lua_pushstring(L,"tolua_super"); lua_newtable(L); lua_rawset(L,LUA_REGISTRYINDEX);
+  lua_pushstring(L,"tolua_gc"); lua_newtable(L);lua_rawset(L,LUA_REGISTRYINDEX);
+
+  /* create gc_event closure */
+  lua_pushstring(L, "tolua_gc_event");
+  lua_pushstring(L, "tolua_gc");
+  lua_rawget(L, LUA_REGISTRYINDEX);
+  lua_pushstring(L, "tolua_super");
+  lua_rawget(L, LUA_REGISTRYINDEX);
+  lua_pushcclosure(L, class_gc_event, 2);
+  lua_rawset(L, LUA_REGISTRYINDEX);
+
+  tolua_newmetatable(L,"tolua_commonclass");
+
+  tolua_module(L,NULL,0);
+  tolua_beginmodule(L,NULL);
+  tolua_module(L,"tolua",0);
+  tolua_beginmodule(L,"tolua");
+  tolua_function(L,"type",tolua_bnd_type);
+  tolua_function(L,"takeownership",tolua_bnd_takeownership);
+  tolua_function(L,"releaseownership",tolua_bnd_releaseownership);
+  tolua_function(L,"cast",tolua_bnd_cast);
+  tolua_function(L,"inherit", tolua_bnd_inherit);
+  #ifdef LUA_VERSION_NUM /* lua 5.1 */
+  tolua_function(L, "setpeer", tolua_bnd_setpeer);
+  tolua_function(L, "getpeer", tolua_bnd_getpeer);
+  #endif
+
+  tolua_endmodule(L);
+  tolua_endmodule(L);
+ }
+ lua_settop(L,top);
+}
+
+/* Copy a C object
+*/
+TOLUA_API void* tolua_copy (lua_State* L, void* value, unsigned int size)
+{
+	void* clone = (void*)malloc(size);
+	if (clone)
+	 memcpy(clone,value,size);
+	else
+		tolua_error(L,"insuficient memory",NULL);
+	return clone;
+}
+
+/* Default collect function
+*/
+TOLUA_API int tolua_default_collect (lua_State* tolua_S)
+{
+ void* self = tolua_tousertype(tolua_S,1,0);
+ free(self);
+ return 0;
+}
+
+/* Do clone
+*/
+TOLUA_API int tolua_register_gc (lua_State* L, int lo)
+{
+ int success = 1;
+ void *value = *(void **)lua_touserdata(L,lo);
+ lua_pushstring(L,"tolua_gc");
+ lua_rawget(L,LUA_REGISTRYINDEX);
+	lua_pushlightuserdata(L,value);
+	lua_rawget(L,-2);
+	if (!lua_isnil(L,-1)) /* make sure that object is not already owned */
+		success = 0;
+	else
+	{
+		lua_pushlightuserdata(L,value);
+		lua_getmetatable(L,lo);
+		lua_rawset(L,-4);
+	}
+	lua_pop(L,2);
+	return success;
+}
+
+/* Register a usertype
+	* It creates the correspoding metatable in the registry, for both 'type' and 'const type'.
+	* It maps 'const type' as being also a 'type'
+*/
+TOLUA_API void tolua_usertype (lua_State* L, char* type)
+{
+ char ctype[128] = "const ";
+ strncat(ctype,type,120);
+
+	/* create both metatables */
+ if (tolua_newmetatable(L,ctype) && tolua_newmetatable(L,type))
+	 mapsuper(L,type,ctype);             /* 'type' is also a 'const type' */
+}
+
+
+/* Begin module
+	* It pushes the module (or class) table on the stack
+*/
+TOLUA_API void tolua_beginmodule (lua_State* L, char* name)
+{
+	if (name)
+	{
+	 lua_pushstring(L,name);
+		lua_rawget(L,-2);
+	}
+	else
+	 lua_pushvalue(L,LUA_GLOBALSINDEX);
+}
+
+/* End module
+	* It pops the module (or class) from the stack
+*/
+TOLUA_API void tolua_endmodule (lua_State* L)
+{
+	lua_pop(L,1);
+}
+
+/* Map module
+	* It creates a new module
+*/
+#if 1
+TOLUA_API void tolua_module (lua_State* L, char* name, int hasvar)
+{
+	if (name)
+	{
+		/* tolua module */
+		lua_pushstring(L,name);
+		lua_rawget(L,-2);
+		if (!lua_istable(L,-1))  /* check if module already exists */
+		{
+			lua_pop(L,1);
+		 lua_newtable(L);
+		 lua_pushstring(L,name);
+			lua_pushvalue(L,-2);
+		 lua_rawset(L,-4);       /* assing module into module */
+		}
+	}
+	else
+	{
+		/* global table */
+		lua_pushvalue(L,LUA_GLOBALSINDEX);
+	}
+	if (hasvar)
+	{
+		if (!tolua_ismodulemetatable(L))  /* check if it already has a module metatable */
+		{
+			/* create metatable to get/set C/C++ variable */
+			lua_newtable(L);
+			tolua_moduleevents(L);
+			if (lua_getmetatable(L,-2))
+				lua_setmetatable(L,-2);  /* set old metatable as metatable of metatable */
+			lua_setmetatable(L,-2);
+		}
+	}
+	lua_pop(L,1);               /* pop module */
+}
+#else
+TOLUA_API void tolua_module (lua_State* L, char* name, int hasvar)
+{
+	if (name)
+	{
+		/* tolua module */
+		lua_pushstring(L,name);
+		lua_newtable(L);
+	}
+	else
+	{
+		/* global table */
+		lua_pushvalue(L,LUA_GLOBALSINDEX);
+	}
+	if (hasvar)
+	{
+		/* create metatable to get/set C/C++ variable */
+		lua_newtable(L);
+		tolua_moduleevents(L);
+		if (lua_getmetatable(L,-2))
+			lua_setmetatable(L,-2);  /* set old metatable as metatable of metatable */
+		lua_setmetatable(L,-2);
+	}
+	if (name)
+		lua_rawset(L,-3);       /* assing module into module */
+	else
+		lua_pop(L,1);           /* pop global table */
+}
+#endif
+
+static void push_collector(lua_State* L, const char* type, lua_CFunction col) {
+
+	/* push collector function, but only if it's not NULL, or if there's no
+	   collector already */
+	if (!col) return;
+	luaL_getmetatable(L,type);
+	lua_pushstring(L,".collector");
+	/*
+	if (!col) {
+		lua_pushvalue(L, -1);
+		lua_rawget(L, -3);
+		if (!lua_isnil(L, -1)) {
+			lua_pop(L, 3);
+			return;
+		};
+		lua_pop(L, 1);
+	};
+	//	*/
+	lua_pushcfunction(L,col);
+
+	lua_rawset(L,-3);
+	lua_pop(L, 1);
+};
+
+/* Map C class
+	* It maps a C class, setting the appropriate inheritance and super classes.
+*/
+TOLUA_API void tolua_cclass (lua_State* L, char* lname, char* name, char* base, lua_CFunction col)
+{
+	char cname[128] = "const ";
+	char cbase[128] = "const ";
+	strncat(cname,name,120);
+	strncat(cbase,base,120);
+
+	mapinheritance(L,name,base);
+	mapinheritance(L,cname,name);
+
+	mapsuper(L,cname,cbase);
+	mapsuper(L,name,base);
+
+	lua_pushstring(L,lname);
+	
+	push_collector(L, name, col);
+	/*
+	luaL_getmetatable(L,name);
+	lua_pushstring(L,".collector");
+	lua_pushcfunction(L,col);
+
+	lua_rawset(L,-3);
+	*/
+	
+	luaL_getmetatable(L,name);
+	lua_rawset(L,-3);              /* assign class metatable to module */
+
+	/* now we also need to store the collector table for the const
+	   instances of the class */
+	push_collector(L, cname, col);
+	/*
+	luaL_getmetatable(L,cname);
+	lua_pushstring(L,".collector");
+	lua_pushcfunction(L,col);
+	lua_rawset(L,-3);
+	lua_pop(L,1);
+	*/
+	
+
+}
+
+/* Add base
+	* It adds additional base classes to a class (for multiple inheritance)
+	* (not for now)
+TOLUA_API void tolua_addbase(lua_State* L, char* name, char* base) {
+
+	char cname[128] = "const ";
+	char cbase[128] = "const ";
+	strncat(cname,name,120);
+	strncat(cbase,base,120);
+
+	mapsuper(L,cname,cbase);
+	mapsuper(L,name,base);
+};
+*/
+
+/* Map function
+	* It assigns a function into the current module (or class)
+*/
+TOLUA_API void tolua_function (lua_State* L, char* name, lua_CFunction func)
+{
+ lua_pushstring(L,name);
+ lua_pushcfunction(L,func);
+	lua_rawset(L,-3);
+}
+
+/* sets the __call event for the class (expects the class' main table on top) */
+/*	never really worked :(
+TOLUA_API void tolua_set_call_event(lua_State* L, lua_CFunction func, char* type) {
+
+	lua_getmetatable(L, -1);
+	//luaL_getmetatable(L, type);
+	lua_pushstring(L,"__call");
+	lua_pushcfunction(L,func);
+	lua_rawset(L,-3);
+	lua_pop(L, 1);
+};
+*/
+
+/* Map constant number
+	* It assigns a constant number into the current module (or class)
+*/
+TOLUA_API void tolua_constant (lua_State* L, char* name, double value)
+{
+	lua_pushstring(L,name);
+	tolua_pushnumber(L,value);
+	lua_rawset(L,-3);
+}
+
+
+/* Map variable
+	* It assigns a variable into the current module (or class)
+*/
+TOLUA_API void tolua_variable (lua_State* L, char* name, lua_CFunction get, lua_CFunction set)
+{
+	/* get func */
+	lua_pushstring(L,".get");
+	lua_rawget(L,-2);
+	if (!lua_istable(L,-1))
+	{
+		/* create .get table, leaving it at the top */
+		lua_pop(L,1);
+		lua_newtable(L);
+	 lua_pushstring(L,".get");
+		lua_pushvalue(L,-2);
+		lua_rawset(L,-4);
+	}
+	lua_pushstring(L,name);
+	lua_pushcfunction(L,get);
+ lua_rawset(L,-3);                  /* store variable */
+	lua_pop(L,1);                      /* pop .get table */
+
+	/* set func */
+	if (set)
+	{
+		lua_pushstring(L,".set");
+		lua_rawget(L,-2);
+		if (!lua_istable(L,-1))
+		{
+			/* create .set table, leaving it at the top */
+			lua_pop(L,1);
+			lua_newtable(L);
+			lua_pushstring(L,".set");
+			lua_pushvalue(L,-2);
+			lua_rawset(L,-4);
+		}
+		lua_pushstring(L,name);
+		lua_pushcfunction(L,set);
+		lua_rawset(L,-3);                  /* store variable */
+		lua_pop(L,1);                      /* pop .set table */
+	}
+}
+
+/* Access const array
+	* It reports an error when trying to write into a const array
+*/
+static int const_array (lua_State* L)
+{
+ luaL_error(L,"value of const array cannot be changed");
+ return 0;
+}
+
+/* Map an array
+	* It assigns an array into the current module (or class)
+*/
+TOLUA_API void tolua_array (lua_State* L, char* name, lua_CFunction get, lua_CFunction set)
+{
+	lua_pushstring(L,".get");
+	lua_rawget(L,-2);
+	if (!lua_istable(L,-1))
+	{
+		/* create .get table, leaving it at the top */
+		lua_pop(L,1);
+		lua_newtable(L);
+	 lua_pushstring(L,".get");
+		lua_pushvalue(L,-2);
+		lua_rawset(L,-4);
+	}
+	lua_pushstring(L,name);
+
+ lua_newtable(L);           /* create array metatable */
+ lua_pushvalue(L,-1);
+	lua_setmetatable(L,-2);    /* set the own table as metatable (for modules) */
+ lua_pushstring(L,"__index");
+ lua_pushcfunction(L,get);
+	lua_rawset(L,-3);
+ lua_pushstring(L,"__newindex");
+ lua_pushcfunction(L,set?set:const_array);
+	lua_rawset(L,-3);
+
+ lua_rawset(L,-3);                  /* store variable */
+	lua_pop(L,1);                      /* pop .get table */
+}
+
+
+TOLUA_API void tolua_dobuffer(lua_State* L, char* B, unsigned int size, const char* name) {
+
+ #ifdef LUA_VERSION_NUM /* lua 5.1 */
+ luaL_loadbuffer(L, B, size, name) || lua_pcall(L, 0, 0, 0);
+ #else
+ lua_dobuffer(L, B, size, name);
+ #endif
+};
+
Index: /code/branches/rocket2/src/external/tolua/tolua_push.c
===================================================================
--- /code/branches/rocket2/src/external/tolua/tolua_push.c	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/tolua_push.c	(revision 6952)
@@ -0,0 +1,171 @@
+/* tolua: functions to push C values.
+** Support code for Lua bindings.
+** Written by Waldemar Celes
+** TeCGraf/PUC-Rio
+** Apr 2003
+** $Id: $
+*/
+
+/* This code is free software; you can redistribute it and/or modify it.
+** The software provided hereunder is on an "as is" basis, and
+** the author has no obligation to provide maintenance, support, updates,
+** enhancements, or modifications.
+*/
+
+#include "tolua++.h"
+#include "lauxlib.h"
+
+#include <stdlib.h>
+
+TOLUA_API void tolua_pushvalue (lua_State* L, int lo)
+{
+ lua_pushvalue(L,lo);
+}
+
+TOLUA_API void tolua_pushboolean (lua_State* L, int value)
+{
+ lua_pushboolean(L,value);
+}
+
+TOLUA_API void tolua_pushnumber (lua_State* L, double value)
+{
+ lua_pushnumber(L,value);
+}
+
+TOLUA_API void tolua_pushstring (lua_State* L, const char* value)
+{
+ if (value == NULL)
+  lua_pushnil(L);
+ else
+  lua_pushstring(L,value);
+}
+
+TOLUA_API void tolua_pushuserdata (lua_State* L, void* value)
+{
+ if (value == NULL)
+  lua_pushnil(L);
+ else
+  lua_pushlightuserdata(L,value);
+}
+
+TOLUA_API void tolua_pushusertype (lua_State* L, void* value, const char* type)
+{
+ if (value == NULL)
+  lua_pushnil(L);
+ else
+ {
+  luaL_getmetatable(L, type);
+  lua_pushstring(L,"tolua_ubox");
+  lua_rawget(L,-2);        /* stack: mt ubox */
+  if (lua_isnil(L, -1)) {
+	  lua_pop(L, 1);
+	  lua_pushstring(L, "tolua_ubox");
+	  lua_rawget(L, LUA_REGISTRYINDEX);
+  };
+  lua_pushlightuserdata(L,value);
+  lua_rawget(L,-2);                       /* stack: mt ubox ubox[u] */
+  if (lua_isnil(L,-1))
+  {
+   lua_pop(L,1);                          /* stack: mt ubox */
+   lua_pushlightuserdata(L,value);
+   *(void**)lua_newuserdata(L,sizeof(void *)) = value;   /* stack: mt ubox u newud */
+   lua_pushvalue(L,-1);                   /* stack: mt ubox u newud newud */
+   lua_insert(L,-4);                      /* stack: mt newud ubox u newud */
+   lua_rawset(L,-3);                      /* stack: mt newud ubox */
+   lua_pop(L,1);                          /* stack: mt newud */
+   /*luaL_getmetatable(L,type);*/
+   lua_pushvalue(L, -2);			/* stack: mt newud mt */
+   lua_setmetatable(L,-2);			/* stack: mt newud */
+
+   #ifdef LUA_VERSION_NUM
+   lua_pushvalue(L, TOLUA_NOPEER);
+   lua_setfenv(L, -2);
+   #endif
+  }
+  else
+  {
+   /* check the need of updating the metatable to a more specialized class */
+   lua_insert(L,-2);                       /* stack: mt ubox[u] ubox */
+   lua_pop(L,1);                           /* stack: mt ubox[u] */
+   lua_pushstring(L,"tolua_super");
+   lua_rawget(L,LUA_REGISTRYINDEX);        /* stack: mt ubox[u] super */
+   lua_getmetatable(L,-2);                 /* stack: mt ubox[u] super mt */
+   lua_rawget(L,-2);                       /* stack: mt ubox[u] super super[mt] */
+			if (lua_istable(L,-1))
+			{
+				lua_pushstring(L,type);                 /* stack: mt ubox[u] super super[mt] type */
+				lua_rawget(L,-2);                       /* stack: mt ubox[u] super super[mt] flag */
+				if (lua_toboolean(L,-1) == 1)   /* if true */
+				{
+					lua_pop(L,3);	/* mt ubox[u]*/
+					lua_remove(L, -2);
+					return;
+				}
+			}
+			/* type represents a more specilized type */
+			/*luaL_getmetatable(L,type);             // stack: mt ubox[u] super super[mt] flag mt */
+			lua_pushvalue(L, -5);					/* stack: mt ubox[u] super super[mt] flag mt */
+			lua_setmetatable(L,-5);                /* stack: mt ubox[u] super super[mt] flag */
+			lua_pop(L,3);                          /* stack: mt ubox[u] */
+  }
+  lua_remove(L, -2);	/* stack: ubox[u]*/
+ }
+}
+
+TOLUA_API void tolua_pushusertype_and_takeownership (lua_State* L, void* value, const char* type)
+{
+	tolua_pushusertype(L,value,type);
+	tolua_register_gc(L,lua_gettop(L));
+}
+
+TOLUA_API void tolua_pushfieldvalue (lua_State* L, int lo, int index, int v)
+{
+ lua_pushnumber(L,index);
+ lua_pushvalue(L,v);
+ lua_settable(L,lo);
+}
+
+TOLUA_API void tolua_pushfieldboolean (lua_State* L, int lo, int index, int v)
+{
+ lua_pushnumber(L,index);
+ lua_pushboolean(L,v);
+ lua_settable(L,lo);
+}
+
+
+TOLUA_API void tolua_pushfieldnumber (lua_State* L, int lo, int index, double v)
+{
+ lua_pushnumber(L,index);
+ tolua_pushnumber(L,v);
+ lua_settable(L,lo);
+}
+
+TOLUA_API void tolua_pushfieldstring (lua_State* L, int lo, int index, const char* v)
+{
+ lua_pushnumber(L,index);
+ tolua_pushstring(L,v);
+ lua_settable(L,lo);
+}
+
+TOLUA_API void tolua_pushfielduserdata (lua_State* L, int lo, int index, void* v)
+{
+ lua_pushnumber(L,index);
+ tolua_pushuserdata(L,v);
+ lua_settable(L,lo);
+}
+
+TOLUA_API void tolua_pushfieldusertype (lua_State* L, int lo, int index, void* v, const char* type)
+{
+ lua_pushnumber(L,index);
+ tolua_pushusertype(L,v,type);
+ lua_settable(L,lo);
+}
+
+TOLUA_API void tolua_pushfieldusertype_and_takeownership (lua_State* L, int lo, int index, void* v, const char* type)
+{
+ lua_pushnumber(L,index);
+ tolua_pushusertype(L,v,type);
+	tolua_register_gc(L,lua_gettop(L));
+ lua_settable(L,lo);
+}
+
Index: /code/branches/rocket2/src/external/tolua/tolua_to.c
===================================================================
--- /code/branches/rocket2/src/external/tolua/tolua_to.c	(revision 6952)
+++ /code/branches/rocket2/src/external/tolua/tolua_to.c	(revision 6952)
@@ -0,0 +1,133 @@
+/* tolua: funcitons to convert to C types
+** Support code for Lua bindings.
+** Written by Waldemar Celes
+** TeCGraf/PUC-Rio
+** Apr 2003
+** $Id: $
+*/
+
+/* This code is free software; you can redistribute it and/or modify it.
+** The software provided hereunder is on an "as is" basis, and
+** the author has no obligation to provide maintenance, support, updates,
+** enhancements, or modifications.
+*/
+
+#include "tolua++.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+TOLUA_API double tolua_tonumber (lua_State* L, int narg, double def)
+{
+ return lua_gettop(L)<abs(narg) ? def : lua_tonumber(L,narg);
+}
+
+TOLUA_API const char* tolua_tostring (lua_State* L, int narg, const char* def)
+{
+ return lua_gettop(L)<abs(narg) ? def : lua_tostring(L,narg);
+}
+
+TOLUA_API void* tolua_touserdata (lua_State* L, int narg, void* def)
+{
+	
+	/* return lua_gettop(L)<abs(narg) ? def : lua_touserdata(L,narg); */
+
+	if (lua_gettop(L)<abs(narg)) {
+ 		return def;
+	};
+	 
+	if (lua_islightuserdata(L, narg)) {
+	
+		return lua_touserdata(L,narg);
+	};
+	
+	return tolua_tousertype(L, narg, def);
+}
+
+extern int push_table_instance(lua_State* L, int lo);
+
+TOLUA_API void* tolua_tousertype (lua_State* L, int narg, void* def)
+{
+ if (lua_gettop(L)<abs(narg))
+  return def;
+ else
+ {
+  void* u;
+  if (!lua_isuserdata(L, narg)) {
+	  if (!push_table_instance(L, narg)) return NULL;
+  };
+  u = lua_touserdata(L,narg);
+  return (u==NULL) ? NULL : *((void**)u); /* nil represents NULL */
+ }
+}
+
+TOLUA_API int tolua_tovalue (lua_State* L, int narg, int def)
+{
+ return lua_gettop(L)<abs(narg) ? def : narg;
+}
+
+TOLUA_API int tolua_toboolean (lua_State* L, int narg, int def)
+{
+ return lua_gettop(L)<abs(narg) ?  def : lua_toboolean(L,narg);
+}
+
+TOLUA_API double tolua_tofieldnumber (lua_State* L, int lo, int index, double def)
+{
+ double v;
+ lua_pushnumber(L,index);
+ lua_gettable(L,lo);
+ v = lua_isnil(L,-1) ? def : lua_tonumber(L,-1);
+ lua_pop(L,1);
+ return v;
+}
+
+TOLUA_API const char* tolua_tofieldstring
+(lua_State* L, int lo, int index, const char* def)
+{
+ const char* v;
+ lua_pushnumber(L,index);
+ lua_gettable(L,lo);
+ v = lua_isnil(L,-1) ? def : lua_tostring(L,-1);
+ lua_pop(L,1);
+ return v;
+}
+
+TOLUA_API void* tolua_tofielduserdata (lua_State* L, int lo, int index, void* def)
+{
+ void* v;
+ lua_pushnumber(L,index);
+ lua_gettable(L,lo);
+ v = lua_isnil(L,-1) ? def : lua_touserdata(L,-1);
+ lua_pop(L,1);
+ return v;
+}
+
+TOLUA_API void* tolua_tofieldusertype (lua_State* L, int lo, int index, void* def)
+{
+ void* v;
+ lua_pushnumber(L,index);
+ lua_gettable(L,lo);
+ v = lua_isnil(L,-1) ? def : (*(void **)(lua_touserdata(L, -1))); /* lua_unboxpointer(L,-1); */
+ lua_pop(L,1);
+ return v;
+}
+
+TOLUA_API int tolua_tofieldvalue (lua_State* L, int lo, int index, int def)
+{
+ int v;
+ lua_pushnumber(L,index);
+ lua_gettable(L,lo);
+ v = lua_isnil(L,-1) ? def : lo;
+ lua_pop(L,1);
+ return v;
+}
+
+TOLUA_API int tolua_getfieldboolean (lua_State* L, int lo, int index, int def)
+{
+ int v;
+ lua_pushnumber(L,index);
+ lua_gettable(L,lo);
+ v = lua_isnil(L,-1) ? 0 : lua_toboolean(L,-1);
+ lua_pop(L,1);
+ return v;
+}
Index: /code/branches/rocket2/src/libraries/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/libraries/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/libraries/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,30 @@
+ #
+ #             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.
+ #
+
+INCLUDE_DIRECTORIES(
+  ${CMAKE_SOURCE_DIR}/src/external
+  ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+################ Sub Directories ################
+
+ADD_SUBDIRECTORY(util)
+ADD_SUBDIRECTORY(core)
+ADD_SUBDIRECTORY(network)
+ADD_SUBDIRECTORY(tools)
Index: /code/branches/rocket2/src/libraries/core/ArgumentCompleter.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ArgumentCompleter.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ArgumentCompleter.h	(revision 6952)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ArgumentCompleter_H__
+#define _ArgumentCompleter_H__
+
+#include "CorePrereqs.h"
+#include "ArgumentCompletionListElement.h"
+
+namespace orxonox
+{
+    class _CoreExport ArgumentCompleter
+    {
+        public:
+            ArgumentCompleter(ArgumentCompletionList (*function) (void)) : paramCount_(0), function_0_(function) {}
+            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1)) : paramCount_(1), function_1_(function) {}
+            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2)) : paramCount_(2), function_2_(function) {}
+            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2, const std::string& param3)) : paramCount_(3), function_3_(function) {}
+            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4)) : paramCount_(4), function_4_(function) {}
+            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4, const std::string& param5)) : paramCount_(5), function_5_(function) {}
+
+            ArgumentCompletionList operator()(const std::string& param1 = "", const std::string& param2 = "", const std::string& param3 = "", const std::string& param4 = "", const std::string& param5 = "")
+            {
+                switch (this->paramCount_)
+                {
+                    case 0:
+                        return (*this->function_0_)();
+                    case 1:
+                        return (*this->function_1_)(param1);
+                    case 2:
+                        return (*this->function_2_)(param1, param2);
+                    case 3:
+                        return (*this->function_3_)(param1, param2, param3);
+                    case 4:
+                        return (*this->function_4_)(param1, param2, param3, param4);
+                    case 5:
+                        return (*this->function_5_)(param1, param2, param3, param4, param5);
+                    default:
+                        return ArgumentCompletionList();
+                }
+            }
+
+        private:
+            unsigned char paramCount_;
+            ArgumentCompletionList (*function_0_) (void);
+            ArgumentCompletionList (*function_1_) (const std::string& param1);
+            ArgumentCompletionList (*function_2_) (const std::string& param1, const std::string& param2);
+            ArgumentCompletionList (*function_3_) (const std::string& param1, const std::string& param2, const std::string& param3);
+            ArgumentCompletionList (*function_4_) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4);
+            ArgumentCompletionList (*function_5_) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4, const std::string& param5);
+    };
+}
+
+#endif /* _ArgumentCompleter_H__ */
Index: /code/branches/rocket2/src/libraries/core/ArgumentCompletionFunctions.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/ArgumentCompletionFunctions.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ArgumentCompletionFunctions.cc	(revision 6952)
@@ -0,0 +1,154 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ArgumentCompletionFunctions.h"
+
+#include <map>
+#include <boost/version.hpp>
+#include <boost/filesystem.hpp>
+
+#include "util/Convert.h"
+#include "util/StringUtils.h"
+#include "Identifier.h"
+#include "ConfigFileManager.h"
+#include "ConfigValueContainer.h"
+#include "TclThreadManager.h"
+
+// Boost 1.36 has some issues with deprecated functions that have been omitted
+#if (BOOST_VERSION == 103600)
+#  define BOOST_LEAF_FUNCTION filename
+#else
+#  define BOOST_LEAF_FUNCTION leaf
+#endif
+
+namespace orxonox
+{
+    namespace autocompletion
+    {
+        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(fallback)()
+        {
+            return ArgumentCompletionList();
+        }
+
+        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(files)(const std::string& fragment)
+        {
+            ArgumentCompletionList dirlist;
+            ArgumentCompletionList filelist;
+
+            try
+            {
+                boost::filesystem::path input(fragment);
+                boost::filesystem::path startdirectory(input.branch_path());
+
+                if (!boost::filesystem::exists(startdirectory))
+                {
+                    startdirectory = ".";
+                }
+#ifdef ORXONOX_PLATFORM_WINDOWS
+                else
+                {
+                    const std::string& dir = startdirectory.string();
+                    if (dir.size() > 0 && dir[dir.size() - 1] == ':')
+                        startdirectory = dir + '/';
+                }
+#endif
+
+                boost::filesystem::directory_iterator file(startdirectory);
+                boost::filesystem::directory_iterator end;
+
+                while (file != end)
+                {
+                    if (boost::filesystem::is_directory(*file))
+                        dirlist.push_back(ArgumentCompletionListElement(file->string() + '/', getLowercase(file->string()) + '/', file->BOOST_LEAF_FUNCTION() + '/'));
+                    else
+                        filelist.push_back(ArgumentCompletionListElement(file->string(), getLowercase(file->string()), file->BOOST_LEAF_FUNCTION()));
+                    ++file;
+                }
+            }
+            catch (...) {}
+
+            filelist.insert(filelist.begin(), dirlist.begin(), dirlist.end());
+            return filelist;
+        }
+
+        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingssections)()
+        {
+            ArgumentCompletionList sectionList;
+
+            const std::set<std::string>& names = SettingsConfigFile::getInstance().getSectionNames();
+            for (std::set<std::string>::const_iterator it = names.begin(); it != names.end(); ++it)
+                sectionList.push_back(ArgumentCompletionListElement(*it, getLowercase(*it)));
+
+            return sectionList;
+        }
+
+        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingsentries)(const std::string& fragment, const std::string& section)
+        {
+            ArgumentCompletionList entryList;
+            SettingsConfigFile& settings = SettingsConfigFile::getInstance();
+            const std::string& sectionLC = getLowercase(section);
+
+            SettingsConfigFile::ContainerMap::const_iterator upper = settings.getContainerUpperBound(sectionLC);
+            for (SettingsConfigFile::ContainerMap::const_iterator it = settings.getContainerLowerBound(sectionLC); it != upper; ++it)
+                entryList.push_back(ArgumentCompletionListElement(it->second.second->getName(), it->second.first));
+
+            return entryList;
+        }
+
+        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingsvalue)(const std::string& fragment, const std::string& entry, const std::string& section)
+        {
+            ArgumentCompletionList oldValue;
+            SettingsConfigFile& settings = SettingsConfigFile::getInstance();
+            const std::string& sectionLC = getLowercase(section);
+            const std::string& entryLC = getLowercase(entry);
+
+            SettingsConfigFile::ContainerMap::const_iterator upper = settings.getContainerUpperBound(sectionLC);
+            for (SettingsConfigFile::ContainerMap::const_iterator it = settings.getContainerLowerBound(sectionLC); it != upper; ++it)
+            {
+                if (it->second.first == entryLC)
+                {
+                    const std::string& valuestring = it->second.second->toString();
+                    oldValue.push_back(ArgumentCompletionListElement(valuestring, getLowercase(valuestring), "Old value: " + valuestring));
+                }
+            }
+
+            return oldValue;
+        }
+
+        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(tclthreads)()
+        {
+            std::list<unsigned int> threadnumbers = TclThreadManager::getInstance().getThreadList();
+            ArgumentCompletionList threads;
+
+            for (std::list<unsigned int>::const_iterator it = threadnumbers.begin(); it != threadnumbers.end(); ++it)
+                threads.push_back(ArgumentCompletionListElement(multi_cast<std::string>(*it)));
+
+            return threads;
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/ArgumentCompletionFunctions.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ArgumentCompletionFunctions.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ArgumentCompletionFunctions.h	(revision 6952)
@@ -0,0 +1,63 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ArgumentCompletionFunctions_H__
+#define _ArgumentCompletionFunctions_H__
+
+#include "CorePrereqs.h"
+#include "ArgumentCompleter.h"
+
+
+#define ARGUMENT_COMPLETION_FUNCTION_DECLARATION(functionname) \
+    _CoreExport ArgumentCompleter* functionname(); \
+    _CoreExport ArgumentCompletionList acf_##functionname
+
+#define ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(functionname) \
+    ArgumentCompleter* functionname() \
+    { \
+        static ArgumentCompleter completer = ArgumentCompleter(&acf_##functionname); \
+        return &completer; \
+    } \
+    \
+    ArgumentCompletionList acf_##functionname
+
+
+namespace orxonox
+{
+    namespace autocompletion
+    {
+        ARGUMENT_COMPLETION_FUNCTION_DECLARATION(fallback)();
+        ARGUMENT_COMPLETION_FUNCTION_DECLARATION(files)(const std::string& fragment);
+        ARGUMENT_COMPLETION_FUNCTION_DECLARATION(settingssections)();
+        ARGUMENT_COMPLETION_FUNCTION_DECLARATION(settingsentries)(const std::string& fragment, const std::string& section);
+        ARGUMENT_COMPLETION_FUNCTION_DECLARATION(settingsvalue)(const std::string& fragment, const std::string& entry, const std::string& section);
+        ARGUMENT_COMPLETION_FUNCTION_DECLARATION(tclthreads)();
+    }
+}
+
+#endif /* _ArgumentCompletionFunctions_H__ */
Index: /code/branches/rocket2/src/libraries/core/ArgumentCompletionListElement.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ArgumentCompletionListElement.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ArgumentCompletionListElement.h	(revision 6952)
@@ -0,0 +1,73 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ArgumentCompletionListElement_H__
+#define _ArgumentCompletionListElement_H__
+
+#include "CorePrereqs.h"
+
+#include <list>
+#include <string>
+
+namespace orxonox
+{
+    const int ACL_MODE_NORMAL    = 1;
+    const int ACL_MODE_LOWERCASE = 2;
+    const int ACL_MODE_DISPLAY   = 4;
+
+    typedef std::list<ArgumentCompletionListElement> ArgumentCompletionList;
+
+    class _CoreExport ArgumentCompletionListElement
+    {
+        public:
+            ArgumentCompletionListElement(const std::string& normalcase) : mode_(ACL_MODE_NORMAL), normalCase_(normalcase) {}
+            ArgumentCompletionListElement(const std::string& normalcase, const std::string& lowercase) : mode_(ACL_MODE_NORMAL | ACL_MODE_LOWERCASE), normalCase_(normalcase), lowerCase_(lowercase) {}
+            ArgumentCompletionListElement(const std::string& normalcase, const std::string& lowercase, const std::string& display) : mode_(ACL_MODE_NORMAL | ACL_MODE_LOWERCASE | ACL_MODE_DISPLAY), normalCase_(normalcase), lowerCase_(lowercase), display_(display) {}
+
+            const std::string& getString() const
+                { return this->normalCase_; }
+            const std::string& getComparable() const
+                { if (this->mode_ & ACL_MODE_LOWERCASE) { return this->lowerCase_; } else { return this->normalCase_; } }
+            const std::string& getDisplay() const
+                { if (this->mode_ & ACL_MODE_DISPLAY) { return this->display_; } else { return this->normalCase_; } }
+
+            bool lowercaseComparison() const
+                { return (this->mode_ & ACL_MODE_LOWERCASE); }
+
+            bool operator<(const ArgumentCompletionListElement& other) const
+                { return (this->getComparable() < other.getComparable()); }
+
+        private:
+            unsigned char mode_;
+            std::string normalCase_;
+            std::string lowerCase_;
+            std::string display_;
+    };
+}
+
+#endif /* _ArgumentCompletionListElement_H__ */
Index: /code/branches/rocket2/src/libraries/core/BaseObject.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/BaseObject.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/BaseObject.cc	(revision 6952)
@@ -0,0 +1,484 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the BaseObject class.
+*/
+
+#include "BaseObject.h"
+
+#include <tinyxml/tinyxml.h>
+
+#include "CoreIncludes.h"
+#include "Event.h"
+#include "EventIncludes.h"
+#include "Functor.h"
+#include "Iterator.h"
+#include "Template.h"
+#include "XMLFile.h"
+#include "XMLNameListener.h"
+#include "XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(BaseObject);
+
+    /**
+        @brief Constructor: Registers the object in the BaseObject-list.
+    */
+    BaseObject::BaseObject(BaseObject* creator) : bInitialized_(false)
+    {
+        RegisterRootObject(BaseObject);
+
+        this->bInitialized_ = true;
+
+        this->bActive_ = true;
+        this->bVisible_ = true;
+        this->oldGametype_ = 0;
+        this->bRegisteredEventStates_ = false;
+
+        this->lastLoadedXMLElement_ = 0;
+
+        this->mainStateFunctor_ = 0;
+
+        this->setCreator(creator);
+        if (this->creator_)
+        {
+            this->setFile(this->creator_->getFile());
+            this->setNamespace(this->creator_->getNamespace());
+            this->setScene(this->creator_->getScene(), this->creator_->getSceneID());
+            this->setGametype(this->creator_->getGametype());
+            this->setLevel(this->creator_->getLevel());
+        }
+        else
+        {
+            this->file_ = 0;
+            this->namespace_ = 0;
+            this->scene_ = 0;
+            this->sceneID_ = OBJECTID_UNKNOWN;
+            this->gametype_ = 0;
+            this->level_ = 0;
+        }
+    }
+
+    /**
+        @brief Destructor
+    */
+    BaseObject::~BaseObject()
+    {
+        if (this->isInitialized())
+        {
+            for (std::map<BaseObject*, std::string>::const_iterator it = this->eventSources_.begin(); it != this->eventSources_.end(); )
+                this->removeEventSource((it++)->first);
+
+            for (std::set<BaseObject*>::const_iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); )
+                (*(it++))->removeEventSource(this);
+
+            for (std::map<std::string, EventState*>::const_iterator it = this->eventStates_.begin(); it != this->eventStates_.end(); ++it)
+                delete it->second;
+        }
+    }
+    
+    /** @brief Adds an object which listens to the events of this object. */
+    void BaseObject::registerEventListener(BaseObject* object)
+    {
+        COUT(4) << "New EventListener: " << object->getIdentifier()->getName() << " &(" << object << ")." << std::endl;
+        this->eventListeners_.insert(object);
+    }
+
+    /**
+        @brief XML loading and saving.
+        @param xmlelement The XML-element
+        @param loading Loading (true) or saving (false)
+    */
+    void BaseObject::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        XMLPortParam(BaseObject, "name", setXMLName, getName, xmlelement, mode);
+        XMLPortParam(BaseObject, "visible", setVisible, isVisible, xmlelement, mode);
+        XMLPortParam(BaseObject, "active", setActive, isActive, xmlelement, mode);
+        XMLPortParam(BaseObject, "mainstate", setMainStateName, getMainStateName, xmlelement, mode);
+        XMLPortParamTemplate(BaseObject, "template", addTemplate, getSingleTemplate, xmlelement, mode, const std::string&);
+        
+        XMLPortObjectTemplate(BaseObject, Template, "templates", addTemplate, getTemplate, xmlelement, mode, Template*);
+        XMLPortObject(BaseObject, BaseObject, "eventlisteners", addEventListener, getEventListener, xmlelement, mode);
+
+        Element* events = 0;
+        if (mode == XMLPort::LoadObject || mode == XMLPort::ExpandObject)
+            events = xmlelement.FirstChildElement("events", false);
+        else if (mode == XMLPort::SaveObject)
+            {}
+        if (events)
+            this->XMLEventPort(*events, mode);
+    }
+
+    /**
+        @brief Defines the possible event states of this object and parses eventsources from an XML file.
+        @param xmlelement The XML-element
+        @param loading Loading (true) or saving (false)
+    */
+    void BaseObject::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        XMLPortEventState(BaseObject, BaseObject, "activity", setActive, xmlelement, mode);
+        XMLPortEventState(BaseObject, BaseObject, "visibility", setVisible, xmlelement, mode);
+        XMLPortEventState(BaseObject, BaseObject, "mainstate", setMainState, xmlelement, mode);
+
+        this->bRegisteredEventStates_ = true;
+    }
+
+    /**
+        @brief Loads the name of the object through XML and calls all XMLNameListener.
+        @param name The name of the object
+    */
+    void BaseObject::setXMLName(const std::string& name)
+    {
+        this->setName(name);
+
+        for (ObjectList<XMLNameListener>::iterator it = ObjectList<XMLNameListener>::begin(); it != ObjectList<XMLNameListener>::end(); ++it)
+            it->loadedNewXMLName(this);
+    }
+
+    /**
+        @brief Returns the levelfile that loaded this object.
+        @return The levelfile
+    */
+    const std::string& BaseObject::getFilename() const
+    {
+        if (this->file_)
+            return this->file_->getFilename();
+        else
+            return BLANKSTRING;
+    }
+
+    /**
+        @brief Adds a Template to the object.
+        @param name The name of the Template
+    */
+    void BaseObject::addTemplate(const std::string& name)
+    {
+        Template* temp = Template::getTemplate(name);
+        if (temp)
+            this->addTemplate(temp);
+        else
+            COUT(1) << "Error: \"" << name << "\" is not a valid Template name (in class: " << this->getIdentifier()->getName() << ", name: " << this->getName() << ")." << std::endl;
+    }
+
+    /**
+        @brief Adds a Template to the object.
+        @param temp The Template
+    */
+    void BaseObject::addTemplate(Template* temp)
+    {
+        this->templates_.insert(temp);
+        temp->applyOn(this);
+    }
+
+    /**
+        @brief Returns the name of the first Template.
+        @return The name as string.
+    */
+    const std::string& BaseObject::getSingleTemplate(void) const
+    {
+        if(this->templates_.empty())
+            return BLANKSTRING;
+
+        return (*this->templates_.begin())->getName();
+    }
+
+    /**
+        @brief Returns the Template with the given index.
+        @param index The index
+    */
+    Template* BaseObject::getTemplate(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::set<Template*>::const_iterator it = this->templates_.begin(); it != this->templates_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+            i++;
+        }
+        return 0;
+    }
+
+    /**
+        @brief Adds a new event source for a specific state.
+        @param source The object which sends events to this object
+        @param state The state of this object which will be affected by the events
+    */
+    void BaseObject::addEventSource(BaseObject* source, const std::string& state)
+    {
+        this->eventSources_[source] = state;
+        source->registerEventListener(this);
+    }
+
+    /**
+        @brief Removes an eventsource (but doesn't unregister itself at the source).
+    */
+    void BaseObject::removeEventSource(BaseObject* source)
+    {
+        this->eventSources_.erase(source);
+        source->unregisterEventListener(this);
+    }
+
+    /**
+        @brief Returns an eventsource with a given index.
+    */
+    BaseObject* BaseObject::getEventSource(unsigned int index, const std::string& state) const
+    {
+        unsigned int i = 0;
+        for (std::map<BaseObject*, std::string>::const_iterator it = this->eventSources_.begin(); it != this->eventSources_.end(); ++it)
+        {
+            if (it->second != state)
+                continue;
+
+            if (i == index)
+                return it->first;
+            ++i;
+        }
+        return 0;
+    }
+
+    /**
+        @brief Adds an object which listens to the events of this object. The events are sent to the other objects mainstate.
+    */
+    void BaseObject::addEventListener(BaseObject* listener)
+    {
+        this->eventListenersXML_.insert(listener);
+        listener->addEventSource(this, "mainstate");
+    }
+
+    /**
+        @brief Returns an event listener with a given index.
+    */
+    BaseObject* BaseObject::getEventListener(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::set<BaseObject*>::const_iterator it = this->eventListenersXML_.begin(); it != this->eventListenersXML_.end(); ++it)
+        {
+            if (i == index)
+                return *it;
+            ++i;
+        }
+        return 0;
+    }
+
+    /**
+        @brief Adds a new event-state to the object. Event-states are states which can be changed by events.
+        @param name  The name of the event
+        @param state The object containing information about the event-state
+    */
+    void BaseObject::addEventState(const std::string& name, EventState* state)
+    {
+        std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(name);
+        if (it != this->eventStates_.end())
+        {
+            COUT(2) << "Warning: Overwriting EventState in class " << this->getIdentifier()->getName() << '.' << std::endl;
+            delete (it->second);
+        }
+
+        this->eventStates_[name] = state;
+    }
+
+    /**
+        @brief Returns the event-state with the given name.
+    */
+    EventState* BaseObject::getEventState(const std::string& name) const
+    {
+        std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(name);
+        if (it != this->eventStates_.end())
+            return (it->second);
+        else
+            return 0;
+    }
+
+    /**
+        @brief Fires an event (without a state).
+    */
+    void BaseObject::fireEvent(const std::string& name)
+    {
+        this->fireEvent(true, name);
+        this->fireEvent(false, name);
+    }
+
+    /**
+        @brief Fires an event which activates or deactivates a state.
+    */
+    void BaseObject::fireEvent(bool activate, const std::string& name)
+    {
+        this->fireEvent(activate, this, name);
+    }
+
+    /**
+        @brief Fires an event which activates or deactivates a state with agiven originator (the object which triggered the event).
+    */
+    void BaseObject::fireEvent(bool activate, BaseObject* originator, const std::string& name)
+    {
+        Event event(activate, originator, name);
+
+        for (std::set<BaseObject*>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
+        {
+            event.statename_ = (*it)->eventSources_[this];
+            (*it)->processEvent(event);
+        }
+    }
+
+    /**
+        @brief Fires an event, using the Event struct.
+    */
+    void BaseObject::fireEvent(Event& event)
+    {
+        for (std::set<BaseObject*>::iterator it = this->eventListeners_.begin(); it != this->eventListeners_.end(); ++it)
+            (*it)->processEvent(event);
+    }
+
+    /**
+        @brief Processing an event by calling the right main state.
+        @param event The event struct which contains the information about the event
+    */
+    void BaseObject::processEvent(Event& event)
+    {
+        this->registerEventStates();
+        
+        COUT(4) << this->getIdentifier()->getName() << " (&" << this << ") processing event. originator: " << event.originator_->getIdentifier()->getName() << " (&" << event.originator_ << "), activate: " << event.activate_ << ", name: " << event.name_ << ", statename: " << event.statename_ << "." << std::endl;
+
+        std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(event.statename_);
+        if (it != this->eventStates_.end())
+            it->second->process(event, this);
+        else if (!event.statename_.empty())
+            COUT(2) << "Warning: \"" << event.statename_ << "\" is not a valid state in object \"" << this->getName() << "\" of class " << this->getIdentifier()->getName() << "." << std::endl;
+        else
+            COUT(2) << "Warning: Event with invalid source sent to object \"" << this->getName() << "\" of class " << this->getIdentifier()->getName() << "." << std::endl;
+    }
+
+    /**
+        @brief Sets the main state of the object to a given boolean value.
+
+        Note: The main state of an object can be set with the @ref setMainStateName function.
+        It's part of the eventsystem and used for event forwarding (when the target object can't specify a specific state,
+        the main state is used by default).
+    */
+    void BaseObject::setMainState(bool state)
+    {
+        if (this->mainStateFunctor_)
+        {
+            if (this->mainStateFunctor_->getParamCount() == 0)
+            {
+                if (state)
+                    (*this->mainStateFunctor_)();
+            }
+            else
+            {
+                (*this->mainStateFunctor_)(state);
+            }
+        }
+        else
+            COUT(2) << "Warning: No MainState defined in object \"" << this->getName() << "\" (" << this->getIdentifier()->getName() << ")" << std::endl;
+    }
+
+    /**
+        @brief This function gets called if the main state name of the object changes.
+    */
+    void BaseObject::changedMainStateName()
+    {
+        this->mainStateFunctor_ = 0;
+
+        if (!this->mainStateName_.empty())
+        {
+            this->registerEventStates();
+
+            std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(this->mainStateName_);
+            if (it != this->eventStates_.end() && it->second->getFunctor())
+            {
+                if (it->second->getFunctor()->getParamCount() <= 1)
+                    this->mainStateFunctor_ = it->second->getFunctor();
+                else
+                    COUT(2) << "Warning: Can't use \"" << this->mainStateName_ << "\" as MainState because it needs a second argument." << std::endl;
+            }
+            else
+                COUT(2) << "Warning: \"" << this->mainStateName_ << "\" is not a valid MainState." << std::endl;
+        }
+    }
+
+    /**
+        @brief Calls XMLEventPort with an empty XML-element to register the event states if necessary.
+    */
+    void BaseObject::registerEventStates()
+    {
+        if (!this->bRegisteredEventStates_)
+        {
+            Element xmlelement;
+            this->XMLEventPort(xmlelement, XMLPort::NOP);
+        }
+    }
+
+    /**
+        @brief Manually loads all event states, even if the class doesn't officially support them. This is needed by some classes like @ref EventDispatcher or @ref EventTarget.
+    */
+    void BaseObject::loadAllEventStates(Element& xmlelement, XMLPort::Mode mode, BaseObject* object, Identifier* identifier)
+    {
+        Element* events = xmlelement.FirstChildElement("events", false);
+        if (events)
+        {
+            // get the list of all states present
+            std::list<std::string> eventnames;
+            if (mode == XMLPort::LoadObject || mode == XMLPort::ExpandObject)
+            {
+                for (ticpp::Iterator<ticpp::Element> child = events->FirstChildElement(false); child != child.end(); child++)
+                    eventnames.push_back(child->Value());
+            }
+            else if (mode == XMLPort::SaveObject)
+            {
+            }
+
+            // iterate through all states and get the event sources
+            for (std::list<std::string>::iterator it = eventnames.begin(); it != eventnames.end(); ++it)
+            {
+                const std::string& statename = (*it);
+
+                // if the event state is already known, continue with the next state
+                orxonox::EventState* eventstate = object->getEventState(statename);
+                if (eventstate)
+                    continue;
+
+                XMLPortClassObjectContainer<BaseObject, BaseObject>* container = (XMLPortClassObjectContainer<BaseObject, BaseObject>*)(identifier->getXMLPortObjectContainer(statename));
+                if (!container)
+                {
+                    ExecutorMember<BaseObject>* setfunctor = createExecutor(createFunctor(&BaseObject::addEventSource), std::string( "BaseObject" ) + "::" + "addEventSource" + '(' + statename + ')');
+                    ExecutorMember<BaseObject>* getfunctor = createExecutor(createFunctor(&BaseObject::getEventSource), std::string( "BaseObject" ) + "::" + "getEventSource" + '(' + statename + ')');
+                    setfunctor->setDefaultValue(1, statename);
+                    getfunctor->setDefaultValue(1, statename);
+
+                    container = new XMLPortClassObjectContainer<BaseObject, BaseObject>(statename, identifier, setfunctor, getfunctor, false, true);
+                    identifier->addXMLPortObjectContainer(statename, container);
+                }
+                container->port(object, *events, mode);
+            }
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/BaseObject.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/BaseObject.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/BaseObject.h	(revision 6952)
@@ -0,0 +1,241 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the BaseObject class.
+
+    The BaseObject is the parent of all classes representing an instance in the game.
+*/
+
+#ifndef _BaseObject_H__
+#define _BaseObject_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <list>
+
+#include "util/mbool.h"
+#include "OrxonoxClass.h"
+#include "Super.h"
+#include "SmartPtr.h"
+
+namespace orxonox
+{
+    class Scene;
+    class Gametype;
+    class Level;
+
+    //! The BaseObject is the parent of all classes representing an instance in the game.
+    class _CoreExport BaseObject : virtual public OrxonoxClass
+    {
+        template <class T> friend class XMLPortClassParamContainer;
+
+        public:
+            BaseObject(BaseObject* creator);
+            virtual ~BaseObject();
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
+
+            /** @brief Returns if the object was initialized (passed the object registration). @return True was the object is initialized */
+            inline bool isInitialized() const { return this->bInitialized_; }
+
+            /** @brief Sets the name of the object. @param name The name */
+            inline void setName(const std::string& name) { this->oldName_ = this->name_; this->name_ = name; this->changedName(); }
+            /** @brief Returns the name of the object. */
+            inline const std::string& getName() const { return this->name_; }
+            /** @brief Returns the old name of the object. */
+            inline const std::string& getOldName() const { return this->oldName_; }
+            /** @brief This function gets called if the name of the object changes. */
+            virtual void changedName() {}
+
+            /** @brief Sets the state of the objects activity. @param bActive True = active */
+            inline void setActive(bool bActive)
+            {
+                if (this->bActive_ != bActive)
+                {
+                    this->bActive_ = bActive;
+                    this->changedActivity();
+                }
+            }
+            /** @brief Returns the state of the objects activity. @return The state of the activity */
+            inline const mbool& isActive() const { return this->bActive_; }
+            /** @brief This function gets called if the activity of the object changes. */
+            virtual void changedActivity() {}
+
+            /** @brief Sets the state of the objects visibility. @param bVisible True = visible */
+            inline void setVisible(bool bVisible)
+            {
+                if (this->bVisible_ != bVisible)
+                {
+                    this->bVisible_ = bVisible;
+                    this->changedVisibility();
+                }
+            }
+            /** @brief Returns the state of the objects visibility. @return The state of the visibility */
+            inline const mbool& isVisible() const { return this->bVisible_; }
+            /** @brief This function gets called if the visibility of the object changes. */
+            virtual void changedVisibility() {}
+
+            void setMainState(bool state);
+
+            /** @brief Sets the name of the main state (used for event reactions). */
+            void setMainStateName(const std::string& name)
+            {
+                if (this->mainStateName_ != name)
+                {
+                    this->mainStateName_ = name;
+                    this->changedMainStateName();
+                }
+            }
+            /** @brief Returns the name of the main state. */
+            inline const std::string& getMainStateName() const { return this->mainStateName_; }
+            /** @brief This function gets called if the main state name of the object changes. */
+            virtual void changedMainStateName();
+
+            /** @brief Sets a pointer to the xml file that loaded this object. @param file The pointer to the XMLFile */
+            inline void setFile(const XMLFile* file) { this->file_ = file; }
+            /** @brief Returns a pointer to the XMLFile that loaded this object. @return The XMLFile */
+            inline const XMLFile* getFile() const { return this->file_; }
+            const std::string& getFilename() const;
+
+            void addTemplate(const std::string& name);
+            void addTemplate(Template* temp);
+            /** @brief Returns the set of all aplied templates. */
+            inline const std::set<Template*>& getTemplates() const
+                { return this->templates_; }
+
+            virtual inline void setNamespace(Namespace* ns) { this->namespace_ = ns; }
+            inline Namespace* getNamespace() const { return this->namespace_; }
+
+            inline void setCreator(BaseObject* creator) { this->creator_ = creator; }
+            inline BaseObject* getCreator() const { return this->creator_; }
+
+            inline void setScene(const SmartPtr<Scene>& scene, uint32_t sceneID) { this->scene_ = scene; this->sceneID_=sceneID; }
+            inline const SmartPtr<Scene>& getScene() const { return this->scene_; }
+            inline virtual uint32_t getSceneID() const { return this->sceneID_; }
+
+            inline void setGametype(const SmartPtr<Gametype>& gametype)
+            {
+                if (gametype != this->gametype_)
+                {
+                    this->oldGametype_ = this->gametype_;
+                    this->gametype_ = gametype;
+                    this->changedGametype();
+                }
+            }
+            inline const SmartPtr<Gametype>& getGametype() const { return this->gametype_; }
+            inline Gametype* getOldGametype() const { return this->oldGametype_; }
+            virtual void changedGametype() {}
+            
+            inline void setLevel(const SmartPtr<Level>& level)
+            {
+                if (level != this->level_)
+                {
+                    this->level_ = level;
+                    this->changedLevel();
+                }
+            }
+            inline const SmartPtr<Level>& getLevel() const { return this->level_; }
+            virtual void changedLevel() {}
+
+            void addEventSource(BaseObject* source, const std::string& state);
+            void removeEventSource(BaseObject* source);
+            BaseObject* getEventSource(unsigned int index, const std::string& state) const;
+
+            void addEventListener(BaseObject* listener);
+            BaseObject* getEventListener(unsigned int index) const;
+
+            void fireEvent(const std::string& name = "");
+            void fireEvent(bool activate, const std::string& name = "");
+            void fireEvent(bool activate, BaseObject* originator, const std::string& name = "");
+            void fireEvent(Event& event);
+
+            virtual void processEvent(Event& event);
+
+            /** @brief Sets the indentation of the debug output in the Loader. @param indentation The indentation */
+            inline void setLoaderIndentation(const std::string& indentation) { this->loaderIndentation_ = indentation; }
+            /** @brief Returns the indentation of the debug output in the Loader. @return The indentation */
+            inline const std::string& getLoaderIndentation() const { return this->loaderIndentation_; }
+
+            static void loadAllEventStates(Element& xmlelement, XMLPort::Mode mode, BaseObject* object, Identifier* identifier);
+
+        protected:
+            void addEventState(const std::string& name, EventState* container);
+            EventState* getEventState(const std::string& name) const;
+
+            std::string name_;                                 //!< The name of the object
+            std::string oldName_;                              //!< The old name of the object
+            mbool       bActive_;                              //!< True = the object is active
+            mbool       bVisible_;                             //!< True = the object is visible
+            std::string mainStateName_;
+            Functor*    mainStateFunctor_;
+
+        private:
+            /** @brief Adds an object which listens to the events of this object. */
+            void registerEventListener(BaseObject* object);
+            /** @brief Removes an event listener from this object. */
+            inline void unregisterEventListener(BaseObject* object)
+                { this->eventListeners_.erase(object); }
+
+            void setXMLName(const std::string& name);
+            const std::string& getSingleTemplate(void) const;
+            Template* getTemplate(unsigned int index) const;
+            void registerEventStates();
+
+            bool                   bInitialized_;              //!< True if the object was initialized (passed the object registration)
+            const XMLFile*         file_;                      //!< The XMLFile that loaded this object
+            Element*               lastLoadedXMLElement_;      //!< Non 0 if the TinyXML attributes have already been copied to our own lowercase map
+            std::map<std::string, std::string> xmlAttributes_; //!< Lowercase XML attributes
+            std::string            loaderIndentation_;         //!< Indentation of the debug output in the Loader
+            Namespace*             namespace_;
+            BaseObject*            creator_;
+            SmartPtr<Scene>        scene_;
+            uint32_t               sceneID_;
+            SmartPtr<Gametype>     gametype_;
+            Gametype*              oldGametype_;
+            SmartPtr<Level>        level_;
+            std::set<Template*>    templates_;
+
+            std::map<BaseObject*, std::string>  eventSources_;           //!< List of objects which send events to this object, mapped to the state which they affect
+            std::set<BaseObject*>               eventListeners_;         //!< List of objects which listen to the events of this object
+            std::set<BaseObject*>               eventListenersXML_;      //!< List of objects which listen to the events of this object through the "eventlisteners" subsection in XML
+            std::map<std::string, EventState*>  eventStates_;            //!< Maps the name of the event states to their helper objects
+            bool                                bRegisteredEventStates_; //!< Becomes true after the object registered its event states (with XMLEventPort)
+    };
+
+    SUPER_FUNCTION(0, BaseObject, XMLPort, false);
+    SUPER_FUNCTION(2, BaseObject, changedActivity, false);
+    SUPER_FUNCTION(3, BaseObject, changedVisibility, false);
+    SUPER_FUNCTION(4, BaseObject, XMLEventPort, false);
+    SUPER_FUNCTION(8, BaseObject, changedName, false);
+    SUPER_FUNCTION(9, BaseObject, changedGametype, false);
+}
+
+#endif /* _BaseObject_H__ */
Index: /code/branches/rocket2/src/libraries/core/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/libraries/core/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,119 @@
+ #
+ #             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.
+ #
+
+SET_SOURCE_FILES(CORE_SRC_FILES
+  ConfigValueContainer.cc
+  Core.cc
+  DynLib.cc
+  DynLibManager.cc
+  Event.cc
+  Game.cc
+  GameMode.cc
+  GameState.cc
+  GraphicsManager.cc
+  GUIManager.cc
+  IOConsole.cc
+  Language.cc
+  LuaState.cc
+  ObjectListBase.cc
+  OrxonoxClass.cc
+  Resource.cc
+  ScopedSingletonManager.cc
+  WindowEventListener.cc
+
+  # command
+  CommandEvaluation.cc
+  CommandExecutor.cc
+  CommandLineParser.cc
+  ConsoleCommand.cc
+  ConsoleCommandCompilation.cc
+  Executor.cc
+
+  # hierarchy
+  Identifier.cc
+  MetaObjectList.cc
+
+  # level
+  BaseObject.cc
+  ClassTreeMask.cc
+  Loader.cc
+  Namespace.cc
+  NamespaceNode.cc
+  Template.cc
+  XMLPort.cc
+  XMLNameListener.cc
+
+  # shell
+  IRC.cc
+  Shell.cc
+  TclBind.cc
+
+COMPILATION_BEGIN FilesystemCompilation.cc
+  ArgumentCompletionFunctions.cc
+  ConfigFileManager.cc
+  MemoryArchive.cc
+  PathConfig.cc
+COMPILATION_END
+
+  # multithreading
+  ThreadPool.cc
+COMPILATION_BEGIN ThreadCompilation.cc
+  TclThreadManager.cc
+  Thread.cc
+COMPILATION_END
+)
+
+ADD_SUBDIRECTORY(input)
+
+ORXONOX_ADD_LIBRARY(core
+  FIND_HEADER_FILES
+  TOLUA_FILES
+    CommandExecutor.h
+    ConfigFileManager.h
+    Game.h
+    GameMode.h
+    GUIManager.h
+    Loader.h
+    LuaState.h
+    PathConfig.h
+    input/InputManager.h
+    input/KeyBinder.h
+    input/KeyBinderManager.h
+  DEFINE_SYMBOL
+    "CORE_SHARED_BUILD"
+  PCH_FILE
+    CorePrecompiledHeaders.h
+  LINK_LIBRARIES
+    ${OGRE_LIBRARY}
+    ${Boost_FILESYSTEM_LIBRARY}
+    ${Boost_SYSTEM_LIBRARY} # Filesystem dependency
+    ${Boost_THREAD_LIBRARY}
+    ${Boost_DATE_TIME_LIBRARY} # Thread dependency
+    ${CEGUI_LIBRARY}
+    ${CEGUILUA_LIBRARY}
+    ${LUA_LIBRARIES}
+    cpptcl_orxonox
+    ogreceguirenderer_orxonox
+    ois_orxonox
+    tinyxml++_orxonox
+    tolua++_orxonox
+    util
+  SOURCE_FILES
+    ${CORE_SRC_FILES}
+)
Index: /code/branches/rocket2/src/libraries/core/ClassFactory.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ClassFactory.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ClassFactory.h	(revision 6952)
@@ -0,0 +1,90 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition and implementation of the ClassFactory class
+
+    The ClassFactory is able to create new objects of a specific class.
+*/
+
+#ifndef _ClassFactory_H__
+#define _ClassFactory_H__
+
+#include "CorePrereqs.h"
+
+#include <string>
+
+#include "util/Debug.h"
+#include "Identifier.h"
+
+namespace orxonox
+{
+    // ###########################
+    // ###       Factory       ###
+    // ###########################
+    //! Base-class of ClassFactory.
+    class _CoreExport Factory
+    {
+        public:
+            virtual ~Factory() {};
+            virtual BaseObject* fabricate(BaseObject* creator) = 0;
+    };
+
+    // ###############################
+    // ###      ClassFactory       ###
+    // ###############################
+    //! The ClassFactory is able to create new objects of a specific class.
+    template <class T>
+    class ClassFactory : public Factory
+    {
+        public:
+            /**
+                @brief Constructor: Adds the ClassFactory to the Identifier of the same type.
+                @param name The name of the class
+                @param bLoadable True if the class can be loaded through XML
+            */
+            ClassFactory(const std::string& name, bool bLoadable = true)
+            {
+                COUT(4) << "*** ClassFactory: Create entry for " << name << " in Factory." << std::endl;
+                ClassIdentifier<T>::getIdentifier(name)->addFactory(this);
+                ClassIdentifier<T>::getIdentifier()->setLoadable(bLoadable);
+            }
+
+            /**
+                @brief Creates and returns a new object of class T.
+                @return The new object
+            */
+            inline BaseObject* fabricate(BaseObject* creator)
+            {
+                return static_cast<BaseObject*>(new T(creator));
+            }
+    };
+}
+
+#endif /* _ClassFactory_H__ */
Index: /code/branches/rocket2/src/libraries/core/ClassTreeMask.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/ClassTreeMask.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ClassTreeMask.cc	(revision 6952)
@@ -0,0 +1,972 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the ClassTreeMask, ClassTreeMaskNode and ClassTreeMaskIterator classes.
+*/
+
+#include "ClassTreeMask.h"
+#include "Identifier.h"
+
+namespace orxonox
+{
+    // ###############################
+    // ###    ClassTreeMaskNode    ###
+    // ###############################
+    /**
+        @brief Constructor: Creates the node, sets the subclass and the rule.
+        @param subclass The subclass the rule refers to
+        @param bIncluded The rule: included (true) or excluded (false)
+    */
+    ClassTreeMaskNode::ClassTreeMaskNode(const Identifier* subclass, bool bIncluded)
+    {
+        this->subclass_ = subclass;
+        this->bIncluded_ = bIncluded;
+    }
+
+    /**
+        @brief Destructor: Deletes all subnodes.
+    */
+    ClassTreeMaskNode::~ClassTreeMaskNode()
+    {
+        // Go through the list of all subnodes and delete them
+        this->deleteAllSubnodes();
+    }
+
+    /**
+        @brief Sets the rule for the node to "included".
+        @param overwrite True = overwrite previously added rules for inheriting classes
+    */
+    void ClassTreeMaskNode::include(bool overwrite)
+    {
+        this->setIncluded(true, overwrite);
+    }
+
+    /**
+        @brief Sets the rule for the node to "excluded".
+        @param overwrite True = overwrite previously added rules for inheriting classes
+    */
+    void ClassTreeMaskNode::exclude(bool overwrite)
+    {
+        this->setIncluded(false, overwrite);
+    }
+
+    /**
+        @brief Sets the rule for the node to a given value and erases all following rules.
+        @param bIncluded The rule: included (true) or excluded (false)
+        @param overwrite True = overwrite previously added rules for inheriting classes
+    */
+    void ClassTreeMaskNode::setIncluded(bool bIncluded, bool overwrite)
+    {
+        if (overwrite)
+            this->deleteAllSubnodes();
+
+        this->bIncluded_ = bIncluded;
+    }
+
+    /**
+        @brief Adds a new subnode to the list of subnodes.
+        @param subnode The new subnode
+    */
+    void ClassTreeMaskNode::addSubnode(ClassTreeMaskNode* subnode)
+    {
+        this->subnodes_.insert(this->subnodes_.end(), subnode);
+    }
+
+    /**
+        @brief Deletes all subnodes of this node.
+    */
+    void ClassTreeMaskNode::deleteAllSubnodes()
+    {
+        // Go through the list of all subnodes and delete them
+        for (std::list<ClassTreeMaskNode*>::iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); )
+            delete (*(it++));
+
+        // Clear the list
+        this->subnodes_.clear();
+    }
+
+
+    // ###############################
+    // ###  ClassTreeMaskIterator  ###
+    // ###############################
+    /**
+        @brief Constructor: Initializes the iterator by creating a helper-list with the root-node and putting it to the stack.
+        @param node The root-node
+    */
+    ClassTreeMaskIterator::ClassTreeMaskIterator(ClassTreeMaskNode* node)
+    {
+        // Create a list and put the root-note into it
+        std::list<ClassTreeMaskNode*>::iterator it = this->rootlist_.insert(this->rootlist_.end(), node);
+
+        // Put the iterator to the only element of the list and the corresponding end()-iterator on the stack
+        this->nodes_.push(std::pair<std::list<ClassTreeMaskNode*>::iterator, std::list<ClassTreeMaskNode*>::iterator>(it, this->rootlist_.end()));
+    }
+
+    /**
+        @brief Destructor: Does nothing.
+    */
+    ClassTreeMaskIterator::~ClassTreeMaskIterator()
+    {
+    }
+
+    /**
+        @brief Iterates through the rule-tree.
+        @return A reference to the iterator itself
+    */
+    const ClassTreeMaskIterator& ClassTreeMaskIterator::operator++()
+    {
+        // Check if the actual node has subnodes
+        if ((*this->nodes_.top().first)->subnodes_.begin() != (*this->nodes_.top().first)->subnodes_.end())
+        {
+            // Yes it has: Push an iterator, pointing at the first subnode, on the stack
+            this->nodes_.push(std::pair<std::list<ClassTreeMaskNode*>::iterator, std::list<ClassTreeMaskNode*>::iterator>((*this->nodes_.top().first)->subnodes_.begin(), (*this->nodes_.top().first)->subnodes_.end()));
+        }
+        else
+        {
+            // No subnodes, meaning we reached a leaf: Go to the next node
+            do
+            {
+                // Iterate one step in the current list
+                ++this->nodes_.top().first;
+
+                // Check if we reached the end of the list (the second item in the stored pair always represents the end)
+                if (this->nodes_.top().first == this->nodes_.top().second)
+                {
+                    // Yes we've reached the end: Pop the list-iterator from the stack
+                    this->nodes_.pop();
+
+                    // Continue with the loop, meaning: Try to iterate through the previous list
+                    continue;
+                }
+
+                // If we reached this point, we aren't yet at the end of the list: Leave the loop
+                break;
+            } while (!this->nodes_.empty()); // Stop looping if the stack is empty, meaning: We've iterated to the end
+        }
+
+        // Finally return a reference to the iterator itself
+        return *this;
+    }
+
+    /**
+        @brief Returns a pointer to the ClassTreeMaskNode whereon the iterator points.
+        @return The pointer to the node
+    */
+    ClassTreeMaskNode* ClassTreeMaskIterator::operator*() const
+    {
+        return (*this->nodes_.top().first);
+    }
+
+    /**
+        @brief Returns a pointer to the ClassTreeMaskNode whereon the iterator points.
+        @return The pointer to the node
+    */
+    ClassTreeMaskNode* ClassTreeMaskIterator::operator->() const
+    {
+        return (*this->nodes_.top().first);
+    }
+
+    /**
+        @brief Returns true if the stack is empty, meaning we've reached the end of the tree.
+        @return True if we've reached the end of the tree
+    */
+    ClassTreeMaskIterator::operator bool() const
+    {
+        return (!this->nodes_.empty());
+    }
+
+    /**
+        @brief Compares the current node with the given one and returns true if they match.
+        @param compare The node to compare with
+        @return The result of the comparison (true if they match)
+    */
+    bool ClassTreeMaskIterator::operator==(ClassTreeMaskNode* compare) const
+    {
+        if (!this->nodes_.empty())
+            return ((*this->nodes_.top().first) == compare);
+        else
+            return (compare == 0);
+    }
+
+    /**
+        @brief Compares the current node with the given one and returns true if they don't match.
+        @param compare The node to compare with
+        @return The result of the comparison (true if they don't match)
+    */
+    bool ClassTreeMaskIterator::operator!=(ClassTreeMaskNode* compare) const
+    {
+        if (!this->nodes_.empty())
+            return ((*this->nodes_.top().first) != compare);
+        else
+            return (compare != 0);
+    }
+
+
+    // ###############################
+    // ###      ClassTreeMask      ###
+    // ###############################
+    /**
+        @brief Constructor: Adds the root-node of the tree with the first rule ("include everything").
+    */
+    ClassTreeMask::ClassTreeMask()
+    {
+        this->root_ = new ClassTreeMaskNode(ClassIdentifier<BaseObject>::getIdentifier(), true);
+    }
+
+    /**
+        @brief Copyconstructor: Adds the root-node of the tree with the first rule ("include everything") and adds all rules from the other mask.
+        @param other The other mask
+    */
+    ClassTreeMask::ClassTreeMask(const ClassTreeMask& other)
+    {
+        this->root_ = new ClassTreeMaskNode(ClassIdentifier<BaseObject>::getIdentifier(), true);
+        for (ClassTreeMaskIterator it = other.root_; it; ++it)
+            this->add(it->getClass(), it->isIncluded(), false);
+    }
+
+    /**
+        @brief Destructor: Deletes the root node (which will delete all subnodes too).
+    */
+    ClassTreeMask::~ClassTreeMask()
+    {
+        delete this->root_;
+    }
+
+    /**
+        @brief Adds a new "include" rule for a given subclass to the mask.
+        @param subclass The subclass
+        @param overwrite True = overwrite previously added rules for inheriting classes
+        @param clean True = clean the tree after adding the new rule
+    */
+    void ClassTreeMask::include(const Identifier* subclass, bool overwrite, bool clean)
+    {
+        this->add(subclass, true, overwrite, clean);
+    }
+
+    /**
+        @brief Adds a new "exclude" rule for a given subclass to the mask.
+        @param subclass The subclass
+        @param overwrite True = overwrite previously added rules for inheriting classes
+        @param clean True = clean the tree after adding the new rule
+    */
+    void ClassTreeMask::exclude(const Identifier* subclass, bool overwrite, bool clean)
+    {
+        this->add(subclass, false, overwrite, clean);
+    }
+
+    /**
+        @brief Adds a new rule for a given subclass to the mask.
+        @param subclass The subclass
+        @param bInclude The rule: include (true) or exclude (false)
+        @param overwrite True = overwrite previously added rules for inheriting classes
+        @param clean True = clean the tree after adding the new rule
+    */
+    void ClassTreeMask::add(const Identifier* subclass, bool bInclude, bool overwrite, bool clean)
+    {
+        if (!subclass)
+            return;
+        // Check if the given subclass is a child of our root-class
+        if (subclass->isA(this->root_->getClass()))
+        {
+            // Yes it is: Just add the rule to the three
+            this->add(this->root_, subclass, bInclude, overwrite);
+        }
+        else
+        {
+            // No it's not: Search for classes inheriting from the given class and add the rules for them
+            for (std::set<const Identifier*>::const_iterator it = subclass->getDirectChildrenBegin(); it != subclass->getDirectChildrenEnd(); ++it)
+                if ((*it)->isA(this->root_->getClass()))
+                    if (overwrite || (!this->nodeExists(*it))) // If we don't want to overwrite, only add nodes that don't already exist
+                        this->add(this->root_, *it, bInclude, overwrite);
+        }
+
+        // Clean the rule-tree
+        if (clean)
+            this->clean();
+    }
+
+    /**
+        @brief Adds a new rule for a given subclass to a node of the internal rule-tree (recursive function).
+        @param node The node
+        @param subclass The subclass
+        @param bInclude The rule: include (true) or exclude (false)
+        @param overwrite True = overwrite previously added rules for inheriting classes
+    */
+    void ClassTreeMask::add(ClassTreeMaskNode* node, const Identifier* subclass, bool bInclude, bool overwrite)
+    {
+        if (!subclass)
+            return;
+        // Check if the current node contains exactly the subclass we want to add
+        if (subclass == node->getClass())
+        {
+            // We're at the right place, just change the mask and return
+            node->setIncluded(bInclude, overwrite);
+            return;
+        }
+        else if (subclass->isA(node->getClass()))
+        {
+            // Search for an already existing node, containing the subclass we want to add
+            for (std::list<ClassTreeMaskNode*>::iterator it = node->subnodes_.begin(); it != node->subnodes_.end(); ++it)
+            {
+                if (subclass->isA((*it)->getClass()))
+                {
+                    // We've found an existing node -> delegate the work with a recursive function-call and return
+                    this->add(*it, subclass, bInclude, overwrite);
+                    return;
+                }
+            }
+
+            // There is no existing node satisfying our needs -> we create a new node
+            ClassTreeMaskNode* newnode = new ClassTreeMaskNode(subclass, bInclude);
+
+            // Search for nodes that should actually be subnodes of our new node and erase them
+            for (std::list<ClassTreeMaskNode*>::iterator it = node->subnodes_.begin(); it != node->subnodes_.end(); )
+            {
+                if ((*it)->getClass()->isChildOf(subclass))
+                {
+                    // We've found a subnode: add it to the new node and erase it from the current node
+                    if (!overwrite)
+                        newnode->addSubnode(*it);
+                    else
+                        delete (*it);
+
+                    node->subnodes_.erase(it++);
+                }
+                else
+                {
+                    ++it;
+                }
+            }
+
+            // Finally add the new node as a subnode to the current node
+            node->addSubnode(newnode);
+        }
+    }
+
+    /**
+        @brief Adds a new "include" rule for a single subclass. The new rule doesn't change the mask for inheriting classes.
+        @param subclass The subclass
+        @param clean True = clean the tree after adding the new rule
+    */
+    void ClassTreeMask::includeSingle(const Identifier* subclass, bool clean)
+    {
+        this->addSingle(subclass, true, clean);
+    }
+
+    /**
+        @brief Adds a new "exclude" rule for a single subclass. The new rule doesn't change the mask for inheriting classes.
+        @param subclass The subclass
+        @param clean True = clean the tree after adding the new rule
+    */
+    void ClassTreeMask::excludeSingle(const Identifier* subclass, bool clean)
+    {
+        this->addSingle(subclass, false, clean);
+    }
+
+    /**
+        @brief Adds a new rule for a single subclass. The new rule doesn't change the mask for inheriting classes.
+        @param bInclude The rule: include (true) or exclude (false)
+        @param subclass The subclass
+        @param clean True = clean the tree after adding the new rule
+    */
+    void ClassTreeMask::addSingle(const Identifier* subclass, bool bInclude, bool clean)
+    {
+        if (!subclass)
+            return;
+        for (std::set<const Identifier*>::const_iterator it = subclass->getDirectChildrenBegin(); it != subclass->getDirectChildrenEnd(); ++it)
+            this->add(*it, this->isIncluded(*it), false, false);
+
+        this->add(subclass, bInclude, false, clean);
+    }
+
+    /**
+        @brief Resets the mask to "include everything".
+    */
+    void ClassTreeMask::reset()
+    {
+        delete this->root_;
+        this->root_ = new ClassTreeMaskNode(ClassIdentifier<BaseObject>::getIdentifier(), true);
+    }
+
+    /**
+        @brief Tells if a given subclass is included or not.
+        @param subclass The subclass
+        @return Included (true) or excluded (false)
+    */
+    bool ClassTreeMask::isIncluded(const Identifier* subclass) const
+    {
+        return this->isIncluded(this->root_, subclass);
+    }
+
+    /**
+        @brief Tells if a given subclass of a node in the rule-tree is included or not (recursive function).
+        @param node The node
+        @param subclass The subclass
+        @return Included (true) or excluded (false)
+    */
+    bool ClassTreeMask::isIncluded(ClassTreeMaskNode* node, const Identifier* subclass) const
+    {
+        if (!subclass)
+            return false;
+        // Check if the searched subclass is of the same type as the class in the current node or a derivative
+        if (subclass->isA(node->getClass()))
+        {
+            // Check for the special case
+            if (subclass == node->getClass())
+                return node->isIncluded();
+
+            // Go through the list of subnodes and look for a node containing the searched subclass and delegate the request by a recursive function-call.
+            for (std::list<ClassTreeMaskNode*>::iterator it = node->subnodes_.begin(); it != node->subnodes_.end(); ++it)
+                if (subclass->isA((*it)->getClass()))
+                    return isIncluded(*it, subclass);
+
+            // There is no subnode containing our class -> the rule of the current node takes in effect
+            return node->isIncluded();
+        }
+        else
+        {
+            // The class is not included in the mask: return false
+            return false;
+        }
+    }
+
+    /**
+        @brief Tells if a given subclass is excluded or not.
+        @param subclass The subclass
+        @return The inverted rule: Excluded (true) or included (false)
+    */
+    bool ClassTreeMask::isExcluded(const Identifier* subclass) const
+    {
+        return (!this->isIncluded(subclass));
+    }
+
+    /**
+        @brief Removes all unneeded rules that don't change the information of the mask.
+    */
+    void ClassTreeMask::clean()
+    {
+        this->clean(this->root_);
+    }
+
+    /**
+        @brief Removes all unneded rules that don't change the information of a node of a mask (recursive function).
+        @param node The node
+    */
+    void ClassTreeMask::clean(ClassTreeMaskNode* node)
+    {
+        // Iterate through all subnodes of the given node
+        for (std::list<ClassTreeMaskNode*>::iterator it = node->subnodes_.begin(); it != node->subnodes_.end(); )
+        {
+            // Recursive function-call: Clean the subnode
+            this->clean(*it);
+
+            // Now check if the subnode contains the same rule as the current node
+            if ((*it)->isIncluded() == node->isIncluded())
+            {
+                // It does: Move all subnodes of the redundant subnode to the current node
+                node->subnodes_.insert(node->subnodes_.end(), (*it)->subnodes_.begin(), (*it)->subnodes_.end());
+                (*it)->subnodes_.clear();
+
+                // Remove the redundant subnode from the current node
+                delete (*it);
+                node->subnodes_.erase(it++);
+            }
+            else
+            {
+                // The subnode is necessary: Move on to the next subnode
+                ++it;
+            }
+        }
+    }
+
+    /**
+        @brief Checks if a node for the given subclass exists.
+        @param subclass The Identifier of the subclass
+        @return True = the node exists
+    */
+    bool ClassTreeMask::nodeExists(const Identifier* subclass)
+    {
+        for (ClassTreeMaskIterator it = this->root_; it; ++it)
+            if ((*it)->getClass() == subclass)
+                return true;
+
+        return false;
+    }
+
+    /**
+        @brief Assignment operator: Adds all rules of the other mask.
+        @param other The other mask
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator=(const ClassTreeMask& other)
+    {
+        // Make a copy to avoid troubles with self-assignments (like A = A).
+        ClassTreeMask temp(other);
+
+        // Removes all current rules
+        this->reset();
+
+        // Copy all rules from the other mask
+        for (ClassTreeMaskIterator it = temp.root_; it; ++it)
+            this->add(it->getClass(), it->isIncluded(), false, false);
+
+        // Return a reference to the mask itself
+        return (*this);
+    }
+
+    /**
+        @brief Compares the mask with another mask and returns true if they represent the same logic.
+        @param other The other mask
+        @return True if both masks represent the same logic
+    */
+    bool ClassTreeMask::operator==(const ClassTreeMask& other) const
+    {
+        ClassTreeMask temp1 = other;
+        ClassTreeMask temp2 = (*this);
+
+        temp1.clean();
+        temp2.clean();
+
+        ClassTreeMaskIterator it1 = temp1.root_;
+        ClassTreeMaskIterator it2 = temp2.root_;
+
+        for ( ; it1 && it2; ++it1, ++it2)
+            if (it1->getClass() != it2->getClass())
+                return false;
+
+        return true;
+    }
+
+    /**
+        @brief Compares the mask with another mask and returns true if they represent different logics.
+        @param other The other mask
+        @return True if the masks represent different logics
+    */
+    bool ClassTreeMask::operator!=(const ClassTreeMask& other) const
+    {
+        return (!((*this) == other));
+    }
+
+    /**
+        @brief Prefix operator + does nothing.
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator+() const
+    {
+        return (*this);
+    }
+
+    /**
+        @brief Prefix operator - inverts the mask.
+        @return The inverted mask
+    */
+    ClassTreeMask ClassTreeMask::operator-() const
+    {
+        return (!(*this));
+    }
+
+    /**
+        @brief Adds two masks in the sense of a union (all classes that are included in at least one of the masks will be included in the resulting mask too).
+        @param other The mask to unite with
+        @return The union
+    */
+    ClassTreeMask ClassTreeMask::operator+(const ClassTreeMask& other) const
+    {
+        // Create a new mask
+        ClassTreeMask newmask;
+
+        // Add all nodes from the first mask, calculate the rule with the or-operation
+        for (ClassTreeMaskIterator it = this->root_; it; ++it)
+        {
+            const Identifier* subclass = it->getClass();
+            newmask.add(subclass, this->isIncluded(subclass) or other.isIncluded(subclass), false, false);
+        }
+
+        // Add all nodes from the second mask, calculate the rule with the or-operation
+        for (ClassTreeMaskIterator it = other.root_; it; ++it)
+        {
+            const Identifier* subclass = it->getClass();
+            newmask.add(subclass, this->isIncluded(subclass) or other.isIncluded(subclass), false, false);
+        }
+
+        // Drop all redundant rules
+        newmask.clean();
+
+        // Return the new mask
+        return newmask;
+    }
+
+    /**
+        @brief Intersects two masks (only classes that are included in both masks will be included in the resulting mask too).
+        @param other The mask to intersect with
+        @return The intersection
+    */
+    ClassTreeMask ClassTreeMask::operator*(const ClassTreeMask& other) const
+    {
+        // Create a new mask
+        ClassTreeMask newmask;
+
+        // Add all nodes from the first mask, calculate the rule with the and-operation
+        for (ClassTreeMaskIterator it = this->root_; it; ++it)
+        {
+            const Identifier* subclass = it->getClass();
+            newmask.add(subclass, this->isIncluded(subclass) and other.isIncluded(subclass), false, false);
+        }
+
+        // Add all nodes from the second mask, calculate the rule with the and-operation
+        for (ClassTreeMaskIterator it = other.root_; it; ++it)
+        {
+            const Identifier* subclass = it->getClass();
+            newmask.add(subclass, this->isIncluded(subclass) and other.isIncluded(subclass), false, false);
+        }
+
+        // Drop all redundant rules
+        newmask.clean();
+
+        // Return the new mask
+        return newmask;
+    }
+
+    /**
+        @brief Removes all elements of the second mask from the first mask (all classes that are included in the first mask stay included, except those that are included in the second mask too).
+        @param other The mask to subtract.
+        @return The difference
+    */
+    ClassTreeMask ClassTreeMask::operator-(const ClassTreeMask& other) const
+    {
+        return ((*this) * (!other));
+    }
+
+    /**
+        @brief Inverts the mask (all included classes are now excluded and vice versa).
+        @return The complement
+    */
+    ClassTreeMask ClassTreeMask::operator!() const
+    {
+        // Create a new mask
+        ClassTreeMask newmask;
+
+        // Add all nodes from the other mask, inverting the rules
+        for (ClassTreeMaskIterator it = this->root_; it; ++it)
+        {
+            const Identifier* subclass = it->getClass();
+            newmask.add(subclass, !this->isIncluded(subclass), false, false);
+        }
+
+        // Return the new mask
+        return newmask;
+    }
+
+    /**
+        @brief Unites this mask with another mask.
+        @param other The other mask
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator+=(const ClassTreeMask& other)
+    {
+        (*this) = (*this) + other;
+        return (*this);
+    }
+
+    /**
+        @brief Intersects this mask with another mask.
+        @param other The other mask
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator*=(const ClassTreeMask& other)
+    {
+        (*this) = (*this) * other;
+        return (*this);
+    }
+
+    /**
+        @brief Subtracts another mask from this mask.
+        @param other The other mask
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator-=(const ClassTreeMask& other)
+    {
+        (*this) = (*this) - other;
+        return (*this);
+    }
+
+    /**
+        @brief Intersects two masks (only classes that are included in both masks will be included in the resulting mask too).
+        @param other The mask to intersect with
+        @return The intersection
+    */
+    ClassTreeMask ClassTreeMask::operator&(const ClassTreeMask& other) const
+    {
+        return ((*this) * other);
+    }
+
+    /**
+        @brief Adds two masks in the sense of a union (all classes that are included in at least one of the masks will be included in the resulting mask too).
+        @param other The mask to unite with
+        @return The union
+    */
+    ClassTreeMask ClassTreeMask::operator|(const ClassTreeMask& other) const
+    {
+        return ((*this) + other);
+    }
+
+    /**
+        @brief Joins two masks in the sense of a xor (exclusivity) operation (all classes that are included in exactly one of the masks, but not in both, will be included in the resulting mask too).
+        @param other The mask to join with
+        @return The result
+    */
+    ClassTreeMask ClassTreeMask::operator^(const ClassTreeMask& other) const
+    {
+        // Create a new mask
+        ClassTreeMask newmask;
+
+        // Add all nodes from the first mask, calculate the rule with the xor-operation
+        for (ClassTreeMaskIterator it = this->root_; it; ++it)
+        {
+            const Identifier* subclass = it->getClass();
+            newmask.add(subclass, this->isIncluded(subclass) xor other.isIncluded(subclass), false, false);
+        }
+
+        // Add all nodes from the second mask, calculate the rule with the xor-operation
+        for (ClassTreeMaskIterator it = other.root_; it; ++it)
+        {
+            const Identifier* subclass = it->getClass();
+            newmask.add(subclass, this->isIncluded(subclass) xor other.isIncluded(subclass), false, false);
+        }
+
+        // Drop all redundant rules
+        newmask.clean();
+
+        // Return the new mask
+        return newmask;
+    }
+
+    /**
+        @brief Inverts the mask (all included classes are now excluded and vice versa).
+        @return The complement
+    */
+    ClassTreeMask ClassTreeMask::operator~() const
+    {
+        return (!(*this));
+    }
+
+    /**
+        @brief Intersects this mask with another mask (and-operation)
+        @param other The other mask
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator&=(const ClassTreeMask& other)
+    {
+        (*this) = (*this) & other;
+        return (*this);
+    }
+
+    /**
+        @brief Unites this mask with another mask (or-operation).
+        @param other The other mask
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator|=(const ClassTreeMask& other)
+    {
+        (*this) = (*this) | other;
+        return (*this);
+    }
+
+    /**
+        @brief Joins this mask with another mask with a xor-operation.
+        @param other The other mask
+        @return A reference to the mask itself
+    */
+    const ClassTreeMask& ClassTreeMask::operator^=(const ClassTreeMask& other)
+    {
+        (*this) = (*this) ^ other;
+        return (*this);
+    }
+
+    /**
+        @brief Converts the content of a mask into a human readable string and puts it on the ostream.
+        @param out The ostream
+        @param mask The mask
+        @return A reference to the ostream
+    */
+    std::ostream& operator<<(std::ostream& out, const ClassTreeMask& mask)
+    {
+        // Iterate through all rules
+        for (ClassTreeMaskIterator it = mask.root_; it; ++it)
+        {
+            // Calculate the prefix: + means included, - means excluded
+            if (it->isIncluded())
+                out << '+';
+            else
+                out << '-';
+
+            // Put the name of the corresponding class on the stream
+            out << it->getClass()->getName() << ' ';
+        }
+
+        return out;
+    }
+
+
+    // ###################################
+    // ### ClassTreeMaskObjectIterator ###
+    // ###################################
+    /**
+        @brief Initializes the iterator from a given ClassTreeMask.
+        @param mask The mask
+    */
+    const ClassTreeMaskObjectIterator& ClassTreeMaskObjectIterator::operator=(const ClassTreeMask& mask)
+    {
+        // Clear everything, use a cleaned copy of the mask
+        this->subclasses_.clear();
+        ClassTreeMask temp = mask;
+        temp.clean();
+
+        // Create the subclass-list by going through the mask-tree, starting with the root-node
+        this->create(temp.root_);
+
+        // Move the subclass-iterator to the beginning of the subclass-list
+        this->subclassIterator_ = this->subclasses_.begin();
+
+        // If there is a first subclass, move the object-iterator to the first object of this class. Else go to the end
+        if (this->subclassIterator_ != this->subclasses_.end())
+            this->objectIterator_ = this->subclassIterator_->first->getObjects()->begin();
+        else
+            this->objectIterator_ = ObjectList<BaseObject>::end();
+
+        // Check if the iterator points on a valid object. If not, go to the next object by calling ++
+        if (!this->objectIterator_ || (this->subclassIterator_->second && !this->objectIterator_->isExactlyA(this->subclassIterator_->first)))
+            this->operator++();
+
+        return (*this);
+    }
+
+    /**
+        @brief Iterate to the next object (if any).
+        @return The iterator itself
+    */
+    const ClassTreeMaskObjectIterator& ClassTreeMaskObjectIterator::operator++()
+    {
+        if (this->objectIterator_)
+        {
+            // The iterator points on a valid object, therefore we also have a valid subclass-iterator at the moment
+            do
+            {
+                // Go to the next object
+                ++this->objectIterator_;
+
+                while (!this->objectIterator_)
+                {
+                    // We reached the end of the current objectlist - go to the next class
+                    ++this->subclassIterator_;
+
+                    // Check if there really is a next class. If yes, move the object-iterator to the first object
+                    if (this->subclassIterator_ != this->subclasses_.end())
+                        this->objectIterator_ = this->subclassIterator_->first->getObjects()->begin();
+                    else
+                        return (*this);
+                }
+
+            // Repeat this until we reach a valid object or the end
+            } while (this->subclassIterator_->second && !this->objectIterator_->isExactlyA(this->subclassIterator_->first));
+        }
+        return (*this);
+    }
+
+    /**
+        @brief Recursive function to create the Iterators subclass-list by going through the node-tree of the mask.
+        @param node The current node
+    */
+    void ClassTreeMaskObjectIterator::create(ClassTreeMaskNode* node)
+    {
+        // Add the class of this node to the list, if the class is included
+        if (node->isIncluded())
+        {
+            // If there are some subnodes, the bool is "true", meaning we have to check for the exact clss when iterating
+            if (node->hasSubnodes())
+                this->subclasses_.insert(this->subclasses_.end(), std::pair<const Identifier*, bool>(node->getClass(), true));
+            else
+                this->subclasses_.insert(this->subclasses_.end(), std::pair<const Identifier*, bool>(node->getClass(), false));
+        }
+
+        // Now check if the node has subnodes
+        if (node->hasSubnodes())
+        {
+            // Get all _direct_ children of the nodes class
+            std::set<const Identifier*> directChildren = node->getClass()->getDirectChildren();
+
+            // Iterate through all subnodes
+            for (std::list<ClassTreeMaskNode*>::iterator it1 = node->subnodes_.begin(); it1 != node->subnodes_.end(); ++it1)
+            {
+                // Recursive call to this function with the subnode
+                this->create(*it1);
+
+                // Only execute the following code if the current node is included, meaning some of the subnodes might be included too
+                if (node->isIncluded())
+                {
+                    scanChildren: // This is a label for goto
+
+                    // Iterate through all direct children
+                    for (std::set<const Identifier*>::iterator it2 = directChildren.begin(); it2 != directChildren.end(); ++it2)
+                    {
+                        // Check if the subnode (it1) is a child of the directChild (it2)
+                        if ((*it1)->getClass()->isA(*it2))
+                        {
+                            // Yes it is - remove the directChild (it2) from the list, because it will already be handled by a recursive call to the create() function
+                            directChildren.erase(it2);
+
+                            // Check if the removed directChild was exactly the subnode
+                            if (!(*it1)->getClass()->isExactlyA(*it2))
+                            {
+                                // No, it wasn't exactly the subnode - therefore there are some classes between
+
+                                // Add the previously removed directChild (it2) to the subclass-list
+                                this->subclasses_.insert(this->subclasses_.end(), std::pair<const Identifier*, bool>(*it2, true));
+
+                                // Insert all directChildren of the directChild
+                                directChildren.insert((*it2)->getDirectChildrenBegin(), (*it2)->getDirectChildrenEnd());
+
+                                // Restart the scan with the expanded set of directChildren
+                                goto scanChildren;
+                            }
+                            break;
+                        }
+                    }
+                }
+            }
+
+            // Now add all directChildren which don't have subnodes on their own to the subclass-list
+            // The bool is "false", meaning they have no subnodes and therefore need no further checks
+            if (node->isIncluded())
+                for (std::set<const Identifier*>::iterator it = directChildren.begin(); it != directChildren.end(); ++it)
+                    this->subclasses_.insert(this->subclasses_.end(), std::pair<const Identifier*, bool>(*it, false));
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/ClassTreeMask.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ClassTreeMask.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ClassTreeMask.h	(revision 6952)
@@ -0,0 +1,286 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the ClassTreeMask, ClassTreeMaskNode and ClassTreeMaskIterator classes.
+
+    ClassTreeMask is a class to define a mask of the class-tree beginning with BaseObject.
+    You can include or exclude classes by calling the corresponding functions with the
+    Identifier of the class.
+
+    You can work with a ClassTreeMask in the sense of the set-theory, meaning that you can create
+    unions, intersections, complements and differences by using overloaded operators.
+
+
+
+    The ClassTreeMask is internally represented by a tree. The nodes in the tree are
+    ClassTreeMaskNodes, containing the rule (included or excluded) for this class and all
+    subclasses and a list of all subnodes. To minimize the size, the tree contains only
+    nodes changing the mask. By adding new rules, the tree gets reordered dynamically.
+
+    Adding a new rule overwrites all rules assigned to inherited classes. Use overwrite = false
+    if you don't like this feature. Useless rules that don't change the information of the mask
+    aren't saved in the internal tree. Use clean = false if you wan't to save them.
+
+    With overwrite = false and clean = false it doesn't matter in which way you create the mask.
+    You can manually drop useless rules from the tree by calling clean().
+
+
+
+    Because of the complicated shape of the internal tree, there is an iterator to iterate
+    through all ClassTreeMaskNodes of a mask. It starts with the BaseObject and moves on to
+    the first subclass until it reaches a leaf of the tree. Then the iterator moves one step
+    back and iterates to the second subclass. If there are no more subclasses, it steps another
+    step back, and so on.
+
+    Example: A and B are children of BaseObject, A1 and A2 are children of A, B1 and B2 are children of B.
+    The ClassTreeMaskIterator would move trough the tree in the following order:
+    BaseObject, A, A1, A2, B, B1, B2.
+
+    Note that the iterator doesn't move trough the whole class-tree, but only through the
+    internal tree of the mask, containing the minimal needed set of nodes to describe the mask.
+*/
+
+#ifndef _ClassTreeMask_H__
+#define _ClassTreeMask_H__
+
+#include "CorePrereqs.h"
+
+#include <list>
+#include <stack>
+#include "BaseObject.h"
+#include "Iterator.h"
+
+namespace orxonox
+{
+    // ###################################
+    // ###      ClassTreeMaskNode      ###
+    // ###################################
+    //! The ClassTreeMaskNode is a node in the internal tree of the ClassTreeMask, containing the rules of the mask.
+    /**
+        The ClassTreeMaskNode is used to store the rule (included or excluded) for a given
+        class (described by the corresponding Identifier). The nodes are used in the internal
+        tree of ClassTreeMask. To build a tree, they store a list of all subnodes.
+    */
+    class _CoreExport ClassTreeMaskNode
+    {
+        friend class ClassTreeMask;
+        friend class ClassTreeMaskIterator;
+        friend class ClassTreeMaskObjectIterator;
+
+        public:
+            ClassTreeMaskNode(const Identifier* subclass, bool bIncluded = true);
+            ~ClassTreeMaskNode();
+
+            void include(bool overwrite = true);
+            void exclude(bool overwrite = true);
+            void setIncluded(bool bIncluded, bool overwrite = true);
+
+            void addSubnode(ClassTreeMaskNode* subnode);
+
+            /** @brief Tells if the rule is "included" or not. @return The rule: true = included, false = excluded */
+            inline bool isIncluded() const { return this->bIncluded_; }
+            /** @brief Tells if the rule is "excluded" or not. @return The inverted rule: true = excluded, false = included */
+            inline bool isExcluded() const { return (!this->bIncluded_); }
+
+            /** @brief Returns the Identifier of the class the rule refers to. @return The Identifier representing the class */
+            inline const Identifier* getClass() const { return this->subclass_; }
+
+            /** @brief Returns true if the Node has some subnodes. */
+            inline bool hasSubnodes() const { return !this->subnodes_.empty(); }
+
+        private:
+            void deleteAllSubnodes();
+
+            const Identifier* subclass_;                //!< The Identifier of the subclass the rule refers to
+            bool bIncluded_;                            //!< The rule: included or excluded
+            std::list<ClassTreeMaskNode*> subnodes_;    //!< A list containing all subnodes in the tree
+    };
+
+
+    // ###################################
+    // ###    ClassTreeMaskIterator    ###
+    // ###################################
+    //! The ClassTreeMaskIterator moves through all ClassTreeMaskNodes of the internal tree of a ClassTreeMask, containing the rules.
+    /**
+        Because of the complicated shape of the internal rule-tree of ClassTreeMask, an
+        iterator is used to move through all nodes of the tree. It starts with the BaseObject
+        and moves on to the first subclass until it reaches a leaf of the tree. Then the
+        iterator moves one step back and iterates to the second subclass. If there are no more
+        subclasses, it steps another step back, and so on.
+    */
+    class _CoreExport ClassTreeMaskIterator
+    {
+        public:
+            ClassTreeMaskIterator(ClassTreeMaskNode* node);
+            ~ClassTreeMaskIterator();
+
+            const ClassTreeMaskIterator& operator++();
+            ClassTreeMaskNode* operator*() const;
+            ClassTreeMaskNode* operator->() const;
+            operator bool() const;
+            bool operator==(ClassTreeMaskNode* compare) const;
+            bool operator!=(ClassTreeMaskNode* compare) const;
+
+        private:
+            std::stack<std::pair<std::list<ClassTreeMaskNode*>::iterator, std::list<ClassTreeMaskNode*>::iterator> > nodes_;    //!< A stack to store list-iterators
+            std::list<ClassTreeMaskNode*> rootlist_;                                                                            //!< A list for internal use (it only stores the root-node)
+    };
+
+
+    // ###################################
+    // ###        ClassTreeMask        ###
+    // ###################################
+    //! The ClassTreeMask is a set of rules, containing the information for each class whether it's included or not.
+    /**
+        With a ClassTreeMask, you can include or exclude subtrees of the class-tree, starting
+        with a given subclass, described by the corresponding Identifier. To minimize the size
+        of the mask, the mask saves only relevant rules. But you can manually add rules that
+        don't change the information of the mask by using clean = false. If you want to drop
+        useless rules, call the clean() function.
+    */
+    class _CoreExport ClassTreeMask
+    {
+        friend class ClassTreeMaskObjectIterator;
+
+        public:
+            ClassTreeMask();
+            ClassTreeMask(const ClassTreeMask& other);
+            ~ClassTreeMask();
+
+            void include(const Identifier* subclass, bool overwrite = true, bool clean = true);
+            void exclude(const Identifier* subclass, bool overwrite = true, bool clean = true);
+            void add(const Identifier* subclass, bool bInclude, bool overwrite = true, bool clean = true);
+
+            void includeSingle(const Identifier* subclass, bool clean = true);
+            void excludeSingle(const Identifier* subclass, bool clean = true);
+            void addSingle(const Identifier* subclass, bool bInclude, bool clean = true);
+
+            void reset();
+            void clean();
+
+            bool isIncluded(const Identifier* subclass) const;
+            bool isExcluded(const Identifier* subclass) const;
+
+            /** @brief Begin of the ClassTreeMaskObjectIterator. */
+            inline const ClassTreeMask& begin() const { return (*this); }
+            /** @brief End of the ClassTreeMaskObjectIterator. */
+            inline BaseObject*          end()   const { return 0; }
+
+            const ClassTreeMask& operator=(const ClassTreeMask& other);
+
+            bool operator==(const ClassTreeMask& other) const;
+            bool operator!=(const ClassTreeMask& other) const;
+
+            const ClassTreeMask& operator+() const;
+            ClassTreeMask operator-() const;
+
+            ClassTreeMask operator+(const ClassTreeMask& other) const;
+            ClassTreeMask operator*(const ClassTreeMask& other) const;
+            ClassTreeMask operator-(const ClassTreeMask& other) const;
+            ClassTreeMask operator!() const;
+
+            const ClassTreeMask& operator+=(const ClassTreeMask& other);
+            const ClassTreeMask& operator*=(const ClassTreeMask& other);
+            const ClassTreeMask& operator-=(const ClassTreeMask& other);
+
+            ClassTreeMask operator&(const ClassTreeMask& other) const;
+            ClassTreeMask operator|(const ClassTreeMask& other) const;
+            ClassTreeMask operator^(const ClassTreeMask& other) const;
+            ClassTreeMask operator~() const;
+
+            const ClassTreeMask& operator&=(const ClassTreeMask& other);
+            const ClassTreeMask& operator|=(const ClassTreeMask& other);
+            const ClassTreeMask& operator^=(const ClassTreeMask& other);
+
+            friend std::ostream& operator<<(std::ostream& out, const ClassTreeMask& mask);
+
+        private:
+            void add(ClassTreeMaskNode* node, const Identifier* subclass, bool bInclude, bool overwrite = true);
+            bool isIncluded(ClassTreeMaskNode* node, const Identifier* subclass) const;
+            void clean(ClassTreeMaskNode* node);
+            bool nodeExists(const Identifier* subclass);
+
+            ClassTreeMaskNode* root_;   //!< The root-node of the internal rule-tree, usually BaseObject
+    };
+
+
+    // ###################################
+    // ### ClassTreeMaskObjectIterator ###
+    // ###################################
+    //! The ClassTreeMaskObjectIterator iterates through all objects of all classes, included by a ClassTreeMask.
+    /**
+        The ClassTreeMaskObjectIterator iterates through all objects of all classes,
+        included by a ClassTreeMask. This is done the following way:
+
+        ClassTreeMask mask;
+        for (ClassTreeMaskObjectIterator it = mask.begin(); it != mask.end(); ++it)
+            it->doSomething();
+
+        Note: The ClassTreeMaskObjectIterator handles all objects as BaseObjects. If
+              you want to use another class, you should use a dynamic_cast.
+
+        Performance of ClassTreeMaskObjectIterator is good as long as you don't exclude
+        subclasses of included classes. Of course you can still exlucde subclasses, but
+        if this is done more often, we need a new implementation using a second ObjectList
+        in the Identifier, containing all objects of exactly one class.
+    */
+    class _CoreExport ClassTreeMaskObjectIterator
+    {
+        public:
+            /** @brief Defaultconstructor: Does nothing. */
+            inline ClassTreeMaskObjectIterator() {}
+            /** @brief Constructor: Initializes the iterator from a given ClassTreeMask. @param mask The mask */
+            inline ClassTreeMaskObjectIterator(const ClassTreeMask& mask) { (*this) = mask; }
+
+            const ClassTreeMaskObjectIterator& operator=(const ClassTreeMask& mask);
+
+            const ClassTreeMaskObjectIterator& operator++();
+
+            /** @brief Returns true if the ClassTreeMaskObjectIterator points at the given object. @param pointer The pointer of the object */
+            inline bool operator==(BaseObject* pointer) const { return (this->objectIterator_ && (*this->objectIterator_) == pointer) || (!this->objectIterator_ && pointer == 0); }
+            /** @brief Returns true if the ClassTreeMaskObjectIterator doesn't point at the given object. @param pointer The pointer of the object */
+            inline bool operator!=(BaseObject* pointer) const { return (this->objectIterator_ && (*this->objectIterator_) != pointer) || (!this->objectIterator_ && pointer != 0); }
+            /** @brief Returns true if the ClassTreeMaskObjectIterator hasn't already reached the end. */
+            inline operator bool() const { return (this->objectIterator_); }
+            /** @brief Returns the object the ClassTreeMaskObjectIterator currently points at. */
+            inline BaseObject* operator*() const { return (*this->objectIterator_); }
+            /** @brief Returns the object the ClassTreeMaskObjectIterator currently points at. */
+            inline BaseObject* operator->() const { return (*this->objectIterator_); }
+
+        private:
+            void create(ClassTreeMaskNode* node);
+
+            std::list<std::pair<const Identifier*, bool> >           subclasses_;       //!< A list of all Identifiers through which objects the iterator should iterate
+            std::list<std::pair<const Identifier*, bool> >::iterator subclassIterator_; //!< The current class of the iterator
+            Iterator<BaseObject>                                     objectIterator_;   //!< The current object of the iterator
+    };
+}
+
+#endif /* _ClassTreeMask_H__ */
Index: /code/branches/rocket2/src/libraries/core/CommandEvaluation.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/CommandEvaluation.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/CommandEvaluation.cc	(revision 6952)
@@ -0,0 +1,313 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "CommandEvaluation.h"
+
+#include "util/Debug.h"
+#include "util/StringUtils.h"
+#include "ConsoleCommand.h"
+#include "Identifier.h"
+
+namespace orxonox
+{
+    CommandEvaluation::CommandEvaluation()
+    {
+        this->initialize("");
+        this->state_ = CommandState::Uninitialized;
+    }
+
+    void CommandEvaluation::initialize(const std::string& command)
+    {
+        this->bNewCommand_ = true;
+        this->bCommandChanged_ = false;
+        this->originalCommand_ = command;
+        this->command_ = command;
+        this->commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
+
+        this->additionalParameter_.clear();
+
+        this->bEvaluatedParams_ = false;
+
+        this->listOfPossibleIdentifiers_.clear();
+        this->listOfPossibleFunctions_.clear();
+        this->listOfPossibleArguments_.clear();
+
+        this->functionclass_ = 0;
+        this->function_ = 0;
+        this->possibleArgument_.clear();
+        this->argument_.clear();
+
+        this->errorMessage_.clear();
+        this->state_ = CommandState::Empty;
+    }
+
+    bool CommandEvaluation::isValid() const
+    {
+        return (this->function_);
+    }
+
+    bool CommandEvaluation::execute() const
+    {
+        if (!this->isValid())
+            return false;
+
+        if (this->bEvaluatedParams_ && this->function_)
+        {
+            COUT(6) << "CE_execute (evaluation): " << this->function_->getName() << ' ' << this->param_[0] << ' ' << this->param_[1] << ' ' << this->param_[2] << ' ' << this->param_[3] << ' ' << this->param_[4] << std::endl;
+            (*this->function_)(this->param_[0], this->param_[1], this->param_[2], this->param_[3], this->param_[4]);
+            return true;
+        }
+
+        if (!this->bCommandChanged_ || nocaseCmp(removeTrailingWhitespaces(this->command_), removeTrailingWhitespaces(this->originalCommand_)) == 0)
+        {
+            COUT(4) << "CE_execute: " << this->command_ << "\n";
+
+            unsigned int startindex = this->getStartindex();
+            if (this->commandTokens_.size() > startindex)
+                return this->function_->parse(removeSlashes(this->commandTokens_.subSet(startindex).join() + this->getAdditionalParameter()));
+            else
+                return this->function_->parse(removeSlashes(this->additionalParameter_));
+        }
+
+        return false;
+    }
+
+    const std::string& CommandEvaluation::complete()
+    {
+        if (!this->bNewCommand_)
+        {
+            switch (this->state_)
+            {
+                case CommandState::Uninitialized:
+                    break;
+                case CommandState::Empty:
+                    break;
+                case CommandState::ShortcutOrIdentifier:
+                    if (this->function_)
+                    {
+                        if (this->function_->getParamCount() == 0)
+                            return (this->command_ = this->function_->getName());
+                        else
+                            return (this->command_ = this->function_->getName() + ' ');
+                    }
+                    else if (this->functionclass_)
+                        return (this->command_ = this->functionclass_->getName() + ' ');
+                    break;
+                case CommandState::Function:
+                    if (this->function_)
+                    {
+                        if (this->function_->getParamCount() == 0)
+                            return (this->command_ = this->functionclass_->getName() + ' ' + this->function_->getName());
+                        else
+                            return (this->command_ = this->functionclass_->getName() + ' ' + this->function_->getName() + ' ');
+                    }
+                    break;
+                case CommandState::ParamPreparation:
+                case CommandState::Params:
+                {
+                    if (this->argument_.empty() && this->possibleArgument_.empty())
+                        break;
+
+                    unsigned int maxIndex = this->commandTokens_.size();
+                    if (this->command_[this->command_.size() - 1] != ' ')
+                        maxIndex -= 1;
+                    std::string whitespace;
+
+                    if (!this->possibleArgument_.empty())
+                    {
+                        this->argument_ = this->possibleArgument_;
+                        if (this->function_->getParamCount() > (maxIndex + 1 - this->getStartindex()))
+                            whitespace = " ";
+                    }
+
+                    return (this->command_ = this->commandTokens_.subSet(0, maxIndex).join() + ' ' + this->argument_ + whitespace);
+                    break;
+                }
+                case CommandState::Finished:
+                    break;
+                case CommandState::Error:
+                    break;
+            }
+        }
+        this->bNewCommand_ = false;
+        return this->command_;
+    }
+
+    std::string CommandEvaluation::hint() const
+    {
+        switch (this->state_)
+        {
+            case CommandState::Uninitialized:
+                break;
+            case CommandState::Empty:
+            case CommandState::ShortcutOrIdentifier:
+                if (this->listOfPossibleFunctions_.size() == 0)
+                    return CommandEvaluation::dump(this->listOfPossibleIdentifiers_);
+                else if (this->listOfPossibleIdentifiers_.size() == 0)
+                    return CommandEvaluation::dump(this->listOfPossibleFunctions_);
+                else
+                    return (CommandEvaluation::dump(this->listOfPossibleFunctions_) + "\n" + CommandEvaluation::dump(this->listOfPossibleIdentifiers_));
+                break;
+            case CommandState::Function:
+                return CommandEvaluation::dump(this->listOfPossibleFunctions_);
+                break;
+            case CommandState::ParamPreparation:
+            case CommandState::Params:
+                if (this->listOfPossibleArguments_.size() > 0)
+                    return CommandEvaluation::dump(this->listOfPossibleArguments_);
+                else
+                    return CommandEvaluation::dump(this->function_);
+            case CommandState::Finished:
+                if (this->function_)
+                    return CommandEvaluation::dump(this->function_);
+                break;
+            case CommandState::Error:
+                return this->errorMessage_;
+                break;
+        }
+
+        return "";
+    }
+
+    void CommandEvaluation::evaluateParams()
+    {
+        this->bEvaluatedParams_ = false;
+
+        for (unsigned int i = 0; i < MAX_FUNCTOR_ARGUMENTS; i++)
+            this->param_[i] = MT_Type::Null;
+
+        if (!this->isValid())
+            return;
+
+        unsigned int startindex = this->getStartindex();
+
+        if (this->commandTokens_.size() <= startindex)
+        {
+            if (this->function_->evaluate(this->getAdditionalParameter(), this->param_, " "))
+                this->bEvaluatedParams_ = true;
+        }
+        else if (this->commandTokens_.size() > startindex)
+        {
+            if (this->function_->evaluate(this->commandTokens_.subSet(startindex).join() + this->getAdditionalParameter(), this->param_, " "))
+                this->bEvaluatedParams_ = true;
+        }
+    }
+
+    void CommandEvaluation::setEvaluatedParameter(unsigned int index, MultiType param)
+    {
+        if (index < MAX_FUNCTOR_ARGUMENTS)
+            this->param_[index] = param;
+    }
+
+    MultiType CommandEvaluation::getEvaluatedParameter(unsigned int index) const
+    {
+        if (index < MAX_FUNCTOR_ARGUMENTS)
+            return this->param_[index];
+
+        return MT_Type::Null;
+    }
+
+    bool CommandEvaluation::hasReturnvalue() const
+    {
+        if (this->function_)
+            return this->function_->hasReturnvalue();
+
+        return MT_Type::Null;
+    }
+
+    MultiType CommandEvaluation::getReturnvalue() const
+    {
+        if (this->function_)
+            return this->function_->getReturnvalue();
+
+        return MultiType();
+    }
+
+
+    unsigned int CommandEvaluation::getStartindex() const
+    {
+        if (this->functionclass_ && this->function_)
+            return 2;
+        else if (this->function_)
+            return 1;
+        else
+            return 0;
+    }
+
+    std::string CommandEvaluation::dump(const std::list<std::pair<const std::string*, const std::string*> >& list)
+    {
+        std::string output;
+        for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)
+        {
+            if (it != list.begin())
+                output += ' ';
+
+            output += *(it->second);
+        }
+        return output;
+    }
+
+    std::string CommandEvaluation::dump(const ArgumentCompletionList& list)
+    {
+        std::string output;
+        for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
+        {
+            if (it != list.begin())
+                output += ' ';
+
+            output += it->getDisplay();
+        }
+        return output;
+    }
+
+    std::string CommandEvaluation::dump(const ConsoleCommand* command)
+    {
+        std::string output = command->getName();
+        if (command->getParamCount() > 0)
+            output += ": ";
+
+        for (unsigned int i = 0; i < command->getParamCount(); i++)
+        {
+            if (i != 0)
+                output += ' ';
+
+            if (command->defaultValueSet(i))
+                output += '[';
+            else
+                output += '{';
+
+            output += command->getTypenameParam(i);
+
+            if (command->defaultValueSet(i))
+                output += '=' + command->getDefaultValue(i).getString() + ']';
+            else
+                output += '}';
+        }
+        return output;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/CommandEvaluation.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/CommandEvaluation.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/CommandEvaluation.h	(revision 6952)
@@ -0,0 +1,124 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _CommandEvaluation_H__
+#define _CommandEvaluation_H__
+
+#include "CorePrereqs.h"
+
+#include <string>
+#include <list>
+
+#include "ArgumentCompletionListElement.h"
+#include "util/SubString.h"
+#include "util/MultiType.h"
+
+namespace orxonox
+{
+    namespace CommandState
+    {
+        enum Value
+        {
+            Uninitialized,
+            Empty,
+            ShortcutOrIdentifier,
+            Function,
+            ParamPreparation,
+            Params,
+            Finished,
+            Error
+        };
+    }
+
+    class _CoreExport CommandEvaluation
+    {
+        friend class CommandExecutor;
+
+        public:
+            CommandEvaluation();
+
+            void initialize(const std::string& command);
+
+            bool execute() const;
+            const std::string& complete();
+            std::string hint() const;
+            void evaluateParams();
+
+            bool isValid() const;
+
+            inline ConsoleCommand* getConsoleCommand() const
+                { return this->function_; }
+            inline const std::string& getOriginalCommand() const
+                { return this->originalCommand_; }
+            inline const std::string& getCommand() const
+                { return this->command_; }
+
+            inline void setAdditionalParameter(const std::string& param)
+                { this->additionalParameter_ = param; this->bEvaluatedParams_ = false; }
+            inline std::string getAdditionalParameter() const
+                { return (!this->additionalParameter_.empty()) ? (' ' + this->additionalParameter_) : ""; }
+
+            void setEvaluatedParameter(unsigned int index, MultiType param);
+            MultiType getEvaluatedParameter(unsigned int index) const;
+
+            bool hasReturnvalue() const;
+            MultiType getReturnvalue() const;
+
+        private:
+            unsigned int getStartindex() const;
+            static std::string dump(const std::list<std::pair<const std::string*, const std::string*> >& list);
+            static std::string dump(const ArgumentCompletionList& list);
+            static std::string dump(const ConsoleCommand* command);
+
+
+            bool bNewCommand_;
+            bool bCommandChanged_;
+
+            std::string originalCommand_;
+            std::string command_;
+            SubString commandTokens_;
+            std::string additionalParameter_;
+
+            std::list<std::pair<const std::string*, const std::string*> > listOfPossibleIdentifiers_;
+            std::list<std::pair<const std::string*, const std::string*> > listOfPossibleFunctions_;
+            ArgumentCompletionList listOfPossibleArguments_;
+
+            Identifier* functionclass_;
+            ConsoleCommand* function_;
+            std::string possibleArgument_;
+            std::string argument_;
+
+            std::string errorMessage_;
+            CommandState::Value state_;
+
+            bool bEvaluatedParams_;
+            MultiType param_[5];
+    };
+}
+
+#endif /* _CommandEvaluation_H__ */
Index: /code/branches/rocket2/src/libraries/core/CommandExecutor.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/CommandExecutor.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/CommandExecutor.cc	(revision 6952)
@@ -0,0 +1,677 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "CommandExecutor.h"
+
+#include "util/Debug.h"
+#include "util/StringUtils.h"
+#include "ConsoleCommand.h"
+#include "Identifier.h"
+#include "Language.h"
+#include "TclBind.h"
+
+namespace orxonox
+{
+    CommandExecutor& CommandExecutor::getInstance()
+    {
+        static CommandExecutor instance;
+        return instance;
+    }
+
+    CommandEvaluation& CommandExecutor::getEvaluation()
+    {
+        return CommandExecutor::getInstance().evaluation_;
+    }
+
+    const CommandEvaluation& CommandExecutor::getLastEvaluation()
+    {
+        return CommandExecutor::getInstance().evaluation_;
+    }
+
+    ConsoleCommand& CommandExecutor::addConsoleCommandShortcut(ConsoleCommand* command, bool bDeleteAtExit)
+    {
+        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(command->getName());
+        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
+        {
+            COUT(2) << "Warning: Overwriting console-command shortcut with name " << command->getName() << '.' << std::endl;
+        }
+
+        // Make sure we can also delete the external ConsoleCommands that don't belong to an Identifier
+        if (command && bDeleteAtExit)
+        {
+            CommandExecutor::getInstance().consoleCommandExternals_.insert(command);
+        }
+
+        CommandExecutor::getInstance().consoleCommandShortcuts_[command->getName()] = command;
+        CommandExecutor::getInstance().consoleCommandShortcuts_LC_[getLowercase(command->getName())] = command;
+        return (*command);
+    }
+
+    /**
+        @brief Returns the executor of a console command shortcut with given name.
+        @brief name The name of the requested console command shortcut
+        @return The executor of the requested console command shortcut
+    */
+    ConsoleCommand* CommandExecutor::getConsoleCommandShortcut(const std::string& name)
+    {
+        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(name);
+        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
+            return it->second;
+        else
+            return 0;
+    }
+
+    /**
+        @brief Returns the executor of a console command shortcut with given name in lowercase.
+        @brief name The name of the requested console command shortcut in lowercase
+        @return The executor of the requested console command shortcut
+    */
+    ConsoleCommand* CommandExecutor::getLowercaseConsoleCommandShortcut(const std::string& name)
+    {
+        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_LC_.find(name);
+        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_LC_.end())
+            return it->second;
+        else
+            return 0;
+    }
+
+    bool CommandExecutor::execute(const std::string& command, bool useTcl)
+    {
+        if (useTcl)
+            return TclBind::eval(command);
+
+        CommandExecutor::parseIfNeeded(command);
+        return CommandExecutor::getEvaluation().execute();
+    }
+
+    MultiType CommandExecutor::getReturnValue()
+    {
+        return CommandExecutor::getEvaluation().getReturnvalue();
+    }
+
+    std::string CommandExecutor::getReturnValueString()
+    {
+        return CommandExecutor::getEvaluation().getReturnvalue().getString();
+    }
+
+    std::string CommandExecutor::complete(const std::string& command)
+    {
+        CommandExecutor::parseIfNeeded(command);
+        return CommandExecutor::getEvaluation().complete();
+    }
+
+    std::string CommandExecutor::hint(const std::string& command)
+    {
+        CommandExecutor::parseIfNeeded(command);
+        return CommandExecutor::getEvaluation().hint();
+    }
+
+    CommandEvaluation CommandExecutor::evaluate(const std::string& command)
+    {
+        CommandExecutor::parse(command);
+        CommandExecutor::getEvaluation().evaluateParams();
+        return CommandExecutor::getEvaluation();
+    }
+
+    void CommandExecutor::parseIfNeeded(const std::string& command)
+    {
+        if (CommandExecutor::getEvaluation().state_ == CommandState::Uninitialized)
+        {
+            CommandExecutor::parse(command);
+        }
+        else if (CommandExecutor::getEvaluation().originalCommand_ != command)
+        {
+            if (CommandExecutor::getEvaluation().command_ == command)
+            {
+                CommandExecutor::parse(command);
+                CommandExecutor::getEvaluation().bNewCommand_ = false;
+            }
+            else
+            {
+                CommandExecutor::parse(command);
+            }
+        }
+    }
+
+    void CommandExecutor::parse(const std::string& command, bool bInitialize)
+    {
+        if (bInitialize)
+            CommandExecutor::getEvaluation().initialize(command);
+
+        CommandExecutor::getEvaluation().commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
+        CommandExecutor::getEvaluation().command_ = command;
+
+        switch (CommandExecutor::getEvaluation().state_)
+        {
+            case CommandState::Uninitialized:
+            {
+                // Impossible
+                break;
+            }
+            case CommandState::Empty:
+            {
+                if (CommandExecutor::argumentsGiven() == 0)
+                {
+                    CommandExecutor::createListOfPossibleFunctions("");
+                    CommandExecutor::createListOfPossibleIdentifiers("");
+                    break;
+                }
+                else
+                {
+                    CommandExecutor::getEvaluation().state_ = CommandState::ShortcutOrIdentifier;
+                    // Move on to next case
+                }
+            }
+            case CommandState::ShortcutOrIdentifier:
+            {
+                if (CommandExecutor::argumentsGiven() > 1)
+                {
+                    // There's a finished first argument - check if it's a shortcut or a classname
+                    CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(0));
+                    CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(CommandExecutor::getArgument(0));
+
+                    if (CommandExecutor::getEvaluation().function_)
+                    {
+                        // It's a shortcut
+                        CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
+                        CommandExecutor::getEvaluation().functionclass_ = 0;
+                        // Move on to next case
+                    }
+                    else if (CommandExecutor::getEvaluation().functionclass_)
+                    {
+                        // It's a functionname
+                        CommandExecutor::getEvaluation().state_ = CommandState::Function;
+                        CommandExecutor::getEvaluation().function_ = 0;
+                        // Move on to next case
+                    }
+                    else
+                    {
+                        // The first argument is bad
+                        CommandExecutor::getEvaluation().state_ = CommandState::Error;
+                        AddLanguageEntry("commandexecutorunknownfirstargument", "is not a shortcut nor a classname");
+                        CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(0) + ' ' + GetLocalisation("commandexecutorunknownfirstargument") + '.';
+                        return;
+                    }
+                }
+                else
+                {
+                    // There's no finished first argument - search possible shortcuts or classnames
+                    CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getArgument(0));
+                    CommandExecutor::createListOfPossibleIdentifiers(CommandExecutor::getArgument(0));
+
+                    unsigned int num_functions = CommandExecutor::getEvaluation().listOfPossibleFunctions_.size();
+                    unsigned int num_identifiers = CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.size();
+
+                    if (num_functions == 1 && num_identifiers == 0)
+                    {
+                        // It's a shortcut
+                        const std::string& functionname = *CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()->first;
+                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname);
+                        if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(0)))
+                        {
+                            // Unfinished shortcut
+                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
+                        }
+                        CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
+                        CommandExecutor::getEvaluation().functionclass_ = 0;
+                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().function_->getName();
+                        if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
+                        {
+                            CommandExecutor::getEvaluation().command_ += ' ';
+                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
+                        }
+                        // Move on to next case
+                    }
+                    else if (num_identifiers == 1 && num_functions == 0)
+                    {
+                        // It's a classname
+                        const std::string& classname = *CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin()->first;
+                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(classname);
+                        if (getLowercase(classname) != getLowercase(CommandExecutor::getArgument(0)))
+                        {
+                            // Unfinished classname
+                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
+                        }
+                        CommandExecutor::getEvaluation().state_ = CommandState::Function;
+                        CommandExecutor::getEvaluation().function_ = 0;
+                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + ' ';
+                        // Move on to next case
+                    }
+                    else if (num_identifiers == 0 && num_functions == 0)
+                    {
+                        // No possibilities
+                        CommandExecutor::getEvaluation().state_ = CommandState::Error;
+                        AddLanguageEntry("commandexecutorunknownfirstargumentstart", "There is no command or classname starting with");
+                        CommandExecutor::getEvaluation().errorMessage_ = "Error: " + GetLocalisation("commandexecutorunknownfirstargumentstart") + ' ' + CommandExecutor::getArgument(0) + '.';
+                        return;
+                    }
+                    else
+                    {
+                        // There are several possiblilities
+                        std::list<std::pair<const std::string*, const std::string*> > temp;
+                        temp.insert(temp.end(), CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin(), CommandExecutor::getEvaluation().listOfPossibleFunctions_.end());
+                        temp.insert(temp.end(), CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin(), CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.end());
+                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getCommonBegin(temp);
+                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(0));
+                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(CommandExecutor::getArgument(0));
+                        CommandExecutor::getEvaluation().bCommandChanged_ = true;
+                        return;
+                    }
+                }
+            }
+            case CommandState::Function:
+            {
+                if (CommandExecutor::getEvaluation().functionclass_)
+                {
+                    // There is a classname - search for the commandname
+                    if (CommandExecutor::argumentsGiven() > 2)
+                    {
+                        // There is a finished second argument - check if it's a commandname
+                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
+
+                        if (CommandExecutor::getEvaluation().function_)
+                        {
+                            // It's a function
+                            CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
+                            // Move on to next case
+                        }
+                        else
+                        {
+                            // The second argument is bad
+                            CommandExecutor::getEvaluation().state_ = CommandState::Error;
+                            AddLanguageEntry("commandexecutorunknownsecondargument", "is not a function of");
+                            CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(1) + " " + GetLocalisation("commandexecutorunknownsecondargument") + " " + CommandExecutor::getEvaluation().functionclass_->getName() + ".";
+                            return;
+                        }
+                    }
+                    else
+                    {
+                        // There is no finished second argument - search for possibilities
+                        CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
+                        unsigned int num_functions = CommandExecutor::getEvaluation().listOfPossibleFunctions_.size();
+
+                        if (num_functions == 1)
+                        {
+                            // It's a function
+                            const std::string& functionname = *CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()->first;
+                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname, CommandExecutor::getEvaluation().functionclass_);
+                            if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(1)))
+                            {
+                                // Unfinished function
+                                CommandExecutor::getEvaluation().bCommandChanged_ = true;
+                            }
+                            CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
+                            CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + ' ' + CommandExecutor::getEvaluation().function_->getName();
+                            if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
+                            {
+                                CommandExecutor::getEvaluation().command_ += ' ';
+                                CommandExecutor::getEvaluation().bCommandChanged_ = true;
+                            }
+                            // Move on to next case
+                        }
+                        else if (num_functions == 0)
+                        {
+                            // No possibilities
+                            CommandExecutor::getEvaluation().state_ = CommandState::Error;
+                            AddLanguageEntry("commandexecutorunknownsecondargumentstart", "has no function starting with");
+                            CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getEvaluation().functionclass_->getName() + ' ' + GetLocalisation("commandexecutorunknownsecondargumentstart") + ' ' + CommandExecutor::getArgument(1) + '.';
+                            return;
+                        }
+                        else
+                        {
+                            // There are several possibilities
+                            CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + ' ' + CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleFunctions_);
+                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
+                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
+                            return;
+                        }
+                    }
+                }
+                else
+                {
+                    // There is no classname - move on to CommandState::ParamPreparation
+                }
+            }
+            case CommandState::ParamPreparation:
+            {
+                if (CommandExecutor::getEvaluation().function_->getParamCount() == 0 || CommandExecutor::enoughArgumentsGiven(CommandExecutor::getEvaluation().function_))
+                {
+                    CommandExecutor::getEvaluation().state_ = CommandState::Finished;
+                    return;
+                }
+                else
+                {
+                    unsigned int argumentNumber = CommandExecutor::argumentsGiven() - 2;
+                    if (CommandExecutor::getEvaluation().functionclass_)
+                        argumentNumber -= 1;
+
+                    CommandExecutor::createListOfPossibleArguments(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber);
+                    CommandExecutor::getEvaluation().state_ = CommandState::Params;
+
+                    if (CommandExecutor::getEvaluation().bCommandChanged_)
+                    {
+                        // Don't do more than one change
+                        return;
+                    }
+                }
+            }
+            case CommandState::Params:
+            {
+                if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 1)
+                {
+                    // There is exactly one possible argument
+                    CommandExecutor::getEvaluation().argument_ = CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()->getString();
+                    CommandExecutor::getEvaluation().possibleArgument_ = CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()->getString();
+                    CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
+                    return;
+                }
+                else if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 0)
+                {
+                    // The user tries something new - we let him do
+                    CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
+                    CommandExecutor::getEvaluation().argument_ = CommandExecutor::getLastArgument();
+                    return;
+                }
+                else
+                {
+                    // There are several possibilities
+                    unsigned int argumentNumber = CommandExecutor::argumentsGiven();
+                    if (argumentNumber > 0)
+                        --argumentNumber;
+                    if (CommandExecutor::getEvaluation().functionclass_ && argumentNumber > 0)
+                        --argumentNumber;
+
+                    CommandExecutor::getEvaluation().argument_ = CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleArguments_);
+                    CommandExecutor::getEvaluation().possibleArgument_ = CommandExecutor::getPossibleArgument(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber);
+                    CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
+                    return;
+                }
+            }
+            case CommandState::Finished:
+            {
+                // Nothing more to do
+                break;
+            }
+            case CommandState::Error:
+            {
+                // Bad, very bad
+                break;
+            }
+        }
+    }
+
+    unsigned int CommandExecutor::argumentsFinished()
+    {
+        unsigned int argumentsGiven = CommandExecutor::argumentsGiven();
+        if (argumentsGiven > 0)
+            return argumentsGiven - 1;
+        else
+            return 0;
+    }
+
+    unsigned int CommandExecutor::argumentsGiven()
+    {
+        if (CommandExecutor::getEvaluation().command_.size() > 0 && CommandExecutor::getEvaluation().command_[CommandExecutor::getEvaluation().command_.size() - 1] == ' ')
+            return CommandExecutor::getEvaluation().commandTokens_.size() + 1;
+        else
+            return CommandExecutor::getEvaluation().commandTokens_.size();
+    }
+
+    bool CommandExecutor::enoughArgumentsGiven(ConsoleCommand* command)
+    {
+        if (CommandExecutor::getEvaluation().functionclass_)
+            return (CommandExecutor::argumentsGiven() > (2 + command->getParamCount()));
+        else
+            return (CommandExecutor::argumentsGiven() > (1 + command->getParamCount()));
+    }
+
+    const std::string& CommandExecutor::getArgument(unsigned int index)
+    {
+        if (index < (CommandExecutor::getEvaluation().commandTokens_.size()))
+            return CommandExecutor::getEvaluation().commandTokens_[index];
+        else
+            return BLANKSTRING;
+    }
+
+    const std::string& CommandExecutor::getLastArgument()
+    {
+        return CommandExecutor::getArgument(CommandExecutor::argumentsGiven() - 1);
+    }
+
+    void CommandExecutor::createListOfPossibleIdentifiers(const std::string& fragment)
+    {
+        CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.clear();
+        const std::string& lowercase = getLowercase(fragment);
+        for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseStringIdentifierMapBegin(); it != Identifier::getLowercaseStringIdentifierMapEnd(); ++it)
+            if (it->second->hasConsoleCommands())
+                if (it->first.find(lowercase) == 0 || fragment.empty())
+                    CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.push_back(std::pair<const std::string*, const std::string*>(&it->first, &it->second->getName()));
+    }
+
+    void CommandExecutor::createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier)
+    {
+        CommandExecutor::getEvaluation().listOfPossibleFunctions_.clear();
+        const std::string& lowercase = getLowercase(fragment);
+        if (!identifier)
+        {
+            for (std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMapBegin(); it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd(); ++it)
+                if (it->first.find(lowercase) == 0 || fragment.empty())
+                    CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&it->first, &it->second->getName()));
+        }
+        else
+        {
+            for (std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMapBegin(); it != identifier->getLowercaseConsoleCommandMapEnd(); ++it)
+                if (it->first.find(lowercase) == 0 || fragment.empty())
+                    CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&it->first, &it->second->getName()));
+        }
+    }
+
+    void CommandExecutor::createListOfPossibleArguments(const std::string& fragment, ConsoleCommand* command, unsigned int param)
+    {
+        CommandExecutor::createArgumentCompletionList(command, param);
+
+        CommandExecutor::getEvaluation().listOfPossibleArguments_.clear();
+        const std::string& lowercase = getLowercase(fragment);
+        for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it)
+        {
+            if (it->lowercaseComparison())
+            {
+                if (it->getComparable().find(lowercase) == 0 || fragment.empty())
+                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
+            }
+            else
+            {
+                if (it->getComparable().find(fragment) == 0 || fragment.empty())
+                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
+            }
+        }
+    }
+
+    Identifier* CommandExecutor::getPossibleIdentifier(const std::string& name)
+    {
+        const std::string& lowercase = getLowercase(name);
+        std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseStringIdentifierMap().find(lowercase);
+        if ((it != Identifier::getLowercaseStringIdentifierMapEnd()) && it->second->hasConsoleCommands())
+            return it->second;
+
+        return 0;
+    }
+
+    ConsoleCommand* CommandExecutor::getPossibleCommand(const std::string& name, Identifier* identifier)
+    {
+        const std::string& lowercase = getLowercase(name);
+        if (!identifier)
+        {
+            std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMap().find(lowercase);
+            if (it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd())
+                return it->second;
+        }
+        else
+        {
+            std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMap().find(lowercase);
+            if (it != identifier->getLowercaseConsoleCommandMapEnd())
+                return it->second;
+        }
+        return 0;
+    }
+
+    const std::string& CommandExecutor::getPossibleArgument(const std::string& name, ConsoleCommand* command, unsigned int param)
+    {
+        CommandExecutor::createArgumentCompletionList(command, param);
+
+        const std::string& lowercase = getLowercase(name);
+        for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it)
+        {
+            if (it->lowercaseComparison())
+            {
+                if (it->getComparable() == lowercase)
+                    return it->getString();
+            }
+            else
+            {
+                if (it->getComparable() == name)
+                    return it->getString();
+            }
+        }
+
+        return BLANKSTRING;
+    }
+
+    void CommandExecutor::createArgumentCompletionList(ConsoleCommand* command, unsigned int param)
+    {
+        std::string params[5];
+
+        unsigned int index = 0;
+        unsigned int lowestIndex = 1 + (CommandExecutor::getEvaluation().functionclass_ != 0);
+
+        for (unsigned int i = CommandExecutor::argumentsGiven() - 1; i >= lowestIndex; --i)
+        {
+            params[index] = CommandExecutor::getArgument(i);
+            ++index;
+            if (index >= 5)
+                break;
+        }
+
+        command->createArgumentCompletionList(param, params[0], params[1], params[2], params[3], params[4]);
+    }
+
+    std::string CommandExecutor::getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list)
+    {
+        if (list.size() == 0)
+        {
+            return "";
+        }
+        else if (list.size() == 1)
+        {
+            return ((*list.begin()->first) + ' ');
+        }
+        else
+        {
+            std::string output;
+            for (unsigned int i = 0; true; i++)
+            {
+                char temp = 0;
+                for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)
+                {
+                    if (it->first->size() > i)
+                    {
+                        if (it == list.begin())
+                        {
+                            temp = (*it->first)[i];
+                        }
+                        else
+                        {
+                            if (temp != (*it->first)[i])
+                                return output;
+                        }
+                    }
+                    else
+                    {
+                        return output;
+                    }
+                }
+                output += temp;
+            }
+            return output;
+        }
+    }
+
+    std::string CommandExecutor::getCommonBegin(const ArgumentCompletionList& list)
+    {
+        if (list.size() == 0)
+        {
+            return "";
+        }
+        else if (list.size() == 1)
+        {
+            return (list.begin()->getComparable() + ' ');
+        }
+        else
+        {
+            std::string output;
+            for (unsigned int i = 0; true; i++)
+            {
+                char tempComparable = 0;
+                char temp = 0;
+                for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
+                {
+                    const std::string& argumentComparable = it->getComparable();
+                    const std::string& argument = it->getString();
+                    if (argument.size() > i)
+                    {
+                        if (it == list.begin())
+                        {
+                            tempComparable = argumentComparable[i];
+                            temp = argument[i];
+                        }
+                        else
+                        {
+                            if (tempComparable != argumentComparable[i])
+                                return output;
+                            else if (temp != argument[i])
+                                temp = tempComparable;
+                        }
+                    }
+                    else
+                    {
+                        return output;
+                    }
+                }
+                output += temp;
+            }
+            return output;
+        }
+    }
+
+    void CommandExecutor::destroyExternalCommands()
+    {
+        for (std::set<ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandExternals_.begin();
+            it != CommandExecutor::getInstance().consoleCommandExternals_.end(); ++it)
+            delete *it;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/CommandExecutor.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/CommandExecutor.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/CommandExecutor.h	(revision 6952)
@@ -0,0 +1,114 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _CommandExecutor_H__
+#define _CommandExecutor_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "util/MultiType.h"
+#include "CommandEvaluation.h"
+
+// tolua_begin
+namespace orxonox
+{
+    class _CoreExport CommandExecutor
+    {
+// tolua_end
+        public:
+            static bool execute(const std::string& command, bool useTcl = true); // tolua_export
+            static MultiType getReturnValue();
+            static std::string getReturnValueString(); // tolua_export
+
+            static std::string complete(const std::string& command);
+            static std::string hint(const std::string& command);
+
+            static CommandEvaluation evaluate(const std::string& command);
+            static const CommandEvaluation& getLastEvaluation();
+
+            static ConsoleCommand& addConsoleCommandShortcut(ConsoleCommand* command, bool bDeleteAtExit = false);
+            static ConsoleCommand* getConsoleCommandShortcut(const std::string& name);
+            static ConsoleCommand* getLowercaseConsoleCommandShortcut(const std::string& name);
+
+            /** @brief Returns the map that stores all console commands. @return The const_iterator */
+            static inline const std::map<std::string, ConsoleCommand*>& getConsoleCommandShortcutMap() { return CommandExecutor::getInstance().consoleCommandShortcuts_; }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all console commands. @return The const_iterator */
+            static inline std::map<std::string, ConsoleCommand*>::const_iterator getConsoleCommandShortcutMapBegin() { return CommandExecutor::getInstance().consoleCommandShortcuts_.begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all console commands. @return The const_iterator */
+            static inline std::map<std::string, ConsoleCommand*>::const_iterator getConsoleCommandShortcutMapEnd() { return CommandExecutor::getInstance().consoleCommandShortcuts_.end(); }
+
+            /** @brief Returns the map that stores all console commands with their names in lowercase. @return The const_iterator */
+            static inline const std::map<std::string, ConsoleCommand*>& getLowercaseConsoleCommandShortcutMap() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_; }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all console commands with their names in lowercase. @return The const_iterator */
+            static inline std::map<std::string, ConsoleCommand*>::const_iterator getLowercaseConsoleCommandShortcutMapBegin() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_.begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all console commands with their names in lowercase. @return The const_iterator */
+            static inline std::map<std::string, ConsoleCommand*>::const_iterator getLowercaseConsoleCommandShortcutMapEnd() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_.end(); }
+
+            static void destroyExternalCommands();
+
+        private:
+            CommandExecutor() {}
+            CommandExecutor(const CommandExecutor& other);
+            ~CommandExecutor() {}
+
+            static CommandExecutor& getInstance();
+            static CommandEvaluation& getEvaluation();
+
+            static void parseIfNeeded(const std::string& command);
+            static void parse(const std::string& command, bool bInitialize = true);
+
+            static unsigned int argumentsFinished();
+            static unsigned int argumentsGiven();
+            static bool enoughArgumentsGiven(ConsoleCommand* command);
+            static const std::string& getArgument(unsigned int index);
+            static const std::string& getLastArgument();
+
+            static void createListOfPossibleIdentifiers(const std::string& fragment);
+            static void createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier = 0);
+            static void createListOfPossibleArguments(const std::string& fragment, ConsoleCommand* command, unsigned int param);
+
+            static Identifier* getPossibleIdentifier(const std::string& name);
+            static ConsoleCommand* getPossibleCommand(const std::string& name, Identifier* identifier = 0);
+            static const std::string& getPossibleArgument(const std::string& name, ConsoleCommand* command, unsigned int param);
+
+            static void createArgumentCompletionList(ConsoleCommand* command, unsigned int param);
+            static std::string getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list);
+            static std::string getCommonBegin(const ArgumentCompletionList& list);
+
+            CommandEvaluation evaluation_;
+            std::map<std::string, ConsoleCommand*> consoleCommandShortcuts_;
+            std::map<std::string, ConsoleCommand*> consoleCommandShortcuts_LC_;
+            std::set<ConsoleCommand*>              consoleCommandExternals_;
+    }; // tolua_export
+} // tolua_export
+
+#endif /* _CommandExecutor_H__ */
Index: /code/branches/rocket2/src/libraries/core/CommandLineParser.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/CommandLineParser.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/CommandLineParser.cc	(revision 6952)
@@ -0,0 +1,377 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "CommandLineParser.h"
+
+#include <algorithm>
+#include <sstream>
+
+#include "util/Convert.h"
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/StringUtils.h"
+#include "util/SubString.h"
+#include "PathConfig.h"
+
+namespace orxonox
+{
+    SetCommandLineOnlyArgument(optionsFile, "start.ini").shortcut("o");
+
+    /**
+    @brief
+        Parses a value string for a command line argument.
+        It simply uses convertValue(Output, Input) to do that.
+        Bools are treated specially. That is necessary
+        so that you can have simple command line switches.
+    */
+    void CommandLineArgument::parse(const std::string& value, bool bParsingFile)
+    {
+        if (bParsingFile && this->bCommandLineOnly_)
+            ThrowException(Argument, "Command line argument '" + getName() + "' is not allowed in files.");
+        if (value_.getType() == MT_Type::Bool)
+        {
+            // simulate command line switch
+            bool temp;
+            if (convertValue(&temp, value))
+            {
+                this->bHasDefaultValue_ = false;
+                this->value_ = temp;
+            }
+            else if (value.empty())
+            {
+                this->bHasDefaultValue_ = false;
+                this->value_ = true;
+            }
+            else
+                ThrowException(Argument, "Could not read command line argument '" + getName() + "'.");
+        }
+        else
+        {
+            if (!value_.setValue(value))
+            {
+                value_.setValue(defaultValue_);
+                ThrowException(Argument, "Could not read command line argument '" + getName() + "'.");
+            }
+            else
+                this->bHasDefaultValue_ = false;
+        }
+    }
+
+
+    /**
+    @brief
+        Destructor destroys all CommandLineArguments with it.
+    */
+    CommandLineParser::~CommandLineParser()
+    {
+        CommandLineParser::destroyAllArguments();
+    }
+
+    /**
+    @brief
+        Returns a unique instance (Meyers Singleton).
+    */
+    CommandLineParser& CommandLineParser::_getInstance()
+    {
+        static CommandLineParser instance;
+        return instance;
+    }
+
+    /**
+    @brief
+        Destroys all command line arguments. This should be called at the end
+        of main. Do not use before that.
+    */
+    void CommandLineParser::destroyAllArguments()
+    {
+        for (std::map<std::string, CommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.begin();
+            it != _getInstance().cmdLineArgs_.end(); ++it)
+            delete it->second;
+        _getInstance().cmdLineArgs_.clear();
+    }
+
+    /**
+    @brief
+        Reads the command line parses the values of each argument.
+        It is then stored in the corresponding CommandLineArgument.
+    @note
+        The reason that you have to provide the string to be parsed as
+        space separted list is because of argc and argv. If you only have
+        a whole string, simply use getAllStrings() of SubString.
+    @param arguments
+        Vector of space separated strings.
+    */
+    void CommandLineParser::_parse(const std::vector<std::string>& arguments, bool bParsingFile)
+    {
+        try
+        {
+            // why this? See bFirstTimeParse_ declaration.
+            if (bFirstTimeParse_)
+            {
+                // first shove all the shortcuts in a map
+                for (std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgs_.begin();
+                    it != cmdLineArgs_.end(); ++it)
+                {
+                    OrxAssert(cmdLineArgsShortcut_.find(it->second->getShortcut()) == cmdLineArgsShortcut_.end(),
+                        "Cannot have two command line shortcut with the same name.");
+                    if (!it->second->getShortcut().empty())
+                        cmdLineArgsShortcut_[it->second->getShortcut()] = it->second;
+                }
+                bFirstTimeParse_ = false;
+            }
+
+            std::string name;
+            std::string shortcut;
+            std::string value;
+            for (unsigned int i = 0; i < arguments.size(); ++i)
+            {
+                if (arguments[i].size() != 0)
+                {
+                    // sure not ""
+                    if (arguments[i][0] == '-')
+                    {
+                        // start with "-"
+                        if (arguments[i].size() == 1)
+                        {
+                            // argument[i] is "-", probably a minus sign
+                            value += "- ";
+                        }
+                        else if (arguments[i][1] <= 57 && arguments[i][1] >= 48)
+                        {
+                            // negative number as a value
+                            value += arguments[i] + ' ';
+                        }
+                        else
+                        {
+                            // can be shortcut or full name argument
+
+                            // save old data first
+                            value = removeTrailingWhitespaces(value);
+                            if (!name.empty())
+                            {
+                                checkFullArgument(name, value, bParsingFile);
+                                name.clear();
+                                assert(shortcut.empty());
+                            }
+                            else if (!shortcut.empty())
+                            {
+                                checkShortcut(shortcut, value, bParsingFile);
+                                shortcut.clear();
+                                assert(name.empty());
+                            }
+
+                            if (arguments[i][1] == '-')
+                            {
+                                // full name argument with "--name"
+                                name = arguments[i].substr(2);
+                            }
+                            else
+                            {
+                                // shortcut with "-s"
+                                shortcut = arguments[i].substr(1);
+                            }
+
+                            // reset value string
+                            value.clear();
+                        }
+                    }
+                    else
+                    {
+                        // value string
+
+                        if (name.empty() && shortcut.empty())
+                        {
+                            ThrowException(Argument, "Expected \"-\" or \"-\" in command line arguments.\n");
+                        }
+
+                        // Concatenate strings as long as there's no new argument by "-" or "--"
+                        value += arguments[i] + ' ';
+                    }
+                }
+            }
+
+            // parse last argument
+            value = removeTrailingWhitespaces(value);
+            if (!name.empty())
+            {
+                checkFullArgument(name, value, bParsingFile);
+                assert(shortcut.empty());
+            }
+            else if (!shortcut.empty())
+            {
+                checkShortcut(shortcut, value, bParsingFile);
+                assert(name.empty());
+            }
+        }
+        catch (const ArgumentException& ex)
+        {
+            COUT(0) << "Could not parse command line (including additional files): " << ex.what() << std::endl;
+            COUT(0) << CommandLineParser::getUsageInformation() << std::endl;
+            throw GeneralException("");
+        }
+    }
+
+    /**
+    @brief
+        Parses an argument based on its full name.
+    @param name
+        Full name of the argument
+    @param value
+        String containing the value
+    */
+    void CommandLineParser::checkFullArgument(const std::string& name, const std::string& value, bool bParsingFile)
+    {
+        std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgs_.find(name);
+        if (it == cmdLineArgs_.end())
+            ThrowException(Argument, "Command line argument '" + name + "' does not exist.");
+
+        it->second->parse(value, bParsingFile);
+    }
+
+    /**
+    @brief
+        Parses an argument based on its shortcut.
+    @param shortcut
+        Shotcut to the argument
+    @param value
+        String containing the value
+    */
+    void CommandLineParser::checkShortcut(const std::string& shortcut, const std::string& value, bool bParsingFile)
+    {
+        std::map<std::string, CommandLineArgument*>::const_iterator it = cmdLineArgsShortcut_.find(shortcut);
+        if (it == cmdLineArgsShortcut_.end())
+            ThrowException(Argument, "Command line shortcut '" + shortcut + "' does not exist.");
+
+        it->second->parse(value, bParsingFile);
+    }
+
+    std::string CommandLineParser::getUsageInformation()
+    {
+        CommandLineParser& inst = _getInstance();
+        std::ostringstream infoStr;
+
+        // determine maximum name size
+        size_t maxNameSize = 0;
+        for (std::map<std::string, CommandLineArgument*>::const_iterator it = inst.cmdLineArgs_.begin();
+            it != inst.cmdLineArgs_.end(); ++it)
+        {
+            maxNameSize = std::max(it->second->getName().size(), maxNameSize);
+        }
+
+        infoStr << std::endl;
+        infoStr << "Usage: orxonox [options]" << std::endl;
+        infoStr << "Available options:" << std::endl;
+
+        for (std::map<std::string, CommandLineArgument*>::const_iterator it = inst.cmdLineArgs_.begin();
+            it != inst.cmdLineArgs_.end(); ++it)
+        {
+            if (!it->second->getShortcut().empty())
+                infoStr << " [-" << it->second->getShortcut() << "] ";
+            else
+                infoStr << "      ";
+            infoStr << "--" << it->second->getName() << ' ';
+            if (it->second->getValue().getType() != MT_Type::Bool)
+                infoStr << "ARG ";
+            else
+                infoStr << "    ";
+            // fill with the necessary amount of blanks
+            infoStr << std::string(maxNameSize - it->second->getName().size(), ' ');
+            infoStr << ": " << it->second->getInformation();
+            infoStr << std::endl;
+        }
+        return infoStr.str();
+    }
+
+    /**
+    @brief
+        Retrieves a CommandLineArgument.
+        The method throws an exception if 'name' was not found or the value could not be converted.
+    @note
+        You shold of course not call this method before the command line has been parsed.
+    */
+    const CommandLineArgument* CommandLineParser::getArgument(const std::string& name)
+    {
+        std::map<std::string, CommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.find(name);
+        if (it == _getInstance().cmdLineArgs_.end())
+        {
+            ThrowException(Argument, "Could find command line argument '" + name + "'.");
+        }
+        else
+        {
+            return it->second;
+        }
+    }
+
+    /**
+    @brief
+        Parses only the command line for CommandLineArguments.
+    */
+    void CommandLineParser::_parseCommandLine(const std::string& cmdLine)
+    {
+        std::vector<std::string> args;
+        SubString tokens(cmdLine, " ", " ", false, '\\', true, '"', true, '(', ')', false);
+        for (unsigned i = 0; i < tokens.size(); ++i)
+            args.push_back(tokens[i]);
+        this->_parse(args, false);
+    }
+
+    /**
+    @brief
+        Parses start.ini (or the file specified with --optionsFile) for CommandLineArguments.
+    */
+    void CommandLineParser::_parseFile()
+    {
+        const std::string& filename = CommandLineParser::getValue("optionsFile").getString();
+
+        // look for additional arguments in given file or start.ini as default
+        // They will not overwrite the arguments given directly
+        std::ifstream file;
+        file.open((PathConfig::getConfigPathString() + filename).c_str());
+        std::vector<std::string> args;
+        if (file)
+        {
+            while (!file.eof())
+            {
+                std::string line;
+                std::getline(file, line);
+                line = removeTrailingWhitespaces(line);
+                //if (!(line[0] == '#' || line[0] == '%'))
+                //{
+                SubString tokens(line, " ", " ", false, '\\', true, '"', true, '(', ')', false, '#');
+                for (unsigned i = 0; i < tokens.size(); ++i)
+                    if (tokens[i][0] != '#')
+                        args.push_back(tokens[i]);
+                //args.insert(args.end(), tokens.getAllStrings().begin(), tokens.getAllStrings().end());
+                //}
+            }
+            file.close();
+        }
+
+        _parse(args, true);
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/CommandLineParser.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/CommandLineParser.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/CommandLineParser.h	(revision 6952)
@@ -0,0 +1,223 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _CommandLine_H__
+#define _CommandLine_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include "util/OrxAssert.h"
+#include "util/MultiType.h"
+
+#define SetCommandLineArgument(name, defaultValue) \
+    orxonox::CommandLineArgument& CmdArgumentDummyBoolVar##name \
+    = orxonox::CommandLineParser::addArgument(#name, defaultValue, false)
+#define SetCommandLineOnlyArgument(name, defaultValue) \
+    orxonox::CommandLineArgument& CmdArgumentDummyBoolVar##name \
+    = orxonox::CommandLineParser::addArgument(#name, defaultValue, true)
+#define SetCommandLineSwitch(name) \
+    orxonox::CommandLineArgument& CmdArgumentDummyBoolVar##name \
+    = orxonox::CommandLineParser::addArgument(#name, false, false)
+#define SetCommandLineOnlySwitch(name) \
+    orxonox::CommandLineArgument& CmdArgumentDummyBoolVar##name \
+    = orxonox::CommandLineParser::addArgument(#name, false, true)
+
+
+namespace orxonox
+{
+    /**
+    @brief
+        Container class for a command line argument of any type supported by MultiType.
+
+        Whenever you want to have an option specified by a command line switch,
+        you need to first define it with SetCommandLineArgument(name, defaultValue).
+        It is then added to a map and possibly changed when the command line is being parsed.
+        If the option was not given, you can detect this by asking hasDefaultValue().
+
+        There is a possibility to define a short cut so you can write "-p 20" instead of "--port 20".
+        Note the difference between "-" and "--"!
+        Also, there is no restriction to the number of strings you add after --name.
+        So "--startVector (2, 4, 5)" is perfectly legal.
+
+        Retrieving an argument is possible with the getCommandLineArgument function of the
+        CommandLineParser class. It is a Singleton, but the public interface is static.
+    */
+    class _CoreExport CommandLineArgument
+    {
+        friend class CommandLineParser;
+
+    public:
+        //! Tells whether the value has been changed by the command line.
+        bool hasDefaultValue() const { return bHasDefaultValue_; }
+        //! Returns the name of the argument.
+        const std::string& getName() const { return name_; }
+
+        //! Returns the shortcut (example: "-p 22" for "--port 22") of the argument.
+        //! Evaluates to "" if there is none.
+        const std::string& getShortcut() const { return shortcut_; }
+        //! Sets the shortcut for the argument
+        CommandLineArgument& shortcut(const std::string& shortcut)
+        { this->shortcut_ = shortcut; return *this; }
+
+        //! Returns the usage information
+        const std::string& getInformation() const { return this->usageInformation_; }
+        //! Sets the option information when displaying orxonox usage.
+        CommandLineArgument& information(const std::string& usage)
+        { this->usageInformation_ = usage; return *this; }
+
+        //! Returns the actual value of the argument. Can be equal to default value.
+        MultiType getValue() const { return value_; }
+        //! Returns the given default value as type T.
+        MultiType getDefaultValue() const { return defaultValue_; }
+
+    private:
+        //! Constructor initialises both value_ and defaultValue_ with defaultValue.
+        CommandLineArgument(const std::string& name, const MultiType& defaultValue, bool bCommandLineOnly)
+            : bHasDefaultValue_(true)
+            , name_(name)
+            , value_(defaultValue)
+            , defaultValue_(defaultValue)
+            , bCommandLineOnly_(bCommandLineOnly)
+        { }
+
+        //! Undefined copy constructor
+        CommandLineArgument(const CommandLineArgument& instance);
+        ~CommandLineArgument() { }
+
+        //! Parses the value string of a command line argument.
+        void parse(const std::string& value, bool bParsingFile);
+
+        //! Tells whether the value has been changed by the command line.
+        bool bHasDefaultValue_;
+
+    private:
+        std::string name_;             //!< Name of the argument
+        std::string shortcut_;         //!< Shortcut of the argument. @see getShortcut().
+        std::string usageInformation_; //!< Tells about the usage of this parameter
+
+        MultiType   value_;            //!< The actual value
+        MultiType   defaultValue_;     //!< Default value. Should not be changed.
+        bool        bCommandLineOnly_; //!< Whether you cannot specify the value in a text file
+    };
+
+
+    /**
+    @brief
+        Global interface to command line options.
+        Allows to add and retrieve command line arguments. Also does the parsing.
+    @note
+        Internally it is a Singleton, but the public interface is static.
+    @see
+        CommandLineArgument
+    */
+    class _CoreExport CommandLineParser
+    {
+    public:
+
+        //! Parse redirection to internal member method.
+        static void parseCommandLine(const std::string& cmdLine) { _getInstance()._parseCommandLine(cmdLine); }
+        static void parseFile() { _getInstance()._parseFile(); }
+
+        static std::string getUsageInformation();
+
+        static const CommandLineArgument* getArgument(const std::string& name);
+        //! Writes the argument value in the given parameter.
+        template <class T>
+        static void getValue(const std::string& name, T* value)
+        { *value = (T)(getArgument(name)->getValue()); }
+        static MultiType getValue(const std::string& name)
+        { return getArgument(name)->getValue(); }
+        template <class T>
+        static CommandLineArgument& addArgument(const std::string& name, T defaultValue, bool bCommandLineOnly);
+
+        static bool existsArgument(const std::string& name)
+        {
+            std::map<std::string, CommandLineArgument*>::const_iterator it = _getInstance().cmdLineArgs_.find(name);
+            return !(it == _getInstance().cmdLineArgs_.end());
+        }
+
+        static void destroyAllArguments();
+
+    private:
+        //! Constructor initialises bFirstTimeParse_ with true.
+        CommandLineParser() : bFirstTimeParse_(true) { }
+        //! Undefined copy constructor
+        CommandLineParser(const CommandLineParser& instance);
+        ~CommandLineParser();
+
+        static CommandLineParser& _getInstance();
+
+        void _parseCommandLine(const std::string& cmdLine);
+        void _parseFile();
+        void _parse(const std::vector<std::string>& arguments, bool bParsingFile);
+        void checkFullArgument(const std::string& name, const std::string& value, bool bParsingFile);
+        void checkShortcut(const std::string& shortcut, const std::string& value, bool bParsingFile);
+
+        /**
+            Tells whether we parsed for the first time. The CommmandLineArguments are added before main().
+            So when we call parse() the first time, we need to create a map with all shortcuts since these
+            get added after addCommandLineArgument().
+        */
+        bool bFirstTimeParse_;
+
+        //! Holds all pointers to the arguments and serves as a search map by name.
+        std::map<std::string, CommandLineArgument*> cmdLineArgs_;
+        //! Search map by shortcut for the arguments.
+        std::map<std::string, CommandLineArgument*> cmdLineArgsShortcut_;
+    };
+
+    template <>
+    inline void CommandLineParser::getValue<std::string>(const std::string& name, std::string* value)
+    {
+        *value = getArgument(name)->getValue().getString();
+    }
+
+    /**
+    @brief
+        Adds a new CommandLineArgument to the internal map.
+        Note that only such arguments are actually valid.
+    @param name
+        Name of the argument. Shortcut can be added later.
+    @param defaultValue
+        Default value that is used when argument was not given.
+    */
+    template <class T>
+    CommandLineArgument& CommandLineParser::addArgument(const std::string& name, T defaultValue, bool bCommandLineOnly)
+    {
+        OrxAssert(!_getInstance().existsArgument(name),
+            "Cannot add a command line argument with name '" + name + "' twice.");
+        OrxAssert(MultiType(defaultValue).getType() != MT_Type::Bool || MultiType(defaultValue).getBool() != true,
+               "Boolean command line arguments with positive default values are not supported." << std::endl
+            << "Please use SetCommandLineSwitch and adjust your argument: " << name);
+
+        return *(_getInstance().cmdLineArgs_[name] = new CommandLineArgument(name, defaultValue, bCommandLineOnly));
+    }
+}
+
+#endif /* _CommandLine_H__ */
Index: /code/branches/rocket2/src/libraries/core/ConfigFileManager.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/ConfigFileManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ConfigFileManager.cc	(revision 6952)
@@ -0,0 +1,624 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ConfigFileManager.h"
+
+#include <boost/filesystem.hpp>
+
+#include "util/Convert.h"
+#include "util/Math.h"
+#include "ConsoleCommand.h"
+#include "ConfigValueContainer.h"
+#include "PathConfig.h"
+
+namespace orxonox
+{
+    //////////////////////////
+    // ConfigFileEntryValue //
+    //////////////////////////
+
+    void ConfigFileEntryValue::update()
+    {
+        // Make sure we remove the quotes when bString changes
+        if (this->bString_)
+            this->value_ = stripEnclosingQuotes(this->value_);
+        // Assemble the entry line
+        this->fileEntry_ = this->getKeyString() + " = ";
+        if (this->bString_ && !this->value_.empty())
+            this->fileEntry_ += '"' + addSlashes(this->value_) + '"';
+        else
+            this->fileEntry_ += this->value_;
+        if (!this->additionalComment_.empty())
+            this->fileEntry_ += ' ' + this->additionalComment_;
+    }
+
+
+    ////////////////////////////////
+    // ConfigFileEntryVectorValue //
+    ////////////////////////////////
+    void ConfigFileEntryVectorValue::update()
+    {
+        this->keyString_ = this->name_ + '[' + multi_cast<std::string>(this->index_) + ']';
+        ConfigFileEntryValue::update();
+    }
+
+
+    ///////////////////////
+    // ConfigFileSection //
+    ///////////////////////
+    ConfigFileSection::~ConfigFileSection()
+    {
+        for (std::list<ConfigFileEntry*>::iterator it = this->entries_.begin(); it != this->entries_.end(); )
+            delete (*(it++));
+    }
+
+    void ConfigFileSection::deleteVectorEntries(const std::string& name, unsigned int startindex)
+    {
+        for (std::list<ConfigFileEntry*>::iterator it = this->entries_.begin(); it != this->entries_.end(); )
+        {
+            if (((*it)->getName() == name) && ((*it)->getIndex() >= startindex))
+            {
+                delete (*it);
+                this->entries_.erase(it++);
+            }
+            else
+            {
+                ++it;
+            }
+        }
+    }
+
+    unsigned int ConfigFileSection::getVectorSize(const std::string& name) const
+    {
+        unsigned int size = 0;
+        for (std::list<ConfigFileEntry*>::const_iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)
+            if ((*it)->getName() == name)
+                if ((*it)->getIndex() > size)
+                    size = (*it)->getIndex();
+        if (size == 0)
+            return 0;
+        else
+            return (size + 1);
+    }
+
+    std::string ConfigFileSection::getFileEntry() const
+    {
+        if (this->additionalComment_.empty())
+            return ('[' + this->name_ + ']');
+        else
+            return ('[' + this->name_ + "] " + this->additionalComment_);
+    }
+
+    ConfigFileEntry* ConfigFileSection::getEntry(const std::string& name) const
+    {
+        for (std::list<ConfigFileEntry*>::const_iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)
+        {
+            if ((*it)->getName() == name)
+                return *it;
+        }
+        return NULL;
+    }
+
+    ConfigFileEntry* ConfigFileSection::getEntry(const std::string& name, unsigned int index) const
+    {
+        for (std::list<ConfigFileEntry*>::const_iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)
+        {
+            if (((*it)->getName() == name) && ((*it)->getIndex() == index))
+                return *it;
+        }
+        return NULL;
+    }
+
+    std::list<ConfigFileEntry*>::iterator ConfigFileSection::getOrCreateEntryIterator(const std::string& name, const std::string& fallback, bool bString)
+    {
+        for (std::list<ConfigFileEntry*>::iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)
+        {
+            if ((*it)->getName() == name)
+            {
+                (*it)->setString(bString);
+                return it;
+            }
+        }
+
+        this->bUpdated_ = true;
+
+        return this->entries_.insert(this->entries_.end(), new ConfigFileEntryValue(name, fallback, bString));
+    }
+
+    std::list<ConfigFileEntry*>::iterator ConfigFileSection::getOrCreateEntryIterator(const std::string& name, unsigned int index, const std::string& fallback, bool bString)
+    {
+        for (std::list<ConfigFileEntry*>::iterator it = this->entries_.begin(); it != this->entries_.end(); ++it)
+        {
+            if (((*it)->getName() == name) && ((*it)->getIndex() == index))
+            {
+                (*it)->setString(bString);
+                return it;
+            }
+        }
+
+        this->bUpdated_ = true;
+
+        if (index == 0)
+            return this->entries_.insert(this->entries_.end(), new ConfigFileEntryVectorValue(name, index, fallback, bString));
+        else
+            return this->entries_.insert(++this->getOrCreateEntryIterator(name, index - 1, "", bString), new ConfigFileEntryVectorValue(name, index, fallback, bString));
+    }
+
+
+    ////////////////
+    // ConfigFile //
+    ////////////////
+
+    const char* ConfigFile::DEFAULT_CONFIG_FOLDER = "defaultConfig";
+
+    ConfigFile::ConfigFile(const std::string& filename, bool bCopyFallbackFile)
+        : filename_(filename)
+        , bCopyFallbackFile_(bCopyFallbackFile)
+        , bUpdated_(false)
+    {
+    }
+
+    ConfigFile::~ConfigFile()
+    {
+        this->clear();
+    }
+
+    void ConfigFile::load()
+    {
+        // Be sure we start from new in the memory
+        this->clear();
+
+        boost::filesystem::path filepath(this->filename_);
+        if (!filepath.is_complete())
+        {
+            filepath = PathConfig::getConfigPath() / filepath;
+            if (this->bCopyFallbackFile_)
+            {
+                // Look for default file in the data folder
+                if (!boost::filesystem::exists(filepath))
+                {
+                    boost::filesystem::path defaultFilepath(PathConfig::getDataPath() / DEFAULT_CONFIG_FOLDER / this->filename_);
+                    if (boost::filesystem::exists(defaultFilepath))
+                    {
+                        // Try to copy default file from the data folder
+                        try
+                        {
+                            boost::filesystem::copy_file(defaultFilepath, filepath);
+                            COUT(3) << "Copied " << this->filename_ << " from the default config folder." << std::endl;
+                        }
+                        catch (const boost::filesystem::filesystem_error& ex)
+                        { COUT(1) << "Error in ConfigFile: " << ex.what() << std::endl; }
+                    }
+                }
+            }
+        }
+
+        // Open the file
+        std::ifstream file;
+        file.open(filepath.string().c_str(), std::fstream::in);
+        if (file.is_open())
+        {
+            ConfigFileSection* newsection = 0;
+
+            while (file.good() && !file.eof())
+            {
+                std::string line;
+                std::getline(file, line);
+
+                const std::string& temp = getStripped(line);
+                if (!isEmpty(temp) && !isComment(temp))
+                {
+                    size_t   pos1 = temp.find('[');
+                    if (pos1 == 0) pos1 = line.find('['); else pos1 = std::string::npos;
+                    size_t   pos2 = line.find(']');
+
+                    if (pos1 != std::string::npos && pos2 != std::string::npos && pos2 > pos1 + 1)
+                    {
+                        // New section
+                        const std::string& comment = line.substr(pos2 + 1);
+                        if (isComment(comment))
+                            newsection = new ConfigFileSection(line.substr(pos1 + 1, pos2 - pos1 - 1), comment);
+                        else
+                            newsection = new ConfigFileSection(line.substr(pos1 + 1, pos2 - pos1 - 1));
+                        this->sections_.insert(this->sections_.end(), newsection);
+                        continue;
+                    }
+                }
+
+                if (newsection != 0)
+                {
+                    if (isComment(line))
+                    {
+                        // New comment
+                        newsection->getEntries().insert(newsection->getEntries().end(), new ConfigFileEntryComment(removeTrailingWhitespaces(line)));
+                        continue;
+                    }
+                    else
+                    {
+                        size_t pos1 = line.find('=');
+
+                        if (pos1 != std::string::npos && pos1 > 0)
+                        {
+                            // New entry
+                            size_t pos2 = line.find('[');
+                            size_t pos3 = line.find(']');
+                            size_t commentposition = getNextCommentPosition(line, pos1 + 1);
+                            while (isBetweenQuotes(line, commentposition))
+                            {
+                                commentposition = getNextCommentPosition(line, commentposition + 1);
+                            }
+                            std::string value, comment;
+                            if (commentposition == std::string::npos)
+                            {
+                                value = removeTrailingWhitespaces(line.substr(pos1 + 1));
+                            }
+                            else
+                            {
+                                value = removeTrailingWhitespaces(line.substr(pos1 + 1, commentposition - pos1 - 1));
+                                comment = removeTrailingWhitespaces(line.substr(commentposition));
+                            }
+
+                            if (pos2 != std::string::npos && pos3 != std::string::npos && pos3 > pos2 + 1)
+                            {
+                                // There might be an array index
+                                unsigned int index = 0;
+                                if (convertValue(&index, line.substr(pos2 + 1, pos3 - pos2 - 1)))
+                                {
+                                    // New array
+                                    std::list<ConfigFileEntry*>::iterator it = newsection->getOrCreateEntryIterator(getStripped(line.substr(0, pos2)), index, value, false);
+                                    (*it)->setValue(value);
+                                    (*it)->setComment(comment);
+                                    continue;
+                                }
+                            }
+
+                            // New value
+                            newsection->getEntries().insert(newsection->getEntries().end(), new ConfigFileEntryValue(getStripped(line.substr(0, pos1)), value, false, comment));
+                            continue;
+                        }
+                    }
+                }
+            }
+
+            file.close();
+
+            COUT(3) << "Loaded config file \"" << this->filename_ << "\"." << std::endl;
+
+            // DO NOT save the file --> we can open supposedly read only config files
+        } // end file.is_open()
+    }
+
+    void ConfigFile::save() const
+    {
+        this->saveAs(this->filename_);
+    }
+
+    void ConfigFile::saveAs(const std::string& filename) const
+    {
+        boost::filesystem::path filepath(filename);
+        if (!filepath.is_complete())
+            filepath = PathConfig::getConfigPath() / filename;
+        std::ofstream file;
+        file.open(filepath.string().c_str(), std::fstream::out);
+        file.setf(std::ios::fixed, std::ios::floatfield);
+        file.precision(6);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "Error: Couldn't open config-file \"" << filename << "\"." << std::endl;
+            return;
+        }
+
+        for (std::list<ConfigFileSection*>::const_iterator it = this->sections_.begin(); it != this->sections_.end(); ++it)
+        {
+            file << (*it)->getFileEntry() << std::endl;
+
+            for (std::list<ConfigFileEntry*>::const_iterator it_entries = (*it)->getEntriesBegin(); it_entries != (*it)->getEntriesEnd(); ++it_entries)
+                file << (*it_entries)->getFileEntry() << std::endl;
+
+            file << std::endl;
+        }
+
+        file.close();
+
+        COUT(4) << "Saved config file \"" << filename << "\"." << std::endl;
+    }
+
+    void ConfigFile::clear()
+    {
+        for (std::list<ConfigFileSection*>::iterator it = this->sections_.begin(); it != this->sections_.end(); )
+            delete (*(it++));
+        this->sections_.clear();
+    }
+
+    const std::string& ConfigFile::getOrCreateValue(const std::string& section, const std::string& name, const std::string& fallback, bool bString)
+    {
+        const std::string& output = this->getOrCreateSection(section)->getOrCreateValue(name, fallback, bString);
+        this->saveIfUpdated();
+        return output;
+    }
+
+    const std::string& ConfigFile::getOrCreateValue(const std::string& section, const std::string& name, unsigned int index, const std::string& fallback, bool bString)
+    {
+        const std::string& output = this->getOrCreateSection(section)->getOrCreateValue(name, index, fallback, bString);
+        this->saveIfUpdated();
+        return output;
+    }
+
+    void ConfigFile::deleteVectorEntries(const std::string& section, const std::string& name, unsigned int startindex)
+    {
+        if (ConfigFileSection* sectionPtr = this->getSection(section))
+        {
+            sectionPtr->deleteVectorEntries(name, startindex);
+            this->save();
+        }
+    }
+
+    ConfigFileSection* ConfigFile::getSection(const std::string& section) const
+    {
+        for (std::list<ConfigFileSection*>::const_iterator it = this->sections_.begin(); it != this->sections_.end(); ++it)
+            if ((*it)->getName() == section)
+                return (*it);
+        return NULL;
+    }
+
+    ConfigFileSection* ConfigFile::getOrCreateSection(const std::string& section)
+    {
+        for (std::list<ConfigFileSection*>::iterator it = this->sections_.begin(); it != this->sections_.end(); ++it)
+            if ((*it)->getName() == section)
+                return (*it);
+
+        this->bUpdated_ = true;
+
+        return (*this->sections_.insert(this->sections_.end(), new ConfigFileSection(section)));
+    }
+
+    void ConfigFile::saveIfUpdated()
+    {
+        bool sectionsUpdated = false;
+
+        for (std::list<ConfigFileSection*>::iterator it = this->sections_.begin(); it != this->sections_.end(); ++it)
+        {
+            if ((*it)->bUpdated_)
+            {
+                sectionsUpdated = true;
+                (*it)->bUpdated_ = false;
+            }
+        }
+
+        if (this->bUpdated_ || sectionsUpdated)
+        {
+            this->bUpdated_ = false;
+            this->save();
+        }
+    }
+
+
+    ////////////////////////
+    // SettingsConfigFile //
+    ////////////////////////
+
+    SettingsConfigFile* SettingsConfigFile::singletonPtr_s = 0;
+
+    SettingsConfigFile::SettingsConfigFile(const std::string& filename)
+        : ConfigFile(filename)
+    {
+        ConsoleCommand* command = createConsoleCommand(createFunctor(&ConfigFile::load, this), "reloadSettings");
+        CommandExecutor::addConsoleCommandShortcut(command);
+        command = createConsoleCommand(createFunctor(&SettingsConfigFile::setFilename, this), "setSettingsFile");
+        CommandExecutor::addConsoleCommandShortcut(command);
+        command = createConsoleCommand(createFunctor(&SettingsConfigFile::config, this), "config");
+        CommandExecutor::addConsoleCommandShortcut(command).argumentCompleter(0, autocompletion::settingssections()).argumentCompleter(1, autocompletion::settingsentries()).argumentCompleter(2, autocompletion::settingsvalue());
+        command = createConsoleCommand(createFunctor(&SettingsConfigFile::tconfig, this), "tconfig");
+        CommandExecutor::addConsoleCommandShortcut(command).argumentCompleter(0, autocompletion::settingssections()).argumentCompleter(1, autocompletion::settingsentries()).argumentCompleter(2, autocompletion::settingsvalue());
+        command = createConsoleCommand(createFunctor(&SettingsConfigFile::getConfig, this), "getConfig");
+        CommandExecutor::addConsoleCommandShortcut(command).argumentCompleter(0, autocompletion::settingssections()).argumentCompleter(1, autocompletion::settingsentries());
+    }
+
+    SettingsConfigFile::~SettingsConfigFile()
+    {
+    }
+
+    void SettingsConfigFile::load()
+    {
+        ConfigFile::load();
+        this->updateConfigValues();
+    }
+
+    void SettingsConfigFile::setFilename(const std::string& filename)
+    {
+        ConfigFileManager::getInstance().setFilename(ConfigFileType::Settings, filename);
+    }
+
+    void SettingsConfigFile::addConfigValueContainer(ConfigValueContainer* container)
+    {
+        if (container == NULL)
+            return;
+        std::pair<std::string, ConfigValueContainer*> second(getLowercase(container->getName()), container);
+        this->containers_.insert(std::make_pair(getLowercase(container->getSectionName()), second));
+        this->sectionNames_.insert(container->getSectionName());
+    }
+
+    void SettingsConfigFile::removeConfigValueContainer(ConfigValueContainer* container)
+    {
+        if (container == NULL)
+            return;
+        const std::string& sectionLC = getLowercase(container->getSectionName());
+        ContainerMap::iterator upper = this->containers_.upper_bound(sectionLC);
+        for (ContainerMap::iterator it = this->containers_.lower_bound(sectionLC); it != upper; ++it)
+        {
+            if (it->second.second == container)
+            {
+                // Remove entry from section name set this was the last container for that section
+                if (upper == this->containers_.lower_bound(sectionLC))
+                    this->sectionNames_.erase(container->getSectionName());
+                this->containers_.erase(it);
+                break;
+            }
+        }
+    }
+
+    void SettingsConfigFile::updateConfigValues()
+    {
+        for (ContainerMap::const_iterator it = this->containers_.begin(); it != this->containers_.end(); ++it)
+        {
+            it->second.second->update();
+            it->second.second->getIdentifier()->updateConfigValues();
+        }
+    }
+
+    void SettingsConfigFile::clean(bool bCleanComments)
+    {
+        for (std::list<ConfigFileSection*>::iterator itSection = this->sections_.begin(); itSection != this->sections_.end(); )
+        {
+            const std::string& sectionLC = getLowercase((*itSection)->getName());
+            ContainerMap::const_iterator lower = this->containers_.lower_bound(sectionLC);
+            ContainerMap::const_iterator upper = this->containers_.upper_bound(sectionLC);
+            if (lower != upper)
+            {
+                // The section exists, delete comment
+                if (bCleanComments)
+                    (*itSection)->setComment("");
+                for (std::list<ConfigFileEntry*>::iterator itEntry = (*itSection)->entries_.begin(); itEntry != (*itSection)->entries_.end(); )
+                {
+                    const std::string& entryLC = getLowercase((*itEntry)->getName());
+                    bool bFound = false;
+                    for (ContainerMap::const_iterator itContainer = lower; itContainer != upper; ++itContainer)
+                    {
+                        if (itContainer->second.first == entryLC)
+                        {
+                            // The config-value exists, delete comment
+                            if (bCleanComments)
+                                (*itEntry)->setComment("");
+                            ++itEntry;
+                            bFound = true;
+                            break;
+                        }
+                    }
+                    if (!bFound)
+                    {
+                        // The config-value doesn't exist
+                        delete (*itEntry);
+                        (*itSection)->entries_.erase(itEntry++);
+                    }
+                }
+                ++itSection;
+            }
+            else
+            {
+                // The section doesn't exist
+                delete (*itSection);
+                this->sections_.erase(itSection++);
+            }
+        }
+
+        // Save the file
+        this->save();
+    }
+
+    bool SettingsConfigFile::config(const std::string& section, const std::string& entry, const std::string& value)
+    {
+        return this->configImpl(section, entry, value, &ConfigValueContainer::set);
+    }
+
+    bool SettingsConfigFile::tconfig(const std::string& section, const std::string& entry, const std::string& value)
+    {
+        return this->configImpl(section, entry, value, &ConfigValueContainer::tset);
+    }
+
+    bool SettingsConfigFile::configImpl(const std::string& section, const std::string& entry, const std::string& value, bool (ConfigValueContainer::*function)(const MultiType&))
+    {
+        const std::string& sectionLC = getLowercase(section);
+        const std::string& entryLC = getLowercase(entry);
+        ContainerMap::iterator upper = this->containers_.upper_bound(sectionLC);
+        for (ContainerMap::iterator it = this->containers_.lower_bound(sectionLC); it != upper; ++it)
+        {
+            // Note: Config value vectors cannot be supported
+            if (it->second.first == entryLC && !it->second.second->isVector())
+            {
+                return (it->second.second->*function)(value);
+            }
+        }
+        return false;
+    }
+
+    std::string SettingsConfigFile::getConfig(const std::string& section, const std::string& entry)
+    {
+        const std::string& sectionLC = getLowercase(section);
+        const std::string& entryLC = getLowercase(entry);
+        ContainerMap::iterator upper = this->containers_.upper_bound(sectionLC);
+        for (ContainerMap::iterator it = this->containers_.lower_bound(sectionLC); it != upper; ++it)
+        {
+            // Note: Config value vectors cannot be supported
+            if (it->second.first == entryLC && ! it->second.second->isVector())
+            {
+                std::string value;
+                it->second.second->getValue<std::string, OrxonoxClass>(&value, NULL);
+                return value;
+            }
+        }
+        return "";
+    }
+
+
+    ///////////////////////
+    // ConfigFileManager //
+    ///////////////////////
+
+    ConfigFileManager* ConfigFileManager::singletonPtr_s = 0;
+
+    ConfigFileManager::ConfigFileManager()
+    {
+        this->configFiles_.assign(NULL);
+    }
+
+    ConfigFileManager::~ConfigFileManager()
+    {
+        for (boost::array<ConfigFile*, 3>::const_iterator it = this->configFiles_.begin(); it != this->configFiles_.end(); ++it)
+            if (*it)
+                delete (*it);
+    }
+
+    void ConfigFileManager::setFilename(ConfigFileType::Value type, const std::string& filename)
+    {
+        if (this->getConfigFile(type))
+            delete this->configFiles_[type];
+        // Create and load config file
+        switch (type)
+        {
+        case ConfigFileType::Settings:
+            this->configFiles_[type] = new SettingsConfigFile(filename);
+            break;
+        case ConfigFileType::JoyStickCalibration:
+        case ConfigFileType::CommandHistory:
+            this->configFiles_[type] = new ConfigFile(filename);
+            break;
+        }
+        this->configFiles_[type]->load();
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/ConfigFileManager.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ConfigFileManager.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ConfigFileManager.h	(revision 6952)
@@ -0,0 +1,386 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ConfigFileManager_H__
+#define _ConfigFileManager_H__
+
+#include "CorePrereqs.h"
+
+#include <list>
+#include <map>
+#include <set>
+#include <string>
+#include <boost/array.hpp>
+
+#include "util/Singleton.h"
+#include "util/StringUtils.h"
+
+namespace orxonox // tolua_export
+{ // tolua_export
+
+    /////////////////////
+    // ConfigFileEntry //
+    /////////////////////
+    class _CoreExport ConfigFileEntry
+    {
+        public:
+            virtual ~ConfigFileEntry() {};
+            virtual void setValue(const std::string& value) = 0;
+            virtual const std::string& getValue() const = 0;
+            virtual const std::string& getName() const = 0;
+            virtual void setComment(const std::string& comment) = 0;
+            virtual unsigned int getIndex() const { return 0; }
+            virtual void setString(bool bString) = 0;
+            virtual const std::string& getFileEntry() const = 0;
+    };
+
+
+    //////////////////////////
+    // ConfigFileEntryValue //
+    //////////////////////////
+    class _CoreExport ConfigFileEntryValue : public ConfigFileEntry
+    {
+        public:
+            inline ConfigFileEntryValue(const std::string& name, const std::string& value = "", bool bString = false, const std::string& additionalComment = "")
+                : name_(name)
+                , value_(value)
+                , additionalComment_(additionalComment)
+                , bString_(bString)
+                { this->update(); }
+
+            inline virtual ~ConfigFileEntryValue() {}
+
+            inline virtual const std::string& getName() const
+                { return this->name_; }
+
+            inline virtual void setComment(const std::string& comment)
+                { this->additionalComment_ = comment; this->update(); }
+
+            inline virtual void setValue(const std::string& value)
+                { this->value_ = value; this->update(); }
+            inline virtual const std::string& getValue() const
+                { return this->value_; }
+
+            inline void virtual setString(bool bString)
+                { this->bString_ = bString; this->update(); }
+
+            inline virtual const std::string& getFileEntry() const
+                { return this->fileEntry_; }
+
+            inline virtual const std::string& getKeyString() const
+                { return this->name_; }
+
+        protected:
+            virtual void update();
+
+            const std::string name_;
+            std::string value_;
+            std::string additionalComment_;
+            std::string fileEntry_;
+            bool bString_;
+    };
+
+
+    ////////////////////////////////
+    // ConfigFileEntryVectorValue //
+    ////////////////////////////////
+    class _CoreExport ConfigFileEntryVectorValue : public ConfigFileEntryValue
+    {
+        public:
+            inline ConfigFileEntryVectorValue(const std::string& name, unsigned int index, const std::string& value = "", bool bString = false, const std::string& additionalComment = "")
+                : ConfigFileEntryValue(name, value, bString, additionalComment)
+                , index_(index)
+                { this->update(); /*No virtual calls in base class ctor*/ }
+
+            inline ~ConfigFileEntryVectorValue() {}
+
+            inline unsigned int getIndex() const
+                { return this->index_; }
+
+            inline const std::string& getKeyString() const
+                { return this->keyString_; }
+
+        private:
+            void update();
+
+            unsigned int index_;
+            std::string keyString_;
+    };
+
+
+    ////////////////////////////
+    // ConfigFileEntryComment //
+    ////////////////////////////
+    class _CoreExport ConfigFileEntryComment : public ConfigFileEntry
+    {
+        public:
+            inline ConfigFileEntryComment(const std::string& comment) : comment_(comment) {}
+            inline virtual ~ConfigFileEntryComment() {}
+
+            inline virtual const std::string& getName() const
+                { return this->comment_; }
+
+            inline virtual void setComment(const std::string& comment)
+                { this->comment_ = comment; }
+
+            inline virtual void setValue(const std::string& value)
+                {}
+            inline virtual const std::string& getValue() const
+                { return BLANKSTRING; }
+
+            inline void setString(bool bString)
+                {}
+
+            inline virtual const std::string& getFileEntry() const
+                { return this->comment_; }
+
+            inline virtual const std::string& getKeyString() const
+                { return BLANKSTRING; }
+
+        private:
+            std::string comment_;
+    };
+
+
+    ///////////////////////
+    // ConfigFileSection //
+    ///////////////////////
+    class _CoreExport ConfigFileSection
+    {
+        friend class ConfigFile;
+        friend class SettingsConfigFile;
+
+        public:
+            inline ConfigFileSection(const std::string& name, const std::string& additionalComment = "")
+                : name_(name)
+                , additionalComment_(additionalComment)
+                , bUpdated_(false)
+                {}
+            ~ConfigFileSection();
+
+            inline const std::string& getName() const
+                { return this->name_; }
+
+            inline void setComment(const std::string& comment)
+                { this->additionalComment_ = comment; }
+
+            inline void setValue(const std::string& name, const std::string& value, bool bString)
+                { this->getOrCreateEntry(name, value, bString)->setValue(value); }
+            inline const std::string& getValue(const std::string& name, bool bString)
+            {
+                ConfigFileEntry* entry = this->getEntry(name);
+                if (entry)
+                {
+                    entry->setString(bString);
+                    return entry->getValue();
+                }
+                return BLANKSTRING;
+            }
+            inline const std::string& getOrCreateValue(const std::string& name, const std::string& fallback, bool bString)
+                { return this->getOrCreateEntry(name, fallback, bString)->getValue(); }
+
+            inline void setValue(const std::string& name, unsigned int index, const std::string& value, bool bString)
+                { this->getOrCreateEntry(name, index, value, bString)->setValue(value); }
+            inline const std::string& getValue(const std::string& name, unsigned int index, bool bString)
+            {
+                ConfigFileEntry* entry = this->getEntry(name, index);
+                if (entry)
+                {
+                    entry->setString(bString);
+                    return entry->getValue();
+                }
+                return BLANKSTRING;
+            }
+            inline const std::string& getOrCreateValue(const std::string& name, unsigned int index, const std::string& fallback, bool bString)
+                { return this->getOrCreateEntry(name, index, fallback, bString)->getValue(); }
+
+            void deleteVectorEntries(const std::string& name, unsigned int startindex = 0);
+            unsigned int getVectorSize(const std::string& name) const;
+
+            std::string getFileEntry() const;
+
+        private:
+            std::list<ConfigFileEntry*>& getEntries()
+                { return this->entries_; }
+            std::list<ConfigFileEntry*>::const_iterator getEntriesBegin() const
+                { return this->entries_.begin(); }
+            std::list<ConfigFileEntry*>::const_iterator getEntriesEnd() const
+                { return this->entries_.end(); }
+
+            std::list<ConfigFileEntry*>::iterator getOrCreateEntryIterator(const std::string& name, const std::string& fallback, bool bString);
+            std::list<ConfigFileEntry*>::iterator getOrCreateEntryIterator(const std::string& name, unsigned int index, const std::string& fallback, bool bString);
+
+            ConfigFileEntry* getEntry(const std::string& name) const;
+            inline ConfigFileEntry* getOrCreateEntry(const std::string& name, const std::string& fallback, bool bString)
+                { return (*this->getOrCreateEntryIterator(name, fallback, bString)); }
+            ConfigFileEntry* getEntry(const std::string& name, unsigned int index) const;
+            inline ConfigFileEntry* getOrCreateEntry(const std::string& name, unsigned int index, const std::string& fallback, bool bString)
+                { return (*this->getOrCreateEntryIterator(name, index, fallback, bString)); }
+
+            std::string name_;
+            std::string additionalComment_;
+            std::list<ConfigFileEntry*> entries_;
+            bool bUpdated_;
+    };
+
+
+    ////////////////
+    // ConfigFile //
+    ////////////////
+    class _CoreExport ConfigFile
+    {
+        public:
+            ConfigFile(const std::string& filename, bool bCopyFallbackFile = true);
+            virtual ~ConfigFile();
+
+            virtual void load();
+            virtual void save() const;
+            virtual void saveAs(const std::string& filename) const;
+            virtual void clear();
+
+            inline const std::string& getFilename()
+                { return this->filename_; }
+
+            inline void setValue(const std::string& section, const std::string& name, const std::string& value, bool bString)
+            {
+                this->getOrCreateSection(section)->setValue(name, value, bString);
+                this->save();
+            }
+            inline const std::string& getValue(const std::string& section, const std::string& name, bool bString)
+            {
+                ConfigFileSection* sectionPtr = this->getSection(section);
+                return (sectionPtr ? sectionPtr->getValue(name, bString) : BLANKSTRING);
+            }
+            const std::string& getOrCreateValue(const std::string& section, const std::string& name, const std::string& fallback, bool bString);
+
+            inline void setValue(const std::string& section, const std::string& name, unsigned int index, const std::string& value, bool bString)
+            {
+                this->getOrCreateSection(section)->setValue(name, index, value, bString);
+                this->save();
+            }
+            inline const std::string& getValue(const std::string& section, const std::string& name, unsigned int index, bool bString)
+            {
+                ConfigFileSection* sectionPtr = this->getSection(section);
+                return (sectionPtr ? sectionPtr->getValue(name, index, bString) : BLANKSTRING);
+            }
+            const std::string& getOrCreateValue(const std::string& section, const std::string& name, unsigned int index, const std::string& fallback, bool bString);
+
+            void deleteVectorEntries(const std::string& section, const std::string& name, unsigned int startindex = 0);
+            inline unsigned int getVectorSize(const std::string& section, const std::string& name) const
+            {
+                ConfigFileSection* sectionPtr = this->getSection(section);
+                return (sectionPtr ? sectionPtr->getVectorSize(name) : 0);
+            }
+
+            static const char* DEFAULT_CONFIG_FOLDER;
+
+        protected:
+            ConfigFileSection* getSection(const std::string& section) const;
+            ConfigFileSection* getOrCreateSection(const std::string& section);
+
+            std::list<ConfigFileSection*> sections_;
+
+        private:
+            void saveIfUpdated();
+            const std::string filename_;
+            const bool bCopyFallbackFile_;
+            bool bUpdated_;
+    };
+
+
+    ////////////////////////
+    // SettingsConfigFile //
+    ////////////////////////
+    class _CoreExport SettingsConfigFile // tolua_export
+        : public ConfigFile, public Singleton<SettingsConfigFile>
+    { // tolua_export
+        friend class Singleton<SettingsConfigFile>;
+
+        public:
+            typedef std::multimap<std::string, std::pair<std::string, ConfigValueContainer*> > ContainerMap;
+
+            SettingsConfigFile(const std::string& filename);
+            ~SettingsConfigFile();
+
+            void load(); // tolua_export
+            void setFilename(const std::string& filename); // tolua_export
+            void clean(bool bCleanComments = false); // tolua_export
+
+            bool config(const std::string& section, const std::string& entry, const std::string& value); // tolua_export
+            bool tconfig(const std::string& section, const std::string& entry, const std::string& value); // tolua_export
+            std::string getConfig(const std::string& section, const std::string& entry); // tolua_export
+
+            void addConfigValueContainer(ConfigValueContainer* container);
+            void removeConfigValueContainer(ConfigValueContainer* container);
+
+            inline const std::set<std::string>& getSectionNames()
+                { return this->sectionNames_; }
+            inline ContainerMap::const_iterator getContainerLowerBound(const std::string section)
+                { return this->containers_.lower_bound(section); }
+            inline ContainerMap::const_iterator getContainerUpperBound(const std::string section)
+                { return this->containers_.upper_bound(section); }
+
+            static SettingsConfigFile& getInstance() { return Singleton<SettingsConfigFile>::getInstance(); } // tolua_export
+
+        private:
+            void updateConfigValues();
+            bool configImpl(const std::string& section, const std::string& entry, const std::string& value, bool (ConfigValueContainer::*function)(const MultiType&));
+
+            ContainerMap containers_;
+            std::set<std::string> sectionNames_;
+            static SettingsConfigFile* singletonPtr_s;
+    }; // tolua_export
+
+
+    ///////////////////////
+    // ConfigFileManager //
+    ///////////////////////
+    class _CoreExport ConfigFileManager : public Singleton<ConfigFileManager>
+    {
+        friend class Singleton<ConfigFileManager>;
+        public:
+            ConfigFileManager();
+            ~ConfigFileManager();
+
+            void setFilename(ConfigFileType::Value type, const std::string& filename);
+
+            inline ConfigFile* getConfigFile(ConfigFileType::Value type)
+            {
+                // Check array bounds
+                return configFiles_.at(type);
+            }
+
+        private:
+            ConfigFileManager(const ConfigFileManager&);
+
+            boost::array<ConfigFile*, 3> configFiles_;
+            static ConfigFileManager* singletonPtr_s;
+    };
+} // tolua_export
+
+#endif /* _ConfigFileManager_H__ */
Index: /code/branches/rocket2/src/libraries/core/ConfigValueContainer.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/ConfigValueContainer.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ConfigValueContainer.cc	(revision 6952)
@@ -0,0 +1,353 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the ConfigValueContainer class.
+*/
+
+#include "ConfigValueContainer.h"
+
+#include "util/Convert.h"
+#include "util/SubString.h"
+#include "ConfigFileManager.h"
+#include "Language.h"
+
+namespace orxonox
+{
+    const unsigned int MAX_VECTOR_INDEX  = 255; // to avoid up to 4*10^9 vector entries in the config file after accidentally using a wrong argument
+
+    /**
+        @brief Initializes the ConfigValueContainer with default values.
+    */
+    void ConfigValueContainer::init(ConfigFileType::Value type, Identifier* identifier, const std::string& sectionname, const std::string& varname)
+    {
+        this->type_ = type;
+        this->identifier_ = identifier;
+        this->sectionname_ = sectionname;
+        this->varname_ = varname;
+        this->callback_ = 0;
+        this->bContainerIsNew_ = true;
+        this->bDoInitialCallback_ = false;
+        this->bAddedDescription_ = false;
+
+        // Register containers for general settings
+        if (this->type_ == ConfigFileType::Settings)
+            SettingsConfigFile::getInstance().addConfigValueContainer(this);
+    }
+
+    /**
+        @brief Does some special initialization for single config-values.
+    */
+    void ConfigValueContainer::initValue(const MultiType& defvalue)
+    {
+        this->value_ = defvalue;
+        this->bIsVector_ = false;
+
+        this->defvalueString_ = this->value_.getString();
+        this->update();
+    }
+
+    /**
+        @brief Does some special initialization for vector config-values.
+    */
+    void ConfigValueContainer::initVector()
+    {
+        this->bIsVector_ = true;
+
+        for (unsigned int i = 0; i < this->valueVector_.size(); i++)
+        {
+            ConfigFileManager::getInstance().getConfigFile(this->type_)->getOrCreateValue(this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isType(MT_Type::String));
+            this->defvalueStringVector_.push_back(this->valueVector_[i]);
+        }
+
+        this->update();
+    }
+
+    /**
+        @brief Destructor: Deletes the callback object if necessary.
+    */
+    ConfigValueContainer::~ConfigValueContainer()
+    {
+        if (this->callback_)
+            delete this->callback_;
+
+        // Unregister general settings containers
+        if (this->type_ == ConfigFileType::Settings && SettingsConfigFile::exists())
+            SettingsConfigFile::getInstance().removeConfigValueContainer(this);
+    }
+
+    /**
+        @brief Assigns a new value to the config-value of all objects and writes the change into the config-file.
+        @param input The new value
+        @return True if the new value was successfully assigned
+    */
+    bool ConfigValueContainer::set(const MultiType& input)
+    {
+        if (this->bIsVector_)
+        {
+            return this->callFunctionWithIndex(&ConfigValueContainer::set, input);
+        }
+        else
+        {
+            if (this->tset(input))
+            {
+                ConfigFileManager::getInstance().getConfigFile(this->type_)->setValue(this->sectionname_, this->varname_, input, this->value_.isType(MT_Type::String));
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+        @brief Assigns a new value to the config-value of all objects and writes the change into the config-file.
+        @param index The index in the vector
+        @param input The new value
+        @return True if the new value was successfully assigned
+    */
+    bool ConfigValueContainer::set(unsigned int index, const MultiType& input)
+    {
+        if (this->bIsVector_)
+        {
+            if (this->tset(index, input))
+            {
+                ConfigFileManager::getInstance().getConfigFile(this->type_)->setValue(this->sectionname_, this->varname_, index, input, this->value_.isType(MT_Type::String));
+                return true;
+            }
+        }
+        else
+        {
+            COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
+        }
+        return false;
+    }
+
+    /**
+        @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary).
+        @param input The new value. If bIsVector_ then write "index value"
+        @return True if the new value was successfully assigned
+    */
+    bool ConfigValueContainer::tset(const MultiType& input)
+    {
+        if (this->bIsVector_)
+        {
+            return this->callFunctionWithIndex(&ConfigValueContainer::tset, input);
+            return false;
+        }
+        else
+        {
+            this->value_ = input;
+
+            if (this->identifier_)
+                this->identifier_->updateConfigValues();
+
+            return true;
+        }
+    }
+
+    /**
+        @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary).
+        @param index The index in the vector
+        @param input The new value
+        @return True if the new value was successfully assigned
+    */
+    bool ConfigValueContainer::tset(unsigned int index, const MultiType& input)
+    {
+        if (this->bIsVector_)
+        {
+            if (index > MAX_VECTOR_INDEX)
+            {
+                COUT(1) << "Error: Index " << index << " is too large." << std::endl;
+                return false;
+            }
+
+            if (index >= this->valueVector_.size())
+            {
+                for (unsigned int i = this->valueVector_.size(); i <= index; i++)
+                {
+                    this->valueVector_.push_back(MultiType());
+                }
+            }
+
+            this->valueVector_[index] = input;
+
+            if (this->identifier_)
+                this->identifier_->updateConfigValues();
+
+            return true;
+        }
+        else
+        {
+            COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
+            return false;
+        }
+    }
+
+    /**
+        @brief Adds a new entry to the end of the vector.
+        @param input The new entry
+        @return True if the new entry was successfully added
+    */
+    bool ConfigValueContainer::add(const MultiType& input)
+    {
+        if (this->bIsVector_)
+            return this->set(this->valueVector_.size(), input);
+
+        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
+        return false;
+    }
+
+    /**
+        @brief Removes an existing entry from the vector.
+        @param index The index of the entry
+        @return True if the entry was removed
+    */
+    bool ConfigValueContainer::remove(unsigned int index)
+    {
+        if (this->bIsVector_)
+        {
+            if (index < this->valueVector_.size())
+            {
+                // Erase the entry from the vector, change (shift) all entries beginning with index in the config file, remove the last entry from the file
+                this->valueVector_.erase(this->valueVector_.begin() + index);
+                for (unsigned int i = index; i < this->valueVector_.size(); i++)
+                    ConfigFileManager::getInstance().getConfigFile(this->type_)->setValue(this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isType(MT_Type::String));
+                ConfigFileManager::getInstance().getConfigFile(this->type_)->deleteVectorEntries(this->sectionname_, this->varname_, this->valueVector_.size());
+
+                return true;
+            }
+            COUT(1) << "Error: Invalid vector-index." << std::endl;
+        }
+
+        COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
+        return false;
+    }
+
+    /**
+        @brief Sets the value of the variable back to the default value and resets the config-file entry.
+    */
+    bool ConfigValueContainer::reset()
+    {
+        if (!this->bIsVector_)
+            return this->set(this->defvalueString_);
+        else
+        {
+            bool success = true;
+            for (unsigned int i = 0; i < this->defvalueStringVector_.size(); i++)
+                if (!this->set(i, this->defvalueStringVector_[i]))
+                    success = false;
+            ConfigFileManager::getInstance().getConfigFile(this->type_)->deleteVectorEntries(this->sectionname_, this->varname_, this->defvalueStringVector_.size());
+            return success;
+        }
+    }
+
+    /**
+        @brief Retrieves the configured value from the currently loaded config-file.
+    */
+    void ConfigValueContainer::update()
+    {
+        if (!this->bIsVector_)
+            this->value_ = ConfigFileManager::getInstance().getConfigFile(this->type_)->getOrCreateValue(this->sectionname_, this->varname_, this->defvalueString_, this->value_.isType(MT_Type::String));
+        else
+        {
+            this->valueVector_.clear();
+            unsigned int vectorSize = ConfigFileManager::getInstance().getConfigFile(this->type_)->getVectorSize(this->sectionname_, this->varname_);
+            for (unsigned int i = 0; i < vectorSize; i++)
+            {
+                if (i < this->defvalueStringVector_.size())
+                {
+                    this->value_ = ConfigFileManager::getInstance().getConfigFile(this->type_)->getOrCreateValue(this->sectionname_, this->varname_, i, this->defvalueStringVector_[i], this->value_.isType(MT_Type::String));
+                }
+                else
+                {
+                    this->value_ = ConfigFileManager::getInstance().getConfigFile(this->type_)->getOrCreateValue(this->sectionname_, this->varname_, i, MultiType(), this->value_.isType(MT_Type::String));
+                }
+
+                this->valueVector_.push_back(this->value_);
+            }
+        }
+    }
+
+    /**
+        @brief Calls the given function with parsed index and the parsed argument from the input string.
+        @param function The function to call
+        @param input The input string
+        @return The returnvalue of the functioncall
+    */
+    bool ConfigValueContainer::callFunctionWithIndex(bool (ConfigValueContainer::* function) (unsigned int, const MultiType&), const std::string& input)
+    {
+        SubString token(input, " ", SubString::WhiteSpaces, true, '\\', false, '"', false, '(', ')', false, '\0');
+        int index = -1;
+        bool success = false;
+
+        if (token.size() > 0)
+            success = convertValue(&index, token[0]);
+
+        if (!success || index < 0 || index > (signed int)MAX_VECTOR_INDEX)
+        {
+            if (!success)
+            {
+                COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is a vector." << std::endl;
+            }
+            else
+            {
+                COUT(1) << "Error: Invalid vector-index." << std::endl;
+            }
+            return false;
+        }
+
+        if (token.size() >= 2)
+            return (this->*function)(index, token.subSet(1).join());
+        else
+            return (this->*function)(index, "");
+    }
+
+    /**
+        @brief Adds a description to the config-value.
+        @param description The description
+    */
+    ConfigValueContainer& ConfigValueContainer::description(const std::string& description)
+    {
+        if (!this->bAddedDescription_)
+        {
+            this->description_ = std::string("ConfigValueDescription::" + this->sectionname_ + "::" + this->varname_);
+            AddLanguageEntry(this->description_, description);
+            this->bAddedDescription_ = true;
+        }
+        return (*this);
+    }
+
+    /**
+        @brief Returns the description of the config-value.
+        @return The description
+    */
+    const std::string& ConfigValueContainer::getDescription() const
+    {
+        return GetLocalisation(this->description_);
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/ConfigValueContainer.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ConfigValueContainer.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ConfigValueContainer.h	(revision 6952)
@@ -0,0 +1,301 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the ConfigValueContainer class.
+
+    The ConfigValueContainer class contains all needed information about a configurable variable:
+     - the name of the variable
+     - the name of the class the variable belongs to
+     - the default value
+     - the user-specified value
+     - a pointer to the entry in the config-file
+
+    This is needed to assign the configured values to all newly created objects.
+*/
+
+#ifndef _ConfigValueContainer_H__
+#define _ConfigValueContainer_H__
+
+#include "CorePrereqs.h"
+
+#include <string>
+#include <vector>
+
+#include "util/MultiType.h"
+#include "Identifier.h"
+
+namespace orxonox
+{
+    class ConfigValueCallbackBase
+    {
+        public:
+            virtual void call(void* object) = 0;
+            inline virtual ~ConfigValueCallbackBase() {}
+    };
+
+    template <class T>
+    class ConfigValueCallback: public ConfigValueCallbackBase
+    {
+        public:
+            inline ConfigValueCallback(void (T::*function) (void)) : function_(function) {}
+            inline virtual ~ConfigValueCallback() {}
+            inline virtual void call(void* object)
+            {
+                if (!Identifier::isCreatingHierarchy())
+                    (static_cast<T*>(object)->*this->function_)();
+            }
+
+        private:
+            void (T::*function_) (void);
+    };
+
+
+    //! The ConfigValuecontainer contains all needed information about a configurable variable.
+    /**
+        The ConfigValueContainer class contains all needed information about a configurable variable:
+         - the name of the variable
+         - the name of the class the variable belongs to
+         - the default value
+         - the user-specified value
+         - a pointer to the entry in the config-file
+
+        This is needed to assign the configured values to all newly created objects.
+
+        The container searches for the entry in the config file.
+        If there is an entry, it parses the specified value and assigns it to the variable of the right type.
+        If there is no entry, it adds the entry with the default-value to the section of the variables class.
+        If there is no section, the section and the entry are added to the end of the config-file.
+    */
+    class _CoreExport ConfigValueContainer
+    {
+        public:
+            /**
+                @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
+                @param type The type of the corresponding config-file
+                @param identifier The identifier of the class the variable belongs to
+                @param sectionname Name of the section the configValue should be put in.
+                @param varname The name of the variable
+                @param defvalue The default-value
+                @param value Only needed do determine the right type.
+            */
+            template <class D, class V>
+            ConfigValueContainer(ConfigFileType::Value type, Identifier* identifier, const std::string& sectionname, const std::string& varname, const D& defvalue, const V& value)
+            {
+                this->init(type, identifier, sectionname, varname);
+                this->initValue(static_cast<V>(defvalue));
+            }
+
+            /**
+                @brief Constructor: Converts the default-value to a string, checks the config-file for a changed value, sets the intern value variable.
+                @param type The type of the corresponding config-file
+                @param identifier The identifier of the class the variable belongs to
+                @param varname The name of the variable
+                @param defvalue The default-value
+            */
+            template <class D, class V>
+            ConfigValueContainer(ConfigFileType::Value type, Identifier* identifier, const std::string& sectionname, const std::string& varname, const std::vector<D>& defvalue, const std::vector<V>& value)
+            {
+                this->init(type, identifier, sectionname, varname);
+
+                this->value_ = V();
+                for (unsigned int i = 0; i < defvalue.size(); i++)
+                    this->valueVector_.push_back(MultiType(defvalue[i]));
+
+                this->initVector();
+            }
+
+            ~ConfigValueContainer();
+
+            /**
+                @brief Returns the configured value.
+                @param value A pointer to the variable to store the value.
+                @param object The object calling this function
+                @return The ConfigValueContainer
+            */
+            template <typename T, class C>
+            ConfigValueContainer& getValue(T* value, C* object)
+            {
+                if ((this->callback_ && object) || this->bContainerIsNew_)
+                {
+                    T temp = *value;
+                    this->value_.getValue(value);
+                    if (this->bContainerIsNew_ || (*value) != temp)
+                    {
+                        this->bContainerIsNew_ = false;
+                        if (this->callback_ && object)
+                            this->callback_->call(object);
+                        else
+                            this->bDoInitialCallback_ = true;
+                    }
+                }
+                else
+                {
+                    this->value_.getValue(value);
+                }
+                return *this;
+            }
+
+            /**
+                @brief Returns the configured vector.
+                @param value A pointer to the vector to store the values.
+                @param object The object calling this function
+                @return The ConfigValueContainer
+            */
+            template <typename T, class C>
+            ConfigValueContainer& getValue(std::vector<T>* value, C* object)
+            {
+                if ((this->callback_ && object) || this->bContainerIsNew_)
+                {
+                    if (this->bContainerIsNew_)
+                        this->bContainerIsNew_ = false;
+
+                    std::vector<T> temp = *value;
+                    value->clear();
+                    for (unsigned int i = 0; i < this->valueVector_.size(); ++i)
+                        value->push_back(this->valueVector_[i]);
+
+                    if (value->size() != temp.size())
+                    {
+                        if (this->callback_ && object)
+                            this->callback_->call(object);
+                        else
+                            this->bDoInitialCallback_ = true;
+                    }
+                    else
+                    {
+                        for (unsigned int i = 0; i < value->size(); ++i)
+                        {
+                            if ((*value)[i] != temp[i])
+                            {
+                                if (this->callback_ && object)
+                                    this->callback_->call(object);
+                                else
+                                    this->bDoInitialCallback_ = true;
+                                break;
+                            }
+                        }
+                    }
+                }
+                else
+                {
+                    value->clear();
+                    for (unsigned int i = 0; i < this->valueVector_.size(); ++i)
+                        value->push_back(this->valueVector_[i]);
+                }
+                return *this;
+            }
+
+            /** @brief Returns the name of this container. */
+            inline const std::string& getName() const
+                { return this->varname_; }
+            /** @brief Returns the name of the section this config value is in. */
+            inline const std::string& getSectionName() const
+                { return this->sectionname_; }
+            /** @brief Returns the associated identifier (can be NULL). */
+            inline Identifier* getIdentifier() const
+                { return this->identifier_; }
+            /** @brief Returns true if this config-value is a vector */
+            inline bool isVector() const
+                { return this->bIsVector_; }
+            /** @brief Returns the vectors size (or zero if it's not a vector). */
+            inline unsigned int getVectorSize() const
+                { return this->valueVector_.size(); }
+
+            ConfigValueContainer& description(const std::string& description);
+            const std::string& getDescription() const;
+
+            /**
+                @brief Adds a callback function, that gets called after getValue() if the newly assigned value differs from the old value of the variable.
+                @param object The object to call the function
+                @param function The callback function
+            */
+            template <class T>
+            inline ConfigValueContainer& callback(T* object, void (T::*function) (void))
+            {
+                if (!this->callback_)
+                {
+                    this->callback_ = new ConfigValueCallback<T>(function);
+
+                    if (this->bDoInitialCallback_)
+                    {
+                        this->bDoInitialCallback_ = false;
+                        this->callback_->call(object);
+                    }
+                }
+
+                return (*this);
+            }
+
+            bool set(const MultiType& input);
+            bool tset(const MultiType& input);
+
+            bool set(unsigned int index, const MultiType& input);
+            bool tset(unsigned int index, const MultiType& input);
+            bool add(const MultiType& input);
+            bool remove(unsigned int index);
+
+            bool reset();
+            void update();
+
+            /** @brief Converts the config-value to a string. @return The string */
+            inline std::string toString() const
+                { return this->value_; }
+            /** @brief Returns the typename of the assigned config-value. @return The typename */
+            inline std::string getTypename() const
+                { return this->value_.getTypename(); }
+
+        private:
+            void init(ConfigFileType::Value type, Identifier* identifier, const std::string& sectionname, const std::string& varname);
+            void initValue(const MultiType& defvalue);
+            void initVector();
+            bool callFunctionWithIndex(bool (ConfigValueContainer::* function) (unsigned int, const MultiType&), const std::string& input);
+
+            bool                       bIsVector_;                  //!< True if the container contains a std::vector
+
+            ConfigFileType::Value      type_;                       //!< The type of the corresponding config-file
+            Identifier*                identifier_;                 //!< The identifier of the class
+            std::string                sectionname_;                //!< The name of the class the variable belongs to
+            std::string                varname_;                    //!< The name of the variable
+            std::string                defvalueString_;             //!< The string of the default-value
+            std::vector<std::string>   defvalueStringVector_;       //!< A vector, containg the strings of the default-values in case we're storing a vector
+
+            MultiType                  value_;                      //!< The value
+            std::vector<MultiType>     valueVector_;                //!< A vector, containg the values in case we're storing a vector
+
+            bool                       bAddedDescription_;          //!< True if a description was added
+            LanguageEntryLabel         description_;                //!< The description
+            ConfigValueCallbackBase*   callback_;                   //!< A callback function to call after getValue if the value changed
+
+            bool                       bContainerIsNew_;            //!< True if it's the first time getValue() gets called
+            bool                       bDoInitialCallback_;         //!< True if the callback should be called as soon as it gets created
+    };
+}
+
+#endif /* _ConfigValueContainer_H__ */
Index: /code/branches/rocket2/src/libraries/core/ConfigValueIncludes.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ConfigValueIncludes.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ConfigValueIncludes.h	(revision 6952)
@@ -0,0 +1,177 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder (functions)
+ *
+ */
+
+/**
+@file
+@brief
+    Definition of macros and functions for config-values.
+*/
+
+#ifndef _ConfigValueIncludes_H__
+#define _ConfigValueIncludes_H__
+
+#include "CorePrereqs.h"
+
+#include "Identifier.h"
+#include "ConfigValueContainer.h"
+
+namespace orxonox
+{
+    /** Sets a runtime configurable value.
+        If the container for the value doesn't yet exist, a new one is created.
+        Also, the @a variable argument will be modified and set to the new value (default or from ini file).
+    @param object
+        Class instance that the config value should belong to (usually just 'this')
+    @param variable
+        Pointer to the variable where the value should be written to
+    @param type
+        Type of the config file, usually ConfigFileType::Settings
+    @param sectionName
+        Name of the section in the ini file (e.g. [MySection])
+    @param entryName
+        Name of the entry in the ini file (e.g. [MySection] myValue)
+    @param defaultValue
+        Value to be used if it cannot be read from the ini file
+    */
+    template <class T, class D, class V>
+    inline ConfigValueContainer& setConfigValueGeneric(T* object, V* variable, ConfigFileType::Value type, const std::string& sectionName, const std::string& entryName, const D& defaultValue)
+    {
+        ConfigValueContainer* container = ClassIdentifier<T>::getIdentifier()->getConfigValueContainer(entryName);
+        if (!container)
+        {
+            container = new ConfigValueContainer(type, ClassIdentifier<T>::getIdentifier(), sectionName, entryName, defaultValue, *variable);
+            ClassIdentifier<T>::getIdentifier()->addConfigValueContainer(entryName, container);
+        }
+        return container->getValue(variable, object);
+    }
+}
+
+/** Sets a runtime configurable value (simplified macro version of setConfigValueGeneric)
+    If the container for the value doesn't yet exist, a new one is created.
+    Also, the @a varname argument will be modified and set to the new value (default or from ini file).
+@param varname
+    Variable name as C++ identifier. It will be used as entry name and as variable pointer
+@param defaultValue
+    Value to be used if it cannot be read from the ini file
+*/
+#define SetConfigValue(varname, defaultValue) \
+    orxonox::setConfigValueGeneric(this, &varname, ConfigFileType::Settings, this->getIdentifier()->getName(), #varname, defaultValue)
+
+/** Sets a runtime configurable value (simplified macro version of setConfigValueGeneric)
+    If the container for the value doesn't yet exist, a new one is created.
+    Also, the @a varname argument will be modified and set to the new value (default or from ini file).
+@param variable
+    Variable name as C++ identifier.
+@param entryName
+    Name of the entry in the ini file (e.g. [MySection] myValue)
+@param defaultValue
+    Value to be used if it cannot be read from the ini file
+*/
+#define SetConfigValueAlias(variable, entryName, defaultValue) \
+    orxonox::setConfigValueGeneric(this, &variable, ConfigFileType::Settings, this->getIdentifier()->getName(), entryName, defaultValue)
+
+
+namespace orxonox
+{
+    /** Resets a runtime configurable value to its default.
+        If the container for the value doesn't yet exist, a warning is displayed.
+        Also, the @a variable argument will be modified and set to the default value.
+    @param object
+        Class instance that the config value should belong to (usually just 'this')
+    @param variable
+        Pointer to the variable where the value should be written to
+    @param entryName
+        Name of the entry in the ini file (e.g. [MySection] myValue)
+    */
+    template <class T, class V>
+    inline void resetConfigValueGeneric(T* object, V* variable, const std::string& entryName)
+    {
+        ConfigValueContainer* container = ClassIdentifier<T>::getIdentifier()->getConfigValueContainer(entryName);
+        if (container)
+        {
+            container->reset();
+            container->getValue(variable, object);
+        }
+        else
+        {
+            COUT(2) << "Warning: Couldn't reset config-value '" << entryName << "' in class '"
+                    << ClassIdentifier<T>::getIdentifier()->getName() << "', corresponding container doesn't exist." << std::endl;
+        }
+    }
+}
+
+/** Resets a runtime configurable value to its default (simplified macro version of modifyConfigValueGeneric)
+    If the container for the value doesn't yet exist, a warning is displayed.
+    Also, the @a varname argument will be modified and set to the default value.
+@param varname
+    Variable name as C++ identifier. It will be used as entry name and as variable pointer
+*/
+#define ResetConfigValue(varname) \
+    orxonox::resetConfigValueGeneric(this, &varname, #varname)
+
+
+/** Modifies a runtime configurable value by using a modifier and some arguments.
+    If the container for the value doesn't yet exist, a warning is displayed.
+    Also, the @a variable argument will be modified and set to the current value.
+@param object
+    Class instance that the config value should belong to (usually just 'this')
+@param variable
+    Pointer to the variable where the value should be written to
+@param entryName
+    Name of the entry in the ini file (e.g. [MySection] myValue)
+@param modifier
+    On of these functions: set, tset, add, remove, reset, update
+@param ...
+    Arguments for the modifier function
+*/
+#define ModifyConfigValueGeneric(object, variable, entryName, modifier, ...) \
+    if (orxonox::ConfigValueContainer* container = ClassByObjectType(object)->getConfigValueContainer(entryName)) \
+    { \
+        container->modifier(__VA_ARGS__); \
+        container->getValue(variable, object); \
+    } \
+    else \
+    { \
+        COUT(2) << "Warning: Couln't modify config-value '" << entryName << "' in class '" \
+                << ClassByObjectType(object)->getName() << "', corresponding container doesn't exist." << std::endl; \
+    }
+
+/** Modifies a runtime configurable value by using a modifier and some arguments.
+    If the container for the value doesn't yet exist, a warning is displayed.
+    Also, the @a varname argument will be modified and set to the current value.
+@param varname
+    Variable name as C++ identifier. It will be used as entry name and as variable pointer
+@param modifier
+    On of these functions: set, tset, add, remove, reset, update
+@param ...
+    Arguments for the modifier function
+*/
+#define ModifyConfigValue(varname, modifier, ...) \
+    ModifyConfigValueGeneric(this, &varname, #varname, modifier, __VA_ARGS__)
+
+#endif /* _ConfigValueIncludes_H__ */
Index: /code/branches/rocket2/src/libraries/core/ConsoleCommand.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/ConsoleCommand.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ConsoleCommand.cc	(revision 6952)
@@ -0,0 +1,72 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ConsoleCommand.h"
+
+namespace orxonox
+{
+    ConsoleCommand::ConsoleCommand(Functor* functor, const std::string& name) : Executor(functor, name)
+    {
+        this->accessLevel_ = AccessLevel::None;
+        this->argumentCompleter_[0] = 0;
+        this->argumentCompleter_[1] = 0;
+        this->argumentCompleter_[2] = 0;
+        this->argumentCompleter_[3] = 0;
+        this->argumentCompleter_[4] = 0;
+
+        this->keybindMode_ = KeybindMode::OnPress;
+        this->inputConfiguredParam_ = -1;
+    }
+
+    ConsoleCommand& ConsoleCommand::argumentCompleter(unsigned int param, ArgumentCompleter* completer)
+    {
+        if (param < 5)
+            this->argumentCompleter_[param] = completer;
+        else
+        {
+            COUT(2) << "Warning: Couldn't add autocompletion-function for param " << param << ": index out of bound." << std::endl;
+        }
+        return (*this);
+    }
+
+    ArgumentCompleter* ConsoleCommand::getArgumentCompleter(unsigned int param) const
+    {
+        if (param < 5)
+            return this->argumentCompleter_[param];
+        else
+            return 0;
+    }
+
+    void ConsoleCommand::createArgumentCompletionList(unsigned int param, const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4, const std::string& param5)
+    {
+        if (param < 5 && this->argumentCompleter_[param])
+            this->argumentList_ = (*this->argumentCompleter_[param])(param1, param2, param3, param4, param5);
+        else
+            this->argumentList_.clear();
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/ConsoleCommand.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ConsoleCommand.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ConsoleCommand.h	(revision 6952)
@@ -0,0 +1,157 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ConsoleCommand_H__
+#define _ConsoleCommand_H__
+
+#include "CorePrereqs.h"
+
+#include <boost/preprocessor/cat.hpp>
+
+#include "ArgumentCompletionFunctions.h"
+#include "CommandExecutor.h"
+#include "Executor.h"
+#include "Identifier.h"
+
+
+#define SetConsoleCommand(classname, function, bCreateShortcut) \
+    SetConsoleCommandGeneric(classname, function, #function, bCreateShortcut)
+#define SetConsoleCommandAlias(classname, function, name, bCreateShortcut) \
+    SetConsoleCommandGeneric(classname, function, name, bCreateShortcut)
+
+#define SetConsoleCommandGeneric(classname, function, name, bCreateShortcut) \
+    orxonox::ConsoleCommand& BOOST_PP_CAT(classname##function##consolecommand__, __LINE__) = orxonox::ClassIdentifier<classname>::getIdentifier(#classname)->addConsoleCommand(orxonox::createConsoleCommand(orxonox::createFunctor(&classname::function), name), bCreateShortcut)
+
+
+#define SetConsoleCommandShortcut(classname, function) \
+    SetConsoleCommandShortcutAliasGeneric(classname, function, #function)
+#define SetConsoleCommandShortcutAlias(classname, function, name) \
+    SetConsoleCommandShortcutAliasGeneric(classname, function, name)
+#define SetConsoleCommandShortcutAliasGeneric(classname, function, name) \
+    SetConsoleCommandShortcutGeneric(BOOST_PP_CAT(function##consolecommand__, __LINE__), orxonox::createConsoleCommand(orxonox::createFunctor(&classname::function), name))
+
+#define SetConsoleCommandShortcutExtern(function) \
+    SetConsoleCommandShortcutExternAliasGeneric(function, #function)
+#define SetConsoleCommandShortcutExternAlias(function, name) \
+    SetConsoleCommandShortcutExternAliasGeneric(function, name)
+#define SetConsoleCommandShortcutExternAliasGeneric(function, name) \
+    SetConsoleCommandShortcutGeneric(BOOST_PP_CAT(function##consolecommand__, __LINE__), orxonox::createConsoleCommand(orxonox::createFunctor(&function), name))
+
+#define SetConsoleCommandShortcutGeneric(fakevariable, command) \
+    orxonox::ConsoleCommand& fakevariable = orxonox::CommandExecutor::addConsoleCommandShortcut(command, true)
+
+
+namespace orxonox
+{
+    namespace AccessLevel
+    {
+        enum Value
+        {
+            None,
+            User,
+            Admin,
+            Offline,
+            Debug,
+            Disabled
+        };
+    }
+
+    class _CoreExport ConsoleCommand : public Executor
+    {
+        public:
+            ConsoleCommand(Functor* functor, const std::string& name = "");
+
+            inline ConsoleCommand& description(const std::string& description)
+                { this->Executor::setDescription(description); return (*this); }
+            inline ConsoleCommand& descriptionParam(int param, const std::string& description)
+                { this->Executor::setDescriptionParam(param, description); return (*this); }
+            inline ConsoleCommand& descriptionReturnvalue(const std::string& description)
+                { this->Executor::setDescriptionReturnvalue(description); return (*this); }
+            inline ConsoleCommand& defaultValues(const MultiType& param1)
+                { this->Executor::setDefaultValues(param1); return (*this); }
+            inline ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2)
+                { this->Executor::setDefaultValues(param1, param2); return (*this); }
+            inline ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3)
+                { this->Executor::setDefaultValues(param1, param2, param3); return (*this); }
+            inline ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4)
+                { this->Executor::setDefaultValues(param1, param2, param3, param4); return (*this); }
+            inline ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5)
+                { this->Executor::setDefaultValues(param1, param2, param3, param4, param5); return (*this); }
+            inline ConsoleCommand& defaultValue(unsigned int index, const MultiType& param)
+                { this->Executor::setDefaultValue(index, param); return (*this); }
+
+            inline ConsoleCommand& accessLevel(AccessLevel::Value level)
+                { this->accessLevel_ = level; return (*this); }
+            inline AccessLevel::Value getAccessLevel() const
+                { return this->accessLevel_; }
+
+            ConsoleCommand& argumentCompleter(unsigned int param, ArgumentCompleter* completer);
+            ArgumentCompleter* getArgumentCompleter(unsigned int param) const;
+
+            void createArgumentCompletionList(unsigned int param, const std::string& param1 = "", const std::string& param2 = "", const std::string& param3 = "", const std::string& param4 = "", const std::string& param5 = "");
+            const ArgumentCompletionList& getArgumentCompletionList() const
+                { return this->argumentList_; }
+            ArgumentCompletionList::const_iterator getArgumentCompletionListBegin() const
+                { return this->argumentList_.begin(); }
+            ArgumentCompletionList::const_iterator getArgumentCompletionListEnd() const
+                { return this->argumentList_.end(); }
+
+            inline ConsoleCommand& setAsInputCommand()
+            {
+                this->keybindMode(KeybindMode::OnHold);
+                this->defaultValue(0, Vector2(0.0f, 0.0f));
+                this->inputConfiguredParam(0);
+                return *this;
+            }
+
+            inline ConsoleCommand& keybindMode(KeybindMode::Value mode)
+                { this->keybindMode_ = mode; return *this; }
+            inline KeybindMode::Value getKeybindMode() const
+                { return this->keybindMode_; }
+
+            inline ConsoleCommand& inputConfiguredParam(int index)
+                { this->inputConfiguredParam_ = index; return *this; }
+            inline int getInputConfiguredParam_() const
+                { return this->inputConfiguredParam_; }
+
+        private:
+            AccessLevel::Value accessLevel_;
+            ArgumentCompleter* argumentCompleter_[5];
+            ArgumentCompletionList argumentList_;
+
+            KeybindMode::Value keybindMode_;
+            int inputConfiguredParam_;
+    };
+
+    inline ConsoleCommand* createConsoleCommand(Functor* functor, const std::string& name = "")
+    {
+        return new ConsoleCommand(functor, name);
+    }
+}
+
+#endif /* _ConsoleCommand_H__ */
Index: /code/branches/rocket2/src/libraries/core/ConsoleCommandCompilation.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/ConsoleCommandCompilation.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ConsoleCommandCompilation.cc	(revision 6952)
@@ -0,0 +1,181 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ConsoleCommandCompilation.h"
+
+#include <fstream>
+#include <set>
+#include <string>
+
+#include "util/Debug.h"
+#include "util/ExprParser.h"
+#include "util/StringUtils.h"
+#include "ConsoleCommand.h"
+
+namespace orxonox
+{
+    SetConsoleCommandShortcutExtern(source).argumentCompleter(0, autocompletion::files());
+    SetConsoleCommandShortcutExtern(echo);
+    SetConsoleCommandShortcutExtern(puts);
+
+    SetConsoleCommandShortcutExtern(read).argumentCompleter(0, autocompletion::files());
+    SetConsoleCommandShortcutExtern(append).argumentCompleter(0, autocompletion::files());
+    SetConsoleCommandShortcutExtern(write).argumentCompleter(0, autocompletion::files());
+
+    SetConsoleCommandShortcutExtern(calculate);
+
+    void source(const std::string& filename)
+    {
+        static std::set<std::string> executingFiles;
+
+        std::set<std::string>::const_iterator it = executingFiles.find(filename);
+        if (it != executingFiles.end())
+        {
+            COUT(1) << "Error: Recurring source command in \"" << filename << "\". Stopped execution." << std::endl;
+            return;
+        }
+
+        // Open the file
+        std::ifstream file;
+        file.open(filename.c_str(), std::fstream::in);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "Error: Couldn't open file \"" << filename << "\"." << std::endl;
+            return;
+        }
+
+        executingFiles.insert(filename);
+
+        // Iterate through the file and put the lines into the CommandExecutor
+        while (file.good() && !file.eof())
+        {
+            std::string line;
+            std::getline(file, line);
+            CommandExecutor::execute(line);
+        }
+
+        executingFiles.erase(filename);
+        file.close();
+    }
+
+    std::string echo(const std::string& text)
+    {
+        return text;
+    }
+
+    void puts(bool newline, const std::string& text)
+    {
+        if (newline)
+        {
+            COUT(0) << stripEnclosingBraces(text) << std::endl;
+        }
+        else
+        {
+            COUT(0) << stripEnclosingBraces(text);
+        }
+    }
+
+    void write(const std::string& filename, const std::string& text)
+    {
+        std::ofstream file;
+        file.open(filename.c_str(), std::fstream::out);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "Error: Couldn't write to file \"" << filename << "\"." << std::endl;
+            return;
+        }
+
+        file << text << std::endl;
+        file.close();
+    }
+
+    void append(const std::string& filename, const std::string& text)
+    {
+        std::ofstream file;
+        file.open(filename.c_str(), std::fstream::app);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "Error: Couldn't append to file \"" << filename << "\"." << std::endl;
+            return;
+        }
+
+        file << text << std::endl;
+        file.close();
+    }
+
+    std::string read(const std::string& filename)
+    {
+        std::ifstream file;
+        file.open(filename.c_str(), std::fstream::in);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "Error: Couldn't read from file \"" << filename << "\"." << std::endl;
+            return "";
+        }
+
+        std::string output;
+        while (file.good() && !file.eof())
+        {
+            std::string line;
+            std::getline(file, line);
+            output += line;
+            output += "\n";
+        }
+
+        file.close();
+
+        return output;
+    }
+
+    float calculate(const std::string& calculation)
+    {
+        ExprParser expr;
+        expr.parse(calculation);
+        if (expr.getSuccess())
+        {
+            if (expr.getResult() == 42.0)
+            {
+                COUT(3) << "Greetings from the restaurant at the end of the universe." << std::endl;
+            }
+            if (!expr.getRemains().empty())
+            {
+                COUT(2) << "Warning: Expression could not be parsed to the end! Remains: '" << expr.getRemains() << '\'' << std::endl;
+            }
+            return static_cast<float>(expr.getResult());
+        }
+        else
+        {
+            COUT(1) << "Error: Cannot calculate expression: Parse error." << std::endl;
+            return 0;
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/ConsoleCommandCompilation.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ConsoleCommandCompilation.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ConsoleCommandCompilation.h	(revision 6952)
@@ -0,0 +1,47 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ConsoleCommandCompilation_H__
+#define _ConsoleCommandCompilation_H__
+
+#include "CorePrereqs.h"
+
+namespace orxonox
+{
+    _CoreExport void source(const std::string& filename);
+    _CoreExport std::string echo(const std::string& text);
+    _CoreExport void puts(bool newline, const std::string& test);
+
+    _CoreExport void write(const std::string& filename, const std::string& text);
+    _CoreExport void append(const std::string& filename, const std::string& text);
+    _CoreExport std::string read(const std::string& filename);
+
+    _CoreExport float calculate(const std::string& calculation);
+}
+
+#endif /* _ConsoleCommandCompilation_H__ */
Index: /code/branches/rocket2/src/libraries/core/Core.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/Core.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Core.cc	(revision 6952)
@@ -0,0 +1,356 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of the Core singleton with its global variables (avoids boost include)
+*/
+
+#include "Core.h"
+
+#include <cassert>
+#include <vector>
+
+#ifdef ORXONOX_PLATFORM_WINDOWS
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif
+#  include <windows.h>
+#  undef min
+#  undef max
+#endif
+
+#include "util/Clock.h"
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/Scope.h"
+#include "util/SignalHandler.h"
+#include "PathConfig.h"
+#include "CommandExecutor.h"
+#include "CommandLineParser.h"
+#include "ConfigFileManager.h"
+#include "ConfigValueIncludes.h"
+#include "CoreIncludes.h"
+#include "DynLibManager.h"
+#include "GameMode.h"
+#include "GraphicsManager.h"
+#include "GUIManager.h"
+#include "Identifier.h"
+#include "Language.h"
+#include "IOConsole.h"
+#include "LuaState.h"
+#include "ScopedSingletonManager.h"
+#include "TclBind.h"
+#include "TclThreadManager.h"
+#include "input/InputManager.h"
+
+namespace orxonox
+{
+    //! Static pointer to the singleton
+    Core* Core::singletonPtr_s  = 0;
+
+    SetCommandLineArgument(settingsFile, "orxonox.ini").information("THE configuration file");
+    SetCommandLineSwitch(noIOConsole).information("Use this if you don't want to use the IOConsole (for instance for Lua debugging)");
+#ifdef ORXONOX_PLATFORM_WINDOWS
+    SetCommandLineArgument(limitToCPU, 1).information("Limits the program to one CPU/core (1, 2, 3, etc.). Default is the first core (faster than off)");
+#endif
+
+    Core::Core(const std::string& cmdLine)
+        // Cleanup guard for identifier destruction (incl. XMLPort, configValues, consoleCommands)
+        : identifierDestroyer_(Identifier::destroyAllIdentifiers)
+        // Cleanup guard for external console commands that don't belong to an Identifier
+        , consoleCommandDestroyer_(CommandExecutor::destroyExternalCommands)
+        , bGraphicsLoaded_(false)
+        , bStartIOConsole_(true)
+    {
+        // Set the hard coded fixed paths
+        this->pathConfig_.reset(new PathConfig());
+
+        // Create a new dynamic library manager
+        this->dynLibManager_.reset(new DynLibManager());
+
+        // Load modules
+        const std::vector<std::string>& modulePaths = this->pathConfig_->getModulePaths();
+        for (std::vector<std::string>::const_iterator it = modulePaths.begin(); it != modulePaths.end(); ++it)
+        {
+            try
+            {
+                this->dynLibManager_->load(*it);
+            }
+            catch (...)
+            {
+                COUT(1) << "Couldn't load module \"" << *it << "\": " << Exception::handleMessage() << std::endl;
+            }
+        }
+
+        // Parse command line arguments AFTER the modules have been loaded (static code!)
+        CommandLineParser::parseCommandLine(cmdLine);
+
+        // Set configurable paths like log, config and media
+        this->pathConfig_->setConfigurablePaths();
+
+        // create a signal handler (only active for Linux)
+        // This call is placed as soon as possible, but after the directories are set
+        this->signalHandler_.reset(new SignalHandler());
+        this->signalHandler_->doCatch(PathConfig::getExecutablePathString(), PathConfig::getLogPathString() + "orxonox_crash.log");
+
+        // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% (Windows) was used
+        OutputHandler::getInstance().setLogPath(PathConfig::getLogPathString());
+
+        // Parse additional options file now that we know its path
+        CommandLineParser::parseFile();
+
+#ifdef ORXONOX_PLATFORM_WINDOWS
+        // limit the main thread to the first core so that QueryPerformanceCounter doesn't jump
+        // do this after ogre has initialised. Somehow Ogre changes the settings again (not through
+        // the timer though).
+        int limitToCPU = CommandLineParser::getValue("limitToCPU");
+        if (limitToCPU > 0)
+            setThreadAffinity(static_cast<unsigned int>(limitToCPU));
+#endif
+
+        // Manage ini files and set the default settings file (usually orxonox.ini)
+        this->configFileManager_.reset(new ConfigFileManager());
+        this->configFileManager_->setFilename(ConfigFileType::Settings,
+            CommandLineParser::getValue("settingsFile").getString());
+
+        // Required as well for the config values
+        this->languageInstance_.reset(new Language());
+
+        // Do this soon after the ConfigFileManager has been created to open up the
+        // possibility to configure everything below here
+        ClassIdentifier<Core>::getIdentifier("Core")->initialiseObject(this, "Core", true);
+        this->setConfigValues();
+
+        // create persistent io console
+        if (CommandLineParser::getValue("noIOConsole").getBool())
+        {
+            ModifyConfigValue(bStartIOConsole_, tset, false);
+        }
+        if (this->bStartIOConsole_)
+            this->ioConsole_.reset(new IOConsole());
+
+        // creates the class hierarchy for all classes with factories
+        Identifier::createClassHierarchy();
+
+        // Load OGRE excluding the renderer and the render window
+        this->graphicsManager_.reset(new GraphicsManager(false));
+
+        // initialise Tcl
+        this->tclBind_.reset(new TclBind(PathConfig::getDataPathString()));
+        this->tclThreadManager_.reset(new TclThreadManager(tclBind_->getTclInterpreter()));
+
+        // Create singletons that always exist (in other libraries)
+        this->rootScope_.reset(new Scope<ScopeID::Root>());
+    }
+
+    /**
+    @brief
+        All destruction code is handled by scoped_ptrs and ScopeGuards.
+    */
+    Core::~Core()
+    {
+        // Remove us from the object lists again to avoid problems when destroying them
+        this->unregisterObject();
+    }
+
+    //! Function to collect the SetConfigValue-macro calls.
+    void Core::setConfigValues()
+    {
+#ifdef ORXONOX_RELEASE
+        const unsigned int defaultLevelLogFile = 3;
+#else
+        const unsigned int defaultLevelLogFile = 4;
+#endif
+        setConfigValueGeneric(this, &this->softDebugLevelLogFile_, ConfigFileType::Settings, "OutputHandler", "softDebugLevelLogFile", defaultLevelLogFile)
+            .description("The maximum level of debug output shown in the log file");
+        OutputHandler::getInstance().setSoftDebugLevel(OutputHandler::logFileOutputListenerName_s, this->softDebugLevelLogFile_);
+
+        SetConfigValue(language_, Language::getInstance().defaultLanguage_)
+            .description("The language of the in game text")
+            .callback(this, &Core::languageChanged);
+        SetConfigValue(bInitRandomNumberGenerator_, true)
+            .description("If true, all random actions are different each time you start the game")
+            .callback(this, &Core::initRandomNumberGenerator);
+        SetConfigValue(bStartIOConsole_, true)
+            .description("Set to false if you don't want to use the IOConsole (for Lua debugging for instance)");
+    }
+
+    //! Callback function if the language has changed.
+    void Core::languageChanged()
+    {
+        // Read the translation file after the language was configured
+        Language::getInstance().readTranslatedLanguageFile();
+    }
+
+    void Core::initRandomNumberGenerator()
+    {
+        static bool bInitialized = false;
+        if (!bInitialized && this->bInitRandomNumberGenerator_)
+        {
+            srand(static_cast<unsigned int>(time(0)));
+            rand();
+            bInitialized = true;
+        }
+    }
+
+    void Core::loadGraphics()
+    {
+        // Any exception should trigger this, even in upgradeToGraphics (see its remarks)
+        Loki::ScopeGuard unloader = Loki::MakeObjGuard(*this, &Core::unloadGraphics);
+
+        // Upgrade OGRE to receive a render window
+        graphicsManager_->upgradeToGraphics();
+
+        // Calls the InputManager which sets up the input devices.
+        inputManager_.reset(new InputManager());
+
+        // Load the CEGUI interface
+        guiManager_.reset(new GUIManager(inputManager_->getMousePosition()));
+
+        bGraphicsLoaded_ = true;
+        GameMode::bShowsGraphics_s = true;
+
+        // Load some sort of a debug overlay (only denoted by its name, "debug.oxo")
+        graphicsManager_->loadDebugOverlay();
+
+        // Create singletons associated with graphics (in other libraries)
+        graphicsScope_.reset(new Scope<ScopeID::Graphics>());
+
+        unloader.Dismiss();
+    }
+
+    void Core::unloadGraphics()
+    {
+        this->graphicsScope_.reset();
+        this->guiManager_.reset();
+        this->inputManager_.reset();
+        this->graphicsManager_.reset();
+
+        // Load Ogre::Root again, but without the render system
+        try
+            { this->graphicsManager_.reset(new GraphicsManager(false)); }
+        catch (...)
+        {
+            COUT(0) << "An exception occurred during 'unloadGraphics':" << Exception::handleMessage() << std::endl
+                    << "Another exception might be being handled which may lead to undefined behaviour!" << std::endl
+                    << "Terminating the program." << std::endl;
+            abort();
+        }
+
+        bGraphicsLoaded_ = false;
+        GameMode::bShowsGraphics_s = false;
+    }
+
+    //! Sets the language in the config-file back to the default.
+    void Core::resetLanguage()
+    {
+        ResetConfigValue(language_);
+    }
+
+    /**
+    @note
+        The code of this function has been copied and adjusted from OGRE, an open source graphics engine.
+            (Object-oriented Graphics Rendering Engine)
+        For the latest info, see http://www.ogre3d.org/
+
+        Copyright (c) 2000-2008 Torus Knot Software Ltd
+
+        OGRE is licensed under the LGPL. For more info, see OGRE license.
+    */
+    void Core::setThreadAffinity(int limitToCPU)
+    {
+#ifdef ORXONOX_PLATFORM_WINDOWS
+
+        if (limitToCPU <= 0)
+            return;
+
+        unsigned int coreNr = limitToCPU - 1;
+        // Get the current process core mask
+        DWORD procMask;
+        DWORD sysMask;
+#  if _MSC_VER >= 1400 && defined (_M_X64)
+        GetProcessAffinityMask(GetCurrentProcess(), (PDWORD_PTR)&procMask, (PDWORD_PTR)&sysMask);
+#  else
+        GetProcessAffinityMask(GetCurrentProcess(), &procMask, &sysMask);
+#  endif
+
+        // If procMask is 0, consider there is only one core available
+        // (using 0 as procMask will cause an infinite loop below)
+        if (procMask == 0)
+            procMask = 1;
+
+        // if the core specified with coreNr is not available, take the lowest one
+        if (!(procMask & (1 << coreNr)))
+            coreNr = 0;
+
+        // Find the lowest core that this process uses and coreNr suggests
+        DWORD threadMask = 1;
+        while ((threadMask & procMask) == 0 || (threadMask < (1u << coreNr)))
+            threadMask <<= 1;
+
+        // Set affinity to the first core
+        SetThreadAffinityMask(GetCurrentThread(), threadMask);
+#endif
+    }
+
+    void Core::preUpdate(const Clock& time)
+    {
+        // Update singletons before general ticking
+        ScopedSingletonManager::preUpdate<ScopeID::Root>(time);
+        if (this->bGraphicsLoaded_)
+        {
+            // Process input events
+            this->inputManager_->preUpdate(time);
+            // Update GUI
+            this->guiManager_->preUpdate(time);
+            // Update singletons before general ticking
+            ScopedSingletonManager::preUpdate<ScopeID::Graphics>(time);
+        }
+        // Process console events and status line
+        if (this->ioConsole_ != NULL)
+            this->ioConsole_->preUpdate(time);
+        // Process thread commands
+        this->tclThreadManager_->preUpdate(time);
+    }
+
+    void Core::postUpdate(const Clock& time)
+    {
+        // Update singletons just before rendering
+        ScopedSingletonManager::postUpdate<ScopeID::Root>(time);
+        if (this->bGraphicsLoaded_)
+        {
+            // Update singletons just before rendering
+            ScopedSingletonManager::postUpdate<ScopeID::Graphics>(time);
+            // Render (doesn't throw)
+            this->graphicsManager_->postUpdate(time);
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/Core.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Core.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Core.h	(revision 6952)
@@ -0,0 +1,116 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Core_H__
+#define _Core_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include <string>
+#include <boost/scoped_ptr.hpp>
+#include "util/ScopeGuard.h"
+#include "util/Singleton.h"
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        The Core class is a singleton used to configure the program basics.
+    @remark
+        You should only create this singleton once because it destroys the identifiers!
+    */
+    class _CoreExport Core : public Singleton<Core>, public OrxonoxClass
+    {
+        typedef Loki::ScopeGuardImpl0<void (*)()> SimpleScopeGuard;
+        friend class Singleton<Core>;
+        friend class Game;
+
+        public:
+            /**
+            @brief
+                Determines the executable path, checks for build directory runs, creates
+                the output directories and sets up the other core library singletons.
+            @throws
+                GeneralException
+            */
+            Core(const std::string& cmdLine);
+            ~Core();
+
+            void setConfigValues();
+
+            //! Returns the configured language.
+            const std::string& getLanguage()
+                { return this->language_; }
+            void resetLanguage();
+
+        private:
+            Core(const Core&); //!< Don't use (undefined symbol)
+
+            void languageChanged();
+            void initRandomNumberGenerator();
+
+            void preUpdate(const Clock& time);
+            void postUpdate(const Clock& time);
+
+            void loadGraphics();
+            void unloadGraphics();
+
+            void setThreadAffinity(int limitToCPU);
+            // MANAGED SINGLETONS/OBJECTS
+            // Mind the order for the destruction!
+            scoped_ptr<PathConfig>        pathConfig_;
+            scoped_ptr<DynLibManager>     dynLibManager_;
+            scoped_ptr<SignalHandler>     signalHandler_;
+            SimpleScopeGuard              identifierDestroyer_;
+            SimpleScopeGuard              consoleCommandDestroyer_;
+            scoped_ptr<ConfigFileManager> configFileManager_;
+            scoped_ptr<Language>          languageInstance_;
+            scoped_ptr<IOConsole>         ioConsole_;
+            scoped_ptr<TclBind>           tclBind_;
+            scoped_ptr<TclThreadManager>  tclThreadManager_;
+            scoped_ptr<Scope<ScopeID::Root> > rootScope_;
+            // graphical
+            scoped_ptr<GraphicsManager>   graphicsManager_;     //!< Interface to OGRE
+            scoped_ptr<InputManager>      inputManager_;        //!< Interface to OIS
+            scoped_ptr<GUIManager>        guiManager_;          //!< Interface to GUI
+            scoped_ptr<Scope<ScopeID::Graphics> > graphicsScope_;
+
+            bool                          bGraphicsLoaded_;
+            int                           softDebugLevelLogFile_;      //!< The debug level for the log file (belongs to OutputHandler)
+            std::string                   language_;                   //!< The language
+            bool                          bInitRandomNumberGenerator_; //!< If true, srand(time(0)) is called
+            bool                          bStartIOConsole_;            //!< Set to false if you don't want to use the IOConsole
+
+            static Core*                  singletonPtr_s;
+    };
+}
+
+#endif /* _Core_H__ */
Index: /code/branches/rocket2/src/libraries/core/CoreIncludes.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/CoreIncludes.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/CoreIncludes.h	(revision 6952)
@@ -0,0 +1,141 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of macros for Identifiers
+
+    Every class needs the RegisterObject(class) macro in its constructor. If the class is an interface
+    or the BaseObject itself, it needs the macro RegisterRootObject(class) instead.
+
+    To allow the object being created through the factory, use the CreateFactory(class) macro outside
+    the of the class implementation, so it gets executed before main().
+*/
+
+#ifndef _CoreIncludes_H__
+#define _CoreIncludes_H__
+
+#include "CorePrereqs.h"
+
+#include "util/Debug.h"
+#include "Identifier.h"
+#include "SubclassIdentifier.h"
+#include "ClassFactory.h"
+#include "ObjectList.h"
+
+
+/**
+    @brief Intern macro, containing the common parts of RegisterObject and RegisterRootObject.
+    @param ClassName The name of the class
+    @param bRootClass True if the class is directly derived from OrxonoxClass
+*/
+#define InternRegisterObject(ClassName, bRootClass) \
+    if (ClassIdentifier<ClassName>::getIdentifier(#ClassName)->initialiseObject(this, #ClassName, bRootClass)) \
+        return; \
+    else \
+        ((void)0)
+
+/**
+    @brief RegisterObject - with and without debug output.
+    @param ClassName The name of the class
+*/
+#define RegisterObject(ClassName) \
+    InternRegisterObject(ClassName, false)
+
+/**
+    @brief RegisterRootObject - with and without debug output.
+    @param ClassName The name of the class
+*/
+#define RegisterRootObject(ClassName) \
+    InternRegisterObject(ClassName, true)
+
+/**
+    @brief Creates the Factory.
+    @param ClassName The name of the class
+*/
+#define CreateFactory(ClassName) \
+    Factory* _##ClassName##Factory = new orxonox::ClassFactory<ClassName>(#ClassName, true)
+
+/**
+    @brief Creates the Factory for classes which should not be loaded through XML.
+    @param ClassName The name of the class
+*/
+#define CreateUnloadableFactory(ClassName) \
+    Factory* _##ClassName##Factory = new orxonox::ClassFactory<ClassName>(#ClassName, false)
+
+/**
+    @brief Returns the Identifier of the given class.
+    @param ClassName The name of the class
+*/
+#define Class(ClassName) \
+    orxonox::ClassIdentifier<ClassName>::getIdentifier()
+
+
+namespace orxonox
+{
+    /**
+        @brief Returns the Identifier with a given name.
+        @param String The name of the class
+    */
+    inline Identifier* ClassByString(const std::string& name)
+    {
+        return Identifier::getIdentifierByString(name);
+    }
+
+    /**
+        @brief Returns the Identifier with a given lowercase name.
+        @param String The lowercase name of the class
+    */
+    inline Identifier* ClassByLowercaseString(const std::string& name)
+    {
+        return Identifier::getIdentifierByLowercaseString(name);
+    }
+
+    /**
+        @brief Returns the Identifier with a given network ID.
+        @param networkID The network ID of the class
+    */
+    inline Identifier* ClassByID(uint32_t id)
+    {
+        return Identifier::getIdentifierByID(id);
+    }
+
+    /**
+        @brief Returns the Identifier with a given 'this' pointer.
+        @note This of course only works with OrxonoxClasses.
+              The only use is in conjunction with macros that don't know the class type.
+        @param Pointer to an OrxonoxClass
+    */
+    template <class T>
+    inline Identifier* ClassByObjectType(const T* object)
+    {
+        return ClassIdentifier<T>::getIdentifier();
+    }
+}
+
+#endif /* _CoreIncludes_H__ */
Index: /code/branches/rocket2/src/libraries/core/CorePrecompiledHeaders.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/CorePrecompiledHeaders.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/CorePrecompiledHeaders.h	(revision 6952)
@@ -0,0 +1,86 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Compilation of the most often used header files in the core library
+@details
+    Updated: 13. September 2009
+    Total Files: 56
+*/
+
+#include "OrxonoxConfig.h"
+
+///////////////////////////////////////////
+/////          Stable Headers         /////
+///////////////////////////////////////////
+
+#include <string>   // 54
+#include <vector>   // 54
+#include <cassert>  // 53
+#include <fstream>  // 53
+#include <iostream> // 53
+#include <map>      // 53
+#include <sstream>  // 53
+#include <set>      // 50
+
+#include "util/Debug.h" // 48
+
+#include <deque>    // 43
+#include <list>     // 44
+#include <cmath>    // 42
+
+#include "util/ScopeGuard.h" // 38
+
+#include <OgreMath.h>        // 36
+#include <OgreVector2.h>     // 36
+#include <OgreVector3.h>     // 36
+#include <OgreVector4.h>     // 36
+#include <OgreQuaternion.h>  // 36
+#include <OgreColourValue.h> // 36
+#include <boost/preprocessor/cat.hpp> // 27
+#include <boost/shared_ptr.hpp> // 21
+
+#ifdef ORXONOX_COMPILER_MSVC
+
+#include <ois/OISKeyboard.h> // 15
+#include <ois/OISMouse.h>    // 15
+#include <ois/OISJoyStick.h> // 15
+
+#include "util/SubString.h"  // 14
+
+#include <boost/scoped_ptr.hpp> // 13
+#include <stack> // 12
+
+#endif /*ORXONOX_COMPILER_MSVC */
+
+
+// Just in case some header included windows.h
+#undef min
+#undef max
Index: /code/branches/rocket2/src/libraries/core/CorePrereqs.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/CorePrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/CorePrereqs.h	(revision 6952)
@@ -0,0 +1,315 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Shared library macros, enums, constants and forward declarations for the core library
+*/
+
+#ifndef _CorePrereqs_H__
+#define _CorePrereqs_H__
+
+#include "OrxonoxConfig.h"
+
+//-----------------------------------------------------------------------
+// Shared library settings
+//-----------------------------------------------------------------------
+
+#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined( CORE_STATIC_BUILD )
+#  ifdef CORE_SHARED_BUILD
+#    define _CoreExport __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define _CoreExport
+#    else
+#      define _CoreExport __declspec(dllimport)
+#    endif
+#  endif
+#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _CoreExport  __attribute__ ((visibility("default")))
+#else
+#  define _CoreExport
+#endif
+
+//-----------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    static const uint32_t OBJECTID_UNKNOWN = static_cast<uint32_t>(-1);
+}
+
+//-----------------------------------------------------------------------
+// Enums
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    namespace XMLPort
+    {
+        enum Mode
+        {
+            NOP,
+            LoadObject,
+            SaveObject,
+            ExpandObject
+        };
+    }
+
+    namespace ConfigFileType
+    {
+        enum Value
+        {
+            Settings,
+            JoyStickCalibration,
+            CommandHistory
+            // Don't forget to adjust the array size in the ConfigFileManager when adding a new entry here!
+        };
+    }
+
+    namespace KeybindMode
+    {
+        enum Value
+        {
+            OnPress,
+            OnHold,
+            OnRelease,
+            None
+        };
+    };
+}
+
+//-----------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    typedef std::string LanguageEntryLabel;
+
+    class ArgumentCompleter;
+    class ArgumentCompletionListElement;
+    class BaseObject;
+    template <class T>
+    class ClassFactory;
+    template <class T>
+    class ClassIdentifier;
+    class ClassTreeMask;
+    class ClassTreeMaskIterator;
+    class ClassTreeMaskNode;
+    class ClassTreeMaskObjectIterator;
+    class CommandEvaluation;
+    class CommandLineParser;
+    class CommandLineArgument;
+    class ConfigFile;
+    class ConfigFileEntry;
+    class ConfigFileEntryComment;
+    class ConfigFileEntryValue;
+    class ConfigFileManager;
+    class ConfigFileSection;
+    class ConfigValueContainer;
+    class ConsoleCommand;
+    class Core;
+    class DynLib;
+    class DynLibManager;
+    struct Event;
+    class EventState;
+    class Executor;
+    template <class T>
+    class ExecutorMember;
+    class ExecutorStatic;
+    class Factory;
+    class Functor;
+    template <class T>
+    class FunctorMember;
+    class FunctorStatic;
+    class Game;
+    class GameState;
+    struct GameStateInfo;
+    struct GameStateTreeNode;
+    class GraphicsManager;
+    class GUIManager;
+    class Identifier;
+    class IOConsole;
+    class IRC;
+    template <class T>
+    class Iterator;
+    class Language;
+    class LuaState;
+    class MemoryArchive;
+    class MemoryArchiveFactory;
+    class MetaObjectList;
+    class MetaObjectListElement;
+    class Namespace;
+    class NamespaceNode;
+    template <class T>
+    class ObjectList;
+    class ObjectListBase;
+    class ObjectListBaseElement;
+    template <class T>
+    class ObjectListElement;
+    template <class T>
+    class ObjectListIterator;
+    class OgreWindowEventListener;
+    class OrxonoxClass;
+    class PathConfig;
+    struct ResourceInfo;
+    class SettingsConfigFile;
+    class Shell;
+    class ShellListener;
+    template <class T>
+    class SmartPtr;
+    template <class T>
+    class SubclassIdentifier;
+    class TclBind;
+    struct TclInterpreterBundle;
+    template <class T>
+    class TclThreadList;
+    class TclThreadManager;
+    class Template;
+    class Thread;
+    class ThreadPool;
+    template <class T>
+    class WeakPtr;
+    class WindowEventListener;
+    class XMLFile;
+    class XMLNameListener;
+    template <class T, class O>
+    class XMLPortClassObjectContainer;
+    template <class T>
+    class XMLPortClassParamContainer;
+    class XMLPortObjectContainer;
+    class XMLPortParamContainer;
+
+    // Input
+    class BaseCommand;
+    class BufferedParamCommand;
+    class Button;
+    class HalfAxis;
+    class InputBuffer;
+    class InputDevice;
+    template <class Traits>
+    class InputDeviceTemplated;
+    class InputHandler;
+    class InputManager;
+    class InputState;
+    struct InputStatePriority;
+    class JoyStickQuantityListener;
+    class JoyStick;
+    class KeyBinder;
+    class KeyBinderManager;
+    class Keyboard;
+    class KeyDetector;
+    class KeyEvent;
+    class Mouse;
+    class ParamCommand;
+    class SimpleCommand;
+}
+
+// CppTcl
+namespace Tcl
+{
+    class interpreter;
+    class object;
+}
+
+// Boost
+namespace boost
+{
+    namespace filesystem
+    {
+        struct path_traits;
+        template <class String, class Traits> class basic_path;
+        typedef basic_path<std::string, path_traits> path;
+    }
+    class thread;
+    class mutex;
+    class shared_mutex;
+    class condition_variable;
+}
+
+// Ogre
+namespace Ogre
+{
+    class DataStream;
+    template <class T> class SharedPtr;
+    typedef SharedPtr<DataStream> DataStreamPtr;
+}
+namespace orxonox
+{
+    // Import the Ogre::DataStream
+    using Ogre::DataStream;
+    using Ogre::DataStreamPtr;
+}
+
+// CEGUI
+namespace CEGUI
+{
+    class DefaultLogger;
+    class Logger;
+    class LuaScriptModule;
+
+    class OgreCEGUIRenderer;
+    class OgreCEGUIResourceProvider;
+    class OgreCEGUITexture;
+}
+
+// Lua
+struct lua_State;
+
+// TinyXML and TinyXML++
+class TiXmlString;
+class TiXmlOutStream;
+class TiXmlNode;
+class TiXmlHandle;
+class TiXmlDocument;
+class TiXmlElement;
+class TiXmlComment;
+class TiXmlUnknown;
+class TiXmlAttribute;
+class TiXmlText;
+class TiXmlDeclaration;
+class TiXmlParsingData;
+namespace ticpp
+{
+    class Document;
+    class Element;
+    class Declaration;
+    class StylesheetReference;
+    class Text;
+    class Comment;
+    class Attribute;
+}
+namespace orxonox
+{
+    using ticpp::Element;
+}
+
+#endif /* _CorePrereqs_H__ */
Index: /code/branches/rocket2/src/libraries/core/DynLib.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/DynLib.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/DynLib.cc	(revision 6952)
@@ -0,0 +1,138 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2006 Torus Knot Software Ltd
+Also see acknowledgements in Readme.html
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA, or go to
+http://www.gnu.org/copyleft/lesser.txt.
+
+You may alternatively use this source under the terms of a specific version of
+the OGRE Unrestricted License provided you have obtained such a license from
+Torus Knot Software Ltd.
+-----------------------------------------------------------------------------
+*/
+
+// 08/11/2009: Small adjustments for Orxonox by Fabian 'x3n' Landau
+
+#include "DynLib.h"
+
+#include "util/Exception.h"
+
+#ifdef ORXONOX_PLATFORM_WINDOWS
+#  define WIN32_LEAN_AND_MEAN
+#  ifndef NOMINMAX
+#    define NOMINMAX // required to stop windows.h messing up std::min
+#  endif
+#  include <windows.h>
+#endif
+
+#ifdef ORXONOX_PLATFORM_LINUX
+#  include <dlfcn.h>
+#endif
+
+#ifdef ORXONOX_PLATFORM_APPLE
+#  include <macPlugins.h>
+#endif
+
+namespace orxonox
+{
+    //-----------------------------------------------------------------------
+    DynLib::DynLib( const std::string& name )
+    {
+        mName = name;
+        m_hInst = NULL;
+    }
+
+    //-----------------------------------------------------------------------
+    DynLib::~DynLib()
+    {
+    }
+
+    //-----------------------------------------------------------------------
+    void DynLib::load()
+    {
+        // Log library load
+        COUT(2) << "Loading module " << mName << std::endl;
+
+        std::string name = mName;
+#ifdef ORXONOX_PLATFORM_LINUX
+        // dlopen() does not add .so to the filename, like windows does for .dll
+        if (name.substr(name.length() - 3, 3) != ".so")
+           name += ".so";
+#endif
+
+        m_hInst = (DYNLIB_HANDLE)DYNLIB_LOAD( name.c_str() );
+
+        if (!m_hInst)
+            ThrowException(
+                General,
+                "Could not load dynamic library " + mName +
+                ".  System Error: " + dynlibError());
+    }
+
+    //-----------------------------------------------------------------------
+    void DynLib::unload()
+    {
+        // Log library unload
+        COUT(4) << "Unloading module " << mName << std::endl;
+
+        if (DYNLIB_UNLOAD( m_hInst ))
+        {
+            ThrowException(
+                General,
+                "Could not unload dynamic library " + mName +
+                ".  System Error: " + dynlibError());
+        }
+
+    }
+
+    //-----------------------------------------------------------------------
+    void* DynLib::getSymbol( const std::string& strName ) const throw()
+    {
+        return (void*)DYNLIB_GETSYM( m_hInst, strName.c_str() );
+    }
+    //-----------------------------------------------------------------------
+    std::string DynLib::dynlibError( void )
+    {
+#if defined(ORXONOX_PLATFORM_WINDOWS)
+        LPVOID lpMsgBuf;
+        FormatMessage(
+            FORMAT_MESSAGE_ALLOCATE_BUFFER |
+            FORMAT_MESSAGE_FROM_SYSTEM |
+            FORMAT_MESSAGE_IGNORE_INSERTS,
+            NULL,
+            GetLastError(),
+            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+            (LPTSTR) &lpMsgBuf,
+            0,
+            NULL
+            );
+        std::string ret = (char*)lpMsgBuf;
+        // Free the buffer.
+        LocalFree( lpMsgBuf );
+        return ret;
+#elif defined(ORXONOX_PLATFORM_LINUX)
+        return std::string(dlerror());
+#elif defined(ORXONOX_PLATFORM_APPLE)
+        return std::string(mac_errorBundle());
+#else
+        return "";
+#endif
+    }
+
+}
Index: /code/branches/rocket2/src/libraries/core/DynLib.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/DynLib.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/DynLib.h	(revision 6952)
@@ -0,0 +1,121 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2006 Torus Knot Software Ltd
+Also see acknowledgements in Readme.html
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA, or go to
+http://www.gnu.org/copyleft/lesser.txt.
+
+You may alternatively use this source under the terms of a specific version of
+the OGRE Unrestricted License provided you have obtained such a license from
+Torus Knot Software Ltd.
+-----------------------------------------------------------------------------
+*/
+
+// 08/11/2009: Small adjustments for Orxonox by Fabian 'x3n' Landau
+
+#ifndef _Core_DynLib_H__
+#define _Core_DynLib_H__
+
+#include "CorePrereqs.h"
+
+#include <string>
+
+#if defined(ORXONOX_PLATFORM_WINDOWS)
+#    define DYNLIB_HANDLE hInstance
+#    define DYNLIB_LOAD( a ) LoadLibraryEx( a, NULL, LOAD_WITH_ALTERED_SEARCH_PATH )
+#    define DYNLIB_GETSYM( a, b ) GetProcAddress( a, b )
+#    define DYNLIB_UNLOAD( a ) !FreeLibrary( a )
+
+struct HINSTANCE__;
+typedef struct HINSTANCE__* hInstance;
+
+#elif defined(ORXONOX_PLATFORM_LINUX)
+#    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
+
+namespace orxonox
+{
+    /** Resource holding data about a dynamic library.
+        @remarks
+            This class holds the data required to get symbols from
+            libraries loaded at run-time (i.e. from DLL's for so's)
+        @author
+            Adrian Cearnãu (cearny@cearny.ro)
+        @since
+            27 January 2002
+        @see
+            Resource
+    */
+    class _CoreExport DynLib
+    {
+    protected:
+        std::string mName;
+        /// Gets the last loading error
+        std::string dynlibError(void);
+    public:
+        /** Default constructor - used by DynLibManager.
+            @warning
+                Do not call directly
+        */
+        DynLib( const std::string& name );
+
+        /** Default destructor.
+        */
+        ~DynLib();
+
+        /** Load the library
+        */
+        void load();
+        /** Unload the library
+        */
+        void unload();
+        /// Get the name of the library
+        const std::string& getName(void) const { return mName; }
+
+        /**
+            Returns the address of the given symbol from the loaded library.
+            @param
+                strName The name of the symbol to search for
+            @returns
+                If the function succeeds, the returned value is a handle to
+                the symbol.
+            @par
+                If the function fails, the returned value is <b>NULL</b>.
+
+        */
+        void* getSymbol( const std::string& strName ) const throw();
+
+    protected:
+
+        /// Handle to the loaded library.
+        DYNLIB_HANDLE m_hInst;
+    };
+
+}
+
+#endif /* _Core_DynLib_H__ */
Index: /code/branches/rocket2/src/libraries/core/DynLibManager.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/DynLibManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/DynLibManager.cc	(revision 6952)
@@ -0,0 +1,86 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2006 Torus Knot Software Ltd
+Also see acknowledgements in Readme.html
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA, or go to
+http://www.gnu.org/copyleft/lesser.txt.
+
+You may alternatively use this source under the terms of a specific version of
+the OGRE Unrestricted License provided you have obtained such a license from
+Torus Knot Software Ltd.
+-----------------------------------------------------------------------------
+*/
+
+// 08/11/2009: Small adjustments for Orxonox by Fabian 'x3n' Landau
+
+#include "DynLibManager.h"
+
+#include "DynLib.h"
+
+namespace orxonox
+{
+    //-----------------------------------------------------------------------
+    //! Static pointer to the singleton
+    DynLibManager* DynLibManager::singletonPtr_s  = 0;
+
+    //-----------------------------------------------------------------------
+    DynLibManager::DynLibManager()
+    {
+    }
+    //-----------------------------------------------------------------------
+    DynLib* DynLibManager::load( const std::string& filename)
+    {
+        DynLibList::iterator i = mLibList.find(filename);
+        if (i != mLibList.end())
+        {
+            return i->second;
+        }
+        else
+        {
+            DynLib* pLib = new DynLib(filename);
+            pLib->load();
+            mLibList[filename] = pLib;
+            return pLib;
+        }
+    }
+    //-----------------------------------------------------------------------
+    void DynLibManager::unload(DynLib* lib)
+    {
+        DynLibList::iterator i = mLibList.find(lib->getName());
+        if (i != mLibList.end())
+        {
+            mLibList.erase(i);
+        }
+        lib->unload();
+        delete lib;
+    }
+    //-----------------------------------------------------------------------
+    DynLibManager::~DynLibManager()
+    {
+        // Unload & delete resources in turn
+        for (DynLibList::iterator it = mLibList.begin(); it != mLibList.end(); ++it)
+        {
+            it->second->unload();
+            delete it->second;
+        }
+
+        // Empty the list
+        mLibList.clear();
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/DynLibManager.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/DynLibManager.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/DynLibManager.h	(revision 6952)
@@ -0,0 +1,90 @@
+/*
+-----------------------------------------------------------------------------
+This source file is part of OGRE
+    (Object-oriented Graphics Rendering Engine)
+For the latest info, see http://www.ogre3d.org/
+
+Copyright (c) 2000-2006 Torus Knot Software Ltd
+Also see acknowledgements in Readme.html
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along with
+this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+Place - Suite 330, Boston, MA 02111-1307, USA, or go to
+http://www.gnu.org/copyleft/lesser.txt.
+
+You may alternatively use this source under the terms of a specific version of
+the OGRE Unrestricted License provided you have obtained such a license from
+Torus Knot Software Ltd.
+-----------------------------------------------------------------------------
+*/
+
+// 08/11/2009: Small adjustments for Orxonox by Fabian 'x3n' Landau
+
+#ifndef _Core_DynLibManager_H__
+#define _Core_DynLibManager_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <string>
+#include "util/Singleton.h"
+
+namespace orxonox
+{
+    /** Manager for Dynamic-loading Libraries.
+        @remarks
+            This manager keeps a track of all the open dynamic-loading
+            libraries, opens them and returns references to already-open
+            libraries.
+    */
+    class _CoreExport DynLibManager: public Singleton<DynLibManager>
+    {
+        friend class Singleton<DynLibManager>;
+
+        protected:
+            typedef std::map<std::string, DynLib*> DynLibList;
+            DynLibList mLibList;
+
+        public:
+            /** Default constructor.
+                @note
+                    <br>Should never be called as the singleton is automatically
+                    created during the creation of the Root object.
+                @see
+                    Root::Root
+            */
+            DynLibManager();
+
+            /** Default destructor.
+                @see
+                    Root::~Root
+            */
+            virtual ~DynLibManager();
+
+            /** Loads the passed library.
+                @param
+                    filename The name of the library. The extension can be omitted
+            */
+            DynLib* load(const std::string& filename);
+
+            /** Unloads the passed library.
+            @param
+            filename The name of the library. The extension can be omitted
+            */
+            void unload(DynLib* lib);
+
+        private:
+            static DynLibManager* singletonPtr_s;
+    };
+}
+
+#endif /* _Core_DynLibManager_H__ */
Index: /code/branches/rocket2/src/libraries/core/Event.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/Event.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Event.cc	(revision 6952)
@@ -0,0 +1,114 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Event.h"
+
+#include "BaseObject.h"
+#include "Identifier.h"
+
+namespace orxonox
+{
+    /**
+        @brief Destructor: Deletes the functor of the event state.
+    */
+    EventState::~EventState()
+    {
+        if (this->statefunction_)
+            delete this->statefunction_;
+    }
+
+    /**
+        @brief Processes an event (calls the set-function if the necessary conditions are met).
+
+        @param event     The fired event
+        @param object    The object whose state is affected by the event (only needed for debug output)
+    */
+    void EventState::process(const Event& event, BaseObject* object)
+    {
+        if (this->bProcessingEvent_)
+        {
+            COUT(2) << "Warning: Detected Event loop in section \"" << event.statename_ << "\" of object \"" << object->getName() << "\" and fired by \"" << event.originator_->getName() << '"' << std::endl;
+            return;
+        }
+
+        this->bProcessingEvent_ = true;
+
+        COUT(4) << "Processing event (EventState) : originator: " << event.originator_->getIdentifier()->getName() << " (&" << event.originator_ << "), activate: " << event.activate_ << ", name: " << event.name_ << ", statename: " << event.statename_ << ", object: " << object->getIdentifier()->getName() << " (&" << object << ")" << "." << std::endl;
+        
+        // check if the originator is an instance of the requested class
+        if (event.originator_->isA(this->subclass_))
+        {
+            // If the EventState doesn't act as an EventSink.
+            // actualize the activationcounter
+            if(!this->bSink_)
+            {
+                if (event.activate_)
+                    ++this->activeEvents_;
+                else
+                {
+                    --this->activeEvents_;
+
+                    if (this->activeEvents_ < 0)
+                        this->activeEvents_ = 0;
+                }
+            }
+
+            if (this->statefunction_->getParamCount() == 0 && event.activate_)
+            {
+                // if the eventfunction doesn't have a state, just call it whenever an activation-event comes in
+                (*this->statefunction_)();
+            }
+            else if (this->bSink_ || (!this->bSink_ && ((this->activeEvents_ == 1 && event.activate_) || (this->activeEvents_ == 0 && !event.activate_)) ) )
+            {
+                // if the eventfunction needs a state, we just call the function if the state changed from 0 to 1 (state = true) or from 1 to 0 (state = false) [but not if activeEvents_ is > 1]
+                if (this->statefunction_->getParamCount() == 1)
+                {
+                    // one argument: just the eventstate
+                    (*this->statefunction_)(event.activate_);
+                }
+                else if (this->statefunction_->getParamCount() >= 2)
+                {
+                    // two arguments: the eventstate and the originator
+                    if (this->subclass_->isExactlyA(ClassIdentifier<BaseObject>::getIdentifier()))
+                    {
+                        // if the subclass is BaseObject, we don't have to cast the pointer
+                        (*this->statefunction_)(event.activate_, event.originator_);
+                    }
+                    else
+                    {
+                        // else cast the pointer to the desired class
+                        void* castedOriginator = event.originator_->getDerivedPointer(this->subclass_->getClassID());
+                        (*this->statefunction_)(event.activate_, castedOriginator);
+                    }
+                }
+            }
+        }
+
+        this->bProcessingEvent_ = false;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/Event.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Event.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Event.h	(revision 6952)
@@ -0,0 +1,86 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Event_H__
+#define _Event_H__
+
+#include "CorePrereqs.h"
+#include <string>
+
+namespace orxonox
+{
+    /**
+        @brief The Event struct contains information about a fired Event.
+    */
+    struct _CoreExport Event
+    {
+        Event(bool activate, BaseObject* originator, const std::string& name) : activate_(activate), originator_(originator), name_(name) {}
+
+        bool        activate_;   //!< True if this is an activating event (the event source was inactive before and just triggered the event) - false otherwise
+        std::string statename_;  //!< The name of the state this event affects
+        BaseObject* originator_; //!< The object which triggered this event
+        std::string name_;       //!< The name of this event
+
+    };
+
+    /**
+        @brief The EventState contains information about an event state.
+
+        An event state is a state of an object, which can be changed by events.
+        Event states are changed through functions. Possible functions headers for set event states are:
+         - memoryless state: function()
+         - boolean state:    function(bool state)
+         - individual state: function(bool state, SomeClass originator)
+
+        Note that SomeClass may be any class deriving from BaseObject. You will not receive events from originators of other classes.
+        The actual class for SomeClass must be specified as the second argument of the XMLPortEventState macro.
+
+        The this pointer of the affected object is hidden in the functors, because the events are processed in the BaseObject, but some
+        statefunctions may be from child-classes.
+    */
+    class _CoreExport EventState
+    {
+        public:
+            EventState(Functor* statefunction, Identifier* subclass, bool bSink = false) : bProcessingEvent_(false), activeEvents_(0), statefunction_(statefunction), subclass_(subclass), bSink_(bSink) {}
+            virtual ~EventState();
+
+            void process(const Event& event, BaseObject* object);
+
+            Functor* getFunctor() const
+                { return this->statefunction_; }
+
+        private:
+            bool        bProcessingEvent_;  //!< This becomes true while the container processes an event (used to prevent loops)
+            int         activeEvents_;      //!< The number of events which affect this state and are currently active
+            Functor*    statefunction_;     //!< A functor to set the state
+            Identifier* subclass_;          //!< Originators must be an instance of this class (usually BaseObject, but some statefunctions allow a second argument with an originator of a specific class)
+            bool        bSink_;             //!< Determines whether the EventState acts as an EventSink forwarding any Event (even if the state didn't change) or in the normal manner, only processing Events that change the state.
+    };
+}
+
+#endif /* _Event_H__ */
Index: /code/branches/rocket2/src/libraries/core/EventIncludes.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/EventIncludes.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/EventIncludes.h	(revision 6952)
@@ -0,0 +1,98 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _EventIncludes_H__
+#define _EventIncludes_H__
+
+#include "CorePrereqs.h"
+#include "Executor.h"
+#include "XMLPort.h"
+
+/**
+    @brief Defines a new event state (a state of the object which can be changed by events).
+
+    @param classname    The name of this class
+    @param subclassname Usually BaseObject - if different, only instances of this class can send events to this object
+    @param statename    The name (string) of this state
+    @param function     The function which should be used to set the state
+    @param xmlelement   Argument for XMLPort
+    @param mode         Argument for XMLPort
+*/
+#define XMLPortEventState(classname, subclassname, statename, function, xmlelement, mode) \
+    orxonox::EventState* containername##function = this->getEventState(statename); \
+    if (!containername##function) \
+    { \
+        containername##function = new orxonox::EventState(orxonox::createFunctor(&classname::function, this), orxonox::ClassIdentifier<subclassname>::getIdentifier()); \
+        this->addEventState(statename, containername##function); \
+    } \
+    XMLPortEventStateIntern(xmlportevent##function, classname, statename, xmlelement, mode)
+    
+#define XMLPortEventSink(classname, subclassname, statename, function, xmlelement, mode) \
+    orxonox::EventState* containername##function = this->getEventState(statename); \
+    if (!containername##function) \
+    { \
+        containername##function = new orxonox::EventState(orxonox::createFunctor(&classname::function, this), orxonox::ClassIdentifier<subclassname>::getIdentifier(), true); \
+        this->addEventState(statename, containername##function); \
+    } \
+    XMLPortEventStateIntern(xmlportevent##function, classname, statename, xmlelement, mode)
+
+/**
+    @brief Like XMLPortEventState but creates an event sink instead of an event state.
+           The most important destinction between an EventState and an EventSink is, that an EventState only processes event which change the state of the EventState, where as an EventSink is an EventState that processes any Event that reaches it.
+*/
+#define XMLPortEventStateTemplate(classname, subclassname, statename, function, xmlelement, mode, ...) \
+    orxonox::EventState* containername##function = this->getEventState(statename); \
+    if (!containername##function) \
+    { \
+        containername##function = new orxonox::EventState(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::function, this), orxonox::ClassIdentifier<subclassname>::getIdentifier()); \
+        this->addEventState(statename, containername##function); \
+    } \
+    XMLPortEventStateIntern(xmlportevent##function, classname, statename, xmlelement, mode)
+
+#define XMLPortEventStateIntern(name, classname, statename, xmlelement, mode) \
+    static orxonox::ExecutorMember<classname>* xmlsetfunctor##name = (orxonox::ExecutorMember<classname>*)&orxonox::createExecutor(orxonox::createFunctor(&classname::addEventSource), std::string( #classname ) + "::" + "addEventSource" + '(' + statename + ')')->setDefaultValue(1, statename); \
+    static orxonox::ExecutorMember<classname>* xmlgetfunctor##name = (orxonox::ExecutorMember<classname>*)&orxonox::createExecutor(orxonox::createFunctor(&classname::getEventSource), std::string( #classname ) + "::" + "getEventSource" + '(' + statename + ')')->setDefaultValue(1, statename); \
+    XMLPortObjectGeneric(xmlport##name, classname, orxonox::BaseObject, statename, xmlsetfunctor##name, xmlgetfunctor##name, xmlelement, mode, false, true)
+
+
+/**
+    @brief Defines a new event name for a class. Named events can only have names which were defined with this macro.
+
+    @param classname The name of the class
+    @param name      The name of the event
+*/
+#define CreateEventName(classname, name) \
+    static std::string eventname##classname##name = #name
+
+/**
+    @brief This macro is needed to fire an event with this name. The event name must previously be declared with @ref CreateEventName.
+*/
+#define FireEventName(classname, name) \
+    eventname##classname##name
+
+#endif /* _EventIncludes_H__ */
Index: /code/branches/rocket2/src/libraries/core/Executor.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/Executor.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Executor.cc	(revision 6952)
@@ -0,0 +1,251 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ *   Inspiration: Executor by Benjamin Grauer
+ */
+
+#include "Executor.h"
+
+#include "util/Convert.h"
+#include "Language.h"
+
+namespace orxonox
+{
+    Executor::Executor(Functor* functor, const std::string& name)
+    {
+        this->functor_ = functor;
+        this->name_ = name;
+
+        this->bAddedDescription_ = false;
+        this->bAddedDescriptionReturnvalue_ = false;
+
+        this->bAddedDescriptionParam_[0] = false;
+        this->bAddedDescriptionParam_[1] = false;
+        this->bAddedDescriptionParam_[2] = false;
+        this->bAddedDescriptionParam_[3] = false;
+        this->bAddedDescriptionParam_[4] = false;
+
+        this->bAddedDefaultValue_[0] = false;
+        this->bAddedDefaultValue_[1] = false;
+        this->bAddedDefaultValue_[2] = false;
+        this->bAddedDefaultValue_[3] = false;
+        this->bAddedDefaultValue_[4] = false;
+    }
+
+    Executor::~Executor()
+    {
+        delete this->functor_;
+    }
+
+    bool Executor::parse(const std::string& params, const std::string& delimiter) const
+    {
+        EXECUTOR_PARSE(normal);
+    }
+
+    bool Executor::evaluate(const std::string& params, MultiType param[5], const std::string& delimiter) const
+    {
+        unsigned int paramCount = this->functor_->getParamCount();
+
+        if (paramCount == 1)
+        {
+            // only one param: check if there are params given, otherwise try to use default values
+            if (!getStripped(params).empty())
+            {
+                param[0] = params;
+                this->functor_->evaluateParam(0, param[0]);
+                return true;
+            }
+            else if (this->bAddedDefaultValue_[0])
+            {
+                param[0] = this->defaultValue_[0];
+                this->functor_->evaluateParam(0, param[0]);
+                return true;
+            }
+            return false;
+        }
+        else
+        {
+            // more than one param
+            SubString tokens(params, delimiter, SubString::WhiteSpaces, false, '\\', true, '"', true, '(', ')', true, '\0');
+
+            // if there are not enough params given, check if there are default values
+            for (unsigned int i = tokens.size(); i < this->functor_->getParamCount(); i++)
+                if (!this->bAddedDefaultValue_[i])
+                    return false;
+
+            // assign all given arguments to the multitypes
+            for (unsigned int i = 0; i < std::min(tokens.size(), MAX_FUNCTOR_ARGUMENTS); i++)
+                param[i] = tokens[i];
+
+            // fill the remaining multitypes with default values
+            for (unsigned int i = tokens.size(); i < std::min(paramCount, MAX_FUNCTOR_ARGUMENTS); i++)
+                param[i] = this->defaultValue_[i];
+
+            // evaluate the param types through the functor
+            for (unsigned int i = 0; i < std::min(paramCount, MAX_FUNCTOR_ARGUMENTS); i++)
+                this->functor_->evaluateParam(i, param[i]);
+
+            return true;
+        }
+    }
+
+    Executor& Executor::setDescription(const std::string& description)
+    {
+        if (!this->bAddedDescription_)
+        {
+            this->description_ = std::string("ExecutorDescription::" + this->name_ + "::function");
+            AddLanguageEntry(this->description_, description);
+            this->bAddedDescription_ = true;
+        }
+        return (*this);
+    }
+
+    const std::string& Executor::getDescription() const
+    {
+        return GetLocalisation(this->description_);
+    }
+
+    Executor& Executor::setDescriptionParam(unsigned int param, const std::string& description)
+    {
+        if (param < MAX_FUNCTOR_ARGUMENTS)
+        {
+            if (!this->bAddedDescriptionParam_[param])
+            {
+                std::string paramnumber;
+                if (!convertValue(&paramnumber, param))
+                    return (*this);
+
+                this->descriptionParam_[param] = std::string("ExecutorDescription::" + this->name_ + "::param" + paramnumber);
+                AddLanguageEntry(this->descriptionParam_[param], description);
+                this->bAddedDescriptionParam_[param] = true;
+            }
+        }
+        return (*this);
+    }
+
+    const std::string& Executor::getDescriptionParam(unsigned int param) const
+    {
+        if (param < MAX_FUNCTOR_ARGUMENTS)
+            return GetLocalisation(this->descriptionParam_[param]);
+
+        return this->descriptionParam_[0];
+    }
+
+    Executor& Executor::setDescriptionReturnvalue(const std::string& description)
+    {
+        if (!this->bAddedDescriptionReturnvalue_)
+        {
+            this->descriptionReturnvalue_ = std::string("ExecutorDescription::" + this->name_ + "::returnvalue");
+            AddLanguageEntry(this->descriptionReturnvalue_, description);
+            this->bAddedDescriptionReturnvalue_ = true;
+        }
+        return (*this);
+    }
+
+    const std::string& Executor::getDescriptionReturnvalue(int param) const
+    {
+        return GetLocalisation(this->descriptionReturnvalue_);
+    }
+
+    Executor& Executor::setDefaultValues(const MultiType& param1)
+    {
+        this->defaultValue_[0] = param1;
+        this->bAddedDefaultValue_[0] = true;
+
+        return (*this);
+    }
+
+    Executor& Executor::setDefaultValues(const MultiType& param1, const MultiType& param2)
+    {
+        this->defaultValue_[0] = param1;
+        this->bAddedDefaultValue_[0] = true;
+        this->defaultValue_[1] = param2;
+        this->bAddedDefaultValue_[1] = true;
+
+        return (*this);
+    }
+
+    Executor& Executor::setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3)
+    {
+        this->defaultValue_[0] = param1;
+        this->bAddedDefaultValue_[0] = true;
+        this->defaultValue_[1] = param2;
+        this->bAddedDefaultValue_[1] = true;
+        this->defaultValue_[2] = param3;
+        this->bAddedDefaultValue_[2] = true;
+
+        return (*this);
+    }
+
+    Executor& Executor::setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4)
+    {
+        this->defaultValue_[0] = param1;
+        this->bAddedDefaultValue_[0] = true;
+        this->defaultValue_[1] = param2;
+        this->bAddedDefaultValue_[1] = true;
+        this->defaultValue_[2] = param3;
+        this->bAddedDefaultValue_[2] = true;
+        this->defaultValue_[3] = param4;
+        this->bAddedDefaultValue_[3] = true;
+
+        return (*this);
+    }
+
+    Executor& Executor::setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5)
+    {
+        this->defaultValue_[0] = param1;
+        this->bAddedDefaultValue_[0] = true;
+        this->defaultValue_[1] = param2;
+        this->bAddedDefaultValue_[1] = true;
+        this->defaultValue_[2] = param3;
+        this->bAddedDefaultValue_[2] = true;
+        this->defaultValue_[3] = param4;
+        this->bAddedDefaultValue_[3] = true;
+        this->defaultValue_[4] = param5;
+        this->bAddedDefaultValue_[4] = true;
+
+        return (*this);
+    }
+
+    Executor& Executor::setDefaultValue(unsigned int index, const MultiType& param)
+    {
+        if (index < MAX_FUNCTOR_ARGUMENTS)
+        {
+            this->defaultValue_[index] = param;
+            this->bAddedDefaultValue_[index] = true;
+        }
+        return (*this);
+    }
+
+    bool Executor::allDefaultValuesSet() const
+    {
+        for (unsigned int i = 0; i < this->functor_->getParamCount(); i++)
+            if (!this->bAddedDefaultValue_[i])
+                return false;
+
+        return true;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/Executor.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Executor.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Executor.h	(revision 6952)
@@ -0,0 +1,312 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ *   Inspiration: Executor by Benjamin Grauer
+ */
+
+#ifndef _Executor_H__
+#define _Executor_H__
+
+#include "CorePrereqs.h"
+
+#include <algorithm>
+#include <string>
+
+#include "util/Debug.h"
+#include "util/Math.h"
+#include "util/StringUtils.h"
+#include "util/SubString.h"
+#include "Functor.h"
+
+
+#define EXECUTOR_PARSE_FUNCTORCALL(mode) EXECUTOR_PARSE_FUNCTORCALL##mode
+#define EXECUTOR_PARSE_FUNCTORCALLnormal (*this->functor_)
+#define EXECUTOR_PARSE_FUNCTORCALLobject (*((FunctorMember<T>*)this->functor_))
+
+#define EXECUTOR_PARSE_OBJECT(mode, comma) EXECUTOR_PARSE_OBJECT##mode##comma
+#define EXECUTOR_PARSE_OBJECTnormal0
+#define EXECUTOR_PARSE_OBJECTnormal1
+#define EXECUTOR_PARSE_OBJECTobject0 object
+#define EXECUTOR_PARSE_OBJECTobject1 object,
+
+#define EXECUTOR_PARSE(mode) \
+    unsigned int paramCount = this->functor_->getParamCount(); \
+    \
+    if (paramCount == 0) \
+    { \
+        COUT(5) << "Calling Executor " << this->name_ << " through parser without parameters." << std::endl; \
+        EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 0)); \
+    } \
+    else if (paramCount == 1) \
+    { \
+        const std::string& temp = getStripped(params); \
+        if (!temp.empty()) \
+        { \
+            COUT(5) << "Calling Executor " << this->name_ << " through parser with one parameter, using whole string: " << params << std::endl; \
+            EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) MultiType(params)); \
+        } \
+        else if (this->bAddedDefaultValue_[0]) \
+        { \
+            COUT(5) << "Calling Executor " << this->name_ << " through parser with one parameter, using default value: " << this->defaultValue_[0] << std::endl; \
+            EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) this->defaultValue_[0]); \
+        } \
+        else \
+        { \
+            COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input: " << temp << ")." << std::endl; \
+            return false; \
+        } \
+    } \
+    else \
+    { \
+        SubString tokens(params, delimiter, SubString::WhiteSpaces, false, '\\', true, '"', true, '(', ')', true, '\0'); \
+        \
+        for (unsigned int i = tokens.size(); i < this->functor_->getParamCount(); i++) \
+        { \
+            if (!this->bAddedDefaultValue_[i]) \
+            { \
+                COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input:" << params << ")." << std::endl; \
+                return false; \
+            } \
+        } \
+        \
+        MultiType param[MAX_FUNCTOR_ARGUMENTS]; \
+        COUT(5) << "Calling Executor " << this->name_ << " through parser with " << paramCount << " parameters, using " << tokens.size() << " tokens ("; \
+        for (unsigned int i = 0; i < tokens.size() && i < MAX_FUNCTOR_ARGUMENTS; i++) \
+        { \
+            param[i] = tokens[i]; \
+            if (i != 0) \
+            { \
+                COUT(5) << ", "; \
+            } \
+            COUT(5) << tokens[i]; \
+        } \
+        COUT(5) << ") and " << std::max(static_cast<int>(paramCount) - static_cast<int>(tokens.size()), 0) << " default values ("; \
+        for (unsigned int i = tokens.size(); i < paramCount; i++) \
+        { \
+            param[i] = this->defaultValue_[i]; \
+            if (i != 0) \
+            { \
+                COUT(5) << ", "; \
+            } \
+            COUT(5) << this->defaultValue_[i]; \
+        } \
+        COUT(5) << ")." << std::endl; \
+        \
+        if ((tokens.size() > paramCount) && (this->functor_->getTypenameParam(paramCount - 1) == "string")) \
+            param[paramCount - 1] = tokens.subSet(paramCount - 1).join(); \
+        \
+        switch(paramCount) \
+        { \
+            case 2: \
+                EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) param[0], param[1]); \
+                break; \
+            case 3: \
+                EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) param[0], param[1], param[2]); \
+                break; \
+            case 4: \
+                EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) param[0], param[1], param[2], param[3]); \
+                break; \
+            case 5: \
+                EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) param[0], param[1], param[2], param[3], param[4]); \
+                break; \
+        } \
+    } \
+    \
+    return true
+
+namespace orxonox
+{
+    class _CoreExport Executor
+    {
+        public:
+            Executor(Functor* functor, const std::string& name = "");
+            virtual ~Executor();
+
+            inline void operator()() const
+                { (*this->functor_)(this->defaultValue_[0], this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
+            inline void operator()(const MultiType& param1) const
+                { (*this->functor_)(param1, this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
+            inline void operator()(const MultiType& param1, const MultiType& param2) const
+                { (*this->functor_)(param1, param2, this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
+            inline void operator()(const MultiType& param1, const MultiType& param2, const MultiType& param3) const
+                { (*this->functor_)(param1, param2, param3, this->defaultValue_[3], this->defaultValue_[4]); }
+            inline void operator()(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4) const
+                { (*this->functor_)(param1, param2, param3, param4, this->defaultValue_[4]); }
+            inline void operator()(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) const
+                { (*this->functor_)(param1, param2, param3, param4, param5); }
+
+            bool parse(const std::string& params, const std::string& delimiter = " ") const;
+
+            bool evaluate(const std::string& params, MultiType param[5], const std::string& delimiter = " ") const;
+
+            Executor& setDescription(const std::string& description);
+            const std::string& getDescription() const;
+
+            Executor& setDescriptionParam(unsigned int param, const std::string& description);
+            const std::string& getDescriptionParam(unsigned int param) const;
+
+            Executor& setDescriptionReturnvalue(const std::string& description);
+            const std::string& getDescriptionReturnvalue(int param) const;
+
+            inline Functor* getFunctor() const
+                { return this->functor_; }
+            inline unsigned int getParamCount() const
+                { return this->functor_->getParamCount(); }
+            inline bool hasReturnvalue() const
+                { return this->functor_->hasReturnvalue(); }
+            inline FunctionType::Value getType() const
+                { return this->functor_->getType(); }
+            inline const MultiType& getReturnvalue() const
+                { return this->functor_->getReturnvalue(); }
+            inline const std::string& getTypenameParam(unsigned int param) const
+                { return this->functor_->getTypenameParam(param); }
+            inline const std::string& getTypenameReturnvalue() const
+                { return this->functor_->getTypenameReturnvalue(); }
+
+            inline void setName(const std::string& name)
+                { this->name_ = name; }
+            inline const std::string& getName() const
+                { return this->name_; }
+
+            Executor& setDefaultValues(const MultiType& param1);
+            Executor& setDefaultValues(const MultiType& param1, const MultiType& param2);
+            Executor& setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3);
+            Executor& setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4);
+            Executor& setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5);
+            Executor& setDefaultValue(unsigned int index, const MultiType& param);
+
+            inline MultiType getDefaultValue(unsigned int index) const
+            {
+                if (index < MAX_FUNCTOR_ARGUMENTS)
+                    return this->defaultValue_[index];
+
+                return MT_Type::Null;
+            }
+
+            bool allDefaultValuesSet() const;
+            inline bool defaultValueSet(unsigned int index) const
+            {
+                if (index < MAX_FUNCTOR_ARGUMENTS)
+                    return this->bAddedDefaultValue_[index];
+
+                return false;
+            }
+
+        protected:
+            Functor* functor_;
+            std::string name_;
+            MultiType defaultValue_[MAX_FUNCTOR_ARGUMENTS];
+            bool bAddedDefaultValue_[MAX_FUNCTOR_ARGUMENTS];
+
+        private:
+            LanguageEntryLabel description_;
+            LanguageEntryLabel descriptionReturnvalue_;
+            LanguageEntryLabel descriptionParam_[MAX_FUNCTOR_ARGUMENTS];
+
+            bool bAddedDescription_;
+            bool bAddedDescriptionReturnvalue_;
+            bool bAddedDescriptionParam_[MAX_FUNCTOR_ARGUMENTS];
+    };
+
+    class _CoreExport ExecutorStatic : public Executor
+    {
+        public:
+            ExecutorStatic(FunctorStatic* functor, const std::string& name = "") : Executor(functor, name) {}
+            virtual ~ExecutorStatic() {}
+    };
+
+    template <class T>
+    class ExecutorMember : public Executor
+    {
+        public:
+            ExecutorMember(FunctorMember<T>* functor, const std::string& name = "") : Executor(functor, name) {}
+            virtual ~ExecutorMember() {}
+
+            using Executor::operator();
+
+            inline void operator()(T* object) const
+                { (*((FunctorMember<T>*)this->functor_))(object, this->defaultValue_[0], this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
+            inline void operator()(T* object, const MultiType& param1) const
+                { (*((FunctorMember<T>*)this->functor_))(object, param1, this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
+            inline void operator()(T* object, const MultiType& param1, const MultiType& param2) const
+                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
+            inline void operator()(T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3) const
+                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, param3, this->defaultValue_[3], this->defaultValue_[4]); }
+            inline void operator()(T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4) const
+                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, param3, param4, this->defaultValue_[4]); }
+            inline void operator()(T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) const
+                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, param3, param4, param5); }
+
+
+            inline void operator()(const T* object) const
+                { (*((FunctorMember<T>*)this->functor_))(object, this->defaultValue_[0], this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
+            inline void operator()(const T* object, const MultiType& param1) const
+                { (*((FunctorMember<T>*)this->functor_))(object, param1, this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
+            inline void operator()(const T* object, const MultiType& param1, const MultiType& param2) const
+                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
+            inline void operator()(const T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3) const
+                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, param3, this->defaultValue_[3], this->defaultValue_[4]); }
+            inline void operator()(const T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4) const
+                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, param3, param4, this->defaultValue_[4]); }
+            inline void operator()(const T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) const
+                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, param3, param4, param5); }
+
+            inline void setObject(T* object) const
+                { ((FunctorMember<T>*)this->functor_)->setObject(object); }
+            inline void setObject(const T* object) const
+                { ((FunctorMember<T>*)this->functor_)->setObject(object); }
+
+            using Executor::parse;
+
+            bool parse(T* object, const std::string& params, const std::string& delimiter = " ") const
+            {
+                EXECUTOR_PARSE(object);
+            }
+
+            bool parse(const T* object, const std::string& params, const std::string& delimiter = " ") const
+            {
+                EXECUTOR_PARSE(object);
+            }
+    };
+
+    inline Executor* createExecutor(Functor* functor, const std::string& name = "")
+    {
+        return new Executor(functor, name);
+    }
+
+    template <class T>
+    inline ExecutorMember<T>* createExecutor(FunctorMember<T>* functor, const std::string& name = "")
+    {
+        return new ExecutorMember<T>(functor, name);
+    }
+
+    inline ExecutorStatic* createExecutor(FunctorStatic* functor, const std::string& name = "")
+    {
+        return new ExecutorStatic(functor, name);
+    }
+}
+
+#endif /* _Executor_H__ */
Index: /code/branches/rocket2/src/libraries/core/Functor.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Functor.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Functor.h	(revision 6952)
@@ -0,0 +1,505 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ *   Inspiration: Functor by Benjamin Grauer
+ */
+
+#ifndef _Functor_H__
+#define _Functor_H__
+
+#include "CorePrereqs.h"
+
+#include "util/Debug.h"
+#include "util/MultiType.h"
+
+namespace orxonox
+{
+    const unsigned int MAX_FUNCTOR_ARGUMENTS = 5;
+
+    namespace FunctionType
+    {
+        enum Value
+        {
+            Member,
+            ConstMember,
+            Static
+        };
+    }
+
+
+    template <class T>
+    inline std::string typeToString() { return "unknown"; }
+
+#define CreateTypeToStringTemplate(type) \
+    template <> \
+    inline std::string typeToString<type>() { return #type; } \
+    template <> \
+    inline std::string typeToString<type&>() { return #type; } \
+    template <> \
+    inline std::string typeToString<const type>() { return #type; } \
+    template <> \
+    inline std::string typeToString<const type&>() { return #type; }
+
+    CreateTypeToStringTemplate(int);
+    CreateTypeToStringTemplate(unsigned int);
+    CreateTypeToStringTemplate(char);
+    CreateTypeToStringTemplate(unsigned char);
+    CreateTypeToStringTemplate(short);
+    CreateTypeToStringTemplate(unsigned short);
+    CreateTypeToStringTemplate(long);
+    CreateTypeToStringTemplate(unsigned long);
+    CreateTypeToStringTemplate(long long);
+    CreateTypeToStringTemplate(unsigned long long);
+    CreateTypeToStringTemplate(float);
+    CreateTypeToStringTemplate(double);
+    CreateTypeToStringTemplate(long double);
+    CreateTypeToStringTemplate(bool);
+    CreateTypeToStringTemplate(Vector2);
+    CreateTypeToStringTemplate(Vector3);
+    CreateTypeToStringTemplate(Quaternion);
+    CreateTypeToStringTemplate(ColourValue);
+    CreateTypeToStringTemplate(Radian);
+    CreateTypeToStringTemplate(Degree);
+
+    template <>
+    inline std::string typeToString<std::string>() { return "string"; }
+    template <>
+    inline std::string typeToString<std::string&>() { return "string"; }
+    template <>
+    inline std::string typeToString<const std::string>() { return "string"; }
+    template <>
+    inline std::string typeToString<const std::string&>() { return "string"; }
+
+    class _CoreExport Functor
+    {
+        public:
+            Functor() {}
+            virtual ~Functor() {}
+
+            virtual void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0;
+
+            inline unsigned int getParamCount() const { return this->numParams_; }
+            inline bool hasReturnvalue() const { return this->hasReturnValue_; }
+            inline FunctionType::Value getType() const { return this->type_; }
+            inline const MultiType& getReturnvalue() const { return this->returnedValue_; }
+
+            const std::string& getTypenameParam(unsigned int param) const { return (param < 5) ? this->typeParam_[param] : BLANKSTRING; }
+            const std::string& getTypenameReturnvalue() const { return this->typeReturnvalue_; }
+
+            virtual void evaluateParam(unsigned int index, MultiType& param) const = 0;
+
+        protected:
+            unsigned int numParams_;
+            bool hasReturnValue_;
+            FunctionType::Value type_;
+            MultiType returnedValue_;
+
+            std::string typeReturnvalue_;
+            std::string typeParam_[MAX_FUNCTOR_ARGUMENTS];
+    };
+
+    class _CoreExport FunctorStatic : public Functor
+    {
+        public:
+            virtual ~FunctorStatic() {}
+            virtual void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0;
+    };
+
+    template <class T>
+    class FunctorMember : public Functor
+    {
+        public:
+            FunctorMember()
+            {
+                constObject_ = 0;
+                object_ = 0;
+                bConstObject_ = false;
+            }
+            virtual ~FunctorMember() {}
+
+            virtual void operator()(T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0;
+            virtual void operator()(const T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0;
+
+            virtual void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null)
+            {
+                if (this->bConstObject_)
+                {
+                    if (this->constObject_)
+                        (*this)(this->constObject_, param1, param2, param3, param4, param5);
+                    else
+                    {
+                        COUT(1) << "An error occurred in Functor.h:" << std::endl;
+                        COUT(1) << "Error: No const object set." << std::endl;
+                    }
+                }
+                else
+                {
+                    if (this->object_)
+                        (*this)(this->object_, param1, param2, param3, param4, param5);
+                    else
+                    {
+                        COUT(1) << "An error occurred in Functor.h:" << std::endl;
+                        COUT(1) << "Error: No object set." << std::endl;
+                    }
+                }
+            }
+
+            FunctorMember<T>* setObject(T* object)
+            {
+                this->bConstObject_ = false;
+                this->object_ = object;
+                return this;
+            }
+
+            FunctorMember<T>* setObject(const T* object)
+            {
+                this->bConstObject_ = true;
+                this->constObject_ = object;
+                return this;
+            }
+
+        private:
+            const T* constObject_;
+            T* object_;
+            bool bConstObject_;
+    };
+
+
+
+#define FUNCTOR_TEMPLATE(ismember, returnvalue, numparams, additionalobject) FUNCTOR_TEMPLATE##ismember##returnvalue##numparams(additionalobject)
+#define FUNCTOR_TEMPLATE000(additionalobject)
+#define FUNCTOR_TEMPLATE001(additionalobject) template <class P1>
+#define FUNCTOR_TEMPLATE002(additionalobject) template <class P1, class P2>
+#define FUNCTOR_TEMPLATE003(additionalobject) template <class P1, class P2, class P3>
+#define FUNCTOR_TEMPLATE004(additionalobject) template <class P1, class P2, class P3, class P4>
+#define FUNCTOR_TEMPLATE005(additionalobject) template <class P1, class P2, class P3, class P4, class P5>
+#define FUNCTOR_TEMPLATE010(additionalobject) template <class R>
+#define FUNCTOR_TEMPLATE011(additionalobject) template <class R, class P1>
+#define FUNCTOR_TEMPLATE012(additionalobject) template <class R, class P1, class P2>
+#define FUNCTOR_TEMPLATE013(additionalobject) template <class R, class P1, class P2, class P3>
+#define FUNCTOR_TEMPLATE014(additionalobject) template <class R, class P1, class P2, class P3, class P4>
+#define FUNCTOR_TEMPLATE015(additionalobject) template <class R, class P1, class P2, class P3, class P4, class P5>
+#define FUNCTOR_TEMPLATE100(additionalobject) template <class T FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
+#define FUNCTOR_TEMPLATE101(additionalobject) template <class T, class P1 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
+#define FUNCTOR_TEMPLATE102(additionalobject) template <class T, class P1, class P2 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
+#define FUNCTOR_TEMPLATE103(additionalobject) template <class T, class P1, class P2, class P3 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
+#define FUNCTOR_TEMPLATE104(additionalobject) template <class T, class P1, class P2, class P3, class P4 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
+#define FUNCTOR_TEMPLATE105(additionalobject) template <class T, class P1, class P2, class P3, class P4, class P5 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
+#define FUNCTOR_TEMPLATE110(additionalobject) template <class T, class R FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
+#define FUNCTOR_TEMPLATE111(additionalobject) template <class T, class R, class P1 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
+#define FUNCTOR_TEMPLATE112(additionalobject) template <class T, class R, class P1, class P2 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
+#define FUNCTOR_TEMPLATE113(additionalobject) template <class T, class R, class P1, class P2, class P3 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
+#define FUNCTOR_TEMPLATE114(additionalobject) template <class T, class R, class P1, class P2, class P3, class P4 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
+#define FUNCTOR_TEMPLATE115(additionalobject) template <class T, class R, class P1, class P2, class P3, class P4, class P5 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
+
+
+
+#define FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT##additionalobject
+#define FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT0
+#define FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT1 , class O
+
+
+
+#define FUNCTOR_TEMPLATE_CLASSES(ismember, returnvalue, numparams) FUNCTOR_TEMPLATE_CLASSES##ismember##returnvalue##numparams
+#define FUNCTOR_TEMPLATE_CLASSES000
+#define FUNCTOR_TEMPLATE_CLASSES001 <P1>
+#define FUNCTOR_TEMPLATE_CLASSES002 <P1, P2>
+#define FUNCTOR_TEMPLATE_CLASSES003 <P1, P2, P3>
+#define FUNCTOR_TEMPLATE_CLASSES004 <P1, P2, P3, P4>
+#define FUNCTOR_TEMPLATE_CLASSES005 <P1, P2, P3, P4, P5>
+#define FUNCTOR_TEMPLATE_CLASSES010 <R>
+#define FUNCTOR_TEMPLATE_CLASSES011 <R, P1>
+#define FUNCTOR_TEMPLATE_CLASSES012 <R, P1, P2>
+#define FUNCTOR_TEMPLATE_CLASSES013 <R, P1, P2, P3>
+#define FUNCTOR_TEMPLATE_CLASSES014 <R, P1, P2, P3, P4>
+#define FUNCTOR_TEMPLATE_CLASSES015 <R, P1, P2, P3, P4, P5>
+#define FUNCTOR_TEMPLATE_CLASSES100 <T>
+#define FUNCTOR_TEMPLATE_CLASSES101 <T, P1>
+#define FUNCTOR_TEMPLATE_CLASSES102 <T, P1, P2>
+#define FUNCTOR_TEMPLATE_CLASSES103 <T, P1, P2, P3>
+#define FUNCTOR_TEMPLATE_CLASSES104 <T, P1, P2, P3, P4>
+#define FUNCTOR_TEMPLATE_CLASSES105 <T, P1, P2, P3, P4, P5>
+#define FUNCTOR_TEMPLATE_CLASSES110 <T, R>
+#define FUNCTOR_TEMPLATE_CLASSES111 <T, R, P1>
+#define FUNCTOR_TEMPLATE_CLASSES112 <T, R, P1, P2>
+#define FUNCTOR_TEMPLATE_CLASSES113 <T, R, P1, P2, P3>
+#define FUNCTOR_TEMPLATE_CLASSES114 <T, R, P1, P2, P3, P4>
+#define FUNCTOR_TEMPLATE_CLASSES115 <T, R, P1, P2, P3, P4, P5>
+
+
+
+#define FUNCTOR_TYPENAME_PARAMS(numparams) FUNCTOR_TYPENAME_PARAMS##numparams
+#define FUNCTOR_TYPENAME_PARAMS0
+#define FUNCTOR_TYPENAME_PARAMS1 this->typeParam_[0] = typeToString<P1>();
+#define FUNCTOR_TYPENAME_PARAMS2 this->typeParam_[0] = typeToString<P1>(); this->typeParam_[1] = typeToString<P2>();
+#define FUNCTOR_TYPENAME_PARAMS3 this->typeParam_[0] = typeToString<P1>(); this->typeParam_[1] = typeToString<P2>(); this->typeParam_[2] = typeToString<P3>();
+#define FUNCTOR_TYPENAME_PARAMS4 this->typeParam_[0] = typeToString<P1>(); this->typeParam_[1] = typeToString<P2>(); this->typeParam_[2] = typeToString<P3>(); this->typeParam_[3] = typeToString<P4>();
+#define FUNCTOR_TYPENAME_PARAMS5 this->typeParam_[0] = typeToString<P1>(); this->typeParam_[1] = typeToString<P2>(); this->typeParam_[2] = typeToString<P3>(); this->typeParam_[3] = typeToString<P4>(); this->typeParam_[4] = typeToString<P5>();
+
+#define FUNCTOR_TYPENAME_RETURN(returnvalue) FUNCTOR_TYPENAME_RETURN##returnvalue
+#define FUNCTOR_TYPENAME_RETURN0
+#define FUNCTOR_TYPENAME_RETURN1 this->typeReturnvalue_ = typeToString<R>();
+
+
+
+#define FUNCTOR_FUNCTION_PARAMS(numparams) FUNCTOR_FUNCTION_PARAMS##numparams
+#define FUNCTOR_FUNCTION_PARAMS0
+#define FUNCTOR_FUNCTION_PARAMS1 P1 param1
+#define FUNCTOR_FUNCTION_PARAMS2 P1 param1, P2 param2
+#define FUNCTOR_FUNCTION_PARAMS3 P1 param1, P2 param2, P3 param3
+#define FUNCTOR_FUNCTION_PARAMS4 P1 param1, P2 param2, P3 param3, P4 param4
+#define FUNCTOR_FUNCTION_PARAMS5 P1 param1, P2 param2, P3 param3, P4 param4, P5 param5
+
+#define FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) FUNCTOR_FUNCTION_RETURNVALUE##returnvalue
+#define FUNCTOR_FUNCTION_RETURNVALUE0 void
+#define FUNCTOR_FUNCTION_RETURNVALUE1 R
+
+
+
+#define FUNCTOR_FUNCTION_CALL(numparams) FUNCTOR_FUNCTION_CALL##numparams
+#define FUNCTOR_FUNCTION_CALL0
+#define FUNCTOR_FUNCTION_CALL1 param1
+#define FUNCTOR_FUNCTION_CALL2 param1, param2
+#define FUNCTOR_FUNCTION_CALL3 param1, param2, param3
+#define FUNCTOR_FUNCTION_CALL4 param1, param2, param3, param4
+#define FUNCTOR_FUNCTION_CALL5 param1, param2, param3, param4, param5
+
+#define FUNCTOR_STORE_RETURNVALUE(returnvalue, functioncall) FUNCTOR_STORE_RETURNVALUE##returnvalue(functioncall)
+#define FUNCTOR_STORE_RETURNVALUE0(functioncall) functioncall
+#define FUNCTOR_STORE_RETURNVALUE1(functioncall) this->returnedValue_ = functioncall
+
+
+
+#define FUNCTOR_EVALUATE_PARAM(numparams) FUNCTOR_EVALUATE_PARAM##numparams
+#define FUNCTOR_EVALUATE_PARAM0
+#define FUNCTOR_EVALUATE_PARAM1 \
+    if (index == 0) { param.convert<P1>(); }
+#define FUNCTOR_EVALUATE_PARAM2 \
+    if (index == 0) { param.convert<P1>(); } \
+    else if (index == 1) { param.convert<P2>(); }
+#define FUNCTOR_EVALUATE_PARAM3 \
+    if (index == 0) { param.convert<P1>(); } \
+    else if (index == 1) { param.convert<P2>(); } \
+    else if (index == 2) { param.convert<P3>(); }
+#define FUNCTOR_EVALUATE_PARAM4 \
+    if (index == 0) { param.convert<P1>(); } \
+    else if (index == 1) { param.convert<P2>(); } \
+    else if (index == 2) { param.convert<P3>(); } \
+    else if (index == 3) { param.convert<P4>(); }
+#define FUNCTOR_EVALUATE_PARAM5 \
+    if (index == 0) { param.convert<P1>(); } \
+    else if (index == 1) { param.convert<P2>(); } \
+    else if (index == 2) { param.convert<P3>(); } \
+    else if (index == 3) { param.convert<P4>(); } \
+    else if (index == 4) { param.convert<P5>(); }
+
+
+
+
+
+#define CREATE_STATIC_FUNCTOR(returnvalue, numparams) \
+    FUNCTOR_TEMPLATE(0, returnvalue, numparams, 0) \
+    class FunctorStatic##returnvalue##numparams : public FunctorStatic \
+    { \
+        public: \
+            FunctorStatic##returnvalue##numparams(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
+            { \
+                this->numParams_ = numparams; \
+                this->hasReturnValue_ = returnvalue; \
+                this->type_ = FunctionType::Static; \
+                this->functionPointer_ = functionPointer; \
+                \
+                FUNCTOR_TYPENAME_PARAMS(numparams); \
+                FUNCTOR_TYPENAME_RETURN(returnvalue); \
+            } \
+    \
+            void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
+            { \
+                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
+            } \
+    \
+            virtual void evaluateParam(unsigned int index, MultiType& param) const \
+            { \
+                FUNCTOR_EVALUATE_PARAM(numparams); \
+            } \
+    \
+        private: \
+            FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (*functionPointer_)(FUNCTOR_FUNCTION_PARAMS(numparams)); \
+    }; \
+    \
+    \
+    FUNCTOR_TEMPLATE(0, returnvalue, numparams, 0) \
+    inline FunctorStatic##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(0, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
+    { \
+        return new FunctorStatic##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(0, returnvalue, numparams) (functionPointer); \
+    }
+
+
+
+
+
+#define CREATE_MEMBER_FUNCTOR(returnvalue, numparams) \
+    FUNCTOR_TEMPLATE(1, returnvalue, numparams, 0) \
+    class FunctorMember##returnvalue##numparams : public FunctorMember<T> \
+    { \
+        public: \
+            FunctorMember##returnvalue##numparams(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
+            { \
+                this->numParams_ = numparams; \
+                this->hasReturnValue_ = returnvalue; \
+                this->type_ = FunctionType::Member; \
+                this->functionPointer_ = functionPointer; \
+            } \
+    \
+            void operator()(T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
+            { \
+                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
+            } \
+    \
+            void operator()(const T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
+            { \
+                COUT(1) << "An error occurred in Functor.h:" << std::endl; \
+                COUT(1) << "Error: Function is not const." << std::endl; \
+            } \
+    \
+            virtual void evaluateParam(unsigned int index, MultiType& param) const \
+            { \
+                FUNCTOR_EVALUATE_PARAM(numparams); \
+            } \
+    \
+        private: \
+            FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer_)(FUNCTOR_FUNCTION_PARAMS(numparams)); \
+    }; \
+    \
+    \
+    FUNCTOR_TEMPLATE(1, returnvalue, numparams, 0) \
+    class FunctorConstMember##returnvalue##numparams : public FunctorMember<T> \
+    { \
+        public: \
+            FunctorConstMember##returnvalue##numparams(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams)) const) \
+            { \
+                this->numParams_ = numparams; \
+                this->hasReturnValue_ = returnvalue; \
+                this->type_ = FunctionType::ConstMember; \
+                this->functionPointer_ = functionPointer; \
+            } \
+    \
+            void operator()(T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
+            { \
+                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
+            } \
+    \
+            void operator()(const T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
+            { \
+                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
+            } \
+    \
+            virtual void evaluateParam(unsigned int index, MultiType& param) const \
+            { \
+                FUNCTOR_EVALUATE_PARAM(numparams); \
+            } \
+    \
+        private: \
+            FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer_)(FUNCTOR_FUNCTION_PARAMS(numparams)) const; \
+    }; \
+    \
+    \
+    FUNCTOR_TEMPLATE(1, returnvalue, numparams, 0) \
+    inline FunctorMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
+    { \
+        return new FunctorMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams) (functionPointer); \
+    } \
+    \
+    \
+    FUNCTOR_TEMPLATE(1, returnvalue, numparams, 0) \
+    inline FunctorConstMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams)) const) \
+    { \
+        return new FunctorConstMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams) (functionPointer); \
+    } \
+    \
+    FUNCTOR_TEMPLATE(1, returnvalue, numparams, 1) \
+    inline FunctorMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams)), O* object) \
+    { \
+        FunctorMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* functor = new FunctorMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams) (functionPointer); \
+        functor->setObject(object); \
+        return functor; \
+    } \
+    \
+    \
+    FUNCTOR_TEMPLATE(1, returnvalue, numparams, 1) \
+    inline FunctorConstMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams)) const, O* object) \
+    { \
+        FunctorConstMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* functor = new FunctorConstMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams) (functionPointer); \
+        functor->setObject(object); \
+        return functor; \
+    }
+
+
+// disable annoying warning about forcing value to boolean
+#ifdef ORXONOX_COMPILER_MSVC
+#pragma warning(push)
+#pragma warning(disable:4100 4800)
+#endif
+
+#define CREATE_ALL_STATIC_FUNCTORS() \
+    CREATE_STATIC_FUNCTOR(0, 0); \
+    CREATE_STATIC_FUNCTOR(0, 1); \
+    CREATE_STATIC_FUNCTOR(0, 2); \
+    CREATE_STATIC_FUNCTOR(0, 3); \
+    CREATE_STATIC_FUNCTOR(0, 4); \
+    CREATE_STATIC_FUNCTOR(0, 5); \
+    CREATE_STATIC_FUNCTOR(1, 0); \
+    CREATE_STATIC_FUNCTOR(1, 1); \
+    CREATE_STATIC_FUNCTOR(1, 2); \
+    CREATE_STATIC_FUNCTOR(1, 3); \
+    CREATE_STATIC_FUNCTOR(1, 4); \
+    CREATE_STATIC_FUNCTOR(1, 5)
+
+
+#define CREATE_ALL_MEMBER_FUNCTORS() \
+    CREATE_MEMBER_FUNCTOR(0, 0); \
+    CREATE_MEMBER_FUNCTOR(0, 1); \
+    CREATE_MEMBER_FUNCTOR(0, 2); \
+    CREATE_MEMBER_FUNCTOR(0, 3); \
+    CREATE_MEMBER_FUNCTOR(0, 4); \
+    CREATE_MEMBER_FUNCTOR(0, 5); \
+    CREATE_MEMBER_FUNCTOR(1, 0); \
+    CREATE_MEMBER_FUNCTOR(1, 1); \
+    CREATE_MEMBER_FUNCTOR(1, 2); \
+    CREATE_MEMBER_FUNCTOR(1, 3); \
+    CREATE_MEMBER_FUNCTOR(1, 4); \
+    CREATE_MEMBER_FUNCTOR(1, 5)
+
+
+    CREATE_ALL_STATIC_FUNCTORS();
+    CREATE_ALL_MEMBER_FUNCTORS();
+}
+
+#ifdef ORXONOX_COMPILER_MSVC
+#pragma warning(pop)
+#endif
+
+#endif /* _Functor_H__ */
Index: /code/branches/rocket2/src/libraries/core/GUIManager.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/GUIManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/GUIManager.cc	(revision 6952)
@@ -0,0 +1,440 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "GUIManager.h"
+
+#include <boost/bind.hpp>
+#include <memory>
+extern "C" {
+#include <lua.h>
+}
+#include <CEGUIDefaultLogger.h>
+#include <CEGUIExceptions.h>
+#include <CEGUIInputEvent.h>
+#include <CEGUIMouseCursor.h>
+#include <CEGUIResourceProvider.h>
+#include <CEGUISystem.h>
+#include <CEGUIWindow.h>
+#include <CEGUIWindowManager.h>
+#include <ogreceguirenderer/OgreCEGUIRenderer.h>
+
+#include "SpecialConfig.h" // Configures the macro below
+#ifdef CEGUILUA_USE_INTERNAL_LIBRARY
+#   include <ceguilua/CEGUILua.h>
+#else
+#   include <CEGUILua.h>
+#endif
+
+#include "util/Clock.h"
+#include "util/Convert.h"
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/OrxAssert.h"
+#include "ConsoleCommand.h"
+#include "Core.h"
+#include "GraphicsManager.h"
+#include "LuaState.h"
+#include "PathConfig.h"
+#include "Resource.h"
+#include "input/InputManager.h"
+#include "input/InputState.h"
+#include "input/KeyBinderManager.h"
+
+namespace orxonox
+{
+    static void key_esc()
+        { GUIManager::getInstance().keyESC(); }
+    SetConsoleCommandShortcutExternAlias(key_esc, "keyESC");
+
+    class CEGUILogger : public CEGUI::DefaultLogger
+    {
+    public:
+        void logEvent(const CEGUI::String& message, CEGUI::LoggingLevel level = CEGUI::Standard)
+        {
+            int orxonoxLevel = CEGUI::Standard;
+            switch (level)
+            {
+                case CEGUI::Errors:      orxonoxLevel = 1; break;
+                case CEGUI::Warnings:    orxonoxLevel = 2; break;
+                case CEGUI::Standard:    orxonoxLevel = 4; break;
+                case CEGUI::Informative: orxonoxLevel = 5; break;
+                case CEGUI::Insane:      orxonoxLevel = 6; break;
+                default: OrxAssert(false, "CEGUI log level out of range, inpect immediately!");
+            }
+            OutputHandler::getOutStream(orxonoxLevel)
+                << "CEGUI: " << message << std::endl;
+
+            CEGUI::DefaultLogger::logEvent(message, level);
+        }
+    };
+
+    static CEGUI::MouseButton convertButton(MouseButtonCode::ByEnum button);
+
+    GUIManager* GUIManager::singletonPtr_s = 0;
+
+    SetConsoleCommandShortcut(GUIManager, showGUI).accessLevel(AccessLevel::User).defaultValue(1, false).defaultValue(2, true);
+    SetConsoleCommandShortcut(GUIManager, hideGUI).accessLevel(AccessLevel::User);
+
+    /**
+    @brief
+        Constructs the GUIManager by starting up CEGUI
+
+        Creates the interface to Ogre, sets up the CEGUI renderer and the Lua script module together with the Lua engine.
+        The log is set up and connected to the CEGUILogger.
+        After Lua setup tolua++-elements are linked to Lua-state to give Lua access to C++-code.
+        Finally initial Lua code is executed (maybe we can do this with the CEGUI startup script automatically).
+    @param renderWindow
+        Ogre's render window. Without this, the GUI cannot be displayed.
+    @return true if success, otherwise false
+    */
+    GUIManager::GUIManager(const std::pair<int, int>& mousePosition)
+        : resourceProvider_(NULL)
+        , camera_(NULL)
+    {
+        using namespace CEGUI;
+
+        COUT(3) << "Initialising CEGUI." << std::endl;
+
+        // Note: No SceneManager specified yet
+        guiRenderer_.reset(new OgreCEGUIRenderer(GraphicsManager::getInstance().getRenderWindow(), Ogre::RENDER_QUEUE_OVERLAY, false, 3000));
+        resourceProvider_ = guiRenderer_->createResourceProvider();
+        resourceProvider_->setDefaultResourceGroup("GUI");
+
+        // Setup scripting
+        luaState_.reset(new LuaState());
+        rootFileInfo_ = Resource::getInfo("InitialiseGUI.lua");
+        // This is necessary to ensure that input events also use the right resource info when triggering lua functions
+        luaState_->setDefaultResourceInfo(this->rootFileInfo_);
+        scriptModule_.reset(new LuaScriptModule(luaState_->getInternalLuaState()));
+        scriptModule_->setDefaultPCallErrorHandler(LuaState::ERROR_HANDLER_NAME);
+
+        // Create our own logger to specify the filepath
+        std::auto_ptr<CEGUILogger> ceguiLogger(new CEGUILogger());
+        ceguiLogger->setLogFilename(PathConfig::getLogPathString() + "cegui.log");
+        // set the log level according to ours (translate by subtracting 1)
+        ceguiLogger->setLoggingLevel(
+            static_cast<LoggingLevel>(OutputHandler::getInstance().getSoftDebugLevel("logFile") - 1));
+        this->ceguiLogger_ = ceguiLogger.release();
+
+        // Create the CEGUI system singleton
+        guiSystem_.reset(new System(guiRenderer_.get(), resourceProvider_, 0, scriptModule_.get()));
+
+        // Align CEGUI mouse with OIS mouse
+        guiSystem_->injectMousePosition((float)mousePosition.first, (float)mousePosition.second);
+
+        // Initialise the Lua framework and load the schemes
+        this->luaState_->doFile("InitialiseGUI.lua");
+
+        // Create the root nodes
+        this->rootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("MenuWidgets/StaticImage", "AbsoluteRootWindow");
+        this->rootWindow_->setProperty("FrameEnabled", "False");
+        this->hudRootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("DefaultWindow", "HUDRootWindow");
+        this->menuRootWindow_ = CEGUI::WindowManager::getSingleton().createWindow("DefaultWindow", "MenuRootWindow");
+        // And connect them
+        CEGUI::System::getSingleton().setGUISheet(this->rootWindow_);
+        this->rootWindow_->addChildWindow(this->hudRootWindow_);
+        this->rootWindow_->addChildWindow(this->menuRootWindow_);
+
+        // No background to start with (sets the alpha value to 0)
+        this->setBackgroundImage("");
+
+        // Set up the sheet manager in the Lua framework
+        this->luaState_->doFile("SheetManager.lua");
+    }
+
+    /**
+    @brief
+        Basically shuts down CEGUI (member smart pointers) but first unloads our Tolua modules.
+    */
+    GUIManager::~GUIManager()
+    {
+    }
+
+    /**
+    @brief
+        used to tick the GUI
+    @param time
+        clock which provides time value for the GUI System
+
+        Ticking the GUI means updating it with a certain regularity.
+        The elapsed time since the last call is given in the time value provided by the clock.
+        This time value is then used to provide a fluent animation of the GUI.
+    */
+    void GUIManager::preUpdate(const Clock& time)
+    {
+        assert(guiSystem_);
+        this->protectedCall(boost::bind(&CEGUI::System::injectTimePulse, _1, time.getDeltaTime()));
+    }
+
+    /**
+    @brief
+        Tells the GUIManager which SceneManager to use
+    @param camera
+        The current camera on which the GUI should be displayed on.
+
+        In fact the GUIManager needs the SceneManager and not the Camera to display the GUI.
+        This means the GUI is not bound to a camera but rather to the SceneManager.
+        Hiding the GUI when needed can therefore not be resolved by just NOT setting the current camera.
+    */
+    void GUIManager::setCamera(Ogre::Camera* camera)
+    {
+        this->camera_ = camera;
+        if (camera == NULL)
+            this->guiRenderer_->setTargetSceneManager(0);
+        else
+            this->guiRenderer_->setTargetSceneManager(camera->getSceneManager());
+    }
+
+    /**
+    @brief
+        Executes Lua code
+    @param str
+        reference to string object holding the Lua code which is to be executed
+    */
+    void GUIManager::executeCode(const std::string& str)
+    {
+        this->luaState_->doString(str, rootFileInfo_);
+    }
+
+    /** Loads a GUI sheet by Lua script
+    @param name
+        The name of the GUI (like the script name, but without the extension)
+    */
+    void GUIManager::loadGUI(const std::string& name)
+    {
+        this->executeCode("loadSheet(\"" + name + "\")");
+    }
+
+    /**
+    @brief
+        Displays specified GUI on screen
+    @param name
+        The name of the GUI
+
+        The function executes the Lua function with the same name in case the GUIManager is ready.
+    */
+    /*static*/ void GUIManager::showGUI(const std::string& name, bool bHidePrevious)
+    {
+        GUIManager::getInstance().executeCode("showMenuSheet(\"" + name + "\", " + multi_cast<std::string>(bHidePrevious) + ")");
+    }
+
+    /**
+    @brief
+        Hack-ish. Needed for GUIOverlay.
+    */
+    void GUIManager::showGUIExtra(const std::string& name, const std::string& ptr, bool bHidePrevious)
+    {
+        this->executeCode("showMenuSheet(\"" + name + "\", " + multi_cast<std::string>(bHidePrevious) + ", " + ptr + ")");
+    }
+
+    /**
+    @brief
+        Hides specified GUI.
+    @param name
+        The name of the GUI.
+    */
+    /*static*/ void GUIManager::hideGUI(const std::string& name)
+    {
+        GUIManager::getInstance().executeCode("hideMenuSheet(\"" + name + "\")");
+    }
+
+    const std::string& GUIManager::createInputState(const std::string& name, TriBool::Value showCursor, TriBool::Value useKeyboard, bool bBlockJoyStick)
+    {
+        InputState* state = InputManager::getInstance().createInputState(name);
+
+        /* Table that maps isFullScreen() and showCursor to mouseExclusive
+        isFullscreen / showCursor | True  | False | Dontcare
+        ----------------------------------------------------
+        true                      | True  | True  | Dontcare
+        ----------------------------------------------------
+        false                     | False | True  | Dontcare
+        */
+        if (showCursor == TriBool::Dontcare)
+            state->setMouseExclusive(TriBool::Dontcare);
+        else if (GraphicsManager::getInstance().isFullScreen() || showCursor == TriBool::False)
+            state->setMouseExclusive(TriBool::True);
+        else
+            state->setMouseExclusive(TriBool::False);
+
+        if (showCursor == TriBool::True)
+            state->setMouseHandler(this);
+        else if (showCursor == TriBool::False)
+            state->setMouseHandler(&InputHandler::EMPTY);
+
+        if (useKeyboard == TriBool::True)
+            state->setKeyHandler(this);
+        else if (useKeyboard == TriBool::False)
+            state->setKeyHandler(&InputHandler::EMPTY);
+
+        if (bBlockJoyStick)
+            state->setJoyStickHandler(&InputHandler::EMPTY);
+
+        return state->getName();
+    }
+
+    void GUIManager::keyESC()
+    {
+        this->executeCode("keyESC()");
+    }
+
+    void GUIManager::setBackgroundImage(const std::string& imageSet, const std::string imageName)
+    {
+        if (imageSet.empty() || imageName.empty())
+            this->setBackgroundImage("");
+        else
+            this->setBackgroundImage("set: " + imageSet + " image: " + imageName);
+    }
+
+    void GUIManager::setBackgroundImage(const std::string& image)
+    {
+        if (image.empty())
+            this->rootWindow_->setProperty("Alpha", "0.0");
+        else
+            this->rootWindow_->setProperty("Alpha", "1.0");
+        this->rootWindow_->setProperty("Image", image);
+    }
+
+    void GUIManager::keyPressed(const KeyEvent& evt)
+    {
+        this->protectedCall(boost::bind(&CEGUI::System::injectKeyDown, _1, evt.getKeyCode()));
+        this->protectedCall(boost::bind(&CEGUI::System::injectChar, _1, evt.getText()));
+    }
+
+    void GUIManager::keyReleased(const KeyEvent& evt)
+    {
+        this->protectedCall(boost::bind(&CEGUI::System::injectKeyUp, _1, evt.getKeyCode()));
+    }
+
+    /**
+    @brief
+        Function receiving a mouse button pressed event.
+    @param id
+        ID of the mouse button which got pressed
+
+        This function is inherited by MouseHandler and injects the event into CEGUI.
+        It is for CEGUI to process the event.
+    */
+    void GUIManager::buttonPressed(MouseButtonCode::ByEnum id)
+    {
+        this->protectedCall(boost::bind(&CEGUI::System::injectMouseButtonDown, _1, convertButton(id)));
+    }
+
+    /**
+    @brief
+        Function receiving a mouse button released event.
+    @param id
+        ID of the mouse button which got released
+
+        This function is inherited by MouseHandler and injects the event into CEGUI.
+        It is for CEGUI to process the event.
+    */
+    void GUIManager::buttonReleased(MouseButtonCode::ByEnum id)
+    {
+        this->protectedCall(boost::bind(&CEGUI::System::injectMouseButtonUp, _1, convertButton(id)));
+    }
+
+    void GUIManager::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
+    {
+        this->protectedCall(boost::bind(&CEGUI::System::injectMousePosition, _1, (float)abs.x, (float)abs.y));
+    }
+
+    void GUIManager::mouseScrolled(int abs, int rel)
+    {
+        this->protectedCall(boost::bind(&CEGUI::System::injectMouseWheelChange, _1, (float)rel));
+    }
+
+    /**
+    @brief
+        converts mouse event code to CEGUI event code
+    @param button
+        code of the mouse button as we use it in Orxonox
+    @return
+        code of the mouse button as it is used by CEGUI
+
+        Simple conversion from mouse event code in Orxonox to the one used in CEGUI.
+     */
+    static inline CEGUI::MouseButton convertButton(MouseButtonCode::ByEnum button)
+    {
+        switch (button)
+        {
+        case MouseButtonCode::Left:
+            return CEGUI::LeftButton;
+
+        case MouseButtonCode::Right:
+            return CEGUI::RightButton;
+
+        case MouseButtonCode::Middle:
+            return CEGUI::MiddleButton;
+
+        case MouseButtonCode::Button3:
+            return CEGUI::X1Button;
+
+        case MouseButtonCode::Button4:
+            return CEGUI::X2Button;
+
+        default:
+            return CEGUI::NoButton;
+        }
+    }
+
+    /** Executes a CEGUI function normally, but catches CEGUI::ScriptException.
+        When a ScriptException occurs, the error message will be displayed and
+        the program carries on.
+    @remarks
+        The exception behaviour may pose problems if the code is not written
+        exception-safe (and you can forget about that in Lua). The program might
+        be left in an undefined state. But otherwise one script error would
+        terminate the whole program...
+    @note
+        Your life gets easier if you use boost::bind to create the object/function.
+    @param function
+        Any callable object/function that takes this->guiSystem_ as its only parameter.
+    @return
+        True if input was handled, false otherwise. A caught exception yields true.
+    */
+    template <typename FunctionType>
+    bool GUIManager::protectedCall(FunctionType function)
+    {
+        try
+        {
+            return function(this->guiSystem_);
+        }
+        catch (CEGUI::ScriptException& ex)
+        {
+            // Display the error and proceed. See @remarks why this can be dangerous.
+            COUT(1) << ex.getMessage() << std::endl;
+            return true;
+        }
+    }
+
+    void GUIManager::subscribeEventHelper(CEGUI::Window* window, const std::string& event, const std::string& function)
+    {
+        window->subscribeScriptedEvent(event, function);
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/GUIManager.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/GUIManager.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/GUIManager.h	(revision 6952)
@@ -0,0 +1,140 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GUIManager_H__
+#define _GUIManager_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <set>
+#include <string>
+#include <CEGUIForwardRefs.h>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include "util/OgreForwardRefs.h"
+#include "util/TriBool.h"
+#include "util/Singleton.h"
+#include "input/InputHandler.h"
+
+// Tolua includes (have to be relative to the current directory)
+/*
+$cfile "../util/TriBool.h" // tolua_export
+*/
+
+namespace orxonox // tolua_export
+{ // tolua_export
+    class PlayerInfo; // Forward declaration
+
+    /**
+    @class GUIManager
+    @brief
+        Provides a simple interface to CEGUI with tolua methods and console commands. It also acts as a key and mouse handler.
+
+        The GUIManager is a singleton and can be called anywhere when access on the GUI is needed.
+
+        Since the GUI needs user input, the GUIManager implements the functions needed to act as a key and/or mouse handler.
+        Those input events are then injected into CEGUI in Lua.
+    */
+    class _CoreExport GUIManager // tolua_export
+        : public Singleton<GUIManager>, public InputHandler
+    { // tolua_export
+        friend class Singleton<GUIManager>;
+    public:
+        GUIManager(const std::pair<int, int>& mousePosition);
+        ~GUIManager();
+
+        void preUpdate(const Clock& time);
+
+        void loadGUI(const std::string& name);
+        static void showGUI(const std::string& name, bool bHidePrevious = false);
+        void showGUIExtra(const std::string& name, const std::string& ptr, bool bHidePrevious = false);
+        static void hideGUI(const std::string& name);
+        void keyESC();
+        void setBackgroundImage(const std::string& imageSet, const std::string imageName); // tolua_export
+        void setBackgroundImage(const std::string& image);
+
+        //! Creates a new InputState to be used with a GUI Sheet
+        const std::string& createInputState(const std::string& name, TriBool::Value showCursor = TriBool::True, TriBool::Value useKeyboard = TriBool::True, bool bBlockJoyStick = false); // tolua_export
+
+        //! Returns the root window for all menu sheets
+        CEGUI::Window* getMenuRootWindow() { return this->menuRootWindow_; } // tolua_export
+        //! Returns the root window for all HUD sheets
+        CEGUI::Window* getHUDRootWindow() { return this->hudRootWindow_; } // tolua_export
+
+        void setCamera(Ogre::Camera* camera);
+        Ogre::Camera* getCamera() { return this->camera_; }
+
+        inline void setPlayer(const std::string& guiname, PlayerInfo* player)
+            { this->players_[guiname] = player; }
+        inline PlayerInfo* getPlayer(const std::string& guiname) const
+            { std::map<std::string, PlayerInfo*>::const_iterator it = this->players_.find(guiname); return (it != this->players_.end()) ? it->second : 0; }
+
+        // TODO: Temporary hack because the tolua exported CEGUI method does not seem to work
+        static void subscribeEventHelper(CEGUI::Window* window, const std::string& event, const std::string& function); //tolua_export
+
+        static GUIManager& getInstance() { return Singleton<GUIManager>::getInstance(); } // tolua_export
+
+    private:
+        GUIManager(const GUIManager& instance); //!< private and undefined copy c'tor (this is a singleton class)
+
+        void executeCode(const std::string& str);
+        template <typename FunctionType>
+        bool protectedCall(FunctionType function);
+
+        // keyHandler functions
+        void keyPressed (const KeyEvent& evt);
+        void keyReleased(const KeyEvent& evt);
+
+        // mouseHandler functions
+        void buttonPressed (MouseButtonCode::ByEnum id);
+        void buttonReleased(MouseButtonCode::ByEnum id);
+        void mouseMoved    (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
+        void mouseScrolled (int abs, int rel);
+
+        scoped_ptr<CEGUI::OgreCEGUIRenderer> guiRenderer_;      //!< CEGUI's interface to the Ogre Engine
+        scoped_ptr<LuaState>                 luaState_;         //!< LuaState, access point to the Lua engine
+        scoped_ptr<CEGUI::LuaScriptModule>   scriptModule_;     //!< CEGUI's script module to use Lua
+        scoped_ptr<CEGUI::System>            guiSystem_;        //!< CEGUI's main system
+        shared_ptr<ResourceInfo>             rootFileInfo_;     //!< Resource information about the root script
+        CEGUI::ResourceProvider*             resourceProvider_; //!< CEGUI's resource provider
+        CEGUI::Logger*                       ceguiLogger_;      //!< CEGUI's logger to be able to log CEGUI errors in our log
+        CEGUI::Window*                       rootWindow_;       //!< Root node for all windows
+        CEGUI::Window*                       hudRootWindow_;    //!< Root node for the HUD sheets
+        CEGUI::Window*                       menuRootWindow_;   //!< Root node for the menu sheets (used by Lua)
+        std::map<std::string, PlayerInfo*>   players_;          //!< Stores the player (owner) for each GUI
+        Ogre::Camera*                        camera_;           //!< Camera used to render the scene with the GUI
+
+        static GUIManager*                   singletonPtr_s;    //!< Singleton reference to GUIManager
+
+    }; // tolua_export
+} // tolua_export
+
+#endif /* _GUIManager_H__ */
Index: /code/branches/rocket2/src/libraries/core/Game.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/Game.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Game.cc	(revision 6952)
@@ -0,0 +1,610 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of the Game class.
+*/
+
+#include "Game.h"
+
+#include <exception>
+#include <boost/weak_ptr.hpp>
+
+#include "util/Clock.h"
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/ScopeGuard.h"
+#include "util/Sleep.h"
+#include "util/SubString.h"
+#include "CommandLineParser.h"
+#include "ConsoleCommand.h"
+#include "Core.h"
+#include "CoreIncludes.h"
+#include "ConfigValueIncludes.h"
+#include "GameMode.h"
+#include "GameState.h"
+#include "GUIManager.h"
+
+namespace orxonox
+{
+    static void stop_game()
+        { Game::getInstance().stop(); }
+    SetConsoleCommandShortcutExternAlias(stop_game, "exit");
+    static void printFPS()
+        { COUT(0) << Game::getInstance().getAvgFPS() << std::endl; }
+    SetConsoleCommandShortcutExternAlias(printFPS, "printFPS");
+    static void printTickTime()
+        { COUT(0) << Game::getInstance().getAvgTickTime() << std::endl; }
+    SetConsoleCommandShortcutExternAlias(printTickTime, "printTickTime");
+
+    std::map<std::string, GameStateInfo> Game::gameStateDeclarations_s;
+    Game* Game::singletonPtr_s = 0;
+
+    //! Represents one node of the game state tree.
+    struct GameStateTreeNode
+    {
+        std::string name_;
+        weak_ptr<GameStateTreeNode> parent_;
+        std::vector<shared_ptr<GameStateTreeNode> > children_;
+    };
+
+    Game::Game(const std::string& cmdLine)
+        // Destroy factories before the Core!
+        : gsFactoryDestroyer_(Game::GameStateFactory::getFactories(), &std::map<std::string, shared_ptr<GameStateFactory> >::clear)
+    {
+        this->bAbort_ = false;
+        bChangingState_ = false;
+
+#ifdef ORXONOX_PLATFORM_WINDOWS
+        minimumSleepTime_ = 1000/*us*/;
+#else
+        minimumSleepTime_ = 0/*us*/;
+#endif
+
+        // reset statistics
+        this->statisticsStartTime_ = 0;
+        this->statisticsTickTimes_.clear();
+        this->periodTickTime_ = 0;
+        this->periodTime_ = 0;
+        this->avgFPS_ = 0.0f;
+        this->avgTickTime_ = 0.0f;
+        this->excessSleepTime_ = 0;
+
+        // Create an empty root state
+        this->declareGameState<GameState>("GameState", "emptyRootGameState", true, false);
+
+        // Set up a basic clock to keep time
+        this->gameClock_.reset(new Clock());
+
+        // Create the Core
+        this->core_.reset(new Core(cmdLine));
+
+        // Do this after the Core creation!
+        ClassIdentifier<Game>::getIdentifier("Game")->initialiseObject(this, "Game", true);
+        this->setConfigValues();
+
+        // After the core has been created, we can safely instantiate the GameStates that don't require graphics
+        for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin();
+            it != gameStateDeclarations_s.end(); ++it)
+        {
+            if (!it->second.bGraphicsMode)
+                constructedStates_[it->second.stateName] = GameStateFactory::fabricate(it->second);
+        }
+
+        // The empty root state is ALWAYS loaded!
+        this->rootStateNode_ = shared_ptr<GameStateTreeNode>(new GameStateTreeNode());
+        this->rootStateNode_->name_ = "emptyRootGameState";
+        this->loadedTopStateNode_ = this->rootStateNode_;
+        this->loadedStates_.push_back(this->getState(rootStateNode_->name_));
+    }
+
+    /**
+    @brief
+        All destruction code is handled by scoped_ptrs and SimpleScopeGuards.
+    */
+    Game::~Game()
+    {
+        // Remove us from the object lists again to avoid problems when destroying them
+        this->unregisterObject();
+    }
+
+    void Game::setConfigValues()
+    {
+        SetConfigValue(statisticsRefreshCycle_, 250000)
+            .description("Sets the time in microseconds interval at which average fps, etc. get updated.");
+        SetConfigValue(statisticsAvgLength_, 1000000)
+            .description("Sets the time in microseconds interval at which average fps, etc. gets calculated.");
+        SetConfigValue(fpsLimit_, 50)
+            .description("Sets the desired frame rate (0 for no limit).");
+    }
+
+    /**
+    @brief
+        Main loop of the orxonox game.
+    @note
+        We use the Ogre::Timer to measure time since it uses the most precise
+        method an any platform (however the windows timer lacks time when under
+        heavy kernel load!).
+    */
+    void Game::run()
+    {
+        if (this->requestedStateNodes_.empty())
+            COUT(0) << "Warning: Starting game without requesting GameState. This automatically terminates the program." << std::endl;
+
+        // START GAME
+        // first delta time should be about 0 seconds
+        this->gameClock_->capture();
+        // A first item is required for the fps limiter
+        StatisticsTickInfo tickInfo = {0, 0};
+        statisticsTickTimes_.push_back(tickInfo);
+        while (!this->bAbort_ && (!this->loadedStates_.empty() || this->requestedStateNodes_.size() > 0))
+        {
+            // Generate the dt
+            this->gameClock_->capture();
+
+            // Statistics init
+            StatisticsTickInfo tickInfo = {gameClock_->getMicroseconds(), 0};
+            statisticsTickTimes_.push_back(tickInfo);
+            this->periodTime_ += this->gameClock_->getDeltaTimeMicroseconds();
+
+            // Update the GameState stack if required
+            this->updateGameStateStack();
+
+            // Core preUpdate
+            try
+                { this->core_->preUpdate(*this->gameClock_); }
+            catch (...)
+            {
+                COUT(0) << "An exception occurred in the Core preUpdate: " << Exception::handleMessage() << std::endl;
+                COUT(0) << "This should really never happen! Closing the program." << std::endl;
+                this->stop();
+                break;
+            }
+
+            // Update the GameStates bottom up in the stack
+            this->updateGameStates();
+
+            // Core postUpdate
+            try
+                { this->core_->postUpdate(*this->gameClock_); }
+            catch (...)
+            {
+                COUT(0) << "An exception occurred in the Core postUpdate: " << Exception::handleMessage() << std::endl;
+                COUT(0) << "This should really never happen! Closing the program." << std::endl;
+                this->stop();
+                break;
+            }
+
+            // Evaluate statistics
+            this->updateStatistics();
+
+            // Limit frame rate
+            this->updateFPSLimiter();
+        }
+
+        // UNLOAD all remaining states
+        while (this->loadedStates_.size() > 1)
+            this->unloadState(this->loadedStates_.back()->getName());
+        this->loadedTopStateNode_ = this->rootStateNode_;
+        this->requestedStateNodes_.clear();
+    }
+
+    void Game::updateGameStateStack()
+    {
+        while (this->requestedStateNodes_.size() > 0)
+        {
+            shared_ptr<GameStateTreeNode> requestedStateNode = this->requestedStateNodes_.front();
+            assert(this->loadedTopStateNode_);
+            if (!this->loadedTopStateNode_->parent_.expired() && requestedStateNode == this->loadedTopStateNode_->parent_.lock())
+                this->unloadState(loadedTopStateNode_->name_);
+            else // has to be child
+            {
+                try
+                {
+                    this->loadState(requestedStateNode->name_);
+                }
+                catch (...)
+                {
+                    COUT(1) << "Error: Loading GameState '" << requestedStateNode->name_ << "' failed: " << Exception::handleMessage() << std::endl;
+                    // All scheduled operations have now been rendered inert --> flush them and issue a warning
+                    if (this->requestedStateNodes_.size() > 1)
+                        COUT(4) << "All " << this->requestedStateNodes_.size() - 1 << " scheduled transitions have been ignored." << std::endl;
+                    this->requestedStateNodes_.clear();
+                    break;
+                }
+            }
+            this->loadedTopStateNode_ = requestedStateNode;
+            this->requestedStateNodes_.erase(this->requestedStateNodes_.begin());
+        }
+    }
+
+    void Game::updateGameStates()
+    {
+        // Note: The first element is the empty root state, which doesn't need ticking
+        for (GameStateVector::const_iterator it = this->loadedStates_.begin() + 1;
+            it != this->loadedStates_.end(); ++it)
+        {
+            try
+            {
+                // Add tick time for most of the states
+                uint64_t timeBeforeTick = 0;
+                if ((*it)->getInfo().bIgnoreTickTime)
+                    timeBeforeTick = this->gameClock_->getRealMicroseconds();
+                (*it)->update(*this->gameClock_);
+                if ((*it)->getInfo().bIgnoreTickTime)
+                    this->subtractTickTime(static_cast<int32_t>(this->gameClock_->getRealMicroseconds() - timeBeforeTick));
+            }
+            catch (...)
+            {
+                COUT(1) << "An exception occurred while updating '" << (*it)->getName() << "': " << Exception::handleMessage() << std::endl;
+                COUT(1) << "This should really never happen!" << std::endl;
+                COUT(1) << "Unloading all GameStates depending on the one that crashed." << std::endl;
+                shared_ptr<GameStateTreeNode> current = this->loadedTopStateNode_;
+                while (current->name_ != (*it)->getName() && current)
+                    current = current->parent_.lock();
+                if (current && current->parent_.lock())
+                    this->requestState(current->parent_.lock()->name_);
+                else
+                    this->stop();
+                break;
+            }
+        }
+    }
+
+    void Game::updateStatistics()
+    {
+        // Add the tick time of this frame (rendering time has already been subtracted)
+        uint64_t currentTime = gameClock_->getMicroseconds();
+        uint64_t currentRealTime = gameClock_->getRealMicroseconds();
+        this->statisticsTickTimes_.back().tickLength += (uint32_t)(currentRealTime - currentTime);
+        this->periodTickTime_ += (uint32_t)(currentRealTime - currentTime);
+        if (this->periodTime_ > this->statisticsRefreshCycle_)
+        {
+            std::list<StatisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
+            assert(it != this->statisticsTickTimes_.end());
+            int64_t lastTime = currentTime - this->statisticsAvgLength_;
+            if (static_cast<int64_t>(it->tickTime) < lastTime)
+            {
+                do
+                {
+                    assert(this->periodTickTime_ >= it->tickLength);
+                    this->periodTickTime_ -= it->tickLength;
+                    ++it;
+                    assert(it != this->statisticsTickTimes_.end());
+                } while (static_cast<int64_t>(it->tickTime) < lastTime);
+                this->statisticsTickTimes_.erase(this->statisticsTickTimes_.begin(), it);
+            }
+
+            uint32_t framesPerPeriod = this->statisticsTickTimes_.size();
+            // Why minus 1? No idea, but otherwise the fps rate is always (from 10 to 200!) one frame too low
+            this->avgFPS_ = -1 + static_cast<float>(framesPerPeriod) / (currentTime - this->statisticsTickTimes_.front().tickTime) * 1000000.0f;
+            this->avgTickTime_ = static_cast<float>(this->periodTickTime_) / framesPerPeriod / 1000.0f;
+
+            this->periodTime_ -= this->statisticsRefreshCycle_;
+        }
+    }
+
+    void Game::updateFPSLimiter()
+    {
+        uint64_t nextTime = gameClock_->getMicroseconds() - excessSleepTime_ + static_cast<uint32_t>(1000000.0f / fpsLimit_);
+        uint64_t currentRealTime = gameClock_->getRealMicroseconds();
+        while (currentRealTime < nextTime - minimumSleepTime_)
+        {
+            usleep((unsigned long)(nextTime - currentRealTime));
+            currentRealTime = gameClock_->getRealMicroseconds();
+        }
+        // Integrate excess to avoid steady state error
+        excessSleepTime_ = (int)(currentRealTime - nextTime);
+        // Anti windup
+        if (excessSleepTime_ > 50000) // 20ms is about the maximum time Windows would sleep for too long
+            excessSleepTime_ = 50000;
+    }
+
+    void Game::stop()
+    {
+        this->bAbort_ = true;
+    }
+
+    void Game::subtractTickTime(int32_t length)
+    {
+        assert(!this->statisticsTickTimes_.empty());
+        this->statisticsTickTimes_.back().tickLength -= length;
+        this->periodTickTime_ -= length;
+    }
+
+
+    /***** GameState related *****/
+
+    void Game::requestState(const std::string& name)
+    {
+        if (!this->checkState(name))
+        {
+            COUT(2) << "Warning: GameState named '" << name << "' doesn't exist!" << std::endl;
+            return;
+        }
+
+        if (this->bChangingState_)
+        {
+            COUT(2) << "Warning: Requesting GameStates while loading/unloading a GameState is illegal! Ignoring." << std::endl;
+            return;
+        }
+
+        shared_ptr<GameStateTreeNode> lastRequestedNode;
+        if (this->requestedStateNodes_.empty())
+            lastRequestedNode = this->loadedTopStateNode_;
+        else
+            lastRequestedNode = this->requestedStateNodes_.back();
+        if (name == lastRequestedNode->name_)
+        {
+            COUT(2) << "Warning: Requesting the currently active state! Ignoring." << std::endl;
+            return;
+        }
+
+        // Check children first
+        std::vector<shared_ptr<GameStateTreeNode> > requestedNodes;
+        for (unsigned int i = 0; i < lastRequestedNode->children_.size(); ++i)
+        {
+            if (lastRequestedNode->children_[i]->name_ == name)
+            {
+                requestedNodes.push_back(lastRequestedNode->children_[i]);
+                break;
+            }
+        }
+
+        if (requestedNodes.empty())
+        {
+            // Check parent and all its grand parents
+            shared_ptr<GameStateTreeNode> currentNode = lastRequestedNode;
+            while (currentNode != NULL)
+            {
+                if (currentNode->name_ == name)
+                    break;
+                currentNode = currentNode->parent_.lock();
+                requestedNodes.push_back(currentNode);
+            }
+            if (currentNode == NULL)
+                requestedNodes.clear();
+        }
+
+        if (requestedNodes.empty())
+            COUT(1) << "Error: Requested GameState transition is not allowed. Ignoring." << std::endl;
+        else
+            this->requestedStateNodes_.insert(requestedStateNodes_.end(), requestedNodes.begin(), requestedNodes.end());
+    }
+
+    void Game::requestStates(const std::string& names)
+    {
+        SubString tokens(names, ",;", " ");
+        for (unsigned int i = 0; i < tokens.size(); ++i)
+            this->requestState(tokens[i]);
+    }
+
+    void Game::popState()
+    {
+        shared_ptr<GameStateTreeNode> lastRequestedNode;
+        if (this->requestedStateNodes_.empty())
+            lastRequestedNode = this->loadedTopStateNode_;
+        else
+            lastRequestedNode = this->requestedStateNodes_.back();
+        if (lastRequestedNode != this->rootStateNode_)
+            this->requestState(lastRequestedNode->parent_.lock()->name_);
+        else
+            COUT(2) << "Warning: Can't pop the internal dummy root GameState" << std::endl;
+    }
+
+    shared_ptr<GameState> Game::getState(const std::string& name)
+    {
+        GameStateMap::const_iterator it = constructedStates_.find(name);
+        if (it != constructedStates_.end())
+            return it->second;
+        else
+        {
+            std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(name);
+            if (it != gameStateDeclarations_s.end())
+                COUT(1) << "Error: GameState '" << name << "' has not yet been loaded." << std::endl;
+            else
+                COUT(1) << "Error: Could not find GameState '" << name << "'." << std::endl;
+            return shared_ptr<GameState>();
+        }
+    }
+
+    void Game::setStateHierarchy(const std::string& str)
+    {
+        // Split string into pieces of the form whitespacesText
+        std::vector<std::pair<std::string, int> > stateStrings;
+        size_t pos = 0;
+        size_t startPos = 0;
+        while (pos < str.size())
+        {
+            int indentation = 0;
+            while (pos < str.size() && str[pos] == ' ')
+                ++indentation, ++pos;
+            startPos = pos;
+            while (pos < str.size() && str[pos] != ' ')
+                ++pos;
+            stateStrings.push_back(std::make_pair(str.substr(startPos, pos - startPos), indentation));
+        }
+        if (stateStrings.empty())
+            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));
+
+        // Parse elements recursively
+        std::vector<std::pair<std::string, int> >::const_iterator begin = stateStrings.begin();
+        parseStates(begin, this->rootStateNode_);
+    }
+
+    /*** Internal ***/
+
+    void Game::parseStates(std::vector<std::pair<std::string, int> >::const_iterator& it, shared_ptr<GameStateTreeNode> currentNode)
+    {
+        SubString tokens(it->first, ",");
+        std::vector<std::pair<std::string, int> >::const_iterator startIt = it;
+
+        for (unsigned int i = 0; i < tokens.size(); ++i)
+        {
+            it = startIt; // Reset iterator to the beginning of the sub tree
+            if (!this->checkState(tokens[i]))
+                ThrowException(GameState, "GameState with name '" << tokens[i] << "' not found!");
+            if (tokens[i] == this->rootStateNode_->name_)
+                ThrowException(GameState, "You shouldn't use 'emptyRootGameState' in the hierarchy...");
+            shared_ptr<GameStateTreeNode> node(new GameStateTreeNode());
+            node->name_ = tokens[i];
+            node->parent_ = currentNode;
+            currentNode->children_.push_back(node);
+
+            int currentLevel = it->second;
+            ++it;
+            while (it->second != -1)
+            {
+                if (it->second <= currentLevel)
+                    break;
+                else if (it->second == currentLevel + 1)
+                    parseStates(it, node);
+                else
+                    ThrowException(GameState, "Indentation error while parsing the hierarchy.");
+            }
+        }
+    }
+
+    void Game::loadGraphics()
+    {
+        if (!GameMode::showsGraphics())
+        {
+            core_->loadGraphics();
+            Loki::ScopeGuard graphicsUnloader = Loki::MakeObjGuard(*this, &Game::unloadGraphics);
+
+            // Construct all the GameStates that require graphics
+            for (std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.begin();
+                it != gameStateDeclarations_s.end(); ++it)
+            {
+                if (it->second.bGraphicsMode)
+                {
+                    // Game state loading failure is serious --> don't catch
+                    shared_ptr<GameState> gameState = GameStateFactory::fabricate(it->second);
+                    if (!constructedStates_.insert(std::make_pair(
+                        it->second.stateName, gameState)).second)
+                        assert(false); // GameState was already created!
+                }
+            }
+            graphicsUnloader.Dismiss();
+        }
+    }
+
+    void Game::unloadGraphics()
+    {
+        if (GameMode::showsGraphics())
+        {
+            // Destroy all the GameStates that require graphics
+            for (GameStateMap::iterator it = constructedStates_.begin(); it != constructedStates_.end();)
+            {
+                if (it->second->getInfo().bGraphicsMode)
+                    constructedStates_.erase(it++);
+                else
+                    ++it;
+            }
+
+            core_->unloadGraphics();
+        }
+    }
+
+    bool Game::checkState(const std::string& name) const
+    {
+        std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(name);
+        if (it == gameStateDeclarations_s.end())
+            return false;
+        else
+            return true;
+    }
+
+    void Game::loadState(const std::string& name)
+    {
+        this->bChangingState_ = true;
+        LOKI_ON_BLOCK_EXIT_OBJ(*this, &Game::resetChangingState);
+
+        // If state requires graphics, load it
+        Loki::ScopeGuard graphicsUnloader = Loki::MakeObjGuard(*this, &Game::unloadGraphics);
+        if (gameStateDeclarations_s[name].bGraphicsMode && !GameMode::showsGraphics())
+            this->loadGraphics();
+        else
+            graphicsUnloader.Dismiss();
+
+        shared_ptr<GameState> state = this->getState(name);
+        state->activateInternal();
+        if (!this->loadedStates_.empty())
+            this->loadedStates_.back()->activity_.topState = false;
+        this->loadedStates_.push_back(state);
+        state->activity_.topState = true;
+
+        graphicsUnloader.Dismiss();
+    }
+
+    void Game::unloadState(const std::string& name)
+    {
+        this->bChangingState_ = true;
+        try
+        {
+            shared_ptr<GameState> state = this->getState(name);
+            state->activity_.topState = false;
+            this->loadedStates_.pop_back();
+            if (!this->loadedStates_.empty())
+                this->loadedStates_.back()->activity_.topState = true;
+            state->deactivateInternal();
+        }
+        catch (...)
+        {
+            COUT(2) << "Warning: Unloading GameState '" << name << "' threw an exception: " << Exception::handleMessage() << std::endl;
+            COUT(2) << "         There might be potential resource leaks involved! To avoid this, improve exception-safety." << std::endl;
+        }
+        // Check if graphics is still required
+        if (!bAbort_)
+        {
+            bool graphicsRequired = false;
+            for (unsigned i = 0; i < loadedStates_.size(); ++i)
+                graphicsRequired |= loadedStates_[i]->getInfo().bGraphicsMode;
+            if (!graphicsRequired)
+                this->unloadGraphics();
+        }
+        this->bChangingState_ = false;
+    }
+
+    /*static*/ std::map<std::string, shared_ptr<Game::GameStateFactory> >& Game::GameStateFactory::getFactories()
+    {
+        static std::map<std::string, shared_ptr<GameStateFactory> > factories;
+        return factories;
+    }
+
+    /*static*/ shared_ptr<GameState> Game::GameStateFactory::fabricate(const GameStateInfo& info)
+    {
+        std::map<std::string, shared_ptr<Game::GameStateFactory> >::const_iterator it = getFactories().find(info.className);
+        assert(it != getFactories().end());
+        return it->second->fabricateInternal(info);
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/Game.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Game.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Game.h	(revision 6952)
@@ -0,0 +1,225 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Declaration of Game Singleton.
+ */
+
+#ifndef _Game_H__
+#define _Game_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include <list>
+#include <map>
+#include <string>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/preprocessor/cat.hpp>
+
+#include "util/Debug.h"
+#include "util/ScopeGuard.h"
+#include "util/Singleton.h"
+#include "OrxonoxClass.h"
+
+/**
+@def
+    Adds a new GameState to the Game. The second parameter is the name as string
+    and every following paramter is a constructor argument (which is usually non existent)
+*/
+#define DeclareGameState(className, stateName, bIgnoreTickTime, bGraphicsMode) \
+    static bool BOOST_PP_CAT(bGameStateDummy_##className, __LINE__) = orxonox::Game::declareGameState<className>(#className, stateName, bIgnoreTickTime, bGraphicsMode)
+// tolua_begin
+namespace orxonox
+{
+// tolua_end
+
+    //! Helper object required before GameStates are being constructed
+    struct GameStateInfo
+    {
+        std::string stateName;
+        std::string className;
+        bool bIgnoreTickTime;
+        bool bGraphicsMode;
+    };
+
+    /**
+    @brief
+        Main class responsible for running the game.
+    @remark
+        You should only create this singleton once because it owns the Core class! (see remark there)
+    */
+// tolua_begin
+    class _CoreExport Game
+// tolua_end
+        : public Singleton<Game>, public OrxonoxClass
+    { // tolua_export
+        friend class Singleton<Game>;
+        typedef std::vector<shared_ptr<GameState> > GameStateVector;
+        typedef std::map<std::string, shared_ptr<GameState> > GameStateMap;
+        typedef shared_ptr<GameStateTreeNode> GameStateTreeNodePtr;
+
+    public:
+        Game(const std::string& cmdLine);
+        ~Game();
+
+        void setConfigValues();
+
+        void setStateHierarchy(const std::string& str);
+        shared_ptr<GameState> getState(const std::string& name);
+
+        void run();
+        void stop();
+
+        static Game& getInstance(){ return Singleton<Game>::getInstance(); } // tolua_export
+
+        void requestState(const std::string& name); //tolua_export
+        void requestStates(const std::string& names); //tolua_export
+        void popState(); //tolua_export
+
+        const Clock& getGameClock() { return *this->gameClock_; }
+
+        float getAvgTickTime() { return this->avgTickTime_; }
+        float getAvgFPS()      { return this->avgFPS_; }
+
+        void subtractTickTime(int32_t length);
+
+        template <class T>
+        static bool declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bConsoleMode);
+
+    private:
+        class _CoreExport GameStateFactory
+        {
+        public:
+            virtual ~GameStateFactory() { }
+            static shared_ptr<GameState> fabricate(const GameStateInfo& info);
+            template <class T>
+            static void createFactory(const std::string& className)
+                { getFactories()[className].reset(new TemplateGameStateFactory<T>()); }
+
+            virtual shared_ptr<GameState> fabricateInternal(const GameStateInfo& info) = 0;
+            static std::map<std::string, shared_ptr<GameStateFactory> >& getFactories();
+        };
+        template <class T>
+        class TemplateGameStateFactory : public GameStateFactory
+        {
+        public:
+            shared_ptr<GameState> fabricateInternal(const GameStateInfo& info)
+                { return shared_ptr<GameState>(new T(info)); }
+        };
+        // For the factory destruction
+        typedef Loki::ObjScopeGuardImpl0<std::map<std::string, shared_ptr<GameStateFactory> >, void (std::map<std::string, shared_ptr<GameStateFactory> >::*)()> ObjScopeGuard;
+
+        struct StatisticsTickInfo
+        {
+            uint64_t    tickTime;
+            uint32_t    tickLength;
+        };
+
+        Game(Game&); // don't mess with singletons
+
+        void loadGraphics();
+        void unloadGraphics();
+
+        void parseStates(std::vector<std::pair<std::string, int> >::const_iterator& it, shared_ptr<GameStateTreeNode> currentNode);
+        bool checkState(const std::string& name) const;
+        void loadState(const std::string& name);
+        void unloadState(const std::string& name);
+
+        // Main loop structuring
+        void updateGameStateStack();
+        void updateGameStates();
+        void updateStatistics();
+        void updateFPSLimiter();
+
+        // ScopeGuard helper function
+        void resetChangingState() { this->bChangingState_ = false; }
+
+        scoped_ptr<Clock>                  gameClock_;
+        scoped_ptr<Core>                   core_;
+        ObjScopeGuard                      gsFactoryDestroyer_;
+
+        GameStateMap                       constructedStates_;
+        GameStateVector                    loadedStates_;
+        GameStateTreeNodePtr               rootStateNode_;
+        GameStateTreeNodePtr               loadedTopStateNode_;
+        std::vector<GameStateTreeNodePtr>  requestedStateNodes_;
+
+        bool                               bChangingState_;
+        bool                               bAbort_;
+
+        // variables for time statistics
+        uint64_t                           statisticsStartTime_;
+        std::list<StatisticsTickInfo>      statisticsTickTimes_;
+        uint32_t                           periodTime_;
+        uint32_t                           periodTickTime_;
+        float                              avgFPS_;
+        float                              avgTickTime_;
+        int                                excessSleepTime_;
+        unsigned int                       minimumSleepTime_;
+
+        // config values
+        unsigned int                       statisticsRefreshCycle_;
+        unsigned int                       statisticsAvgLength_;
+        unsigned int                       fpsLimit_;
+
+        static std::map<std::string, GameStateInfo> gameStateDeclarations_s;
+        static Game* singletonPtr_s;        //!< Pointer to the Singleton
+    }; //tolua_export
+
+    template <class T>
+    /*static*/ bool Game::declareGameState(const std::string& className, const std::string& stateName, bool bIgnoreTickTime, bool bGraphicsMode)
+    {
+        std::map<std::string, GameStateInfo>::const_iterator it = gameStateDeclarations_s.find(stateName);
+        if (it == gameStateDeclarations_s.end())
+        {
+            GameStateInfo& info = gameStateDeclarations_s[stateName];
+            info.stateName = stateName;
+            info.className = className;
+            info.bIgnoreTickTime = bIgnoreTickTime;
+            info.bGraphicsMode = bGraphicsMode;
+        }
+        else
+        {
+            COUT(0) << "Error: Cannot declare two GameStates with the same name." << std::endl;
+            COUT(0) << "       Ignoring second one ('" << stateName << "')." << std::endl;
+        }
+
+        // Create a factory to delay GameState creation
+        GameStateFactory::createFactory<T>(className);
+
+        // just a required dummy return value
+        return true;
+    }
+} //tolua_export
+
+#endif /* _Game_H__ */
Index: /code/branches/rocket2/src/libraries/core/GameMode.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/GameMode.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/GameMode.cc	(revision 6952)
@@ -0,0 +1,39 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "GameMode.h"
+
+namespace orxonox
+{
+    bool GameMode::bShowsGraphics_s = false;
+    bool GameMode::bPlaysSound_s    = false;
+    bool GameMode::bHasServer_s     = false;
+    bool GameMode::bIsClient_s      = false;
+    bool GameMode::bIsStandalone_s  = false;
+    bool GameMode::bIsMaster_s      = false;
+}
Index: /code/branches/rocket2/src/libraries/core/GameMode.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/GameMode.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/GameMode.h	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Declaration of the GameMode class.
+*/
+
+#ifndef _GameMode_H__
+#define _GameMode_H__
+
+#include "CorePrereqs.h"
+
+// tolua_begin
+namespace orxonox
+{
+    class _CoreExport GameMode
+    {
+// tolua_end
+        friend class Core;
+
+        public:
+// tolua_begin
+            static bool showsGraphics() { return bShowsGraphics_s; }
+            static bool playsSound()    { return bPlaysSound_s; }
+            static bool hasServer()     { return bHasServer_s; }
+            static bool isClient()      { return bIsClient_s; }
+            static bool isStandalone()  { return bIsStandalone_s; }
+            static bool isMaster()      { return bIsMaster_s; }
+// tolua_end
+
+            static void setPlaysSound   (bool val) { bPlaysSound_s    = val; }
+            static void setHasServer    (bool val) { bHasServer_s     = val; updateIsMaster(); }
+            static void setIsClient     (bool val) { bIsClient_s      = val; updateIsMaster(); }
+            static void setIsStandalone (bool val) { bIsStandalone_s  = val; updateIsMaster(); }
+
+        private:
+            GameMode();
+            GameMode(const GameMode& inst);
+            ~GameMode();
+
+            static void updateIsMaster()
+            {
+                bIsMaster_s = (bHasServer_s || bIsStandalone_s);
+            }
+
+            static bool bShowsGraphics_s;                   //!< global variable that tells whether to show graphics
+            static bool bPlaysSound_s;                      //!< global variable that tells whether to sound works
+            static bool bHasServer_s;                       //!< global variable that tells whether this is a server
+            static bool bIsClient_s;
+            static bool bIsStandalone_s;
+            static bool bIsMaster_s;
+    }; // tolua_export
+} // tolua_export
+
+#endif /* _GameMode_H__ */
Index: /code/branches/rocket2/src/libraries/core/GameState.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/GameState.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/GameState.cc	(revision 6952)
@@ -0,0 +1,97 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of GameState class.
+*/
+
+#include "GameState.h"
+
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/OrxAssert.h"
+#include "Game.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Constructor only initialises variables and sets the name permanently.
+    */
+    GameState::GameState(const GameStateInfo& info)
+        : info_(info)
+    {
+        this->activity_.activating   = false;
+        this->activity_.active       = false;
+        this->activity_.deactivating = false;
+        this->activity_.suspended    = false;
+        this->activity_.topState     = false;
+        this->activity_.updating     = false;
+    }
+
+    /**
+    @brief
+        Destructor only checks that we don't delete an active state.
+    */
+    GameState::~GameState()
+    {
+        OrxAssert(this->activity_.active == false, "Deleting an active GameState is a very bad idea..");
+    }
+
+    const std::string& GameState::getName() const
+    {
+        return info_.stateName;
+    }
+
+    void GameState::activateInternal()
+    {
+        this->activity_.activating = true;
+        this->activate();
+        this->activity_.activating = false;
+        this->activity_.active = true;
+    }
+
+    void GameState::deactivateInternal()
+    {
+        this->activity_.active = false;
+        this->activity_.deactivating = true;
+        this->deactivate();
+        this->activity_.deactivating = false;
+        this->activity_.suspended = false;
+        this->activity_.updating = false;
+    }
+
+    void GameState::updateInternal(const Clock& time)
+    {
+        this->activity_.updating = true;
+        this->update(time);
+        this->activity_.updating = false;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/GameState.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/GameState.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/GameState.h	(revision 6952)
@@ -0,0 +1,103 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Definition of GameState class.
+*/
+
+#ifndef _GameState_H__
+#define _GameState_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <string>
+#include "util/UtilPrereqs.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        An implementation of a tree to manage game states.
+        This leads to a certain hierarchy that is created at runtime.
+        To actually use the structure, you will have to derive from it and
+        implement 'enter', 'leave' and 'tick'. The latter corresponds to an
+        update function.
+
+        Internally the tree is managed by two maps per node: One stores all its
+        children, grandchildren, etc. by name of the state. The other maps these
+        children states to the actual child of the node.
+        An example: Foo is a grandchildren of Bar and Foofoo is the Foo's parent.
+        Then Bar stores Foo in map by its name. The other one then maps Foo to Foofoo.
+    */
+    class _CoreExport GameState
+    {
+        friend class Game;
+
+    public:
+        /**
+        @brief
+            Gives information about what the GameState is currently doing
+        */
+        struct State
+        {
+            unsigned active       : 1;
+            unsigned activating   : 1;
+            unsigned deactivating : 1;
+            unsigned updating     : 1;
+            unsigned suspended    : 1;
+            unsigned topState     : 1;
+        };
+
+    public:
+        GameState(const GameStateInfo& info);
+        virtual ~GameState();
+
+        const std::string& getName()   const;
+        State getActivity()            const { return activity_; }
+        const GameStateInfo& getInfo() const { return info_; }
+
+    protected:
+        virtual void activate() { }
+        virtual void deactivate() { }
+        virtual void update(const Clock& time) { }
+
+    private:
+        void setActivity(State activity);
+        void activateInternal();
+        void deactivateInternal();
+        void updateInternal(const Clock& time);
+
+        const GameStateInfo& info_;
+        State                activity_;
+    };
+}
+
+#endif /* _GameState_H__ */
Index: /code/branches/rocket2/src/libraries/core/GraphicsManager.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/GraphicsManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/GraphicsManager.cc	(revision 6952)
@@ -0,0 +1,455 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
+ *   Co-authors:
+ *      Felix Schulthess
+ *
+ */
+
+#include "GraphicsManager.h"
+
+#include <fstream>
+#include <sstream>
+#include <boost/filesystem.hpp>
+#include <boost/shared_array.hpp>
+
+#include <OgreArchiveFactory.h>
+#include <OgreArchiveManager.h>
+#include <OgreFrameListener.h>
+#include <OgreRoot.h>
+#include <OgreLogManager.h>
+#include <OgreRenderWindow.h>
+#include <OgreRenderSystem.h>
+#include <OgreResourceGroupManager.h>
+#include <OgreTextureManager.h>
+#include <OgreViewport.h>
+#include <OgreWindowEventUtilities.h>
+
+#include "SpecialConfig.h"
+#include "util/Clock.h"
+#include "util/Exception.h"
+#include "util/StringUtils.h"
+#include "util/SubString.h"
+#include "ConsoleCommand.h"
+#include "ConfigValueIncludes.h"
+#include "CoreIncludes.h"
+#include "Game.h"
+#include "GameMode.h"
+#include "Loader.h"
+#include "MemoryArchive.h"
+#include "PathConfig.h"
+#include "WindowEventListener.h"
+#include "XMLFile.h"
+
+namespace orxonox
+{
+    class OgreWindowEventListener : public Ogre::WindowEventListener
+    {
+    public:
+        void windowResized     (Ogre::RenderWindow* rw)
+            { orxonox::WindowEventListener::resizeWindow(rw->getWidth(), rw->getHeight()); }
+        void windowFocusChange (Ogre::RenderWindow* rw)
+            { orxonox::WindowEventListener::changeWindowFocus(); }
+        void windowClosed      (Ogre::RenderWindow* rw)
+            { orxonox::Game::getInstance().stop(); }
+        void windowMoved       (Ogre::RenderWindow* rw)
+            { orxonox::WindowEventListener::moveWindow(); }
+    };
+
+    GraphicsManager* GraphicsManager::singletonPtr_s = 0;
+
+    /**
+    @brief
+        Non-initialising constructor.
+    */
+    GraphicsManager::GraphicsManager(bool bLoadRenderer)
+        : ogreWindowEventListener_(new OgreWindowEventListener())
+#if OGRE_VERSION < 0x010600
+        , memoryArchiveFactory_(new MemoryArchiveFactory())
+#endif
+        , renderWindow_(0)
+        , viewport_(0)
+    {
+        RegisterObject(GraphicsManager);
+
+        this->setConfigValues();
+
+        // Ogre setup procedure (creating Ogre::Root)
+        this->loadOgreRoot();
+
+        // At first, add the root paths of the data directories as resource locations
+        Ogre::ResourceGroupManager::getSingleton().addResourceLocation(PathConfig::getDataPathString(), "FileSystem");
+        // Load resources
+        resources_.reset(new XMLFile("DefaultResources.oxr"));
+        resources_->setLuaSupport(false);
+        Loader::open(resources_.get());
+
+        // Only for development runs
+        if (PathConfig::isDevelopmentRun())
+        {
+            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(PathConfig::getExternalDataPathString(), "FileSystem");
+            extResources_.reset(new XMLFile("resources.oxr"));
+            extResources_->setLuaSupport(false);
+            Loader::open(extResources_.get());
+        }
+
+        if (bLoadRenderer)
+        {
+            // Reads the ogre config and creates the render window
+            this->upgradeToGraphics();
+        }
+    }
+
+    /**
+    @brief
+        Destruction is done by the member scoped_ptrs.
+    */
+    GraphicsManager::~GraphicsManager()
+    {
+        Loader::unload(debugOverlay_.get());
+
+        Ogre::WindowEventUtilities::removeWindowEventListener(renderWindow_, ogreWindowEventListener_.get());
+        // TODO: Destroy the console command
+
+        // Undeclare the resources
+        Loader::unload(resources_.get());
+        if (PathConfig::isDevelopmentRun())
+            Loader::unload(extResources_.get());
+    }
+
+    void GraphicsManager::setConfigValues()
+    {
+        SetConfigValue(ogreConfigFile_,  "ogre.cfg")
+            .description("Location of the Ogre config file");
+        SetConfigValue(ogrePluginsDirectory_, specialConfig::ogrePluginsDirectory)
+            .description("Folder where the Ogre plugins are located.");
+        SetConfigValue(ogrePlugins_, specialConfig::ogrePlugins)
+            .description("Comma separated list of all plugins to load.");
+        SetConfigValue(ogreLogFile_,     "ogre.log")
+            .description("Logfile for messages from Ogre. Use \"\" to suppress log file creation.");
+        SetConfigValue(ogreLogLevelTrivial_ , 5)
+            .description("Corresponding orxonox debug level for ogre Trivial");
+        SetConfigValue(ogreLogLevelNormal_  , 4)
+            .description("Corresponding orxonox debug level for ogre Normal");
+        SetConfigValue(ogreLogLevelCritical_, 2)
+            .description("Corresponding orxonox debug level for ogre Critical");
+    }
+
+    /**
+    @brief
+        Loads the renderer and creates the render window if not yet done so.
+    @remarks
+        This operation is irreversible without recreating the GraphicsManager!
+        So if it throws you HAVE to recreate the GraphicsManager!!!
+        It therefore offers almost no exception safety.
+    */
+    void GraphicsManager::upgradeToGraphics()
+    {
+        if (renderWindow_ != NULL)
+            return;
+
+        // load all the required plugins for Ogre
+        this->loadOgrePlugins();
+
+        this->loadRenderer();
+
+#if OGRE_VERSION < 0x010600
+        // WORKAROUND: There is an incompatibility for particle scripts when trying
+        // to support both Ogre 1.4 and 1.6. The hacky solution is to create
+        // scripts for the 1.6 version and then remove the inserted "particle_system"
+        // keyword. But we need to supply these new scripts as well, which is why
+        // there is an extra Ogre::Archive dealing with it in the memory.
+        using namespace Ogre;
+        ArchiveManager::getSingleton().addArchiveFactory(memoryArchiveFactory_.get());
+        const StringVector& groups = ResourceGroupManager::getSingleton().getResourceGroups();
+        // Travers all groups
+        for (StringVector::const_iterator itGroup = groups.begin(); itGroup != groups.end(); ++itGroup)
+        {
+            FileInfoListPtr files = ResourceGroupManager::getSingleton().findResourceFileInfo(*itGroup, "*.particle");
+            for (FileInfoList::const_iterator itFile = files->begin(); itFile != files->end(); ++itFile)
+            {
+                // open file
+                Ogre::DataStreamPtr input = ResourceGroupManager::getSingleton().openResource(itFile->filename, *itGroup, false);
+                std::stringstream output;
+                // Parse file and replace "particle_system" with nothing
+                while (!input->eof())
+                {
+                    std::string line = input->getLine();
+                    size_t pos = line.find("particle_system");
+                    if (pos != std::string::npos)
+                    {
+                        // 15 is the length of "particle_system"
+                        line.replace(pos, 15, "");
+                    }
+                    output << line << std::endl;
+                }
+                // Add file to the memory archive
+                shared_array<char> data(new char[output.str().size()]);
+                // Debug optimisations
+                const std::string& outputStr = output.str();
+                char* rawData = data.get();
+                for (unsigned i = 0; i < outputStr.size(); ++i)
+                    rawData[i] = outputStr[i];
+                MemoryArchive::addFile("particle_scripts_ogre_1.4_" + *itGroup, itFile->filename, data, output.str().size());
+            }
+            if (!files->empty())
+            {
+                // Declare the files, but using a new group
+                ResourceGroupManager::getSingleton().addResourceLocation("particle_scripts_ogre_1.4_" + *itGroup,
+                    "Memory", "particle_scripts_ogre_1.4_" + *itGroup);
+            }
+        }
+#endif
+
+        // Initialise all resources (do this AFTER the renderer has been loaded!)
+        // Note: You can only do this once! Ogre will check whether a resource group has
+        // already been initialised. If you need to load resources later, you will have to
+        // choose another resource group.
+        Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
+    }
+
+    /**
+    @brief
+        Creates the Ogre Root object and sets up the ogre log.
+    */
+    void GraphicsManager::loadOgreRoot()
+    {
+        COUT(3) << "Setting up Ogre..." << std::endl;
+
+        if (ogreConfigFile_.empty())
+        {
+            COUT(2) << "Warning: Ogre config file set to \"\". Defaulting to config.cfg" << std::endl;
+            ModifyConfigValue(ogreConfigFile_, tset, "config.cfg");
+        }
+        if (ogreLogFile_.empty())
+        {
+            COUT(2) << "Warning: Ogre log file set to \"\". Defaulting to ogre.log" << std::endl;
+            ModifyConfigValue(ogreLogFile_, tset, "ogre.log");
+        }
+
+        boost::filesystem::path ogreConfigFilepath(PathConfig::getConfigPath() / this->ogreConfigFile_);
+        boost::filesystem::path ogreLogFilepath(PathConfig::getLogPath() / this->ogreLogFile_);
+
+        // create a new logManager
+        // Ogre::Root will detect that we've already created a Log
+        ogreLogger_.reset(new Ogre::LogManager());
+        COUT(4) << "Ogre LogManager created" << std::endl;
+
+        // create our own log that we can listen to
+        Ogre::Log *myLog;
+        myLog = ogreLogger_->createLog(ogreLogFilepath.string(), true, false, false);
+        COUT(4) << "Ogre Log created" << std::endl;
+
+        myLog->setLogDetail(Ogre::LL_BOREME);
+        myLog->addListener(this);
+
+        COUT(4) << "Creating Ogre Root..." << std::endl;
+
+        // check for config file existence because Ogre displays (caught) exceptions if not
+        if (!boost::filesystem::exists(ogreConfigFilepath))
+        {
+            // create a zero sized file
+            std::ofstream creator;
+            creator.open(ogreConfigFilepath.string().c_str());
+            creator.close();
+        }
+
+        // Leave plugins file empty. We're going to do that part manually later
+        ogreRoot_.reset(new Ogre::Root("", ogreConfigFilepath.string(), ogreLogFilepath.string()));
+
+        COUT(3) << "Ogre set up done." << std::endl;
+    }
+
+    void GraphicsManager::loadOgrePlugins()
+    {
+        // just to make sure the next statement doesn't segfault
+        if (ogrePluginsDirectory_.empty())
+            ogrePluginsDirectory_ = '.';
+
+        boost::filesystem::path folder(ogrePluginsDirectory_);
+        // Do some SubString magic to get the comma separated list of plugins
+        SubString plugins(ogrePlugins_, ",", " ", false, '\\', false, '"', false, '(', ')', false, '\0');
+        // Use backslash paths on Windows! file_string() already does that though.
+        for (unsigned int i = 0; i < plugins.size(); ++i)
+            ogreRoot_->loadPlugin((folder / plugins[i]).file_string());
+    }
+
+    void GraphicsManager::loadRenderer()
+    {
+        CCOUT(4) << "Configuring Renderer" << std::endl;
+
+        if (!ogreRoot_->restoreConfig())
+            if (!ogreRoot_->showConfigDialog())
+                ThrowException(InitialisationFailed, "OGRE graphics configuration dialogue failed.");
+
+        CCOUT(4) << "Creating render window" << std::endl;
+
+        this->renderWindow_ = ogreRoot_->initialise(true, "Orxonox");
+        // Propagate the size of the new winodw
+        this->ogreWindowEventListener_->windowResized(renderWindow_);
+
+        Ogre::WindowEventUtilities::addWindowEventListener(this->renderWindow_, ogreWindowEventListener_.get());
+
+        // create a full screen default viewport
+        // Note: This may throw when adding a viewport with an existing z-order!
+        //       But in our case we only have one viewport for now anyway, therefore
+        //       no ScopeGuards or anything to handle exceptions.
+        this->viewport_ = this->renderWindow_->addViewport(0, 0);
+
+        Ogre::TextureManager::getSingleton().setDefaultNumMipmaps(Ogre::MIP_UNLIMITED);
+
+        // add console commands
+        ccPrintScreen_ = createConsoleCommand(createFunctor(&GraphicsManager::printScreen, this), "printScreen");
+        CommandExecutor::addConsoleCommandShortcut(ccPrintScreen_);
+    }
+
+    void GraphicsManager::loadDebugOverlay()
+    {
+        // Load debug overlay to show info about fps and tick time
+        COUT(4) << "Loading Debug Overlay..." << std::endl;
+        debugOverlay_.reset(new XMLFile("debug.oxo"));
+        Loader::open(debugOverlay_.get());
+    }
+
+    /**
+    @note
+        A note about the Ogre::FrameListener: Even though we don't use them,
+        they still get called. However, the delta times are not correct (except
+        for timeSinceLastFrame, which is the most important). A little research
+        as shown that there is probably only one FrameListener that doesn't even
+        need the time. So we shouldn't run into problems.
+    */
+    void GraphicsManager::postUpdate(const Clock& time)
+    {
+        Ogre::FrameEvent evt;
+        evt.timeSinceLastFrame = time.getDeltaTime();
+        evt.timeSinceLastEvent = time.getDeltaTime(); // note: same time, but shouldn't matter anyway
+
+        // don't forget to call _fireFrameStarted to OGRE to make sure
+        // everything goes smoothly
+        ogreRoot_->_fireFrameStarted(evt);
+
+        // Pump messages in all registered RenderWindows
+        // This calls the WindowEventListener objects.
+        Ogre::WindowEventUtilities::messagePump();
+        // make sure the window stays active even when not focused
+        // (probably only necessary on windows)
+        this->renderWindow_->setActive(true);
+
+        // Time before rendering
+        uint64_t timeBeforeTick = time.getRealMicroseconds();
+
+        // Render frame
+        ogreRoot_->_updateAllRenderTargets();
+
+        uint64_t timeAfterTick = time.getRealMicroseconds();
+        // Subtract the time used for rendering from the tick time counter
+        Game::getInstance().subtractTickTime((int32_t)(timeAfterTick - timeBeforeTick));
+
+        // again, just to be sure OGRE works fine
+        ogreRoot_->_fireFrameEnded(evt); // note: uses the same time as _fireFrameStarted
+    }
+
+    void GraphicsManager::setCamera(Ogre::Camera* camera)
+    {
+        this->viewport_->setCamera(camera);
+    }
+
+    /**
+    @brief
+        Method called by the LogListener interface from Ogre.
+        We use it to capture Ogre log messages and handle it ourselves.
+    @param message
+        The message to be logged
+    @param lml
+        The message level the log is using
+    @param maskDebug
+        If we are printing to the console or not
+    @param logName
+        The name of this log (so you can have several listeners
+        for different logs, and identify them)
+    */
+    void GraphicsManager::messageLogged(const std::string& message,
+        Ogre::LogMessageLevel lml, bool maskDebug, const std::string& logName)
+    {
+        int orxonoxLevel;
+        std::string introduction;
+        // Do not show caught OGRE exceptions in front
+        if (message.find("EXCEPTION") != std::string::npos)
+        {
+            orxonoxLevel = OutputLevel::Debug;
+            introduction = "Ogre, caught exception: ";
+        }
+        else
+        {
+            switch (lml)
+            {
+            case Ogre::LML_TRIVIAL:
+                orxonoxLevel = this->ogreLogLevelTrivial_;
+                break;
+            case Ogre::LML_NORMAL:
+                orxonoxLevel = this->ogreLogLevelNormal_;
+                break;
+            case Ogre::LML_CRITICAL:
+                orxonoxLevel = this->ogreLogLevelCritical_;
+                break;
+            default:
+                orxonoxLevel = 0;
+            }
+            introduction = "Ogre: ";
+        }
+        OutputHandler::getOutStream(orxonoxLevel)
+            << introduction << message << std::endl;
+    }
+
+    size_t GraphicsManager::getRenderWindowHandle()
+    {
+        size_t windowHnd = 0;
+        renderWindow_->getCustomAttribute("WINDOW", &windowHnd);
+        return windowHnd;
+    }
+
+    bool GraphicsManager::isFullScreen() const
+    {
+        Ogre::ConfigOptionMap& options = ogreRoot_->getRenderSystem()->getConfigOptions();
+        if (options.find("Full Screen") != options.end())
+        {
+            if (options["Full Screen"].currentValue == "Yes")
+                return true;
+            else
+                return false;
+        }
+        else
+        {
+            COUT(0) << "Could not find 'Full Screen' render system option. Fix This!!!" << std::endl;
+            return false;
+        }
+    }
+
+    void GraphicsManager::printScreen()
+    {
+        assert(this->renderWindow_);
+        this->renderWindow_->writeContentsToTimestampedFile(PathConfig::getLogPathString() + "screenShot_", ".png");
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/GraphicsManager.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/GraphicsManager.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/GraphicsManager.h	(revision 6952)
@@ -0,0 +1,123 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
+ *   Co-authors:
+ *      Felix Schulthess
+ *
+ */
+
+/**
+@file
+@brief
+    Declaration of GraphicsManager Singleton.
+ */
+
+#ifndef _GraphicsManager_H__
+#define _GraphicsManager_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include <string>
+#include <OgreLog.h>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+
+#include "util/Singleton.h"
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Graphics engine manager class
+    */
+    class _CoreExport GraphicsManager : public Singleton<GraphicsManager>, public OrxonoxClass, public Ogre::LogListener
+    {
+        friend class Singleton<GraphicsManager>;
+    public:
+        GraphicsManager(bool bLoadRenderer = true);
+        ~GraphicsManager();
+
+        void setConfigValues();
+
+        void postUpdate(const Clock& time);
+
+        Ogre::Viewport* getViewport()         { return this->viewport_; }
+        Ogre::RenderWindow* getRenderWindow() { return this->renderWindow_; }
+        size_t getRenderWindowHandle();
+        bool isFullScreen() const;
+
+        void upgradeToGraphics();
+        void loadDebugOverlay();
+        bool rendererLoaded() const { return renderWindow_ != NULL; }
+
+        void setCamera(Ogre::Camera* camera);
+
+    private:
+        GraphicsManager(GraphicsManager&); // don't mess with singletons
+
+        // OGRE initialisation
+        void loadOgreRoot();
+        void loadOgrePlugins();
+        void loadRenderer();
+
+        // event from Ogre::LogListener
+        void messageLogged(const std::string& message, Ogre::LogMessageLevel lml,
+            bool maskDebug, const std::string& logName);
+
+        // console commands
+        void printScreen();
+
+        scoped_ptr<OgreWindowEventListener> ogreWindowEventListener_; //!< Pimpl to hide OgreWindowUtilities.h
+#if OGRE_VERSION < 0x010600
+        scoped_ptr<MemoryArchiveFactory>    memoryArchiveFactory_;    //!< Stores the modified particle scripts
+#endif
+        scoped_ptr<Ogre::LogManager>        ogreLogger_;
+        scoped_ptr<Ogre::Root>              ogreRoot_;                //!< Ogre's root
+        Ogre::RenderWindow* renderWindow_;             //!< the one and only render window
+        Ogre::Viewport*     viewport_;                 //!< default full size viewport
+
+        // XML files for the resources and the debug overlay
+        shared_ptr<XMLFile> resources_;                //!< XML with resource locations
+        shared_ptr<XMLFile> extResources_;             //!< XML with resource locations in the external path (only for dev runs)
+        shared_ptr<XMLFile> debugOverlay_;             //!< XML with various debug overlays
+
+        // config values
+        std::string         ogreConfigFile_;           //!< ogre config filename
+        std::string         ogrePluginsDirectory_;     //!< Directory where the Ogre plugins are located
+        std::string         ogrePlugins_;              //!< Comma separated list of all plugins to load
+        std::string         ogreLogFile_;              //!< log filename for Ogre log messages
+        int                 ogreLogLevelTrivial_;      //!< Corresponding Orxonox debug level for LL_TRIVIAL
+        int                 ogreLogLevelNormal_;       //!< Corresponding Orxonox debug level for LL_NORMAL
+        int                 ogreLogLevelCritical_;     //!< Corresponding Orxonox debug level for LL_CRITICAL
+
+        // console commands
+        ConsoleCommand*     ccPrintScreen_;
+
+        static GraphicsManager* singletonPtr_s;        //!< Pointer to the Singleton
+    };
+}
+
+#endif /* _GraphicsManager_H__ */
Index: /code/branches/rocket2/src/libraries/core/IOConsole.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/IOConsole.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/IOConsole.cc	(revision 6952)
@@ -0,0 +1,799 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "IOConsole.h"
+
+#include <iomanip>
+#include <iostream>
+
+#include "util/Clock.h"
+#include "util/Math.h"
+#include "Game.h"
+#include "input/InputBuffer.h"
+
+// ##########################
+// ###   Mutual methods   ###
+// ##########################
+namespace orxonox
+{
+    IOConsole* IOConsole::singletonPtr_s = NULL;
+
+    // ###############################
+    // ###  ShellListener methods  ###
+    // ###############################
+
+    //! Called if all output-lines have to be reprinted
+    void IOConsole::linesChanged()
+    {
+        // Method only gets called upon start to draw all the lines
+        // or when scrolling. But scrolling is disabled and the output
+        // is already in std::cout when we start the IOConsole
+    }
+
+    //! Called if a command is about to be executed
+    void IOConsole::executed()
+    {
+        this->shell_->addOutput(this->promptString_ + this->shell_->getInput() + '\n', Shell::Command);
+    }
+
+    //! Called if the console gets closed
+    void IOConsole::exit()
+    {
+        // Exit is not an option, just do nothing (Shell doesn't really exit too)
+    }
+}
+
+#ifdef ORXONOX_PLATFORM_UNIX
+// ###############################
+// ###   Unix Implementation   ###
+// ###############################
+
+#include <termios.h>
+#include <sys/ioctl.h>
+
+namespace orxonox
+{
+    namespace EscapeMode
+    {
+        enum Value
+        {
+            None,
+            First,
+            Second
+        };
+    }
+
+    IOConsole::IOConsole()
+        : shell_(new Shell("IOConsole", false))
+        , buffer_(shell_->getInputBuffer())
+        , cout_(std::cout.rdbuf())
+        , promptString_("orxonox # ")
+        , bStatusPrinted_(false)
+        , originalTerminalSettings_(0)
+    {
+        this->setTerminalMode();
+        this->shell_->registerListener(this);
+
+        // Manually set the widths of the individual status lines
+        this->statusLineWidths_.push_back(29);
+        this->statusLineMaxWidth_ = 29;
+
+        this->getTerminalSize();
+        this->lastTerminalWidth_ = this->terminalWidth_;
+        this->lastTerminalHeight_ = this->terminalHeight_;
+
+        // Disable standard std::cout logging
+        OutputHandler::getInstance().disableCout();
+        // Redirect std::cout to an ostringstream
+        // (Other part is in the initialiser list)
+        std::cout.rdbuf(this->origCout_.rdbuf());
+
+        // Make sure we make way for the status lines
+        this->preUpdate(Game::getInstance().getGameClock());
+    }
+
+    IOConsole::~IOConsole()
+    {
+        // Process output written to std::cout in the meantime
+        std::cout.flush();
+        if (!this->origCout_.str().empty())
+            this->shell_->addOutput(this->origCout_.str(), Shell::None);
+        // Erase input and status lines
+        this->cout_ << "\033[1G\033[J";
+        // Move cursor to the bottom
+        this->cout_ << "\033[" << this->statusLineWidths_.size() << 'B';
+        // Scroll terminal to compensate for erased lines
+        this->cout_ << "\033[" << this->statusLineWidths_.size() << 'T';
+
+        resetTerminalMode();
+        this->shell_->destroy();
+
+        // Restore this->cout_ redirection
+        std::cout.rdbuf(this->cout_.rdbuf());
+        // Enable standard std::cout logging again
+        OutputHandler::getInstance().enableCout();
+    }
+
+    void IOConsole::preUpdate(const Clock& time)
+    {
+        unsigned char c;
+        std::string escapeSequence;
+        EscapeMode::Value escapeMode = EscapeMode::None;
+        while (std::cin.good())
+        {
+            c = std::cin.get();
+            if (!std::cin.good())
+                break;
+
+            if (escapeMode == EscapeMode::First && (c == '[' || c=='O') )
+                escapeMode = EscapeMode::Second;
+            // Get Alt+Tab combination when switching applications
+            else if (escapeMode == EscapeMode::First && c == '\t')
+            {
+                this->buffer_->buttonPressed(KeyEvent(KeyCode::Tab, '\t', KeyboardModifier::Alt));
+                escapeMode = EscapeMode::None;
+            }
+            else if (escapeMode == EscapeMode::Second)
+            {
+                escapeSequence += c;
+                escapeMode = EscapeMode::None;
+                if      (escapeSequence == "A")
+                    this->buffer_->buttonPressed(KeyEvent(KeyCode::Up,       0, 0));
+                else if (escapeSequence == "B")
+                    this->buffer_->buttonPressed(KeyEvent(KeyCode::Down,     0, 0));
+                else if (escapeSequence == "C")
+                    this->buffer_->buttonPressed(KeyEvent(KeyCode::Right,    0, 0));
+                else if (escapeSequence == "D")
+                    this->buffer_->buttonPressed(KeyEvent(KeyCode::Left,     0, 0));
+                else if (escapeSequence == "1~" || escapeSequence == "H")
+                    this->buffer_->buttonPressed(KeyEvent(KeyCode::Home,     0, 0));
+                else if (escapeSequence == "2~")
+                    this->buffer_->buttonPressed(KeyEvent(KeyCode::Insert,   0, 0));
+                else if (escapeSequence == "3~")
+                    this->buffer_->buttonPressed(KeyEvent(KeyCode::Delete,   0, 0));
+                else if (escapeSequence == "4~" || escapeSequence == "F")
+                    this->buffer_->buttonPressed(KeyEvent(KeyCode::End,      0, 0));
+                else if (escapeSequence == "5~")
+                    this->buffer_->buttonPressed(KeyEvent(KeyCode::PageUp,   0, 0));
+                else if (escapeSequence == "6~")
+                    this->buffer_->buttonPressed(KeyEvent(KeyCode::PageDown, 0, 0));
+                else
+                    // Waiting for sequence to complete
+                    // If the user presses ESC and then '[' or 'O' while the loop is not
+                    // running (for instance while loading), the whole sequence gets dropped
+                    escapeMode = EscapeMode::Second;
+            }
+            else // not in an escape sequence OR user might have pressed just ESC
+            {
+                if (escapeMode == EscapeMode::First)
+                {
+                    this->buffer_->buttonPressed(KeyEvent(KeyCode::Escape, c, 0));
+                    escapeMode = EscapeMode::None;
+                }
+                if (c == '\033')
+                {
+                    escapeMode = EscapeMode::First;
+                    escapeSequence.clear();
+                }
+                else
+                {
+                    KeyCode::ByEnum code;
+                    switch (c)
+                    {
+                    case '\n'  : case '\r': code = KeyCode::Return; break;
+                    case '\177': case '\b': code = KeyCode::Back;   break;
+                    case '\t'             : code = KeyCode::Tab;    break;
+                    default:
+                        // We don't encode the key code (would be a very large switch)
+                        // because the InputBuffer will only insert the text anyway
+                        // Replacement character is simply KeyCode::A
+                        code = KeyCode::A;
+                    }
+                    this->buffer_->buttonPressed(KeyEvent(code, c, 0));
+                }
+            }
+        }
+        // Reset error flags in std::cin
+        std::cin.clear();
+
+        // If there is still an escape key pending (escape key ONLY), then
+        // it sure isn't an escape sequence anymore
+        if (escapeMode == EscapeMode::First)
+            this->buffer_->buttonPressed(KeyEvent(KeyCode::Escape, '\033', 0));
+
+        // Determine terminal width and height
+        this->lastTerminalWidth_ = this->terminalWidth_;
+        this->lastTerminalHeight_ = this->terminalHeight_;
+        this->getTerminalSize();
+
+        int heightDiff = this->terminalHeight_ - this->lastTerminalHeight_;
+        if (this->bStatusPrinted_ && heightDiff < 0)
+        {
+            // Terminal width has shrunk. The cursor will still be on the input line,
+            // but that line might very well be the last
+            int newLines = std::min((int)this->statusLineWidths_.size(), -heightDiff);
+            // Scroll terminal to create new lines
+            this->cout_ << "\033[" << newLines << 'S';
+        }
+
+        if (!this->bStatusPrinted_ && this->willPrintStatusLines())
+        {
+            // Scroll console to make way for status lines
+            this->cout_ << "\033[" << this->statusLineWidths_.size() << 'S';
+            this->bStatusPrinted_ = true;
+        }
+
+        // We always assume that the cursor is on the input line.
+        // But we cannot always be sure about that, esp. if we scroll the console
+        this->cout_ << "\033[" << this->statusLineWidths_.size() << 'B';
+        this->cout_ << "\033[" << this->statusLineWidths_.size() << 'A';
+
+        // Erase status and input lines
+        this->cout_ << "\033[1G\033[J";
+        this->printInputLine();
+        this->printStatusLines();
+        this->cout_.flush();
+
+        // Process output written to std::cout
+        std::cout.flush();
+        if (!this->origCout_.str().empty())
+        {
+            this->shell_->addOutput(this->origCout_.str(), Shell::None);
+            this->origCout_.str("");
+        }
+    }
+
+    void IOConsole::printOutputLine(const std::string& text, Shell::LineType type)
+    {
+/*
+        // Colour line
+        switch (type)
+        {
+        case Shell::None:    this->cout_ << "\033[37m"; break;
+        case Shell::Error:   this->cout_ << "\033[91m"; break;
+        case Shell::Warning: this->cout_ << "\033[31m"; break;
+        case Shell::Info:    this->cout_ << "\033[34m"; break;
+        case Shell::Debug:   this->cout_ << "\033[36m"; break;
+        case Shell::Verbose: this->cout_ << "\033[35m"; break;
+        case Shell::Ultra:   this->cout_ << "\033[37m"; break;
+        default: break;
+        }
+*/
+
+        // Print output line
+        this->cout_ << text;
+
+        // Reset colour to white
+//        this->cout_ << "\033[37m";
+    }
+
+    void IOConsole::printInputLine()
+    {
+        // Set cursor to the beginning of the line and erase the line
+        this->cout_ << "\033[1G\033[K";
+        // Indicate a command prompt
+        this->cout_ << this->promptString_;
+        // Save cursor position
+        this->cout_ << "\033[s";
+        // Print command line buffer
+        this->cout_ << this->shell_->getInput();
+        // Restore cursor position and move it to the right
+        this->cout_ << "\033[u";
+        if (this->buffer_->getCursorPosition() > 0)
+            this->cout_ << "\033[" << this->buffer_->getCursorPosition() << 'C';
+    }
+
+    void IOConsole::printStatusLines()
+    {
+        if (this->willPrintStatusLines())
+        {
+            // Save cursor position
+            this->cout_ << "\033[s";
+            // Move cursor down (don't create a new line here because the buffer might flush then!)
+            this->cout_ << "\033[1B\033[1G";
+            this->cout_ << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, ";
+            this->cout_ <<               std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms tick time";
+            // Restore cursor position
+            this->cout_ << "\033[u";
+            this->bStatusPrinted_ = true;
+        }
+        else
+            this->bStatusPrinted_ = false;
+    }
+
+    void IOConsole::setTerminalMode()
+    {
+        termios new_settings;
+        this->originalTerminalSettings_ = new termios();
+
+        tcgetattr(0, this->originalTerminalSettings_);
+        new_settings = *this->originalTerminalSettings_;
+        new_settings.c_lflag &= ~(ICANON | ECHO);
+        //new_settings.c_lflag |= (ISIG | IEXTEN);
+        new_settings.c_cc[VTIME] = 0;
+        new_settings.c_cc[VMIN]  = 0;
+        tcsetattr(0, TCSANOW, &new_settings);
+        atexit(&IOConsole::resetTerminalMode);
+    }
+
+    /*static*/ void IOConsole::resetTerminalMode()
+    {
+        if (IOConsole::singletonPtr_s && IOConsole::singletonPtr_s->originalTerminalSettings_)
+        {
+            tcsetattr(0, TCSANOW, IOConsole::singletonPtr_s->originalTerminalSettings_);
+            delete IOConsole::singletonPtr_s->originalTerminalSettings_;
+            IOConsole::singletonPtr_s->originalTerminalSettings_ = 0;
+        }
+    }
+
+    void IOConsole::getTerminalSize()
+    {
+#ifdef TIOCGSIZE
+        struct ttysize win;
+        if (!ioctl(STDIN_FILENO, TIOCGSIZE, &win))
+        {
+            this->terminalWidth_  = win.ts_cols;
+            this->terminalHeight_ = win.ts_lines;
+            return;
+        }
+#elif defined TIOCGWINSZ
+        struct winsize win;
+        if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &win))
+        {
+            this->terminalWidth_  = win.ws_col;
+            this->terminalHeight_ = win.ws_row;
+            return;
+        }
+#else
+        const char* s = getenv("COLUMNS");
+        this->terminalWidth_  = s ? strtol(s, NULL, 10) : 80;
+        s = getenv("LINES");
+        this->terminalHeight_ = s ? strtol(s, NULL, 10) : 24;
+        return;
+#endif
+        this->terminalWidth_  = 80;
+        this->terminalHeight_ = 24;
+    }
+
+    inline bool IOConsole::willPrintStatusLines()
+    {
+        return !this->statusLineWidths_.empty()
+             && this->terminalWidth_  >= this->statusLineMaxWidth_
+             && this->terminalHeight_ >= this->minOutputLines_ + (int)this->statusLineWidths_.size();
+    }
+
+    // ###############################
+    // ###  ShellListener methods  ###
+    // ###############################
+
+    //! Called if only the last output-line has changed
+    void IOConsole::onlyLastLineChanged()
+    {
+        // Save cursor position and move it to the beginning of the first output line
+        this->cout_ << "\033[s\033[1A\033[1G";
+        // Erase the line
+        this->cout_ << "\033[K";
+        // Reprint the last output line
+        this->printOutputLine(this->shell_->getNewestLineIterator()->first, this->shell_->getNewestLineIterator()->second);
+        // Restore cursor
+        this->cout_ << "\033[u";
+        this->cout_.flush();
+    }
+
+    //! Called if a new output-line was added
+    void IOConsole::lineAdded()
+    {
+        int newLines = this->shell_->getNewestLineIterator()->first.size() / this->terminalWidth_ + 1;
+        // Create new lines by scrolling the screen
+        this->cout_ << "\033[" << newLines << 'S';
+        // Move cursor to the beginning of the new (last) output line
+        this->cout_ << "\033[" << newLines << "A\033[1G";
+        // Erase screen from here
+        this->cout_ << "\033[J";
+        // Print the new output lines
+        for (int i = 0; i < newLines; ++i)
+        {
+            Shell::LineList::const_iterator it = this->shell_->getNewestLineIterator();
+            this->printOutputLine(it->first.substr(i*this->terminalWidth_, this->terminalWidth_), it->second);
+        }
+        // Move cursor down
+        this->cout_ << "\033[1B\033[1G";
+        // Print status and input lines
+        this->printInputLine();
+        this->printStatusLines();
+        this->cout_.flush();
+    }
+
+    //! Called if the text in the input-line has changed
+    void IOConsole::inputChanged()
+    {
+        this->printInputLine();
+        this->cout_.flush();
+    }
+
+    //! Called if the position of the cursor in the input-line has changed
+    void IOConsole::cursorChanged()
+    {
+        this->printInputLine();
+        this->cout_.flush();
+    }
+}
+
+#elif defined(ORXONOX_PLATFORM_WINDOWS)
+// ##################################
+// ###   Windows Implementation   ###
+// ##################################
+
+#include <windows.h>
+
+namespace orxonox
+{
+    //! Redirects std::cout, creates the corresponding Shell and changes the terminal mode
+    IOConsole::IOConsole()
+        : shell_(new Shell("IOConsole", false))
+        , buffer_(shell_->getInputBuffer())
+        , cout_(std::cout.rdbuf())
+        , promptString_("orxonox # ")
+        , inputLineHeight_(1)
+        , statusLines_(1)
+        , lastOutputLineHeight_(0)
+    {
+        // Disable standard this->cout_ logging
+        OutputHandler::getInstance().disableCout();
+        // Redirect std::cout to an ostringstream
+        // (Other part is in the initialiser list)
+        std::cout.rdbuf(this->origCout_.rdbuf());
+
+        this->setTerminalMode();
+        CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo;
+        GetConsoleScreenBufferInfo(this->stdOutHandle_, &screenBufferInfo);
+        this->terminalWidth_  = screenBufferInfo.dwSize.X;
+        this->terminalHeight_ = screenBufferInfo.dwSize.Y;
+        // Determines where we are in respect to output already written with std::cout
+        this->inputLineRow_ = screenBufferInfo.dwCursorPosition.Y;
+/*
+        this->lastTerminalWidth_  = this->terminalWidth_;
+        this->lastTerminalHeight_ = this->terminalHeight_;
+*/
+
+        // Cursor already at the end of the screen buffer?
+        // (assuming the current input line height is 1)
+        if (this->inputLineRow_ >= this->terminalHeight_ - this->statusLines_)
+            SetConsoleCursorPosition(this->stdOutHandle_, makeCOORD(0, this->terminalHeight_ - this->statusLines_));
+
+        // Prevent input line from overflowing
+        int maxInputLength = (this->terminalHeight_ - this->statusLines_) * this->terminalWidth_ - 1 - this->promptString_.size();
+        // Consider that the echo of a command might include the command plus some other characters (assumed max 80)
+        // Also put a minimum so the config file parser is not overwhelmed with the command history
+        this->buffer_->setMaxLength(std::min(8192, (maxInputLength - 80) / 2));
+
+        // Print input and status line and position cursor
+        this->inputChanged();
+        this->cursorChanged();
+        this->lastRefreshTime_ = Game::getInstance().getGameClock().getRealMicroseconds();
+        this->preUpdate(Game::getInstance().getGameClock());
+
+        this->shell_->registerListener(this);
+    }
+
+    //! Resets std::cout redirection and restores the terminal mode
+    IOConsole::~IOConsole()
+    {
+        // Process output written to std::cout in the meantime
+        std::cout.flush();
+        if (!this->origCout_.str().empty())
+            this->shell_->addOutput(this->origCout_.str(), Shell::None);
+
+        this->shell_->unregisterListener(this);
+
+        // Erase input and status lines
+        COORD pos = {0, this->inputLineRow_};
+        this->writeText(std::string((this->inputLineHeight_ + this->statusLines_) * this->terminalWidth_, ' '), pos);
+        // Move cursor to the beginning of the line
+        SetConsoleCursorPosition(stdOutHandle_, pos);
+
+        // Restore this->cout_ redirection
+        std::cout.rdbuf(this->cout_.rdbuf());
+        // Enable standard this->cout_ logging again
+        OutputHandler::getInstance().enableCout();
+
+        resetTerminalMode();
+        this->shell_->destroy();
+    }
+
+    //! Processes the pending input key strokes, refreshes the status lines and handles std::cout (redirected)
+    void IOConsole::preUpdate(const Clock& time)
+    {
+        // Process input
+        while (true)
+        {
+            DWORD count;
+            INPUT_RECORD inrec;
+            PeekConsoleInput(this->stdInHandle_, &inrec, 1, &count);
+            if (count == 0)
+                break;
+            ReadConsoleInput(this->stdInHandle_, &inrec, 1, &count);
+            if (inrec.EventType == KEY_EVENT && inrec.Event.KeyEvent.bKeyDown)
+            {
+                // Process keyboard modifiers (Ctrl, Alt and Shift)
+                DWORD modifiersIn = inrec.Event.KeyEvent.dwControlKeyState;
+                int modifiersOut = 0;
+                if ((modifiersIn & (LEFT_ALT_PRESSED  | RIGHT_ALT_PRESSED))  != 0)
+                    modifiersOut |= KeyboardModifier::Alt;
+                if ((modifiersIn & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) != 0)
+                    modifiersOut |= KeyboardModifier::Ctrl;
+                if ((modifiersIn & SHIFT_PRESSED) != 0)
+                    modifiersOut |= KeyboardModifier::Shift;
+
+                // ASCII character (0 for special keys)
+                char asciiChar = inrec.Event.KeyEvent.uChar.AsciiChar;
+
+                // Process special keys and if not found, use Key::A as dummy (InputBuffer uses the ASCII text anyway)
+                switch (inrec.Event.KeyEvent.wVirtualKeyCode)
+                {
+                case VK_BACK:   this->buffer_->buttonPressed(KeyEvent(KeyCode::Back,     asciiChar, modifiersOut)); break;
+                case VK_TAB:    this->buffer_->buttonPressed(KeyEvent(KeyCode::Tab,      asciiChar, modifiersOut)); break;
+                case VK_RETURN: this->buffer_->buttonPressed(KeyEvent(KeyCode::Return,   asciiChar, modifiersOut)); break;
+                case VK_PAUSE:  this->buffer_->buttonPressed(KeyEvent(KeyCode::Pause,    asciiChar, modifiersOut)); break;
+                case VK_ESCAPE: this->buffer_->buttonPressed(KeyEvent(KeyCode::Escape,   asciiChar, modifiersOut)); break;
+                case VK_SPACE:  this->buffer_->buttonPressed(KeyEvent(KeyCode::Space,    asciiChar, modifiersOut)); break;
+                case VK_PRIOR:  this->buffer_->buttonPressed(KeyEvent(KeyCode::PageUp,   asciiChar, modifiersOut)); break;
+                case VK_NEXT:   this->buffer_->buttonPressed(KeyEvent(KeyCode::PageDown, asciiChar, modifiersOut)); break;
+                case VK_END:    this->buffer_->buttonPressed(KeyEvent(KeyCode::End,      asciiChar, modifiersOut)); break;
+                case VK_HOME:   this->buffer_->buttonPressed(KeyEvent(KeyCode::Home,     asciiChar, modifiersOut)); break;
+                case VK_LEFT:   this->buffer_->buttonPressed(KeyEvent(KeyCode::Left,     asciiChar, modifiersOut)); break;
+                case VK_UP:     this->buffer_->buttonPressed(KeyEvent(KeyCode::Up,       asciiChar, modifiersOut)); break;
+                case VK_RIGHT:  this->buffer_->buttonPressed(KeyEvent(KeyCode::Right,    asciiChar, modifiersOut)); break;
+                case VK_DOWN:   this->buffer_->buttonPressed(KeyEvent(KeyCode::Down,     asciiChar, modifiersOut)); break;
+                case VK_INSERT: this->buffer_->buttonPressed(KeyEvent(KeyCode::Insert,   asciiChar, modifiersOut)); break;
+                case VK_DELETE: this->buffer_->buttonPressed(KeyEvent(KeyCode::Delete,   asciiChar, modifiersOut)); break;
+                default:        this->buffer_->buttonPressed(KeyEvent(KeyCode::A,        asciiChar, modifiersOut));
+                }
+            }
+        }
+
+        // TODO: Respect screen buffer size changes
+/*
+        // The user can manually adjust the screen buffer size on Windows
+        // And we don't want to screw the console because of that
+        this->lastTerminalWidth_ = this->terminalWidth_;
+        this->lastTerminalHeight_ = this->terminalHeight_;
+        this->getTerminalSize(); // Also sets this->inputLineRow_ according to the cursor position
+        // Is there still enough space below the cursor for the status line(s)?
+        if (this->inputLineRow_ >= this->terminalHeight_ - this->statusLines_)
+            this->moveCursor(0, -this->inputLineRow_ + this->terminalHeight_ - this->statusLines_ - 1);
+*/
+
+        // Refresh status line 5 times per second
+        if (time.getMicroseconds() > this->lastRefreshTime_ + 1000000)
+        {
+            this->printStatusLines();
+            this->lastRefreshTime_ = time.getMicroseconds();
+        }
+
+        // Process output written to std::cout
+        std::cout.flush();
+        if (!this->origCout_.str().empty())
+        {
+            this->shell_->addOutput(this->origCout_.str(), Shell::None);
+            this->origCout_.str("");
+        }
+    }
+
+    //! Prints output text. Similar to writeText, but sets the colour according to the output level
+    void IOConsole::printOutputLine(const std::string& text, Shell::LineType type, const COORD& pos)
+    {
+        // Colour line
+        WORD colour = 0;
+        switch (type)
+        {
+        case Shell::Error:   colour = FOREGROUND_INTENSITY                    | FOREGROUND_RED; break;
+        case Shell::Warning: colour = FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED; break;
+        case Shell::Info:
+        case Shell::Debug:
+        case Shell::Verbose:
+        case Shell::Ultra:   colour = FOREGROUND_INTENSITY                                     ; break;
+        case Shell::Command: colour =                        FOREGROUND_GREEN                  | FOREGROUND_BLUE; break;
+        case Shell::Hint:    colour =                        FOREGROUND_GREEN | FOREGROUND_RED                  ; break;
+        default:             colour =                        FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE; break;
+        }
+
+        // Print output line
+        this->writeText(text, pos, colour);
+    }
+
+    //! Prints all status lines with current content
+    void IOConsole::printStatusLines()
+    {
+        // Prepare text to be written
+        std::ostringstream oss;
+        oss << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, ";
+        oss <<               std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms tick time";
+        // Clear rest of the line by inserting spaces
+        oss << std::string(this->terminalWidth_ - oss.str().size(), ' ');
+        this->writeText(oss.str(), makeCOORD(0, this->inputLineRow_ + this->inputLineHeight_), FOREGROUND_GREEN);
+    }
+
+    //! Changes the console parameters for unbuffered input
+    void IOConsole::setTerminalMode()
+    {
+        // Set the console mode to no-echo, raw input, and no window or mouse events
+        this->stdOutHandle_ = GetStdHandle(STD_OUTPUT_HANDLE);
+        this->stdInHandle_  = GetStdHandle(STD_INPUT_HANDLE);
+        if (this->stdInHandle_ == INVALID_HANDLE_VALUE
+            || !GetConsoleMode(this->stdInHandle_, &this->originalTerminalSettings_)
+            || !SetConsoleMode(this->stdInHandle_, 0))
+        {
+            COUT(1) << "Error: Could not set Windows console settings" << std::endl;
+            return;
+        }
+        FlushConsoleInputBuffer(this->stdInHandle_);
+    }
+
+    //! Restores the console parameters
+    void IOConsole::resetTerminalMode()
+    {
+        SetConsoleMode(this->stdInHandle_, this->originalTerminalSettings_);
+    }
+
+    //! Sets this->terminalWidth_ and this->terminalHeight_
+    void IOConsole::getTerminalSize()
+    {
+        CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo;
+        GetConsoleScreenBufferInfo(this->stdOutHandle_, &screenBufferInfo);
+        this->terminalWidth_  = screenBufferInfo.dwSize.X;
+        this->terminalHeight_ = screenBufferInfo.dwSize.Y;
+    }
+
+    //! Writes arbitrary text to the console with a certain colour and screen buffer position
+    void IOConsole::writeText(const std::string& text, const COORD& coord, WORD attributes)
+    {
+        DWORD count;
+        WriteConsoleOutputCharacter(stdOutHandle_, text.c_str(), text.size(), coord, &count);
+        FillConsoleOutputAttribute(stdOutHandle_, attributes, text.size(), coord, &count);
+    }
+
+    /** Scrolls the console screen buffer to create empty lines above the input line.
+    @details
+        If the input and status lines are already at the bottom of the screen buffer
+        the whole output gets scrolled up. In the other case the input and status
+        lines get scrolled down.
+        In any case the status and input lines get scrolled down as far as possible.
+    @param lines
+        Number of lines to be inserted. Behavior for negative values is undefined.
+    */
+    void IOConsole::createNewOutputLines(int lines)
+    {
+        CHAR_INFO fillChar = {{' '}, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED};
+        // Lines to scroll input/status down (if possible)
+        int linesDown = clamp(terminalHeight_ - inputLineRow_ - inputLineHeight_ - statusLines_, 0, lines);
+        if (linesDown > 0)
+        {
+            // Scroll input and status lines down
+            SMALL_RECT oldRect = {0, this->inputLineRow_,
+                this->terminalWidth_ - 1, this->inputLineRow_ + this->inputLineHeight_ + this->statusLines_ - 1};
+            this->inputLineRow_ += linesDown;
+            ScrollConsoleScreenBuffer(stdOutHandle_, &oldRect, NULL, makeCOORD(0, this->inputLineRow_), &fillChar);
+            // Move cursor down to the new bottom so the user can see the status lines
+            COORD pos = {0, this->inputLineRow_ + this->inputLineHeight_ - 1 + this->statusLines_};
+            SetConsoleCursorPosition(stdOutHandle_, pos);
+            // Get cursor back to the right position
+            this->cursorChanged();
+        }
+        // Check how many lines we still have to scroll up the output
+        if (lines - linesDown > 0)
+        {
+            // Scroll output up
+            SMALL_RECT oldRect = {0, lines - linesDown, this->terminalWidth_ - 1, this->inputLineRow_ - 1};
+            ScrollConsoleScreenBuffer(stdOutHandle_, &oldRect, NULL, makeCOORD(0, 0), &fillChar);
+        }
+    }
+
+    // ###############################
+    // ###  ShellListener methods  ###
+    // ###############################
+
+    //! Called if the text in the input line has changed
+    void IOConsole::inputChanged()
+    {
+        int newInputLineLength = this->promptString_.size() + this->shell_->getInput().size();
+        int newInputLineHeight = 1 + newInputLineLength / this->terminalWidth_;
+        int newLines = newInputLineHeight - this->inputLineHeight_;
+        if (newLines > 0)
+        {
+            // Abuse this function to scroll the console
+            this->createNewOutputLines(newLines);
+            // Either Compensate for side effects (input/status lines scrolled down)
+            // or we have to do this anyway (output scrolled up)
+            this->inputLineRow_ -= newLines;
+        }
+        else if (newLines < 0)
+        {
+            // Scroll status lines up
+            int statusLineRow = this->inputLineRow_ + this->inputLineHeight_;
+            SMALL_RECT oldRect = {0, statusLineRow, this->terminalWidth_ - 1, statusLineRow + this->statusLines_};
+            CHAR_INFO fillChar = {{' '}, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED};
+            ScrollConsoleScreenBuffer(stdOutHandle_, &oldRect, NULL, makeCOORD(0, statusLineRow + newLines), &fillChar);
+            // Clear potential leftovers
+            if (-newLines - this->statusLines_ > 0)
+            {
+                COORD pos = {0, this->inputLineRow_ + newInputLineHeight + this->statusLines_};
+                this->writeText(std::string((-newLines - this->statusLines_) * this->terminalWidth_, ' '), pos);
+            }
+        }
+        this->inputLineHeight_ = newInputLineHeight;
+
+        // Print the whole line, including spaces that erase leftovers
+        std::string inputLine = this->promptString_ + this->shell_->getInput();
+        inputLine += std::string(this->terminalWidth_ - newInputLineLength % this->terminalWidth_, ' ');
+        this->writeText(inputLine, makeCOORD(0, this->inputLineRow_), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
+        // If necessary, move cursor
+        if (newLines != 0)
+            this->cursorChanged();
+    }
+
+    //! Called if the position of the cursor in the input-line has changed
+    void IOConsole::cursorChanged()
+    {
+        int rawCursorPos = this->promptString_.size() + this->buffer_->getCursorPosition();
+        // Compensate for cursor further to the right than the terminal width
+        COORD pos;
+        pos.X = rawCursorPos % this->terminalWidth_;
+        pos.Y = this->inputLineRow_ + rawCursorPos / this->terminalWidth_;
+        SetConsoleCursorPosition(stdOutHandle_, pos);
+    }
+
+    //! Called if only the last output-line has changed
+    void IOConsole::onlyLastLineChanged()
+    {
+        int newLineHeight = 1 + this->shell_->getNewestLineIterator()->first.size() / this->terminalWidth_;
+        // Compute the number of new lines needed
+        int newLines = newLineHeight - this->lastOutputLineHeight_;
+        this->lastOutputLineHeight_ = newLineHeight;
+        // Scroll console if necessary
+        if (newLines > 0) // newLines < 0 is assumed impossible
+            this->createNewOutputLines(newLines);
+        Shell::LineList::const_iterator it = this->shell_->getNewestLineIterator();
+        this->printOutputLine(it->first, it->second, makeCOORD(0, this->inputLineRow_ - newLineHeight));
+    }
+
+    //! Called if a new output line was added
+    void IOConsole::lineAdded()
+    {
+        Shell::LineList::const_iterator it = this->shell_->getNewestLineIterator();
+        // Scroll console
+        this->lastOutputLineHeight_ = 1 + it->first.size() / this->terminalWidth_;
+        this->createNewOutputLines(this->lastOutputLineHeight_);
+        // Write the text
+        COORD pos = {0, this->inputLineRow_ - this->lastOutputLineHeight_};
+        this->printOutputLine(it->first, it->second, pos);
+    }
+}
+
+#endif /* ORXONOX_PLATFORM_UNIX */
Index: /code/branches/rocket2/src/libraries/core/IOConsole.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/IOConsole.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/IOConsole.h	(revision 6952)
@@ -0,0 +1,128 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _IOConsole_H__
+#define _IOConsole_H__
+
+#include "CorePrereqs.h"
+
+#include <sstream>
+#include <string>
+#include <vector>
+#include "util/Singleton.h"
+#include "Shell.h"
+
+#ifdef ORXONOX_PLATFORM_UNIX
+struct termios;
+#elif defined(ORXONOX_PLATFORM_WINDOWS)
+#define WIN32_LEAN_AND_MEAN
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif
+#include <windows.h>
+#endif
+
+namespace orxonox
+{
+    class _CoreExport IOConsole : public Singleton<IOConsole>, public ShellListener
+    {
+        friend class Singleton<IOConsole>;
+
+    public:
+        IOConsole();
+        ~IOConsole();
+
+        void preUpdate(const Clock& time);
+
+    private:
+        void setTerminalMode();
+        void getTerminalSize();
+        void printStatusLines();
+        static int extractLogLevel(std::string* text);
+
+        // Methods from ShellListener
+        void linesChanged();
+        void onlyLastLineChanged();
+        void lineAdded();
+        void inputChanged();
+        void cursorChanged();
+        void executed();
+        void exit();
+
+        Shell*                  shell_;
+        InputBuffer*            buffer_;
+        std::ostream            cout_;
+        std::ostringstream      origCout_;
+        int                     terminalWidth_;
+        int                     terminalHeight_;
+        int                     lastTerminalWidth_;
+        int                     lastTerminalHeight_;
+        const std::string       promptString_;
+
+#ifdef ORXONOX_PLATFORM_UNIX
+        bool willPrintStatusLines();
+        void printInputLine();
+        void printOutputLine(const std::string& line, Shell::LineType type);
+        static void resetTerminalMode();
+
+        bool                    bPrintStatusLine_;
+        bool                    bStatusPrinted_;
+        std::vector<int>        statusLineWidths_;
+        int                     statusLineMaxWidth_;
+        static const int        minOutputLines_ = 3;
+        termios*                originalTerminalSettings_;
+
+#elif defined(ORXONOX_PLATFORM_WINDOWS)
+        void resetTerminalMode();
+        void moveCursor(int dx, int dy);
+        void writeText(const std::string& text, const COORD& pos, WORD attributes = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
+        void createNewOutputLines(int lines);
+        void printOutputLine(const std::string& line, Shell::LineType type, const COORD& pos);
+
+        static inline COORD makeCOORD(int x, int y)
+        {
+            COORD val = {x, y};
+            return val;
+        }
+
+        DWORD                   originalTerminalSettings_;
+        HANDLE                  stdInHandle_;
+        HANDLE                  stdOutHandle_;
+        int                     inputLineRow_;
+        int                     inputLineHeight_;
+        const int               statusLines_;
+        int                     lastOutputLineHeight_;
+        uint64_t                lastRefreshTime_;
+#endif
+
+        static IOConsole* singletonPtr_s;
+    };
+}
+
+#endif /* _IOConsole_H__ */
Index: /code/branches/rocket2/src/libraries/core/IRC.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/IRC.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/IRC.cc	(revision 6952)
@@ -0,0 +1,141 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "IRC.h"
+
+#include <cpptcl/cpptcl.h>
+
+#include "util/Convert.h"
+#include "util/Exception.h"
+#include "util/StringUtils.h"
+#include "ConsoleCommand.h"
+#include "CoreIncludes.h"
+#include "TclThreadManager.h"
+
+namespace orxonox
+{
+    static const unsigned int IRC_TCL_THREADID  = 1421421421;
+
+    SetConsoleCommand(IRC, say,  true).accessLevel(AccessLevel::User);
+    SetConsoleCommand(IRC, msg,  false).accessLevel(AccessLevel::User);
+    SetConsoleCommand(IRC, nick, false).accessLevel(AccessLevel::User);
+
+    IRC::IRC()
+    {
+        RegisterRootObject(IRC);
+        this->interpreter_ = 0;
+    }
+
+    void IRC::initialize()
+    {
+        unsigned int threadID = IRC_TCL_THREADID;
+        this->interpreter_ = TclThreadManager::createWithId(threadID);
+
+        try
+        {
+            this->interpreter_->def("::orxonox::irc::say", IRC::tcl_say, Tcl::variadic());
+            this->interpreter_->def("::orxonox::irc::privmsg", IRC::tcl_privmsg, Tcl::variadic());
+            this->interpreter_->def("::orxonox::irc::action", IRC::tcl_action, Tcl::variadic());
+            this->interpreter_->def("::orxonox::irc::info", IRC::tcl_info, Tcl::variadic());
+        }
+        catch (Tcl::tcl_error const &e)
+        {   COUT(1) << "Tcl (IRC) error: " << e.what();   }
+        catch (...)
+        {   COUT(1) << "Error while initializing Tcl (IRC): " << Exception::handleMessage();   }
+
+        this->nickname_ = "orx" + multi_cast<std::string>(static_cast<unsigned int>(rand()));
+        TclThreadManager::execute(threadID, "set nickname " + this->nickname_);
+        TclThreadManager::execute(threadID, "source irc.tcl");
+    }
+
+    IRC& IRC::getInstance()
+    {
+        static IRC instance;
+        return instance;
+    }
+
+    bool IRC::eval(const std::string& command)
+    {
+        if (!IRC::getInstance().interpreter_)
+        {
+            IRC::getInstance().initialize();
+            COUT(1) << "Error: IRC client wasn't yet initialized, please try again." << std::endl;
+            return false;
+        }
+
+        try
+        {
+            IRC::getInstance().interpreter_->eval(command);
+            return true;
+        }
+        catch (Tcl::tcl_error const &e)
+        {   COUT(1) << "Tcl (IRC) error: " << e.what();   }
+        catch (...)
+        {   COUT(1) << "Error while executing Tcl (IRC): " << Exception::handleMessage();   }
+
+        return false;
+    }
+
+    void IRC::say(const std::string& message)
+    {
+        if (IRC::eval("irk::say $conn #orxonox {" + message + '}'))
+            IRC::tcl_say(Tcl::object(), Tcl::object(IRC::getInstance().nickname_), Tcl::object(message));
+    }
+
+    void IRC::msg(const std::string& channel, const std::string& message)
+    {
+        if (IRC::eval("irk::say $conn " + channel + " {" + message + '}'))
+            IRC::tcl_privmsg(Tcl::object(channel), Tcl::object(IRC::getInstance().nickname_), Tcl::object(message));
+    }
+
+    void IRC::nick(const std::string& nickname)
+    {
+        if (IRC::eval("irk::nick $conn " + nickname))
+            IRC::getInstance().nickname_ = nickname;
+    }
+
+    void IRC::tcl_say(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args)
+    {
+        COUT(0) << "IRC> " << nick.get() << ": " << stripEnclosingBraces(args.get()) << std::endl;
+    }
+
+    void IRC::tcl_privmsg(Tcl::object const &query, Tcl::object const &nick, Tcl::object const &args)
+    {
+        COUT(0) << "IRC (" << query.get() << ")> " << nick.get() << ": " << stripEnclosingBraces(args.get()) << std::endl;
+    }
+
+    void IRC::tcl_action(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args)
+    {
+        COUT(0) << "IRC> * " << nick.get() << ' ' << stripEnclosingBraces(args.get()) << std::endl;
+    }
+
+    void IRC::tcl_info(Tcl::object const &channel, Tcl::object const &args)
+    {
+        COUT(0) << "IRC> --> " << stripEnclosingBraces(args.get()) << std::endl;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/IRC.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/IRC.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/IRC.h	(revision 6952)
@@ -0,0 +1,66 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _IRC_H__
+#define _IRC_H__
+
+#include "CorePrereqs.h"
+
+#include <string>
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _CoreExport IRC : public OrxonoxClass
+    {
+        public:
+            static IRC& getInstance();
+
+            static void say(const std::string& message);
+            static void msg(const std::string& channel, const std::string& message);
+            static void nick(const std::string& nickname);
+
+            static void tcl_say(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args);
+            static void tcl_privmsg(Tcl::object const &query, Tcl::object const &nick, Tcl::object const &args);
+            static void tcl_action(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args);
+            static void tcl_info(Tcl::object const &channel, Tcl::object const &args);
+
+        private:
+            static bool eval(const std::string& command);
+            void initialize();
+
+            IRC();
+            IRC(const IRC& other);
+            ~IRC() {}
+
+            Tcl::interpreter* interpreter_;
+            std::string nickname_;
+    };
+}
+
+#endif /* _IRC_H__ */
Index: /code/branches/rocket2/src/libraries/core/Identifier.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/Identifier.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Identifier.cc	(revision 6952)
@@ -0,0 +1,566 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the Identifier class.
+*/
+
+#include "Identifier.h"
+
+#include <ostream>
+
+#include "util/StringUtils.h"
+#include "ConfigValueContainer.h"
+#include "ConsoleCommand.h"
+#include "ClassFactory.h"
+#include "XMLPort.h"
+
+namespace orxonox
+{
+    // ###############################
+    // ###       Identifier        ###
+    // ###############################
+    int Identifier::hierarchyCreatingCounter_s = 0;
+    unsigned int Identifier::classIDCounter_s = 0;
+
+    /**
+        @brief Constructor: No factory, no object created, new ObjectList and a unique networkID.
+    */
+    Identifier::Identifier()
+        : classID_(classIDCounter_s++)
+    {
+        this->objects_ = new ObjectListBase(this);
+
+        this->bCreatedOneObject_ = false;
+        this->bSetName_ = false;
+        this->factory_ = 0;
+        this->bLoadable_ = false;
+
+        this->bHasConfigValues_ = false;
+        this->bHasConsoleCommands_ = false;
+
+        // Default network ID is the class ID
+        this->networkID_ = this->classID_;
+    }
+
+    /**
+        @brief Destructor: Deletes the list containing the children.
+    */
+    Identifier::~Identifier()
+    {
+        delete this->objects_;
+
+        if (this->factory_)
+            delete this->factory_;
+
+        for (std::map<std::string, ConsoleCommand*>::iterator it = this->consoleCommands_.begin(); it != this->consoleCommands_.end(); ++it)
+            delete (it->second);
+        for (std::map<std::string, ConfigValueContainer*>::iterator it = this->configValues_.begin(); it != this->configValues_.end(); ++it)
+            delete (it->second);
+        for (std::map<std::string, XMLPortParamContainer*>::iterator it = this->xmlportParamContainers_.begin(); it != this->xmlportParamContainers_.end(); ++it)
+            delete (it->second);
+        for (std::map<std::string, XMLPortObjectContainer*>::iterator it = this->xmlportObjectContainers_.begin(); it != this->xmlportObjectContainers_.end(); ++it)
+            delete (it->second);
+    }
+
+    /**
+        @brief Returns the identifier map with the names as received by typeid(). This is only used internally.
+    */
+    std::map<std::string, Identifier*>& Identifier::getTypeIDIdentifierMap()
+    {
+        static std::map<std::string, Identifier*> identifiers;    //!< The map to store all Identifiers.
+        return identifiers;
+    }
+
+    /**
+        @brief Returns an identifier by name and adds it if not available
+        @param name The name of the identifier as typeid().name() suggests
+        @param proposal A pointer to a newly created identifier for the case of non existance in the map
+        @return The identifier (unique instance)
+    */
+    Identifier* Identifier::getIdentifierSingleton(const std::string& name, Identifier* proposal)
+    {
+        std::map<std::string, Identifier*>::const_iterator it = getTypeIDIdentifierMap().find(name);
+
+        if (it != getTypeIDIdentifierMap().end())
+        {
+            // There is already an entry: return it and delete the proposal
+            delete proposal;
+            return it->second;
+        }
+        else
+        {
+            // There is no entry: put the proposal into the map and return it
+            getTypeIDIdentifierMap()[name] = proposal;
+            return proposal;
+        }
+    }
+
+    /**
+        @brief Registers a class, which means that the name and the parents get stored.
+        @param parents A list, containing the Identifiers of all parents of the class
+        @param bRootClass True if the class is either an Interface or the BaseObject itself
+    */
+    void Identifier::initializeClassHierarchy(std::set<const Identifier*>* parents, bool bRootClass)
+    {
+        // Check if at least one object of the given type was created
+        if (!this->bCreatedOneObject_ && Identifier::isCreatingHierarchy())
+        {
+            // If no: We have to store the information and initialize the Identifier
+            COUT(4) << "*** ClassIdentifier: Register Class in " << this->getName() << "-Singleton -> Initialize Singleton." << std::endl;
+            if (bRootClass)
+                this->initialize(0); // If a class is derived from two interfaces, the second interface might think it's derived from the first because of the order of constructor-calls. Thats why we set parents to zero in that case.
+            else
+                this->initialize(parents);
+        }
+    }
+
+    /**
+        @brief Initializes the Identifier with a list containing all parents of the class the Identifier belongs to.
+        @param parents A list containing all parents
+    */
+    void Identifier::initialize(std::set<const Identifier*>* parents)
+    {
+        COUT(4) << "*** Identifier: Initialize " << this->name_ << "-Singleton." << std::endl;
+        this->bCreatedOneObject_ = true;
+
+        if (parents)
+        {
+            this->parents_ = (*parents);
+            this->directParents_ = (*parents);
+
+            // Iterate through all parents
+            for (std::set<const Identifier*>::iterator it = parents->begin(); it != parents->end(); ++it)
+            {
+                // Tell the parent we're one of it's children
+                (*it)->children_.insert((*it)->children_.end(), this);
+
+                // Erase all parents of our parent from our direct-parent-list
+                for (std::set<const Identifier*>::const_iterator it1 = (*it)->getParents().begin(); it1 != (*it)->getParents().end(); ++it1)
+                {
+                    // Search for the parent's parent in our direct-parent-list
+                    for (std::set<const Identifier*>::iterator it2 = this->directParents_.begin(); it2 != this->directParents_.end(); ++it2)
+                    {
+                        if ((*it1) == (*it2))
+                        {
+                            // We've found a non-direct parent in our list: Erase it
+                            this->directParents_.erase(it2);
+                            break;
+                        }
+                    }
+                }
+            }
+
+            // Now iterate through all direct parents
+            for (std::set<const Identifier*>::iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it)
+            {
+                // Tell the parent we're one of it's direct children
+                (*it)->directChildren_.insert((*it)->directChildren_.end(), this);
+
+                // Create the super-function dependencies
+                (*it)->createSuperFunctionCaller();
+            }
+        }
+    }
+
+    /**
+        @brief Creates the class-hierarchy by creating and destroying one object of each type.
+    */
+    void Identifier::createClassHierarchy()
+    {
+        COUT(3) << "*** Identifier: Create class-hierarchy" << std::endl;
+        Identifier::startCreatingHierarchy();
+        for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getStringIdentifierMap().begin(); it != Identifier::getStringIdentifierMap().end(); ++it)
+        {
+            // To create the new branch of the class-hierarchy, we create a new object and delete it afterwards.
+            if (it->second->hasFactory())
+            {
+                BaseObject* temp = it->second->fabricate(0);
+                temp->destroy();
+            }
+        }
+        Identifier::stopCreatingHierarchy();
+        COUT(3) << "*** Identifier: Finished class-hierarchy creation" << std::endl;
+    }
+
+    /**
+        @brief Destroys all Identifiers. Called when exiting the program.
+    */
+    void Identifier::destroyAllIdentifiers()
+    {
+        for (std::map<std::string, Identifier*>::iterator it = Identifier::getTypeIDIdentifierMap().begin(); it != Identifier::getTypeIDIdentifierMap().end(); ++it)
+            delete (it->second);
+    }
+
+    /**
+        @brief Sets the name of the class.
+        @param name The name
+    */
+    void Identifier::setName(const std::string& name)
+    {
+        if (!this->bSetName_)
+        {
+            this->name_ = name;
+            this->bSetName_ = true;
+            Identifier::getStringIdentifierMapIntern()[name] = this;
+            Identifier::getLowercaseStringIdentifierMapIntern()[getLowercase(name)] = this;
+            Identifier::getIDIdentifierMapIntern()[this->networkID_] = this;
+        }
+    }
+
+    /**
+        @brief Creates an object of the type the Identifier belongs to.
+        @return The new object
+    */
+    BaseObject* Identifier::fabricate(BaseObject* creator)
+    {
+        if (this->factory_)
+        {
+            return this->factory_->fabricate(creator); // We have to return a BaseObject, because we don't know the exact type.
+        }
+        else
+        {
+            COUT(1) << "An error occurred in Identifier.cc:" << std::endl;
+            COUT(1) << "Error: Cannot fabricate an object of type '" << this->name_ << "'. Class has no factory." << std::endl;
+            COUT(1) << "Aborting..." << std::endl;
+            abort();
+            return 0;
+        }
+    }
+
+    /**
+        @brief Sets the network ID to a new value and changes the entry in the ID-Identifier-map.
+        @param id The new network ID
+    */
+    void Identifier::setNetworkID(uint32_t id)
+    {
+//        Identifier::getIDIdentifierMapIntern().erase(this->networkID_);
+        Identifier::getIDIdentifierMapIntern()[id] = this;
+        this->networkID_ = id;
+    }
+
+    /**
+        @brief Returns true, if the Identifier is at least of the given type.
+        @param identifier The identifier to compare with
+    */
+    bool Identifier::isA(const Identifier* identifier) const
+    {
+        return (identifier == this || (this->parents_.find(identifier) != this->parents_.end()));
+    }
+
+    /**
+        @brief Returns true, if the Identifier is exactly of the given type.
+        @param identifier The identifier to compare with
+    */
+    bool Identifier::isExactlyA(const Identifier* identifier) const
+    {
+        return (identifier == this);
+    }
+
+    /**
+        @brief Returns true, if the assigned identifier is a child of the given identifier.
+        @param identifier The identifier to compare with
+    */
+    bool Identifier::isChildOf(const Identifier* identifier) const
+    {
+        return (this->parents_.find(identifier) != this->parents_.end());
+    }
+
+    /**
+        @brief Returns true, if the assigned identifier is a direct child of the given identifier.
+        @param identifier The identifier to compare with
+    */
+    bool Identifier::isDirectChildOf(const Identifier* identifier) const
+    {
+        return (this->directParents_.find(identifier) != this->directParents_.end());
+    }
+
+    /**
+        @brief Returns true, if the assigned identifier is a parent of the given identifier.
+        @param identifier The identifier to compare with
+    */
+    bool Identifier::isParentOf(const Identifier* identifier) const
+    {
+        return (this->children_.find(identifier) != this->children_.end());
+    }
+
+    /**
+        @brief Returns true, if the assigned identifier is a direct parent of the given identifier.
+        @param identifier The identifier to compare with
+    */
+    bool Identifier::isDirectParentOf(const Identifier* identifier) const
+    {
+        return (this->directChildren_.find(identifier) != this->directChildren_.end());
+    }
+
+    /**
+        @brief Returns the map that stores all Identifiers with their names.
+        @return The map
+    */
+    std::map<std::string, Identifier*>& Identifier::getStringIdentifierMapIntern()
+    {
+        static std::map<std::string, Identifier*> identifierMap;
+        return identifierMap;
+    }
+
+    /**
+        @brief Returns the map that stores all Identifiers with their names in lowercase.
+        @return The map
+    */
+    std::map<std::string, Identifier*>& Identifier::getLowercaseStringIdentifierMapIntern()
+    {
+        static std::map<std::string, Identifier*> lowercaseIdentifierMap;
+        return lowercaseIdentifierMap;
+    }
+
+    /**
+        @brief Returns the map that stores all Identifiers with their network IDs.
+        @return The map
+    */
+    std::map<uint32_t, Identifier*>& Identifier::getIDIdentifierMapIntern()
+    {
+        static std::map<uint32_t, Identifier*> identifierMap;
+        return identifierMap;
+    }
+
+    /**
+        @brief Returns the Identifier with a given name.
+        @param name The name of the wanted Identifier
+        @return The Identifier
+    */
+    Identifier* Identifier::getIdentifierByString(const std::string& name)
+    {
+        std::map<std::string, Identifier*>::const_iterator it = Identifier::getStringIdentifierMapIntern().find(name);
+        if (it != Identifier::getStringIdentifierMapIntern().end())
+            return it->second;
+        else
+            return 0;
+    }
+
+    /**
+        @brief Returns the Identifier with a given name in lowercase.
+        @param name The name of the wanted Identifier
+        @return The Identifier
+    */
+    Identifier* Identifier::getIdentifierByLowercaseString(const std::string& name)
+    {
+        std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseStringIdentifierMapIntern().find(name);
+        if (it != Identifier::getLowercaseStringIdentifierMapIntern().end())
+            return it->second;
+        else
+            return 0;
+    }
+
+    /**
+        @brief Returns the Identifier with a given network ID.
+        @param id The network ID of the wanted Identifier
+        @return The Identifier
+    */
+    Identifier* Identifier::getIdentifierByID(const uint32_t id)
+    {
+        std::map<uint32_t, Identifier*>::const_iterator it = Identifier::getIDIdentifierMapIntern().find(id);
+        if (it != Identifier::getIDIdentifierMapIntern().end())
+            return it->second;
+        else
+            return 0;
+    }
+
+    /**
+        @brief Cleans the NetworkID map (needed on clients for correct initialization)
+    */
+    void Identifier::clearNetworkIDs()
+    {
+        Identifier::getIDIdentifierMapIntern().clear();
+    }
+
+    /**
+        @brief Adds the ConfigValueContainer of a variable, given by the string of its name.
+        @param varname The name of the variablee
+        @param container The container
+    */
+    void Identifier::addConfigValueContainer(const std::string& varname, ConfigValueContainer* container)
+    {
+        std::map<std::string, ConfigValueContainer*>::const_iterator it = this->configValues_.find(varname);
+        if (it != this->configValues_.end())
+        {
+            COUT(2) << "Warning: Overwriting config-value with name " << varname << " in class " << this->getName() << '.' << std::endl;
+            delete (it->second);
+        }
+
+        this->bHasConfigValues_ = true;
+        this->configValues_[varname] = container;
+    }
+
+    /**
+        @brief Returns the ConfigValueContainer of a variable, given by the string of its name.
+        @param varname The name of the variable
+        @return The ConfigValueContainer
+    */
+    ConfigValueContainer* Identifier::getConfigValueContainer(const std::string& varname)
+    {
+        std::map<std::string, ConfigValueContainer*>::const_iterator it = configValues_.find(varname);
+        if (it != configValues_.end())
+            return it->second;
+        else
+            return 0;
+    }
+
+    /**
+        @brief Adds a new console command of this class.
+        @param executor The executor of the command
+        @param bCreateShortcut If this is true a shortcut gets created so you don't have to add the classname to access this command
+        @return The executor of the command
+    */
+    ConsoleCommand& Identifier::addConsoleCommand(ConsoleCommand* command, bool bCreateShortcut)
+    {
+        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_.find(command->getName());
+        if (it != this->consoleCommands_.end())
+        {
+            COUT(2) << "Warning: Overwriting console-command with name " << command->getName() << " in class " << this->getName() << '.' << std::endl;
+            delete (it->second);
+        }
+
+        this->bHasConsoleCommands_ = true;
+        this->consoleCommands_[command->getName()] = command;
+        this->consoleCommands_LC_[getLowercase(command->getName())] = command;
+
+        if (bCreateShortcut)
+            CommandExecutor::addConsoleCommandShortcut(command);
+
+        return (*command);
+    }
+
+    /**
+        @brief Returns the executor of a console command with given name.
+        @brief name The name of the requested console command
+        @return The executor of the requested console command
+    */
+    ConsoleCommand* Identifier::getConsoleCommand(const std::string& name) const
+    {
+        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_.find(name);
+        if (it != this->consoleCommands_.end())
+            return it->second;
+        else
+            return 0;
+    }
+
+    /**
+        @brief Returns the executor of a console command with given name in lowercase.
+        @brief name The name of the requested console command in lowercae
+        @return The executor of the requested console command
+    */
+    ConsoleCommand* Identifier::getLowercaseConsoleCommand(const std::string& name) const
+    {
+        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_LC_.find(name);
+        if (it != this->consoleCommands_LC_.end())
+            return it->second;
+        else
+            return 0;
+    }
+
+    /**
+        @brief Returns a XMLPortParamContainer that loads a parameter of this class.
+        @param paramname The name of the parameter
+        @return The container
+    */
+    XMLPortParamContainer* Identifier::getXMLPortParamContainer(const std::string& paramname)
+    {
+        std::map<std::string, XMLPortParamContainer*>::const_iterator it = this->xmlportParamContainers_.find(paramname);
+        if (it != this->xmlportParamContainers_.end())
+            return it->second;
+        else
+            return 0;
+    }
+
+    /**
+        @brief Adds a new XMLPortParamContainer that loads a parameter of this class.
+        @param paramname The name of the parameter
+        @param container The container
+    */
+    void Identifier::addXMLPortParamContainer(const std::string& paramname, XMLPortParamContainer* container)
+    {
+        std::map<std::string, XMLPortParamContainer*>::const_iterator it = this->xmlportParamContainers_.find(paramname);
+        if (it != this->xmlportParamContainers_.end())
+        {
+            COUT(2) << "Warning: Overwriting XMLPortParamContainer in class " << this->getName() << '.' << std::endl;
+            delete (it->second);
+        }
+
+        this->xmlportParamContainers_[paramname] = container;
+    }
+
+    /**
+        @brief Returns a XMLPortObjectContainer that attaches an object to this class.
+        @param sectionname The name of the section that contains the attachable objects
+        @return The container
+    */
+    XMLPortObjectContainer* Identifier::getXMLPortObjectContainer(const std::string& sectionname)
+    {
+        std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->xmlportObjectContainers_.find(sectionname);
+        if (it != this->xmlportObjectContainers_.end())
+            return it->second;
+        else
+            return 0;
+    }
+
+    /**
+        @brief Adds a new XMLPortObjectContainer that attaches an object to this class.
+        @param sectionname The name of the section that contains the attachable objects
+        @param container The container
+    */
+    void Identifier::addXMLPortObjectContainer(const std::string& sectionname, XMLPortObjectContainer* container)
+    {
+        std::map<std::string, XMLPortObjectContainer*>::const_iterator it = this->xmlportObjectContainers_.find(sectionname);
+        if (it != this->xmlportObjectContainers_.end())
+        {
+            COUT(2) << "Warning: Overwriting XMLPortObjectContainer in class " << this->getName() << '.' << std::endl;
+            delete (it->second);
+        }
+
+        this->xmlportObjectContainers_[sectionname] = container;
+    }
+
+    /**
+        @brief Lists the names of all Identifiers in a std::set<const Identifier*>.
+        @param out The outstream
+        @param list The list (or set) of Identifiers
+        @return The outstream
+    */
+    std::ostream& operator<<(std::ostream& out, const std::set<const Identifier*>& list)
+    {
+        for (std::set<const Identifier*>::const_iterator it = list.begin(); it != list.end(); ++it)
+        {
+            if (it != list.begin())
+                out << ' ';
+            out << (*it)->getName();
+        }
+
+        return out;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/Identifier.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Identifier.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Identifier.h	(revision 6952)
@@ -0,0 +1,500 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the Identifier class, definition and implementation of the ClassIdentifier class.
+
+    The Identifier contains all needed information about the class it belongs to:
+     - the name
+     - a list with all objects
+     - parents and children
+     - the factory (if available)
+     - the networkID that can be synchronised with the server
+     - all configurable variables (if available)
+
+    Every object has a pointer to the Identifier of its class. This allows the use isA(...),
+    isExactlyA(...), isChildOf(...) and isParentOf(...).
+
+    To create the class-hierarchy, the Identifier has some intern functions and variables.
+
+    Every Identifier is in fact a ClassIdentifier, but they are derived from Identifier.
+*/
+
+#ifndef _Identifier_H__
+#define _Identifier_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include <map>
+#include <set>
+#include <string>
+#include <typeinfo>
+
+#include "util/Debug.h"
+#include "util/TypeTraits.h"
+#include "MetaObjectList.h"
+#include "ObjectList.h"
+#include "ObjectListBase.h"
+#include "Super.h"
+
+namespace orxonox
+{
+    // ###############################
+    // ###       Identifier        ###
+    // ###############################
+    //! The Identifier is used to identify the class of an object and to store information about the class.
+    /**
+        The Identifier contains all needed information about the class it belongs to:
+         - the name
+         - a list with all objects
+         - parents and children
+         - the factory (if available)
+         - the networkID that can be synchronised with the server
+         - all configurable variables (if available)
+
+        Every object has a pointer to the Identifier of its class. This allows the use isA(...),
+        isExactlyA(...), isChildOf(...) and isParentOf(...).
+
+        You can't directly create an Identifier, it's just the base-class for ClassIdentifier.
+    */
+    class _CoreExport Identifier
+    {
+        public:
+            /** @brief Returns the name of the class the Identifier belongs to. @return The name */
+            inline const std::string& getName() const { return this->name_; }
+            void setName(const std::string& name);
+
+            /** @brief Returns the network ID to identify a class through the network. @return the network ID */
+            inline const uint32_t getNetworkID() const { return this->networkID_; }
+            void setNetworkID(uint32_t id);
+
+            /** @brief Returns the unique ID of the class */
+            FORCEINLINE unsigned int getClassID() const { return this->classID_; }
+
+            /** @brief Returns the list of all existing objects of this class. @return The list */
+            inline ObjectListBase* getObjects() const { return this->objects_; }
+
+            /** @brief Sets the Factory. @param factory The factory to assign */
+            inline void addFactory(Factory* factory) { this->factory_ = factory; }
+            /** @brief Returns true if the Identifier has a Factory. */
+            inline bool hasFactory() const { return (this->factory_ != 0); }
+
+            BaseObject* fabricate(BaseObject* creator);
+
+            /** @brief Returns true if the class can be loaded through XML. */
+            inline bool isLoadable() const { return this->bLoadable_; }
+            /** @brief Set the class to be loadable through XML or not. */
+            inline void setLoadable(bool bLoadable) { this->bLoadable_ = bLoadable; }
+
+            bool isA(const Identifier* identifier) const;
+            bool isExactlyA(const Identifier* identifier) const;
+            bool isChildOf(const Identifier* identifier) const;
+            bool isDirectChildOf(const Identifier* identifier) const;
+            bool isParentOf(const Identifier* identifier) const;
+            bool isDirectParentOf(const Identifier* identifier) const;
+
+
+            /////////////////////////////
+            ////// Class Hierarchy //////
+            /////////////////////////////
+            static void createClassHierarchy();
+
+            /** @brief Returns true, if a branch of the class-hierarchy is being created, causing all new objects to store their parents. @return The status of the class-hierarchy creation */
+            inline static bool isCreatingHierarchy() { return (hierarchyCreatingCounter_s > 0); }
+
+            /** @brief Returns the parents of the class the Identifier belongs to. @return The list of all parents */
+            inline const std::set<const Identifier*>& getParents() const { return this->parents_; }
+            /** @brief Returns the begin-iterator of the parents-list. @return The begin-iterator */
+            inline std::set<const Identifier*>::const_iterator getParentsBegin() const { return this->parents_.begin(); }
+            /** @brief Returns the end-iterator of the parents-list. @return The end-iterator */
+            inline std::set<const Identifier*>::const_iterator getParentsEnd() const { return this->parents_.end(); }
+
+            /** @brief Returns the children of the class the Identifier belongs to. @return The list of all children */
+            inline const std::set<const Identifier*>& getChildren() const { return this->children_; }
+            /** @brief Returns the begin-iterator of the children-list. @return The begin-iterator */
+            inline std::set<const Identifier*>::const_iterator getChildrenBegin() const { return this->children_.begin(); }
+            /** @brief Returns the end-iterator of the children-list. @return The end-iterator */
+            inline std::set<const Identifier*>::const_iterator getChildrenEnd() const { return this->children_.end(); }
+
+            /** @brief Returns the direct parents of the class the Identifier belongs to. @return The list of all direct parents */
+            inline const std::set<const Identifier*>& getDirectParents() const { return this->directParents_; }
+            /** @brief Returns the begin-iterator of the direct-parents-list. @return The begin-iterator */
+            inline std::set<const Identifier*>::const_iterator getDirectParentsBegin() const { return this->directParents_.begin(); }
+            /** @brief Returns the end-iterator of the direct-parents-list. @return The end-iterator */
+            inline std::set<const Identifier*>::const_iterator getDirectParentsEnd() const { return this->directParents_.end(); }
+
+            /** @brief Returns the direct children the class the Identifier belongs to. @return The list of all direct children */
+            inline const std::set<const Identifier*>& getDirectChildren() const { return this->directChildren_; }
+            /** @brief Returns the begin-iterator of the direct-children-list. @return The begin-iterator */
+            inline std::set<const Identifier*>::const_iterator getDirectChildrenBegin() const { return this->directChildren_.begin(); }
+            /** @brief Returns the end-iterator of the direct-children-list. @return The end-iterator */
+            inline std::set<const Identifier*>::const_iterator getDirectChildrenEnd() const { return this->directChildren_.end(); }
+
+
+            //////////////////////////
+            ///// Identifier Map /////
+            //////////////////////////
+            static void destroyAllIdentifiers();
+
+            static Identifier* getIdentifierByString(const std::string& name);
+            static Identifier* getIdentifierByLowercaseString(const std::string& name);
+            static Identifier* getIdentifierByID(uint32_t id);
+
+            static void clearNetworkIDs();
+
+            /** @brief Returns the map that stores all Identifiers with their names. @return The map */
+            static inline const std::map<std::string, Identifier*>& getStringIdentifierMap() { return Identifier::getStringIdentifierMapIntern(); }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all Identifiers with their names. @return The const_iterator */
+            static inline std::map<std::string, Identifier*>::const_iterator getStringIdentifierMapBegin() { return Identifier::getStringIdentifierMap().begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all Identifiers with their names. @return The const_iterator */
+            static inline std::map<std::string, Identifier*>::const_iterator getStringIdentifierMapEnd() { return Identifier::getStringIdentifierMap().end(); }
+
+            /** @brief Returns the map that stores all Identifiers with their names in lowercase. @return The map */
+            static inline const std::map<std::string, Identifier*>& getLowercaseStringIdentifierMap() { return Identifier::getLowercaseStringIdentifierMapIntern(); }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all Identifiers with their names in lowercase. @return The const_iterator */
+            static inline std::map<std::string, Identifier*>::const_iterator getLowercaseStringIdentifierMapBegin() { return Identifier::getLowercaseStringIdentifierMap().begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all Identifiers with their names in lowercase. @return The const_iterator */
+            static inline std::map<std::string, Identifier*>::const_iterator getLowercaseStringIdentifierMapEnd() { return Identifier::getLowercaseStringIdentifierMap().end(); }
+
+            /** @brief Returns the map that stores all Identifiers with their IDs. @return The map */
+            static inline const std::map<uint32_t, Identifier*>& getIDIdentifierMap() { return Identifier::getIDIdentifierMapIntern(); }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all Identifiers with their IDs. @return The const_iterator */
+            static inline std::map<uint32_t, Identifier*>::const_iterator getIDIdentifierMapBegin() { return Identifier::getIDIdentifierMap().begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all Identifiers with their IDs. @return The const_iterator */
+            static inline std::map<uint32_t, Identifier*>::const_iterator getIDIdentifierMapEnd() { return Identifier::getIDIdentifierMap().end(); }
+
+
+            /////////////////////////
+            ///// Config Values /////
+            /////////////////////////
+            virtual void updateConfigValues(bool updateChildren = true) const = 0;
+
+            /** @brief Returns true if this class has at least one config value. @return True if this class has at least one config value */
+            inline bool hasConfigValues() const { return this->bHasConfigValues_; }
+
+            void addConfigValueContainer(const std::string& varname, ConfigValueContainer* container);
+            ConfigValueContainer* getConfigValueContainer(const std::string& varname);
+
+
+            ////////////////////////////
+            ///// Console Commands /////
+            ////////////////////////////
+            /** @brief Returns true if this class has at least one console command. @return True if this class has at least one console command */
+            inline bool hasConsoleCommands() const { return this->bHasConsoleCommands_; }
+
+            /** @brief Returns the map that stores all console commands. @return The const_iterator */
+            inline const std::map<std::string, ConsoleCommand*>& getConsoleCommandMap() const { return this->consoleCommands_; }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all console commands. @return The const_iterator */
+            inline std::map<std::string, ConsoleCommand*>::const_iterator getConsoleCommandMapBegin() const { return this->consoleCommands_.begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all console commands. @return The const_iterator */
+            inline std::map<std::string, ConsoleCommand*>::const_iterator getConsoleCommandMapEnd() const { return this->consoleCommands_.end(); }
+
+            /** @brief Returns the map that stores all console commands with their names in lowercase. @return The const_iterator */
+            inline const std::map<std::string, ConsoleCommand*>& getLowercaseConsoleCommandMap() const { return this->consoleCommands_LC_; }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all console commands with their names in lowercase. @return The const_iterator */
+            inline std::map<std::string, ConsoleCommand*>::const_iterator getLowercaseConsoleCommandMapBegin() const { return this->consoleCommands_LC_.begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all console commands with their names in lowercase. @return The const_iterator */
+            inline std::map<std::string, ConsoleCommand*>::const_iterator getLowercaseConsoleCommandMapEnd() const { return this->consoleCommands_LC_.end(); }
+
+            ConsoleCommand& addConsoleCommand(ConsoleCommand* command, bool bCreateShortcut);
+            ConsoleCommand* getConsoleCommand(const std::string& name) const;
+            ConsoleCommand* getLowercaseConsoleCommand(const std::string& name) const;
+
+
+            ///////////////////
+            ///// XMLPort /////
+            ///////////////////
+            /** @brief Returns the map that stores all XMLPort params. @return The const_iterator */
+            inline const std::map<std::string, XMLPortParamContainer*>& getXMLPortParamMap() const { return this->xmlportParamContainers_; }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all XMLPort params. @return The const_iterator */
+            inline std::map<std::string, XMLPortParamContainer*>::const_iterator getXMLPortParamMapBegin() const { return this->xmlportParamContainers_.begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all XMLPort params. @return The const_iterator */
+            inline std::map<std::string, XMLPortParamContainer*>::const_iterator getXMLPortParamMapEnd() const { return this->xmlportParamContainers_.end(); }
+
+            /** @brief Returns the map that stores all XMLPort objects. @return The const_iterator */
+            inline const std::map<std::string, XMLPortObjectContainer*>& getXMLPortObjectMap() const { return this->xmlportObjectContainers_; }
+            /** @brief Returns a const_iterator to the beginning of the map that stores all XMLPort objects. @return The const_iterator */
+            inline std::map<std::string, XMLPortObjectContainer*>::const_iterator getXMLPortObjectMapBegin() const { return this->xmlportObjectContainers_.begin(); }
+            /** @brief Returns a const_iterator to the end of the map that stores all XMLPort objects. @return The const_iterator */
+            inline std::map<std::string, XMLPortObjectContainer*>::const_iterator getXMLPortObjectMapEnd() const { return this->xmlportObjectContainers_.end(); }
+
+            void addXMLPortParamContainer(const std::string& paramname, XMLPortParamContainer* container);
+            XMLPortParamContainer* getXMLPortParamContainer(const std::string& paramname);
+
+            void addXMLPortObjectContainer(const std::string& sectionname, XMLPortObjectContainer* container);
+            XMLPortObjectContainer* getXMLPortObjectContainer(const std::string& sectionname);
+
+
+        protected:
+            Identifier();
+            Identifier(const Identifier& identifier); // don't copy
+            virtual ~Identifier();
+
+            static Identifier* getIdentifierSingleton(const std::string& name, Identifier* proposal);
+            virtual void createSuperFunctionCaller() const = 0;
+
+            void initializeClassHierarchy(std::set<const Identifier*>* parents, bool bRootClass);
+
+            /** @brief Returns the map that stores all Identifiers with their names. @return The map */
+            static std::map<std::string, Identifier*>& getStringIdentifierMapIntern();
+            /** @brief Returns the map that stores all Identifiers with their names in lowercase. @return The map */
+            static std::map<std::string, Identifier*>& getLowercaseStringIdentifierMapIntern();
+            /** @brief Returns the map that stores all Identifiers with their network IDs. @return The map */
+            static std::map<uint32_t, Identifier*>& getIDIdentifierMapIntern();
+
+            /** @brief Returns the children of the class the Identifier belongs to. @return The list of all children */
+            inline std::set<const Identifier*>& getChildrenIntern() const { return this->children_; }
+            /** @brief Returns the direct children of the class the Identifier belongs to. @return The list of all direct children */
+            inline std::set<const Identifier*>& getDirectChildrenIntern() const { return this->directChildren_; }
+
+            ObjectListBase* objects_;                                      //!< The list of all objects of this class
+
+        private:
+            /** @brief Increases the hierarchyCreatingCounter_s variable, causing all new objects to store their parents. */
+            inline static void startCreatingHierarchy() { hierarchyCreatingCounter_s++; }
+            /** @brief Decreases the hierarchyCreatingCounter_s variable, causing the objects to stop storing their parents. */
+            inline static void stopCreatingHierarchy()  { hierarchyCreatingCounter_s--; }
+
+            static std::map<std::string, Identifier*>& getTypeIDIdentifierMap();
+
+            void initialize(std::set<const Identifier*>* parents);
+
+            std::set<const Identifier*> parents_;                          //!< The parents of the class the Identifier belongs to
+            mutable std::set<const Identifier*> children_;                 //!< The children of the class the Identifier belongs to
+
+            std::set<const Identifier*> directParents_;                    //!< The direct parents of the class the Identifier belongs to
+            mutable std::set<const Identifier*> directChildren_;           //!< The direct children of the class the Identifier belongs to
+
+            bool bCreatedOneObject_;                                       //!< True if at least one object of the given type was created (used to determine the need of storing the parents)
+            bool bSetName_;                                                //!< True if the name is set
+            bool bLoadable_;                                               //!< False = it's not permitted to load the object through XML
+            std::string name_;                                             //!< The name of the class the Identifier belongs to
+            Factory* factory_;                                             //!< The Factory, able to create new objects of the given class (if available)
+            static int hierarchyCreatingCounter_s;                         //!< Bigger than zero if at least one Identifier stores its parents (its an int instead of a bool to avoid conflicts with multithreading)
+            uint32_t networkID_;                                           //!< The network ID to identify a class through the network
+            const unsigned int classID_;                                   //!< Uniquely identifies a class (might not be the same as the networkID_)
+            static unsigned int classIDCounter_s;                          //!< Static counter for the unique classIDs
+
+            bool bHasConfigValues_;                                        //!< True if this class has at least one assigned config value
+            std::map<std::string, ConfigValueContainer*> configValues_;    //!< A map to link the string of configurable variables with their ConfigValueContainer
+
+            bool bHasConsoleCommands_;                                     //!< True if this class has at least one assigned console command
+            std::map<std::string, ConsoleCommand*> consoleCommands_;       //!< All console commands of this class
+            std::map<std::string, ConsoleCommand*> consoleCommands_LC_;    //!< All console commands of this class with their names in lowercase
+
+            std::map<std::string, XMLPortParamContainer*> xmlportParamContainers_;     //!< All loadable parameters
+            std::map<std::string, XMLPortObjectContainer*> xmlportObjectContainers_;   //!< All attachable objects
+    };
+
+    _CoreExport std::ostream& operator<<(std::ostream& out, const std::set<const Identifier*>& list);
+
+
+    // ###############################
+    // ###     ClassIdentifier     ###
+    // ###############################
+    //! The ClassIdentifier is derived from Identifier and holds all class-specific functions and variables the Identifier cannot have.
+    /**
+        ClassIdentifier is a Singleton, which means that only one object of a given type T exists.
+        This makes it possible to store information about a class, sharing them with all
+        objects of that class without defining static variables in every class.
+
+        To be really sure that not more than exactly one object exists (even with libraries),
+        ClassIdentifiers are stored in the Identifier Singleton.
+    */
+    template <class T>
+    class ClassIdentifier : public Identifier
+    {
+        #define SUPER_INTRUSIVE_DECLARATION_INCLUDE
+        #include "Super.h"
+
+        public:
+            static ClassIdentifier<T>* getIdentifier();
+            static ClassIdentifier<T>* getIdentifier(const std::string& name);
+
+            bool initialiseObject(T* object, const std::string& className, bool bRootClass);
+
+            void updateConfigValues(bool updateChildren = true) const;
+
+        private:
+            static void initialiseIdentifier();
+            ClassIdentifier(const ClassIdentifier<T>& identifier) {}    // don't copy
+            ClassIdentifier()
+            {
+                SuperFunctionInitialization<0, T>::initialize(this);
+            }
+            ~ClassIdentifier()
+            {
+                SuperFunctionDestruction<0, T>::destroy(this);
+            }
+
+            static ClassIdentifier<T>* classIdentifier_s;
+    };
+
+    template <class T>
+    ClassIdentifier<T>* ClassIdentifier<T>::classIdentifier_s = 0;
+
+    /**
+        @brief Returns the only instance of this class.
+        @return The unique Identifier
+    */
+    template <class T>
+    inline ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
+    {
+        // check if the Identifier already exists
+        if (!ClassIdentifier<T>::classIdentifier_s)
+            ClassIdentifier<T>::initialiseIdentifier();
+
+        return ClassIdentifier<T>::classIdentifier_s;
+    }
+
+    /**
+        @brief Does the same as getIdentifier() but sets the name if this wasn't done yet.
+        @param name The name of this Identifier
+        @return The Identifier
+    */
+    template <class T>
+    inline ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier(const std::string& name)
+    {
+        ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier();
+        identifier->setName(name);
+        return identifier;
+    }
+
+    /**
+        @brief Assigns the static field for the identifier singleton.
+    */
+    template <class T>
+    void ClassIdentifier<T>::initialiseIdentifier()
+    {
+        // Get the name of the class
+        const std::string& name = typeid(T).name();
+
+        // create a new identifier anyway. Will be deleted in Identifier::getIdentifier if not used.
+        ClassIdentifier<T>* proposal = new ClassIdentifier<T>();
+
+        // Get the entry from the map
+        ClassIdentifier<T>::classIdentifier_s = (ClassIdentifier<T>*)Identifier::getIdentifierSingleton(name, proposal);
+
+        if (ClassIdentifier<T>::classIdentifier_s == proposal)
+        {
+            COUT(4) << "*** Identifier: Requested Identifier for " << name << " was not yet existing and got created." << std::endl;
+        }
+        else
+        {
+            COUT(4) << "*** Identifier: Requested Identifier for " << name << " was already existing and got assigned." << std::endl;
+        }
+    }
+
+    /**
+        @brief Adds an object of the given type to the ObjectList.
+        @param object The object to add
+    */
+    template <class T>
+    bool ClassIdentifier<T>::initialiseObject(T* object, const std::string& className, bool bRootClass)
+    {
+        if (bRootClass)
+            COUT(5) << "*** Register Root-Object: " << className << std::endl;
+        else
+            COUT(5) << "*** Register Object: " << className << std::endl;
+
+        object->identifier_ = this;
+        if (Identifier::isCreatingHierarchy())
+        {
+            if (bRootClass && !object->parents_)
+                object->parents_ = new std::set<const Identifier*>();
+
+            if (object->parents_)
+            {
+                this->initializeClassHierarchy(object->parents_, bRootClass);
+                object->parents_->insert(object->parents_->end(), this);
+            }
+
+            object->setConfigValues();
+            return true;
+        }
+        else
+        {
+            COUT(5) << "*** ClassIdentifier: Added object to " << this->getName() << "-list." << std::endl;
+            object->metaList_->add(this->objects_, this->objects_->add(new ObjectListElement<T>(object)));
+
+            // Add pointer of type T to the map in the OrxonoxClass instance that enables "dynamic_casts"
+            object->objectPointers_.push_back(std::make_pair(this->getClassID(), static_cast<void*>(object)));
+            return false;
+        }
+    }
+
+    /**
+        @brief Updates the config-values of all existing objects of this class by calling their setConfigValues() function.
+    */
+    template <class T>
+    void ClassIdentifier<T>::updateConfigValues(bool updateChildren) const
+    {
+        if (!this->hasConfigValues())
+            return;
+
+        for (ObjectListIterator<T> it = ObjectList<T>::begin(); it; ++it)
+            it->setConfigValues();
+
+        if (updateChildren)
+            for (std::set<const Identifier*>::const_iterator it = this->getChildrenBegin(); it != this->getChildrenEnd(); ++it)
+                (*it)->updateConfigValues(false);
+    }
+
+
+    // ###############################
+    // ###      orxonox_cast       ###
+    // ###############################
+    /**
+    @brief
+        Casts on object of type OrxonoxClass to any derived type that is
+        registered in the class hierarchy.
+    @return
+        Returns NULL if the cast is not possible
+    @note
+        In case of NULL return (and using MSVC), a dynamic_cast might still be possible if
+        a class forgot to register its objects.
+        Also note that the function is implemented differently for GCC/MSVC.
+    */
+    template <class T, class U>
+    FORCEINLINE T orxonox_cast(U source)
+    {
+#ifdef ORXONOX_COMPILER_MSVC
+        typedef Loki::TypeTraits<typename Loki::TypeTraits<T>::PointeeType>::NonConstType ClassType;
+        if (source != NULL)
+            return source->template getDerivedPointer<ClassType>(ClassIdentifier<ClassType>::getIdentifier()->getClassID());
+        else
+            return NULL;
+#else
+        return dynamic_cast<T>(source);
+#endif
+    }
+}
+
+#endif /* _Identifier_H__ */
Index: /code/branches/rocket2/src/libraries/core/Iterator.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Iterator.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Iterator.h	(revision 6952)
@@ -0,0 +1,295 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition and implementation of the Iterator class.
+
+    The Iterator of a given class allows to iterate through an ObjectList. Objects in
+    this list are casted to the template argument of the Iterator.
+
+    Usage:
+    for (Iterator<myClass> it = anyidentifier->getObjects()->begin(); it != anyidentifier->getObjects()->end(); ++it)
+    {
+        it->someFunction(...);
+        myClass* myObject = *it;
+    }
+*/
+
+#ifndef _Iterator_H__
+#define _Iterator_H__
+
+#include "CorePrereqs.h"
+
+#include "Identifier.h"
+#include "ObjectListBase.h"
+
+namespace orxonox
+{
+    //! The Iterator allows to iterate through a given ObjectList
+    template <class T = OrxonoxClass>
+    class Iterator
+    {
+        public:
+            /**
+                @brief Constructor: Sets the element, whereon the iterator points, to zero.
+            */
+            inline Iterator()
+            {
+                this->element_ = 0;
+                this->list_ = 0;
+            }
+
+            /**
+                @brief Constructor: Sets this element to the exported element.
+                @param exp The exported element
+            */
+            inline Iterator(const ObjectListBase::Export& exp)
+            {
+                this->element_ = exp.element_;
+                this->list_ = exp.list_;
+                this->list_->registerIterator(this);
+            }
+
+            /**
+                @brief Constructor: Sets this element to the element of another Iterator.
+                @param other The other Iterator
+            */
+            inline Iterator(const Iterator<T>& other)
+            {
+                this->element_ = other.element_;
+                this->list_ = other.list_;
+                this->list_->registerIterator(this);
+            }
+
+            /**
+                @brief Constructor: Sets this element to a given element
+                @param element The element
+            */
+            template <class O>
+            inline Iterator(ObjectListElement<O>* element)
+            {
+                this->element_ = (element) ? static_cast<ObjectListBaseElement*>(element) : 0;
+                this->list_ = ClassIdentifier<O>::getIdentifier()->getObjects();
+                this->list_->registerIterator(this);
+            }
+
+            /**
+                @brief Constructor: Sets this element to the element an ObjectListIterator.
+                @param other The ObjectListIterator
+            */
+            template <class O>
+            inline Iterator(const ObjectListIterator<O>& other)
+            {
+                this->element_ = (other.element_) ? static_cast<ObjectListBaseElement*>(other.element_) : 0;
+                this->list_ = ClassIdentifier<O>::getIdentifier()->getObjects();
+                this->list_->registerIterator(this);
+            }
+
+            /**
+                @brief Unregisters the Iterator from the ObjectList.
+            */
+            inline ~Iterator()
+            {
+                this->list_->unregisterIterator(this);
+            }
+
+            /**
+                @brief Assigns an exported element.
+                @param exp The exported element
+            */
+            inline const Iterator<T>& operator=(const ObjectListBase::Export& exp)
+            {
+                if (this->list_)
+                    this->list_->unregisterIterator(this);
+
+                this->element_ = exp.element_;
+                this->list_ = exp.list_;
+                this->list_->registerIterator(this);
+
+                return (*this);
+            }
+
+            /**
+                @brief Assigns the element of another Iterator.
+                @param other The other Iterator
+            */
+            inline const Iterator<T>& operator=(const Iterator<T>& other)
+            {
+                if (this->list_)
+                    this->list_->unregisterIterator(this);
+
+                this->element_ = other.element_;
+                this->list_ = other.list_;
+                this->list_->registerIterator(this);
+
+                return (*this);
+            }
+
+            /**
+                @brief Assigns a given element.
+                @param element The element
+            */
+            template <class O>
+            inline const Iterator<T>& operator=(ObjectListElement<O>* element)
+            {
+                if (this->list_)
+                    this->list_->unregisterIterator(this);
+
+                this->element_ = (element) ? static_cast<ObjectListBaseElement*>(element) : 0;
+                this->list_ = ClassIdentifier<O>::getIdentifier()->getObjects();
+                this->list_->registerIterator(this);
+
+                return (*this);
+            }
+
+            /**
+                @brief Assigns the element of an ObjectListIterator.
+                @param other The ObjectListIterator
+            */
+            template <class O>
+            inline const Iterator<T>& operator=(const ObjectListIterator<O>& other)
+            {
+                if (this->list_)
+                    this->list_->unregisterIterator(this);
+
+                this->element_ = (other.element_) ? static_cast<ObjectListBaseElement*>(other.element_) : 0;
+                this->list_ = ClassIdentifier<O>::getIdentifier()->getObjects();
+                this->list_->registerIterator(this);
+
+                return (*this);
+            }
+
+            /**
+                @brief Overloading of the ++it operator: Iterator points to the next object in the list.
+                @return The Iterator itself
+            */
+            inline const Iterator<T>& operator++()
+            {
+                this->element_ = this->element_->next_;
+                return *this;
+            }
+
+            /**
+                @brief Overloading of the it++ operator: Iterator points to the next object in the list.
+                @return The Iterator itself
+            */
+            inline Iterator<T> operator++(int i)
+            {
+                Iterator<T> copy = *this;
+                this->element_ = this->element_->next_;
+                return copy;
+            }
+
+            /**
+                @brief Overloading of the --it operator: Iterator points to the previous object in the list.
+                @return The Iterator itself
+            */
+            inline const Iterator<T>& operator--()
+            {
+                this->element_ = this->element_->prev_;
+                return *this;
+            }
+
+            /**
+                @brief Overloading of the it-- operator: Iterator points to the previous object in the list.
+                @return The Iterator itself
+            */
+            inline Iterator<T> operator--(int i)
+            {
+                Iterator<T> copy = *this;
+                this->element_ = this->element_->prev_;
+                return copy;
+            }
+
+            /**
+                @brief Overloading of the *it operator: returns the pointer to the object.
+                @return The object the Iterator points at
+            */
+            inline T* operator*() const
+            {
+                return orxonox_cast<T*>(this->element_->objectBase_);
+            }
+
+            /**
+                @brief Overloading of the it-> operator: returns the pointer to the object.
+                @return The object the Iterator points at
+            */
+            inline T* operator->() const
+            {
+                return orxonox_cast<T*>(this->element_->objectBase_);
+            }
+
+            /**
+                @brief Overloading of the typecast-operator to bool: returns true if the iterator points to an existing object.
+                @return True if the Iterator points to an existing object.
+            */
+            inline operator bool() const
+            {
+                return (this->element_ != 0);
+            }
+
+            /**
+                @brief Overloading of the == operator to compare with another Iterator.
+                @param compare The other Iterator
+                @return True if the iterators point to the same element
+            */
+            inline bool operator==(const Iterator<T>& compare) const
+            {
+                return (this->element_ == compare.element_);
+            }
+
+            /**
+                @brief Overloading of the != operator to compare with another Iterator.
+                @param compare The other Iterator
+                @return True if the iterators point to different elements
+            */
+            inline bool operator!=(const Iterator<T>& compare) const
+            {
+                return (this->element_ != compare.element_);
+            }
+
+            /**
+                @brief Increments the Iterator if it points at the given object.
+                @param object The object to compare with
+            */
+            inline void incrementIfEqual(OrxonoxClass* object)
+            {
+                if (this->element_ && this->element_->objectBase_ == object)
+                    this->operator++();
+            }
+
+        protected:
+            ObjectListBaseElement* element_;       //!< The element the Iterator points at
+            ObjectListBase* list_;                 //!< The list wherein the element is
+    };
+
+    typedef Iterator<OrxonoxClass> BaseIterator;
+}
+
+#endif /* _Iterator_H__ */
Index: /code/branches/rocket2/src/libraries/core/Language.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/Language.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Language.cc	(revision 6952)
@@ -0,0 +1,325 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the Language and the LanguageEntry classes.
+*/
+
+#include "Language.h"
+
+#include <fstream>
+#include "util/Debug.h"
+#include "Core.h"
+#include "PathConfig.h"
+
+namespace orxonox
+{
+    // ###############################
+    // ###      LanguageEntry      ###
+    // ###############################
+    /**
+        @brief Constructor: Sets the default entry.
+        @param fallbackEntry The default entry
+    */
+    LanguageEntry::LanguageEntry(const std::string& fallbackEntry)
+    {
+        this->fallbackEntry_ = fallbackEntry;
+        this->localisedEntry_ = fallbackEntry; // Set the localisation to the fallback entry, for the case that no translation gets assigned
+        this->bLocalisationSet_ = false;
+    }
+
+    /**
+        @brief Sets the localisation of the entry.
+        @param localisation The localisation
+    */
+    void LanguageEntry::setLocalisation(const std::string& localisation)
+    {
+        // Check if the translation is more than just an empty string
+        if (!localisation.empty())
+        {
+            this->localisedEntry_ = localisation;
+            this->bLocalisationSet_ = true;
+        }
+        else
+            this->localisedEntry_ = this->fallbackEntry_;
+    }
+
+    /**
+        @brief Sets the default entry.
+        @param fallbackEntry The default entry
+    */
+    void LanguageEntry::setDefault(const std::string& fallbackEntry)
+    {
+        // If the default entry changes and the translation wasn't set yet, use the new default entry as translation
+        if (!this->bLocalisationSet_)
+            this->localisedEntry_ = fallbackEntry;
+
+        this->fallbackEntry_ = fallbackEntry;
+    }
+
+    // ###############################
+    // ###        Language         ###
+    // ###############################
+
+    Language* Language::singletonPtr_s = 0;
+
+    /**
+        @brief Constructor: Reads the default language file and sets some values.
+    */
+    Language::Language()
+    {
+        this->defaultLanguage_ = "default";
+        this->defaultLocalisation_ = "ERROR: LANGUAGE ENTRY DOESN'T EXIST!";
+
+        // Read the default language file to create all known LanguageEntry objects
+        this->readDefaultLanguageFile();
+    }
+
+    /**
+        @brief Destructor: Deletes all language entries.
+    */
+    Language::~Language()
+    {
+        for (std::map<std::string, LanguageEntry*>::iterator it = this->languageEntries_.begin(); it != this->languageEntries_.end(); ++it)
+            delete (it->second);
+    }
+
+    /**
+        @brief Creates a new LanguageEntry with a given label and a given default entry.
+        @param label The label of the entry
+        @param entry The default entry
+        @return The created LanguageEntry object
+    */
+    LanguageEntry* Language::createEntry(const LanguageEntryLabel& label, const std::string& entry)
+    {
+        std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(label);
+
+        // Make sure we don't create a duplicate entry
+        if (it == this->languageEntries_.end())
+        {
+            LanguageEntry* newEntry = new LanguageEntry(entry);
+            newEntry->setLabel(label);
+            this->languageEntries_[label] = newEntry;
+            return newEntry;
+        }
+
+        COUT(2) << "Warning: Language entry " << label << " is duplicate in " << getFilename(this->defaultLanguage_) << '!' << std::endl;
+        return it->second;
+    }
+
+    /**
+        @brief Adds a new LanguageEntry, if it's not already existing.
+        @param label The label of the entry
+        @param entry The default entry
+    */
+    void Language::addEntry(const LanguageEntryLabel& label, const std::string& entry)
+    {
+        COUT(5) << "Language: Called addEntry with\n  label: " << label << "\n  entry: " <<  entry << std::endl;
+        std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(label);
+        if (it == this->languageEntries_.end())
+        {
+            // The entry isn't available yet, meaning it's new, so create it
+            this->createEntry(label, entry);
+        }
+        else if (it->second->getDefault().compare(entry) == 0)
+        {
+            // The entry is available and the default string is the same, so return because everything is fine
+            return;
+        }
+        else
+        {
+            // The defined default entry is not the same as in the default language file - change it to the new entry
+            it->second->setDefault(entry);
+        }
+
+        // Write the default language file because either a new entry was created or an existing entry has changed
+        this->writeDefaultLanguageFile();
+
+    }
+
+    /**
+        @brief Returns the localisation of a given entry.
+        @param label The label of the entry
+        @return The localisation
+    */
+    const std::string& Language::getLocalisation(const LanguageEntryLabel& label) const
+    {
+        std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(label);
+        if (it != this->languageEntries_.end())
+            return it->second->getLocalisation();
+        else
+        {
+            // Uh, oh, an undefined entry was requested: return the default string
+            COUT(2) << "Warning: Language entry \"" << label << "\" not found!" << std::endl;
+            return this->defaultLocalisation_;
+        }
+    }
+
+    /**
+        @brief Creates the name of the language file out of the languages name.
+        @param language The name of the language
+        @return The filename
+    */
+    std::string Language::getFilename(const std::string& language)
+    {
+        return std::string("translation_" + language + ".lang");
+    }
+
+    /**
+        @brief Reads the default language file and creates a LanguageEntry objects for every entry.
+    */
+    void Language::readDefaultLanguageFile()
+    {
+        COUT(4) << "Read default language file." << std::endl;
+
+        const std::string& filepath = PathConfig::getConfigPathString() + getFilename(this->defaultLanguage_);
+
+        // This creates the file if it's not existing
+        std::ofstream createFile;
+        createFile.open(filepath.c_str(), std::fstream::app);
+        createFile.close();
+
+        // Open the file
+        std::ifstream file;
+        file.open(filepath.c_str(), std::fstream::in);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "An error occurred in Language.cc:" << std::endl;
+            COUT(1) << "Error: Couldn't open file " << getFilename(this->defaultLanguage_) << " to read the default language entries!" << std::endl;
+            return;
+        }
+
+        // Iterate through the file and create the LanguageEntries
+        while (file.good() && !file.eof())
+        {
+            std::string lineString;
+            std::getline(file, lineString);
+
+            // Check if the line is empty
+            if (!lineString.empty())
+            {
+                size_t pos = lineString.find('=');
+
+                // Check if the length is at least 3 and if there's an entry before and behind the =
+                if (pos > 0 && pos < (lineString.size() - 1) && lineString.size() >= 3)
+                    this->createEntry(lineString.substr(0, pos), lineString.substr(pos + 1));
+                else
+                {
+                    COUT(2) << "Warning: Invalid language entry \"" << lineString << "\" in " << getFilename(this->defaultLanguage_) << std::endl;
+                }
+            }
+        }
+
+        file.close();
+    }
+
+    /**
+        @brief Reads the language file of the configured language and assigns the localisation to the corresponding LanguageEntry object.
+    */
+    void Language::readTranslatedLanguageFile()
+    {
+        COUT(4) << "Read translated language file (" << Core::getInstance().getLanguage() << ")." << std::endl;
+
+        const std::string& filepath = PathConfig::getConfigPathString() + getFilename(Core::getInstance().getLanguage());
+
+        // Open the file
+        std::ifstream file;
+        file.open(filepath.c_str(), std::fstream::in);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "An error occurred in Language.cc:" << std::endl;
+            COUT(1) << "Error: Couldn't open file " << getFilename(Core::getInstance().getLanguage()) << " to read the translated language entries!" << std::endl;
+            Core::getInstance().resetLanguage();
+            COUT(3) << "Info: Reset language to " << this->defaultLanguage_ << '.' << std::endl;
+            return;
+        }
+
+        // Iterate through the file and create the LanguageEntries
+        while (file.good() && !file.eof())
+        {
+            std::string lineString;
+            std::getline(file, lineString);
+
+            // Check if the line is empty
+            if (!lineString.empty())
+            {
+                size_t pos = lineString.find('=');
+
+                // Check if the length is at least 3 and if there's an entry before and behind the =
+                if (pos > 0 && pos < (lineString.size() - 1) && lineString.size() >= 3)
+                {
+                    std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.find(lineString.substr(0, pos));
+
+                    // Check if the entry exists
+                    if (it != this->languageEntries_.end())
+                        it->second->setLocalisation(lineString.substr(pos + 1));
+                    else
+                        this->createEntry(lineString.substr(0, pos), this->defaultLocalisation_)->setLocalisation(lineString.substr(pos + 1));
+                }
+                else
+                {
+                    COUT(2) << "Warning: Invalid language entry \"" << lineString << "\" in " << getFilename(Core::getInstance().getLanguage()) << std::endl;
+                }
+            }
+        }
+
+        file.close();
+    }
+
+    /**
+        @brief Writes all default entries to the default language file.
+    */
+    void Language::writeDefaultLanguageFile() const
+    {
+        COUT(4) << "Language: Write default language file." << std::endl;
+
+        const std::string& filepath = PathConfig::getConfigPathString() + getFilename(this->defaultLanguage_);
+
+        // Open the file
+        std::ofstream file;
+        file.open(filepath.c_str(), std::fstream::out);
+
+        if (!file.is_open())
+        {
+            COUT(1) << "An error occurred in Language.cc:" << std::endl;
+            COUT(1) << "Error: Couldn't open file " << getFilename(this->defaultLanguage_) << " to write the default language entries!" << std::endl;
+            return;
+        }
+
+        // Iterate through the list an write the lines into the file
+        for (std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.begin(); it != this->languageEntries_.end(); ++it)
+        {
+            file << it->second->getLabel() << '=' << it->second->getDefault() << std::endl;
+        }
+
+        file.close();
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/Language.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Language.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Language.h	(revision 6952)
@@ -0,0 +1,149 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the Language and the LanguageEntry class.
+
+    The Language class is used, to get a localisation of a string in the configured language.
+    The string is identified by another string, the label of the entry.
+    If the translation in the configured language isn't available, the default entry, defined in the code, is used.
+
+    Usage:
+     - Set the entry with the default string:
+       Language::getInstance()->addEntry("label of the entry", "the string to translate");
+
+     - Get the localisation of the entry in the configured language:
+       std::cout << Language::getInstance()->getLocalisation("name of the entry") << std::endl;
+*/
+
+#ifndef _Language_H__
+#define _Language_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <string>
+#include <cassert>
+#include "util/Singleton.h"
+
+namespace orxonox
+{
+    // ###############################
+    // ###      LanguageEntry      ###
+    // ###############################
+    //! The LanguageEntry class stores the default- and the translated string of a given entry in the language file.
+    class _CoreExport LanguageEntry
+    {
+        public:
+            explicit LanguageEntry(const std::string& fallbackEntry);
+            void setLocalisation(const std::string& localisation);
+            void setDefault(const std::string& fallbackEntry);
+
+            /**
+              @brief Returns the localised entry in the configured language.
+              @return The translated entry
+            */
+            inline const std::string& getLocalisation()
+                { return this->localisedEntry_; }
+
+            /**
+              @brief Returns the default entry.
+              @return The default entry
+            */
+            inline const std::string& getDefault()
+                { return this->fallbackEntry_; }
+
+            /**
+                @brief Sets the label of this entry.
+                @param label The label
+            */
+            inline void setLabel(const LanguageEntryLabel& label)
+                { this->label_ = label; }
+
+            /**
+                @brief Returns the label of this entry.
+                @return The label
+            */
+            inline const LanguageEntryLabel& getLabel() const
+                { return this->label_; }
+
+        private:
+            LanguageEntryLabel label_;              //!< The label of the entry
+            std::string fallbackEntry_;             //!< The default entry: Used, if no translation is available or no language configured
+            std::string localisedEntry_;            //!< The localised entry in the configured language
+            bool bLocalisationSet_;                 //!< True if the translation was set
+    };
+
+
+    // ###############################
+    // ###         Language        ###
+    // ###############################
+    //! The Language class manges the language files and entries and stores the LanguageEntry objects in a map.
+    class _CoreExport Language : public Singleton<Language>
+    {
+        friend class Singleton<Language>;
+        friend class Core;
+
+        public:
+            Language();
+            ~Language();
+
+            void addEntry(const LanguageEntryLabel& label, const std::string& entry);
+            const std::string& getLocalisation(const LanguageEntryLabel& label) const;
+
+        private:
+            Language(const Language&);
+
+            void readDefaultLanguageFile();
+            void readTranslatedLanguageFile();
+            void writeDefaultLanguageFile() const;
+            static std::string getFilename(const std::string& language);
+            LanguageEntry* createEntry(const LanguageEntryLabel& label, const std::string& entry);
+
+            std::string defaultLanguage_;                           //!< The default language
+            std::string defaultLocalisation_;                       //!< The returned string, if an entry unavailable entry is requested
+            std::map<std::string, LanguageEntry*> languageEntries_; //!< A map to store all LanguageEntry objects and their labels
+
+            static Language* singletonPtr_s;
+    };
+
+    //! Shortcut function for Language::addEntry
+    inline void AddLanguageEntry(const LanguageEntryLabel& label, const std::string& fallbackString)
+    {
+        Language::getInstance().addEntry(label, fallbackString);
+    }
+
+    //! Shortcut function for Language::getLocalisation
+    inline const std::string& GetLocalisation(const LanguageEntryLabel& label)
+    {
+        return Language::getInstance().getLocalisation(label);
+    }
+}
+
+#endif /* _Language_H__ */
Index: /code/branches/rocket2/src/libraries/core/Loader.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/Loader.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Loader.cc	(revision 6952)
@@ -0,0 +1,368 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Loader.h"
+
+#include <sstream>
+#include <tinyxml/ticpp.h>
+#include <boost/scoped_ptr.hpp>
+
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/StringUtils.h"
+#include "BaseObject.h"
+#include "Iterator.h"
+#include "ObjectList.h"
+#include "LuaState.h"
+#include "Namespace.h"
+#include "Resource.h"
+#include "XMLFile.h"
+
+namespace orxonox
+{
+    std::vector<std::pair<const XMLFile*, ClassTreeMask> > Loader::files_s;
+    ClassTreeMask Loader::currentMask_s;
+
+    bool Loader::open(const XMLFile* file, const ClassTreeMask& mask)
+    {
+        Loader::add(file, mask);
+        return Loader::load(file, mask);
+    }
+
+    void Loader::close()
+    {
+        Loader::unload();
+        Loader::files_s.clear();
+    }
+
+    void Loader::close(const XMLFile* file)
+    {
+        Loader::unload(file);
+        Loader::remove(file);
+    }
+
+    void Loader::add(const XMLFile* file, const ClassTreeMask& mask)
+    {
+        if (!file)
+            return;
+        Loader::files_s.insert(Loader::files_s.end(), std::pair<const XMLFile*, ClassTreeMask>(file, mask));
+    }
+
+    void Loader::remove(const XMLFile* file)
+    {
+        if (!file)
+            return;
+        for (std::vector<std::pair<const XMLFile*, ClassTreeMask> >::iterator it = Loader::files_s.begin(); it != Loader::files_s.end(); ++it)
+        {
+            if (it->first == file)
+            {
+                Loader::files_s.erase(it);
+                break;
+            }
+        }
+    }
+
+    bool Loader::load(const ClassTreeMask& mask)
+    {
+        bool success = true;
+        for (std::vector<std::pair<const XMLFile*, ClassTreeMask> >::iterator it = Loader::files_s.begin(); it != Loader::files_s.end(); ++it)
+            if (!Loader::load(it->first, it->second * mask))
+                success = false;
+
+        return success;
+    }
+
+    void Loader::unload(const ClassTreeMask& mask)
+    {
+        for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it != ObjectList<BaseObject>::end(); )
+        {
+            if (mask.isIncluded(it->getIdentifier()))
+                (it++)->destroy();
+            else
+                ++it;
+        }
+    }
+
+    bool Loader::reload(const ClassTreeMask& mask)
+    {
+        Loader::unload(mask);
+        return Loader::load(mask);
+    }
+
+    bool Loader::load(const XMLFile* file, const ClassTreeMask& mask)
+    {
+        if (!file)
+            return false;
+
+        Loader::currentMask_s = file->getMask() * mask;
+
+        std::string xmlInput;
+        if (file->getLuaSupport())
+        {
+            // Use the LuaState to replace the XML tags (calls our function)
+            scoped_ptr<LuaState> luaState(new LuaState());
+            luaState->setIncludeParser(&Loader::replaceLuaTags);
+            luaState->includeFile(file->getFilename());
+            xmlInput = luaState->getOutput().str();
+        }
+        else
+        {
+            shared_ptr<ResourceInfo> info = Resource::getInfo(file->getFilename());
+            if (info == NULL)
+            {
+                COUT(1) << "Error: Could not find XML file '" << file->getFilename() << "'." << std::endl;
+                return false;
+            }
+            xmlInput = Resource::open(file->getFilename())->getAsString();
+        }
+
+        try
+        {
+            COUT(0) << "Start loading " << file->getFilename() << "..." << std::endl;
+            COUT(3) << "Mask: " << Loader::currentMask_s << std::endl;
+
+            ticpp::Document xmlfile(file->getFilename());
+            xmlfile.Parse(xmlInput, true);
+
+            ticpp::Element rootElement;
+            rootElement.SetAttribute("name", "root");
+            rootElement.SetAttribute("bAutogenerated", true);
+
+            for (ticpp::Iterator<ticpp::Element> child = xmlfile.FirstChildElement(false); child != child.end(); child++)
+                rootElement.InsertEndChild(*child);
+
+            COUT(4) << "  creating root-namespace..." << std::endl;
+            Namespace* rootNamespace = new Namespace(0);
+            rootNamespace->setLoaderIndentation("    ");
+            rootNamespace->setFile(file);
+            rootNamespace->setNamespace(rootNamespace);
+            rootNamespace->setRoot(true);
+            rootNamespace->XMLPort(rootElement, XMLPort::LoadObject);
+
+            COUT(0) << "Finished loading " << file->getFilename() << '.' << std::endl;
+
+            COUT(4) << "Namespace-tree:" << std::endl << rootNamespace->toString("  ") << std::endl;
+
+            return true;
+        }
+        catch (ticpp::Exception& ex)
+        {
+            COUT(1) << std::endl;
+            COUT(1) << "An XML-error occurred in Loader.cc while loading " << file->getFilename() << ':' << std::endl;
+            COUT(1) << ex.what() << std::endl;
+            COUT(1) << "Loading aborted." << std::endl;
+            return false;
+        }
+        catch (Exception& ex)
+        {
+            COUT(1) << std::endl;
+            COUT(1) << "A loading-error occurred in Loader.cc while loading " << file->getFilename() << ':' << std::endl;
+            COUT(1) << ex.what() << std::endl;
+            COUT(1) << "Loading aborted." << std::endl;
+            return false;
+        }
+        catch (...)
+        {
+            COUT(1) << std::endl;
+            COUT(1) << "An error occurred in Loader.cc while loading " << file->getFilename() << ':' << std::endl;
+            COUT(1) << Exception::handleMessage() << std::endl;
+            COUT(1) << "Loading aborted." << std::endl;
+            return false;
+        }
+    }
+
+    void Loader::unload(const XMLFile* file, const ClassTreeMask& mask)
+    {
+        if (!file)
+            return;
+        for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it; )
+        {
+            if ((it->getFile() == file) && mask.isIncluded(it->getIdentifier()))
+                (it++)->destroy();
+            else
+                ++it;
+        }
+    }
+
+    bool Loader::reload(const XMLFile* file, const ClassTreeMask& mask)
+    {
+        Loader::unload(file, mask);
+        return Loader::load(file, mask);
+    }
+
+    std::string Loader::replaceLuaTags(const std::string& text)
+    {
+        // create map with all Lua tags
+        std::map<size_t, bool> luaTags;
+        {
+            size_t pos = 0;
+            while ((pos = text.find("<?lua", pos)) != std::string::npos)
+                luaTags[pos++] = true;
+        }
+        {
+            size_t pos = 0;
+            while ((pos = text.find("?>", pos)) != std::string::npos)
+                luaTags[pos++] = false;
+        }
+
+        // erase all tags from the map that are between two quotes
+        {
+            std::map<size_t, bool>::iterator it = luaTags.begin();
+            std::map<size_t, bool>::iterator it2 = it;
+            bool bBetweenQuotes = false;
+            size_t pos = 0;
+            while ((pos = getNextQuote(text, pos)) != std::string::npos)
+            {
+                while ((it != luaTags.end()) && (it->first < pos))
+                {
+                    if (bBetweenQuotes)
+                    {
+                        it2++;
+                        if (it->second && !(it2->second) && it2->first < pos)
+                            it = ++it2;
+                        else
+                            luaTags.erase(it++);
+                    }
+                    else
+                        ++it;
+                }
+                bBetweenQuotes = !bBetweenQuotes;
+                pos++;
+            }
+        }
+
+        // check whether on every opening <?lua tag a closing ?> tag follows
+        {
+            bool expectedValue = true;
+            for (std::map<size_t, bool>::iterator it = luaTags.begin(); it != luaTags.end(); ++it)
+            {
+                if (it->second == expectedValue)
+                    expectedValue = !expectedValue;
+                else
+                {
+                    expectedValue = false;
+                    break;
+                }
+            }
+            if (!expectedValue)
+            {
+                COUT(2) << "Warning: Error in level file" << std::endl;
+                // todo: errorhandling
+                return "";
+            }
+        }
+
+        // Use a stringstream object to speed up the parsing
+        std::ostringstream output;
+
+        // cut the original string into pieces and put them together with print() instead of lua tags
+        {
+            std::map<size_t, bool>::iterator it = luaTags.begin();
+            bool bInPrintFunction = true;
+            size_t start = 0;
+            size_t end = 0;
+
+            do
+            {
+                if (it != luaTags.end())
+                    end = (it++)->first;
+                else
+                    end = std::string::npos;
+
+                unsigned int equalSignCounter = 0;
+
+                if (bInPrintFunction)
+                {
+                    // count ['='[ and ]'='] and replace tags with print([[ and ]])
+                    const std::string& temp = text.substr(start, end - start);
+                    {
+                    size_t pos = 0;
+                    while ((pos = temp.find('[', pos)) != std::string::npos)
+                    {
+                        unsigned int tempCounter = 1;
+                        size_t tempPos = pos++;
+                        while (temp[++tempPos] == '=')
+                        {
+                            tempCounter++;
+                        }
+                        if (temp[tempPos] != '[')
+                        {
+                            tempCounter = 0;
+                        }
+                        else if (tempCounter == 0)
+                        {
+                            tempCounter = 1;
+                        }
+                        if (tempCounter > equalSignCounter)
+                            equalSignCounter = tempCounter;
+                        }
+                    }
+                    {
+                        size_t pos = 0;
+                        while ((pos = temp.find(']', pos)) != std::string::npos)
+                        {
+                            unsigned int tempCounter = 1;
+                            size_t tempPos = pos++;
+                            while (temp[++tempPos] == '=')
+                            {
+                                tempCounter++;
+                            }
+                            if (temp[tempPos] != ']')
+                            {
+                                tempCounter = 0;
+                            }
+                            else if (tempCounter == 0)
+                            {
+                                tempCounter = 1;
+                            }
+                            if (tempCounter > equalSignCounter)
+                                equalSignCounter = tempCounter;
+                        }
+                    }
+                    std::string equalSigns;
+                    for (unsigned int i = 0; i < equalSignCounter; i++)
+                    {
+                        equalSigns += '=';
+                    }
+                    output << "print([" + equalSigns + '[' + temp + ']' + equalSigns +"])";
+                    start = end + 5;
+                }
+                else
+                {
+                    output << text.substr(start, end - start);
+                    start = end + 2;
+                }
+
+                bInPrintFunction = !bInPrintFunction;
+            }
+            while (end != std::string::npos);
+        }
+
+        return output.str();
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/Loader.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Loader.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Loader.h	(revision 6952)
@@ -0,0 +1,66 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Loader_H__
+#define _Loader_H__
+
+#include "CorePrereqs.h"
+
+#include <vector>
+#include "ClassTreeMask.h"
+
+namespace orxonox
+{
+    class _CoreExport Loader
+    {
+        public:
+            static bool open(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
+            static void close();
+            static void close(const XMLFile* file);
+
+            static void add(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
+            static void remove(const XMLFile* file);
+
+            static bool load(const ClassTreeMask& mask = ClassTreeMask());
+            static void unload(const ClassTreeMask& mask = ClassTreeMask());
+            static bool reload(const ClassTreeMask& mask = ClassTreeMask());
+
+            static bool load(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
+            static void unload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
+            static bool reload(const XMLFile* file, const ClassTreeMask& mask = ClassTreeMask());
+
+            static std::string replaceLuaTags(const std::string& text);
+
+            static ClassTreeMask currentMask_s;
+
+        private:
+            static std::vector<std::pair<const XMLFile*, ClassTreeMask> > files_s;
+    };
+}
+
+#endif /* _Loader_H__ */
Index: /code/branches/rocket2/src/libraries/core/LuaState.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/LuaState.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/LuaState.cc	(revision 6952)
@@ -0,0 +1,376 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "LuaState.h"
+
+#include <tolua/tolua++.h>
+extern "C" {
+#include <lua.h>
+#include <lualib.h>
+}
+
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/ScopeGuard.h"
+#include "IOConsole.h"
+#include "Resource.h"
+#include "ToluaBindCore.h"
+
+namespace orxonox
+{
+    LuaState::ToluaInterfaceMap LuaState::toluaInterfaces_s;
+    std::vector<LuaState*> LuaState::instances_s;
+
+    const std::string LuaState::ERROR_HANDLER_NAME = "errorHandler";
+
+    // Do this after declaring toluaInterfaces_s and instances_s to avoid larger problems
+    DeclareToluaInterface(Core);
+
+    LuaState::LuaState()
+        : bIsRunning_(false)
+        , includeParseFunction_(NULL)
+    {
+        // Create new lua state and configure it
+        luaState_ = lua_open();
+        Loki::ScopeGuard luaStateGuard = Loki::MakeGuard(&lua_close, luaState_);
+#if LUA_VERSION_NUM == 501
+        luaL_openlibs(luaState_);
+#else
+        luaopen_base(luaState_);
+        luaopen_string(luaState_);
+        luaopen_table(luaState_);
+        luaopen_math(luaState_);
+        luaopen_io(luaState_);
+        luaopen_debug(luaState_);
+#endif
+
+        // Open all available tolua interfaces
+        this->openToluaInterfaces(luaState_);
+
+        // Create dummy file info
+        sourceFileInfo_.reset(new ResourceInfo());
+        sourceFileInfo_->group = "General";
+        sourceFileInfo_->size = 0;
+
+        // Push 'this' pointer
+        tolua_pushusertype(luaState_, static_cast<void*>(this), "orxonox::LuaState");
+        lua_setglobal(luaState_, "luaState");
+
+        // Parse init script
+        if (!this->doFile("LuaStateInit.lua"))
+            ThrowException(InitialisationFailed, "Running LuaStateInit.lua failed");
+
+        luaStateGuard.Dismiss();
+    }
+
+    LuaState::~LuaState()
+    {
+        lua_close(luaState_);
+    }
+
+    shared_ptr<ResourceInfo> LuaState::getFileInfo(const std::string& filename)
+    {
+        // Look in the current directory first
+        shared_ptr<ResourceInfo> sourceInfo = Resource::getInfo(sourceFileInfo_->path + filename);
+        // Continue search in root directories
+        if (sourceInfo == NULL && !sourceFileInfo_->path.empty())
+            sourceInfo = Resource::getInfo(filename);
+        return sourceInfo;
+    }
+
+    bool LuaState::includeFile(const std::string& filename)
+    {
+        shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename);
+        if (sourceInfo != NULL)
+            return this->includeString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
+        else
+        {
+            COUT(2) << "LuaState: Cannot include file '" << filename << "' (not found)." << std::endl;
+            return false;
+        }
+    }
+
+    bool LuaState::includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
+    {
+        // Parse string with provided include parser (otherwise don't preparse at all)
+        std::string luaInput;
+        if (includeParseFunction_ != NULL)
+            luaInput = (*includeParseFunction_)(code);
+        else
+            luaInput = code;
+
+        if (sourceFileInfo != NULL)
+        {
+            // Also fill a map with the actual source code. This is just for the include* commands
+            // where the content of sourceFileInfo->filename doesn't match 'code'
+            this->sourceCodeMap_[sourceFileInfo->filename] = code;
+        }
+
+        bool returnValue = this->doString(luaInput, sourceFileInfo);
+
+        if (sourceFileInfo != NULL)
+        {
+            // Delete source code entry
+            if (sourceFileInfo != NULL)
+                this->sourceCodeMap_.erase(sourceFileInfo->filename);
+        }
+
+        return returnValue;
+    }
+
+    bool LuaState::doFile(const std::string& filename)
+    {
+        shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename);
+        if (sourceInfo != NULL)
+            return this->doString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
+        else
+        {
+            COUT(2) << "LuaState: Cannot do file '" << filename << "' (not found)." << std::endl;
+            return false;
+        }
+    }
+
+    bool LuaState::doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
+    {
+        // Save the old source file info
+        shared_ptr<ResourceInfo> oldSourceFileInfo = sourceFileInfo_;
+        // Only override if sourceFileInfo provides useful information
+        if (sourceFileInfo != NULL)
+            sourceFileInfo_ = sourceFileInfo;
+
+        std::string chunkname;
+        if (sourceFileInfo != NULL)
+        {
+            // Provide lua_load with the filename for debug purposes
+            // The '@' is a Lua convention to identify the chunk name as filename
+            chunkname = '@' + sourceFileInfo->filename;
+        }
+        else
+        {
+            // Use the code string to identify the chunk
+            chunkname = code;
+        }
+
+        // Push custom error handler that uses the debugger
+        lua_getglobal(this->luaState_, ERROR_HANDLER_NAME.c_str());
+        int errorHandler = lua_gettop(luaState_);
+        if (lua_isnil(this->luaState_, -1))
+        {
+            lua_pop(this->luaState_, 1);
+            errorHandler = 0;
+        }
+
+#if LUA_VERSION_NUM != 501
+        LoadS ls;
+        ls.s = code.c_str();
+        ls.size = code.size();
+        int error = lua_load(luaState_, &orxonox::LuaState::lua_Chunkreader, &ls, chunkname.c_str());
+#else
+        int error = luaL_loadbuffer(luaState_, code.c_str(), code.size(), chunkname.c_str());
+#endif
+
+        switch (error)
+        {
+        case LUA_ERRSYNTAX: // Syntax error
+            COUT(1) << "Lua syntax error: " << lua_tostring(luaState_, -1) << std::endl;
+            break;
+        case LUA_ERRMEM:    // Memory allocation error
+            COUT(1) << "Lua memory allocation error: Consult your dentist immediately!" << std::endl;
+            break;
+        }
+
+        if (error == 0)
+        {
+            // Execute the chunk in protected mode with an error handler function (stack index)
+            error = lua_pcall(luaState_, 0, 1, errorHandler);
+
+            switch (error)
+            {
+            case LUA_ERRRUN: // Runtime error
+                if (errorHandler)
+                {
+                    // Do nothing (we already display the error in the
+                    // 'errorHandler' Lua function in LuaStateInit.lua)
+                }
+                else
+                {
+                    std::string errorString = lua_tostring(this->luaState_, -1);
+                    if (errorString.find("Error propagation") == std::string::npos)
+                        COUT(1) << "Lua runtime error: " << errorString << std::endl;
+                }
+                break;
+            case LUA_ERRERR: // Error in the error handler
+                COUT(1) << "Lua error in error handler. No message available." << std::endl;
+                break;
+            case LUA_ERRMEM: // Memory allocation error
+                COUT(1) << "Lua memory allocation error: Consult your dentist immediately!" << std::endl;
+                break;
+            }
+        }
+
+        if (error != 0)
+        {
+            lua_pop(luaState_, 1);  // Remove error message
+            lua_pushnil(luaState_); // Push a nil return value
+        }
+
+        if (errorHandler != 0)
+            lua_remove(luaState_, errorHandler); // Remove error handler from stack
+
+        // Set return value to a global variable because we cannot return a table in this function
+        // here. It would work for numbers, pointers and strings, but certainly not for Lua tables.
+        lua_setglobal(luaState_, "LuaStateReturnValue");
+
+        // Load the old info again
+        sourceFileInfo_ = oldSourceFileInfo;
+
+        return (error == 0);
+    }
+
+    void LuaState::luaPrint(const std::string& str)
+    {
+        output_ << str;
+    }
+
+    void LuaState::luaLog(unsigned int level, const std::string& message)
+    {
+        OutputHandler::getOutStream(level) << message << std::endl;
+    }
+
+    bool LuaState::fileExists(const std::string& filename)
+    {
+        shared_ptr<ResourceInfo> info = this->getFileInfo(filename);
+        if (info == NULL)
+            return false;
+        else
+            return true;
+    }
+
+    //! Returns the content of a file
+    std::string LuaState::getSourceCode(const std::string& filename)
+    {
+        // Try the internal map first to get the actual Lua code
+        // and not just some pseudo Lua-XML code when using include* commands
+        std::map<std::string, std::string>::const_iterator it = this->sourceCodeMap_.find(filename);
+        if (it != this->sourceCodeMap_.end())
+            return it->second;
+        shared_ptr<ResourceInfo> info = Resource::getInfo(filename);
+        if (info == NULL)
+            return "";
+        else
+            return Resource::open(info)->getAsString();
+    }
+
+    bool LuaState::usingIOConsole() const
+    {
+        return IOConsole::exists();
+    }
+
+#if LUA_VERSION_NUM != 501
+    const char * LuaState::lua_Chunkreader(lua_State *L, void *data, size_t *size)
+    {
+        LoadS* ls = static_cast<LoadS*>(data);
+        if (ls->size == 0)
+            return NULL;
+        *size = ls->size;
+        ls->size = 0;
+        return ls->s;
+    }
+#endif
+
+    /*static*/ bool LuaState::addToluaInterface(int (*function)(lua_State*), const std::string& name)
+    {
+        for (ToluaInterfaceMap::const_iterator it = toluaInterfaces_s.begin(); it != toluaInterfaces_s.end(); ++it)
+        {
+            if (it->first == name || it->second == function)
+            {
+                COUT(2) << "Warning: Trying to add a Tolua interface with the same name or function." << std::endl;
+                return true;
+            }
+        }
+        toluaInterfaces_s[name] = function;
+
+        // Open interface in all LuaStates
+        for (std::vector<LuaState*>::const_iterator it = instances_s.begin(); it != instances_s.end(); ++it)
+            (*function)((*it)->luaState_);
+
+        // Return dummy bool
+        return true;
+    }
+
+    /*static*/ bool LuaState::removeToluaInterface(const std::string& name)
+    {
+        ToluaInterfaceMap::iterator it = toluaInterfaces_s.find(name);
+        if (it == toluaInterfaces_s.end())
+        {
+            COUT(2) << "Warning: Cannot remove Tolua interface '" << name << "': Not found" << std::endl;
+            return true;
+        }
+
+        // Close interface in all LuaStates
+        for (std::vector<LuaState*>::const_iterator itState = instances_s.begin(); itState != instances_s.end(); ++itState)
+        {
+            lua_pushnil((*itState)->luaState_);
+            lua_setglobal((*itState)->luaState_, it->first.c_str());
+        }
+
+        // Remove entry
+        toluaInterfaces_s.erase(it);
+
+        // Return dummy bool
+        return true;
+    }
+
+    /*static*/ void LuaState::openToluaInterfaces(lua_State* state)
+    {
+        for (ToluaInterfaceMap::const_iterator it = toluaInterfaces_s.begin(); it != toluaInterfaces_s.end(); ++it)
+            (*it->second)(state);
+    }
+
+    /*static*/ void LuaState::closeToluaInterfaces(lua_State* state)
+    {
+        for (ToluaInterfaceMap::const_iterator it = toluaInterfaces_s.begin(); it != toluaInterfaces_s.end(); ++it)
+        {
+            lua_pushnil(state);
+            lua_setglobal(state, it->first.c_str());
+        }
+    }
+
+
+    LuaFunctor::LuaFunctor(const std::string& code, LuaState* luaState)
+    {
+        this->code_ = code;
+        this->lua_ = luaState;
+    }
+
+    void LuaFunctor::operator()(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5)
+    {
+        lua_->doString(this->code_);
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/LuaState.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/LuaState.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/LuaState.h	(revision 6952)
@@ -0,0 +1,130 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _LuaState_H__
+#define _LuaState_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <boost/shared_ptr.hpp>
+
+#include "util/ScopeGuard.h"
+#include "Functor.h"
+#include "ToluaInterface.h"
+
+namespace orxonox // tolua_export
+{ // tolua_export
+    class Functor; // tolua_export
+
+    //! Functor subclass that simply executes code with 0 arguments.
+    class _CoreExport LuaFunctor : public Functor
+    {
+        public:
+            LuaFunctor(const std::string& code, LuaState* luaState);
+            void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null);
+            void evaluateParam(unsigned int index, MultiType& param) const {}
+
+        private:
+            std::string code_;
+            LuaState*   lua_;
+    };
+
+
+    /**
+    @brief
+        Representation of an interface to lua
+    */
+    class _CoreExport LuaState // tolua_export
+    { // tolua_export
+    public:
+        LuaState();
+        ~LuaState();
+
+        bool doFile(const std::string& filename); // tolua_export
+        bool doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>());
+
+        bool includeFile(const std::string& filename); // tolua_export
+        bool includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>());
+
+        void luaPrint(const std::string& str); // tolua_export
+        void luaLog(unsigned int level, const std::string& message); // tolua_export
+        bool fileExists(const std::string& filename); // tolua_export
+        std::string getSourceCode(const std::string& filename); // tolua_export
+
+        const std::stringstream& getOutput() const { return output_; }
+        void clearOutput() { output_.clear(); } // tolua_export
+
+        void setIncludeParser(std::string (*function)(const std::string&)) { includeParseFunction_ = function; }
+        lua_State* getInternalLuaState() { return luaState_; }
+
+        void setDefaultResourceInfo(const shared_ptr<ResourceInfo>& sourceFileInfo) { this->sourceFileInfo_ = sourceFileInfo; }
+        const shared_ptr<ResourceInfo>& getDefaultResourceInfo() { return this->sourceFileInfo_; }
+
+        Functor* createLuaFunctor(const std::string& code) { return new LuaFunctor(code, this); } // tolua_export
+        //! Tells about whether IOConsole was activated. The Lua debugger only works with a normal console.
+        bool usingIOConsole() const; // tolua_export
+
+        static bool addToluaInterface(int (*function)(lua_State*), const std::string& name);
+        static bool removeToluaInterface(const std::string& name);
+        static void openToluaInterfaces(lua_State* state);
+        static void closeToluaInterfaces(lua_State* state);
+
+        static const std::string ERROR_HANDLER_NAME;
+
+    private:
+        shared_ptr<ResourceInfo> getFileInfo(const std::string& filename);
+
+#if LUA_VERSION_NUM != 501
+        struct LoadS
+        {
+            const char* s;
+            size_t size;
+        };
+
+        static const char * lua_Chunkreader(lua_State *L, void *data, size_t *size);
+#endif
+
+        std::stringstream output_;
+        lua_State* luaState_;
+        bool bIsRunning_;
+        shared_ptr<ResourceInfo> sourceFileInfo_;
+        std::map<std::string, std::string> sourceCodeMap_;
+        std::string (*includeParseFunction_)(const std::string&);
+
+        typedef std::map<std::string, int (*)(lua_State *L)> ToluaInterfaceMap;
+        static ToluaInterfaceMap toluaInterfaces_s;
+        static std::vector<LuaState*> instances_s;
+    }; // tolua_export
+} // tolua_export
+
+#endif /* _LuaState_H__ */
Index: /code/branches/rocket2/src/libraries/core/MemoryArchive.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/MemoryArchive.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/MemoryArchive.cc	(revision 6952)
@@ -0,0 +1,141 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "MemoryArchive.h"
+
+#if OGRE_VERSION < 0x010600
+
+#include <OgreException.h>
+#include <boost/filesystem.hpp>
+#include <boost/version.hpp>
+
+// Boost 1.36 has some issues with deprecated functions that have been omitted
+#if (BOOST_VERSION == 103600)
+#  define BOOST_HAS_BRANCH_PATH_FUNCTION has_parent_path
+#else
+#  define BOOST_HAS_BRANCH_PATH_FUNCTION has_branch_path
+#endif
+
+namespace orxonox
+{
+    using namespace Ogre;
+
+    MemoryArchive::ArchiveMap MemoryArchive::archives_s;
+
+    void MemoryArchive::load()
+    {
+        if (archives_s.find(this->getName()) == archives_s.end())
+            OGRE_EXCEPT(Ogre::Exception::ERR_INTERNAL_ERROR, this->getName() + " - MemoryArchive not found.", "MemoryArchive");
+    }
+
+    DataStreamPtr MemoryArchive::open(const String& filename) const
+    {
+        const FileMap& files = archives_s[this->getName()];
+        FileMap::const_iterator itFile = files.find(filename);
+        if (itFile == files.end())
+            return DataStreamPtr();
+        else
+            return MemoryDataStreamPtr(new MemoryDataStream(itFile->second.first.get(), itFile->second.second));
+    }
+
+    void MemoryArchive::findFiles(const String& pattern, bool bRecursive,
+        bool bDirs, StringVector* simpleList, FileInfoList* detailList)
+    {
+        const FileMap& files = archives_s[this->getName()];
+
+        for (FileMap::const_iterator it = files.begin(); it != files.end(); ++it)
+        {
+            boost::filesystem::path file = it->first;
+            // Check pattern
+            if (!StringUtil::match(file.string(), pattern, true))
+                continue;
+            if (bDirs)
+                file = file.branch_path();
+            if (file.empty())
+                continue;
+            if (file.BOOST_HAS_BRANCH_PATH_FUNCTION() && !bRecursive)
+                continue;
+            if (simpleList)
+                simpleList->push_back(file.string());
+            if (detailList)
+            {
+                FileInfo fi;
+                fi.archive = this;
+                fi.filename = file.string();
+                fi.basename = file.leaf();
+                fi.path = file.branch_path().string();
+                fi.compressedSize = it->second.second;
+                fi.uncompressedSize = it->second.second;
+                detailList->push_back(fi);
+            }
+        }
+    }
+    StringVectorPtr MemoryArchive::list(bool recursive, bool dirs)
+    {
+        StringVectorPtr ret(new StringVector());
+        findFiles("*", recursive, dirs, ret.getPointer(), 0);
+        return ret;
+    }
+
+    FileInfoListPtr MemoryArchive::listFileInfo(bool recursive, bool dirs)
+    {
+        FileInfoListPtr ret(new FileInfoList());
+        findFiles("*", recursive, dirs, 0, ret.getPointer());
+        return ret;
+    }
+
+    StringVectorPtr MemoryArchive::find(const String& pattern,
+                                            bool recursive, bool dirs)
+    {
+        StringVectorPtr ret(new StringVector());
+        findFiles(pattern, recursive, dirs, ret.getPointer(), 0);
+        return ret;
+    }
+
+    FileInfoListPtr MemoryArchive::findFileInfo(const String& pattern,
+        bool recursive, bool dirs)
+    {
+        FileInfoListPtr ret(new FileInfoList());
+        findFiles(pattern, recursive, dirs, 0, ret.getPointer());
+        return ret;
+    }
+
+    bool MemoryArchive::exists(const String& filename)
+    {
+        const FileMap& files = archives_s[this->getName()];
+        return files.find(filename) != files.end();
+    }
+
+    const Ogre::String& MemoryArchiveFactory::getType(void) const
+    {
+        static std::string result("Memory");
+        return result;
+    }
+}
+
+#endif /* OGRE_VERSION < 0x010600 */
Index: /code/branches/rocket2/src/libraries/core/MemoryArchive.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/MemoryArchive.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/MemoryArchive.h	(revision 6952)
@@ -0,0 +1,101 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _MemoryArchive_H__
+#define _MemoryArchive_H__
+
+#include "CorePrereqs.h"
+#include <OgrePrerequisites.h>
+
+#if OGRE_VERSION < 0x010600
+
+#include <map>
+#include <OgreArchive.h>
+#include <OgreArchiveFactory.h>
+#include <boost/shared_array.hpp>
+
+namespace orxonox
+{
+    /**
+    @brief
+        Provides a simple mechanism of 'memory mapped IO', but compatible for Ogre 1.4
+
+        Files are stored as shared_array<char> in a static map with the archive names
+        (imaging the different archives as resource locations). This map then contains
+        yet another map with the actual files.
+        If you want to know why we make such a fuss, contact GraphicsManager::upgradeToGraphics()
+        for more information.
+    */
+    class MemoryArchive : public Ogre::Archive
+    {
+    public:
+        MemoryArchive(const Ogre::String& name, const Ogre::String& archiveType) : Ogre::Archive(name, archiveType) { }
+        ~MemoryArchive() { }
+
+        bool isCaseSensitive(void) const { return true; }
+
+        void load();
+        void unload() { }
+
+        Ogre::DataStreamPtr open(const Ogre::String& filename) const;
+
+        Ogre::StringVectorPtr list(bool recursive = true, bool dirs = false);
+        Ogre::FileInfoListPtr listFileInfo(bool recursive = true, bool dirs = false);
+
+        Ogre::StringVectorPtr find(const Ogre::String& pattern, bool recursive = true,
+            bool dirs = false);
+        Ogre::FileInfoListPtr findFileInfo(const Ogre::String& pattern, bool recursive = true,
+            bool dirs = false);
+
+        bool exists(const Ogre::String& filename);
+
+        static void addFile(const std::string& archiveName, const std::string& filename, shared_array<char> content, size_t size)
+            { archives_s[archiveName][filename] = std::make_pair(content, size); }
+
+    private:
+        void findFiles(const Ogre::String& pattern, bool bRecursive,
+            bool bDirs, Ogre::StringVector* simpleList, Ogre::FileInfoList* detailList);
+
+        typedef std::map<std::string, std::pair<shared_array<char>, size_t> > FileMap;
+        typedef std::map<std::string, FileMap> ArchiveMap;
+        static ArchiveMap archives_s;
+    };
+
+    //! Specialisation of ArchiveFactory for MemoryArchive.
+    class _CoreExport MemoryArchiveFactory : public Ogre::ArchiveFactory
+    {
+    public:
+        const Ogre::String& getType(void) const;
+        Ogre::Archive* createInstance(const Ogre::String& name) { return new MemoryArchive(name, "Memory"); }
+        void destroyInstance(Ogre::Archive* arch)               { delete arch; }
+    };
+}
+
+#endif /* OGRE_VERSION < 0x010600 */
+
+#endif /* _MemoryArchive_H__ */
Index: /code/branches/rocket2/src/libraries/core/MetaObjectList.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/MetaObjectList.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/MetaObjectList.cc	(revision 6952)
@@ -0,0 +1,103 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the MetaObjectList class.
+*/
+
+#include "MetaObjectList.h"
+
+#include "util/Debug.h"
+#include "Identifier.h"
+#include "ObjectListBase.h"
+
+namespace orxonox
+{
+    // ###############################
+    // ###  MetaObjectListElement  ###
+    // ###############################
+    /**
+        @brief Destructor: Removes the ObjectListBaseElement from the ObjectListBase by linking next_ and prev_ of the ObjectListBaseElement.
+    */
+    MetaObjectListElement::~MetaObjectListElement()
+    {
+        COUT(5) << "*** MetaObjectList: Removing Object from " << this->list_->getIdentifier()->getName() << "-list." << std::endl;
+        this->list_->notifyIterators(this->element_->objectBase_);
+
+        if (this->element_->next_)
+            this->element_->next_->prev_ = this->element_->prev_;
+        else
+            this->list_->last_ = this->element_->prev_; // If there is no next_, we deleted the last object and have to update the last_ pointer of the list
+
+        if (this->element_->prev_)
+            this->element_->prev_->next_ = this->element_->next_;
+        else
+            this->list_->first_ = this->element_->next_; // If there is no prev_, we deleted the first object and have to update the first_ pointer of the list
+
+        delete this->element_;
+    }
+
+
+    // ###############################
+    // ###     MetaObjectList      ###
+    // ###############################
+    /**
+        @brief Constructor: Sets first_ to zero.
+    */
+    MetaObjectList::MetaObjectList()
+    {
+        this->first_ = 0;
+    }
+
+    /**
+        @brief Destructor: Removes all elements from the list, causing them to remove the stored ObjectListElement from the ObjectList.
+    */
+    MetaObjectList::~MetaObjectList()
+    {
+        MetaObjectListElement* temp;
+        while (this->first_)
+        {
+            temp = this->first_->next_;
+            delete this->first_;
+            this->first_ = temp;
+        }
+    }
+
+    /**
+        @brief Adds an ObjectList and an element of that list to the MetaObjectList.
+        @param list The ObjectList wherein the element is
+        @param element The element wherein the object is
+    */
+    void MetaObjectList::add(ObjectListBase* list, ObjectListBaseElement* element)
+    {
+        MetaObjectListElement* temp = this->first_;
+        this->first_ = new MetaObjectListElement(list, element);
+        this->first_->next_ = temp;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/MetaObjectList.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/MetaObjectList.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/MetaObjectList.h	(revision 6952)
@@ -0,0 +1,84 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the MetaObjectList class.
+
+    The MetaObjectList is a single-linked list, containing all list-elements and their
+    lists wherein the object, owning the MetaObjectList, is registered.
+    This allows much faster deletion of objects because no iteration is needed.
+*/
+
+#ifndef _MetaObjectList_H__
+#define _MetaObjectList_H__
+
+#include "CorePrereqs.h"
+
+namespace orxonox
+{
+    // ###############################
+    // ###  MetaObjectListElement  ###
+    // ###############################
+    //! The list-element of the MetaObjectList
+    class _CoreExport MetaObjectListElement
+    {
+        public:
+            /**
+                @brief Constructor: Creates the list-element with given list and element.
+            */
+            MetaObjectListElement(ObjectListBase* list, ObjectListBaseElement* element) : next_(0), element_(element), list_(list) {}
+            ~MetaObjectListElement();
+
+            MetaObjectListElement* next_;       //!< The next Element in the list
+            ObjectListBaseElement* element_;    //!< The list element, containing the object
+            ObjectListBase* list_;              //!< The list, containing the element
+    };
+
+
+    // ###############################
+    // ###     MetaObjectList      ###
+    // ###############################
+    //!  The MetaObjectList contains ObjectListBaseElements and their ObjectListBases.
+    /**
+        The MetaObjectList is a single-linked list, containing all list-elements and their
+        lists wherein the object that owns the MetaObjectList is registered.
+        This allows much faster deletion of objects because no iteration is needed.
+    */
+    class _CoreExport MetaObjectList
+    {
+        public:
+            MetaObjectList();
+            ~MetaObjectList();
+            void add(ObjectListBase* list, ObjectListBaseElement* element);
+
+            MetaObjectListElement* first_;      //!< The first element in the list
+    };
+}
+
+#endif /* _MetaObjectList_H__ */
Index: /code/branches/rocket2/src/libraries/core/Namespace.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/Namespace.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Namespace.cc	(revision 6952)
@@ -0,0 +1,182 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Namespace.h"
+
+#include <set>
+
+#include "NamespaceNode.h"
+#include "CoreIncludes.h"
+#include "XMLPort.h"
+#include "util/SubString.h"
+
+namespace orxonox
+{
+    CreateFactory(Namespace);
+
+    Namespace::Namespace(BaseObject* creator) : BaseObject(creator),
+      bAutogeneratedFileRootNamespace_(false),
+      bRoot_(false),
+      operator_("or")
+    {
+        RegisterObject(Namespace);
+    }
+
+    Namespace::~Namespace()
+    {
+        if (this->bRoot_)
+            for (std::set<NamespaceNode*>::iterator it = this->representingNamespaces_.begin(); it != this->representingNamespaces_.end(); ++it)
+                delete (*it);
+    }
+
+    /**
+        @brief XML loading and saving.
+        @param xmlelement The XML-element
+        @param loading Loading (true) or saving (false)
+        @return The XML-element
+    */
+    void Namespace::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Namespace, XMLPort, xmlelement, mode);
+
+        std::string name = this->getName();
+        size_t pos = 0;
+        while ((pos = name.find(',')) != std::string::npos)
+            name.replace(pos, 1, " ");
+        while ((pos = name.find(';')) != std::string::npos)
+            name.replace(pos, 1, " ");
+        while ((pos = name.find('\n')) != std::string::npos)
+            name.replace(pos, 1, " ");
+        while ((pos = name.find('\t')) != std::string::npos)
+            name.replace(pos, 1, " ");
+        SubString tokens(name, " ", "", false, '\\', true, '"', true, '\0', '\0', true, '\0');
+        if (this->bRoot_)
+        {
+            this->representingNamespaces_.insert(new NamespaceNode(this->getName()));
+        }
+        else
+        {
+            for (unsigned int i = 0; i < tokens.size(); i++)
+            {
+                for (std::set<NamespaceNode*>::iterator it = this->getNamespace()->representingNamespaces_.begin(); it != this->getNamespace()->representingNamespaces_.end(); ++it)
+                {
+                    std::set<NamespaceNode*> temp = (*it)->getNodeRelative(tokens[i]);
+                    this->representingNamespaces_.insert(temp.begin(), temp.end());
+                }
+            }
+        }
+
+        XMLPortParam(Namespace, "operator", setOperator, getOperator, xmlelement, mode);
+        XMLPortParam(Namespace, "bAutogenerated", setAutogenerated, isAutogenerated, xmlelement, mode);
+
+        if (this->bAutogeneratedFileRootNamespace_)
+        {
+            for (std::set<NamespaceNode*>::iterator it = this->representingNamespaces_.begin(); it != this->representingNamespaces_.end(); ++it)
+            {
+                (*it)->setRoot(true);
+                (*it)->setHidden(true);
+            }
+        }
+
+        XMLPortObjectExtended(Namespace, BaseObject, "", loadObjects, saveObjects, xmlelement, mode, true, false);
+    }
+
+    void Namespace::loadObjects(BaseObject* object)
+    {
+        object->setNamespace(this);
+    }
+
+    const BaseObject* Namespace::saveObjects(unsigned int index) const
+    {
+        return 0; // todo
+    }
+
+    bool Namespace::includes(const Namespace* ns) const
+    {
+        for (std::set<NamespaceNode*>::const_iterator it1 = this->representingNamespaces_.begin(); it1 != this->representingNamespaces_.end(); ++it1)
+        {
+            for (std::set<NamespaceNode*>::const_iterator it2 = ns->representingNamespaces_.begin(); it2 != ns->representingNamespaces_.end(); ++it2)
+            {
+                if ((*it1)->includes(*it2))
+                {
+                    if (this->operator_ == "or")
+                        return true;
+
+                    if (this->operator_ == "not")
+                        return false;
+                }
+                else
+                {
+                    if (this->operator_ == "and")
+                        return false;
+                }
+            }
+        }
+
+        if (this->operator_ == "or")
+            return false;
+        else if (this->operator_ == "and")
+            return true;
+        else if (this->operator_ == "not")
+            return true;
+
+        return false;
+    }
+
+    std::string Namespace::toString() const
+    {
+        std::string output;
+
+        int i = 0;
+        for (std::set<NamespaceNode*>::const_iterator it = this->representingNamespaces_.begin(); it != this->representingNamespaces_.end(); i++, ++it)
+        {
+            if (i > 0)
+                output += " / ";
+
+            output += (*it)->toString();
+        }
+
+        return output;
+    }
+
+    std::string Namespace::toString(const std::string& indentation) const
+    {
+        std::string output;
+
+        int i = 0;
+        for (std::set<NamespaceNode*>::const_iterator it = this->representingNamespaces_.begin(); it != this->representingNamespaces_.end(); i++, ++it)
+        {
+            if (i > 0)
+                output += '\n';
+
+            output += (*it)->toString(indentation);
+        }
+
+        return output;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/Namespace.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Namespace.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Namespace.h	(revision 6952)
@@ -0,0 +1,78 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Namespace_H__
+#define _Namespace_H__
+
+#include "CorePrereqs.h"
+
+#include <set>
+#include <string>
+#include "BaseObject.h"
+
+namespace orxonox
+{
+    class Namespace : public BaseObject
+    {
+        public:
+            Namespace(BaseObject* creator);
+            virtual ~Namespace();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            void loadObjects(BaseObject* object);
+            const BaseObject* saveObjects(unsigned int index) const;
+
+            void setAutogenerated(bool bAutogenerated)
+                { this->bAutogeneratedFileRootNamespace_ = bAutogenerated; }
+            bool isAutogenerated() const
+                { return this->bAutogeneratedFileRootNamespace_; }
+
+            void setOperator(const std::string& op)
+                { this->operator_ = op; }
+            const std::string& getOperator() const
+                { return this->operator_; }
+
+            void setRoot(bool bRoot)
+                { this->bRoot_ = bRoot; }
+
+            bool includes(const Namespace* ns) const;
+            bool isIncludedIn(const Namespace* ns) const { return ns->includes(this); }
+
+            std::string toString() const;
+            std::string toString(const std::string& indentation) const;
+
+        private:
+            std::set<NamespaceNode*> representingNamespaces_;
+            bool bAutogeneratedFileRootNamespace_;
+            bool bRoot_;
+            std::string operator_;
+    };
+}
+
+#endif /* _Namespace_H__ */
Index: /code/branches/rocket2/src/libraries/core/NamespaceNode.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/NamespaceNode.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/NamespaceNode.cc	(revision 6952)
@@ -0,0 +1,174 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "NamespaceNode.h"
+#include "util/Debug.h"
+
+namespace orxonox
+{
+    NamespaceNode::NamespaceNode(const std::string& name, NamespaceNode* parent)
+    {
+        this->name_ = name;
+        this->parent_ = parent;
+        this->bRoot_ = false;
+        this->bHidden_ = false;
+    }
+
+    NamespaceNode::~NamespaceNode()
+    {
+        for (std::map<std::string, NamespaceNode*>::iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); )
+            delete (it++)->second;
+    }
+
+    std::set<NamespaceNode*> NamespaceNode::getNodeRelative(const std::string& name)
+    {
+        std::set<NamespaceNode*> nodes;
+
+        if (name.empty())
+        {
+            nodes.insert(this);
+        }
+        else
+        {
+            size_t pos = name.find("::");
+            std::string firstPart = name;
+            std::string secondPart;
+
+            if (pos != std::string::npos)
+            {
+                firstPart = name.substr(0, pos);
+                secondPart = name.substr(pos + 2, std::string::npos);
+            }
+
+            if (firstPart == "..")
+            {
+                if (this->bRoot_)
+                {
+                    COUT(2) << "Warning: Can't go to enclosing namespace with '..' operator in namespace " << this->name_ << ", namespace is root." << std::endl;
+                    nodes = this->getNodeRelative(secondPart);
+                }
+                else if (!this->parent_)
+                {
+                    COUT(2) << "Warning: Can't go to enclosing namespace with '..' operator in namespace " << this->name_ << ", no parent namespace set." << std::endl;
+                    nodes = this->getNodeRelative(secondPart);
+                }
+                else
+                {
+                    nodes = this->parent_->getNodeRelative(secondPart);
+                }
+            }
+            else if (name.find('@') != 0)
+            {
+                std::map<std::string, NamespaceNode*>::iterator it = this->subnodes_.find(firstPart);
+                if (it == this->subnodes_.end())
+                    it = this->subnodes_.insert(this->subnodes_.begin(), std::pair<std::string, NamespaceNode*>(firstPart, new NamespaceNode(firstPart, this)));
+
+                if (it->second->isHidden())
+                {
+                    COUT(2) << "Warning: Subnamespace '" << firstPart << "' in namespace '" << this->name_ << "' is hidden and can't be accessed." << std::endl;
+                    nodes.insert(this);
+                }
+                else
+                {
+                    nodes = it->second->getNodeRelative(secondPart);
+                }
+            }
+            else
+            {
+                bool bFoundMatchingNamespace = false;
+
+                for (std::map<std::string, NamespaceNode*>::iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); ++it)
+                {
+                    if (it->first.find(firstPart) == (it->first.size() - firstPart.size()))
+                    {
+                        std::set<NamespaceNode*> temp2 = it->second->getNodeRelative(secondPart);
+                        nodes.insert(temp2.begin(), temp2.end());
+                        bFoundMatchingNamespace = true;
+                    }
+                }
+
+                if (!bFoundMatchingNamespace)
+                {
+                    COUT(2) << "Warning: No file included with name '" << firstPart.substr(1, std::string::npos) << "' at this part of the level file, using parent namespace instead." << std::endl;
+                    nodes = this->getNodeRelative(secondPart);
+                }
+            }
+        }
+
+        return nodes;
+    }
+
+    bool NamespaceNode::includes(const NamespaceNode* ns) const
+    {
+        if (ns == this)
+        {
+            return true;
+        }
+        else
+        {
+            for (std::map<std::string, NamespaceNode*>::const_iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); ++it)
+                if (it->second->includes(ns))
+                    return true;
+        }
+
+        return false;
+    }
+
+    std::string NamespaceNode::toString() const
+    {
+        std::string output = this->name_;
+
+        if (this->subnodes_.size() > 0)
+        {
+            output += " (";
+
+            int i = 0;
+            for (std::map<std::string, NamespaceNode*>::const_iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); i++, ++it)
+            {
+                if (i > 0)
+                    output += ", ";
+
+                output += it->second->toString();
+            }
+
+            output += ')';
+        }
+
+        return output;
+    }
+
+    std::string NamespaceNode::toString(const std::string& indentation) const
+    {
+        std::string output = (indentation + this->name_ + '\n');
+
+        for (std::map<std::string, NamespaceNode*>::const_iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); ++it)
+            output += it->second->toString(indentation + "  ");
+
+        return output;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/NamespaceNode.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/NamespaceNode.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/NamespaceNode.h	(revision 6952)
@@ -0,0 +1,68 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NamespaceNode_H__
+#define _NamespaceNode_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <set>
+#include <string>
+
+namespace orxonox
+{
+    class NamespaceNode
+    {
+        public:
+            NamespaceNode(const std::string& name, NamespaceNode* parent = 0);
+            ~NamespaceNode();
+
+            std::set<NamespaceNode*> getNodeRelative(const std::string& name);
+
+            void setRoot(bool bRoot) { this->bRoot_ = bRoot; }
+            void setHidden(bool bHidden) { this->bHidden_ = bHidden; }
+
+            bool isRoot() const { return this->bRoot_; }
+            bool isHidden() const { return this->bHidden_; }
+
+            bool includes(const NamespaceNode*) const;
+
+            std::string toString() const;
+            std::string toString(const std::string& indentation) const;
+
+        private:
+            std::string name_;
+            NamespaceNode* parent_;
+            std::map<std::string, NamespaceNode*> subnodes_;
+            bool bHidden_;
+            bool bRoot_;
+    };
+}
+
+#endif /* _NamespaceNode_H__ */
Index: /code/branches/rocket2/src/libraries/core/ObjectList.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ObjectList.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ObjectList.h	(revision 6952)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition and implementation of the ObjectList class.
+
+    The ObjectList is a wrapper of an ObjectListBase of a given class.
+    Use Iterator<class> to iterate through all objects of the class.
+*/
+
+#ifndef _ObjectList_H__
+#define _ObjectList_H__
+
+#include "CorePrereqs.h"
+
+#include "Identifier.h"
+#include "ObjectListIterator.h"
+
+namespace orxonox
+{
+    // ###############################
+    // ###       ObjectList        ###
+    // ###############################
+    //! The ObjectList contains all objects of the given class.
+    /**
+        Wraps the ObjectListBase of the corresponding Identifier.
+        Use ObjectListIterator<class> to iterate through all objects in the list.
+    */
+    template <class T>
+    class ObjectList
+    {
+        public:
+            typedef ObjectListIterator<T> iterator;
+
+            /** @brief Returns an Iterator to the first element in the list. @return The Iterator */
+            inline static ObjectListElement<T>* begin()
+                { return ((ObjectListElement<T>*)ClassIdentifier<T>::getIdentifier()->getObjects()->begin().element_); }
+
+            /** @brief Returns an Iterator to the element after the last element in the list. @return The Iterator */
+            inline static ObjectListElement<T>* end()
+                { return ((ObjectListElement<T>*)ClassIdentifier<T>::getIdentifier()->getObjects()->end().element_); }
+
+            /** @brief Returns an Iterator to the last element in the list. @return The Iterator */
+            inline static ObjectListElement<T>* rbegin()
+                { return ((ObjectListElement<T>*)ClassIdentifier<T>::getIdentifier()->getObjects()->rbegin().element_); }
+
+            /** @brief Returns an Iterator to the element before the first element in the list. @return The Iterator */
+            inline static ObjectListElement<T>* rend()
+                { return ((ObjectListElement<T>*)ClassIdentifier<T>::getIdentifier()->getObjects()->rend().element_); }
+    };
+}
+
+#endif /* _ObjectList_H__ */
Index: /code/branches/rocket2/src/libraries/core/ObjectListBase.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/ObjectListBase.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ObjectListBase.cc	(revision 6952)
@@ -0,0 +1,106 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the ObjectListBase class.
+
+    The ObjectListBase is a double-linked list, used by Identifiers to store all objects of a given class.
+    Newly created objects are added through the RegisterObject-macro in its constructor.
+*/
+
+#include "ObjectListBase.h"
+
+#include <set>
+#include "Identifier.h"
+#include "Iterator.h"
+#include "ObjectListIterator.h"
+
+namespace orxonox
+{
+    /**
+        @brief Constructor: Sets default values.
+    */
+    ObjectListBase::ObjectListBase(Identifier* identifier)
+    {
+        this->identifier_ = identifier;
+        this->first_ = 0;
+        this->last_ = 0;
+    }
+
+    /**
+        @brief Destructor: Deletes all list-elements, but NOT THE OBJECTS.
+    */
+    ObjectListBase::~ObjectListBase()
+    {
+        ObjectListBaseElement* temp;
+        while (this->first_)
+        {
+            temp = this->first_->next_;
+            delete this->first_;
+            this->first_ = temp;
+        }
+    }
+
+    /**
+        @brief Increases all Iterators that currently point on the given element (because it gets removed).
+        @param element The element that gets removed
+    */
+    void ObjectListBase::notifyIterators(OrxonoxClass* object) const
+    {
+        for (std::vector<void*>::const_iterator it = this->iterators_.begin(); it != this->iterators_.end(); ++it)
+            ((Iterator<OrxonoxClass>*)(*it))->incrementIfEqual(object);
+        for (std::vector<void*>::const_iterator it = this->objectListIterators_.begin(); it != this->objectListIterators_.end(); ++it)
+            ((ObjectListIterator<OrxonoxClass>*)(*it))->incrementIfEqual(object);
+    }
+
+    /**
+        @brief Adds a new object to the end of the list.
+        @param object The object to add
+        @return The pointer to the new ObjectListBaseElement, needed by the MetaObjectList of the added object
+    */
+    ObjectListBaseElement* ObjectListBase::add(ObjectListBaseElement* element)
+    {
+        if (!this->last_)
+        {
+            // If the list is empty
+            this->last_ = element;
+            this->first_ = this->last_; // There's only one object in the list now
+        }
+        else
+        {
+            // If the list isn't empty
+            ObjectListBaseElement* temp = this->last_;
+            this->last_ = element;
+            this->last_->prev_ = temp;
+            temp->next_ = this->last_;
+        }
+
+        return this->last_;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/ObjectListBase.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ObjectListBase.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ObjectListBase.h	(revision 6952)
@@ -0,0 +1,150 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the ObjectListBase class.
+
+    The ObjectListBase is a double-linked list, used by Identifiers to store all objects of a given class.
+    Newly created objects are added through the RegisterObject-macro in its constructor.
+*/
+
+#ifndef _ObjectListBase_H__
+#define _ObjectListBase_H__
+
+#include "CorePrereqs.h"
+
+#include <vector>
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    // ###############################
+    // ###  ObjectListBaseElement  ###
+    // ###############################
+    //! The list-element of the ObjectListBase
+    class _CoreExport ObjectListBaseElement
+    {
+        public:
+            /**
+                @brief Constructor: Creates the list-element with an object.
+                @param object The object to store
+            */
+            ObjectListBaseElement(OrxonoxClass* objectBase) : next_(0), prev_(0), objectBase_(objectBase) {}
+
+            ObjectListBaseElement* next_;       //!< The next element in the list
+            ObjectListBaseElement* prev_;       //!< The previous element in the list
+            OrxonoxClass* objectBase_;
+    };
+
+
+    // ###############################
+    // ###    ObjectListElement    ###
+    // ###############################
+    //! The list-element that actually contains the object
+    template <class T>
+    class ObjectListElement : public ObjectListBaseElement
+    {
+        public:
+            ObjectListElement(T* object) : ObjectListBaseElement(static_cast<OrxonoxClass*>(object)), object_(object) {}
+            T* object_;              //!< The object
+    };
+
+
+    // ###############################
+    // ###     ObjectListBase      ###
+    // ###############################
+    //! The ObjectListBase contains all objects of a given class.
+    /**
+        The ObjectListBase is used by Identifiers to store all objects of their given class.
+        Use ObjectList<T> to get the list of all T's and Iterator<T> to iterate through them.
+    */
+    class _CoreExport ObjectListBase
+    {
+        friend class MetaObjectListElement;
+
+        public:
+            ObjectListBase(Identifier* identifier);
+            ~ObjectListBase();
+
+            ObjectListBaseElement* add(ObjectListBaseElement* element);
+
+            struct Export
+            {
+                Export(ObjectListBase* list, ObjectListBaseElement* element) : list_(list), element_(element) {}
+                ObjectListBase* list_;
+                ObjectListBaseElement* element_;
+            };
+
+            /** @brief Returns a pointer to the first element in the list. @return The element */
+            inline Export begin() { return ObjectListBase::Export(this, this->first_); }
+            /** @brief Returns a pointer to the element after the last element in the list. @return The element */
+            inline Export end() { return ObjectListBase::Export(this, 0); }
+            /** @brief Returns a pointer to the last element in the list. @return The element */
+            inline Export rbegin() { return ObjectListBase::Export(this, this->last_); }
+            /** @brief Returns a pointer to the element in front of the first element in the list. @return The element */
+            inline Export rend() { return ObjectListBase::Export(this, 0); }
+
+            inline void registerIterator(void* iterator) { this->iterators_.push_back(iterator); }
+            inline void unregisterIterator(void* iterator)
+            {
+                for (unsigned int i = 0; i < this->iterators_.size(); ++i)
+                {
+                    if (iterators_[i] == iterator)
+                    {
+                        iterators_.erase(iterators_.begin() + i);
+                        break;
+                    }
+                }
+            }
+            inline void registerObjectListIterator(void* iterator) { this->objectListIterators_.push_back(iterator); }
+            inline void unregisterObjectListIterator(void* iterator)
+            {
+                for (unsigned int i = 0; i < this->objectListIterators_.size(); ++i)
+                {
+                    if (objectListIterators_[i] == iterator)
+                    {
+                        objectListIterators_.erase(objectListIterators_.begin() + i);
+                        break;
+                    }
+                }
+            }
+            void notifyIterators(OrxonoxClass* object) const;
+
+            inline Identifier* getIdentifier() const { return this->identifier_; }
+
+        private:
+            Identifier* identifier_;                 //!< The Iterator owning this list
+            ObjectListBaseElement* first_;           //!< The first element in the list
+            ObjectListBaseElement* last_;            //!< The last element in the list
+            std::vector<void*> iterators_;           //!< A list of Iterators pointing on an element in this list
+            std::vector<void*> objectListIterators_; //!< A list of ObjectListIterators pointing on an element in this list
+    };
+}
+
+#endif /* _ObjectListBase_H__ */
Index: /code/branches/rocket2/src/libraries/core/ObjectListIterator.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ObjectListIterator.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ObjectListIterator.h	(revision 6952)
@@ -0,0 +1,223 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition and implementation of the Iterator class.
+
+    The ObjectListIterator of a given class allows to iterate through the
+    ObjectList of this class, containing all objects of that type.
+    This is the only way to access the objects stored in an ObjectList.
+
+    Usage:
+    for (ObjectListIterator<myClass> it = ObjectList<myClass>::begin(); it != ObjectList<myClass>::end(); ++it)
+    {
+        it->someFunction(...);
+        myClass* myObject = *it;
+    }
+*/
+
+#ifndef _ObjectListIterator_H__
+#define _ObjectListIterator_H__
+
+#include "CorePrereqs.h"
+#include "Identifier.h"
+#include "ObjectList.h"
+
+namespace orxonox
+{
+    //! The Iterator allows to iterate through the ObjectList of a given class.
+    template <class T>
+    class ObjectListIterator
+    {
+        template <class I>
+        friend class Iterator;
+
+        public:
+            /**
+                @brief Constructor: Sets the element, whereon the ObjectListIterator points, to zero.
+            */
+            inline ObjectListIterator()
+            {
+                this->element_ = 0;
+                ClassIdentifier<T>::getIdentifier()->getObjects()->registerObjectListIterator(this);
+            }
+
+            /**
+                @brief Constructor: Sets this element to a given element.
+                @param element The element to start with
+            */
+            inline ObjectListIterator(ObjectListElement<T>* element)
+            {
+                this->element_ = element;
+                ClassIdentifier<T>::getIdentifier()->getObjects()->registerObjectListIterator(this);
+            }
+
+            /**
+                @brief Constructor: Sets this element to the element of another ObjectListIterator.
+                @param other The other ObjectListIterator
+            */
+            inline ObjectListIterator(const ObjectListIterator<T>& other)
+            {
+                this->element_ = other.element_;
+                ClassIdentifier<T>::getIdentifier()->getObjects()->registerObjectListIterator(this);
+            }
+
+            /**
+                @brief Unregisters the ObjectListIterator from the ObjectList.
+            */
+            inline ~ObjectListIterator()
+            {
+                ClassIdentifier<T>::getIdentifier()->getObjects()->unregisterObjectListIterator(this);
+            }
+
+            /**
+                @brief Assigns an ObjectListElement.
+                @param element The ObjectListElement
+            */
+            inline const ObjectListIterator<T>& operator=(ObjectListElement<T>* element)
+            {
+                this->element_ = element;
+                return (*this);
+            }
+
+            /**
+                @brief Assigns the element of another ObjectListIterator.
+                @param element The other ObjectListIterator
+            */
+            inline const ObjectListIterator<T>& operator=(const ObjectListIterator<T>& other)
+            {
+                this->element_ = other.element_;
+                return (*this);
+            }
+
+            /**
+                @brief Overloading of the ++it operator: ObjectListIterator points to the next object in the list.
+                @return The ObjectListIterator itself
+            */
+            inline const ObjectListIterator<T>& operator++()
+            {
+                this->element_ = static_cast<ObjectListElement<T>*>(this->element_->next_);
+                return *this;
+            }
+
+            /**
+                @brief Overloading of the it++ operator: ObjectListIterator points to the next object in the list.
+                @return The ObjectListIterator itself
+            */
+            inline ObjectListIterator<T> operator++(int i)
+            {
+                ObjectListIterator<T> copy = *this;
+                this->element_ = static_cast<ObjectListElement<T>*>(this->element_->next_);
+                return copy;
+            }
+
+            /**
+                @brief Overloading of the --it operator: ObjectListIterator points to the previous object in the list.
+                @return The ObjectListIterator itself
+            */
+            inline const ObjectListIterator<T>& operator--()
+            {
+                this->element_ = static_cast<ObjectListElement<T>*>(this->element_->prev_);
+                return *this;
+            }
+
+            /**
+                @brief Overloading of the it-- operator: ObjectListIterator points to the previous object in the list.
+                @return The ObjectListIterator itself
+            */
+            inline ObjectListIterator<T> operator--(int i)
+            {
+                ObjectListIterator<T> copy = *this;
+                this->element_ = static_cast<ObjectListElement<T>*>(this->element_->prev_);
+                return copy;
+            }
+
+            /**
+                @brief Overloading of the *it operator: returns the pointer to the object.
+                @return The object the ObjectListIterator points at
+            */
+            inline T* operator*() const
+            {
+                return this->element_->object_;
+            }
+
+            /**
+                @brief Overloading of the it-> operator: returns the pointer to the object.
+                @return The object the ObjectListIterator points at
+            */
+            inline T* operator->() const
+            {
+                return this->element_->object_;
+            }
+
+            /**
+                @brief Overloading of the typecast-operator to bool: returns true if the ObjectListIterator points to an existing object.
+                @return True if the ObjectListIterator points to an existing object.
+            */
+            inline operator bool() const
+            {
+                return (this->element_ != 0);
+            }
+
+            /**
+                @brief Overloading of the == operator to compare with another ObjectListIterator.
+                @param compare The other ObjectListIterator
+                @return True if the ObjectListIterator point to the same element
+            */
+            inline bool operator==(const ObjectListIterator<T>& compare) const
+            {
+                return (this->element_ == compare.element_);
+            }
+
+            /**
+                @brief Overloading of the != operator to compare with another ObjectListIterator.
+                @param compare The other ObjectListIterator
+                @return True if the ObjectListIterator point to different elements
+            */
+            inline bool operator!=(const ObjectListIterator<T>& compare) const
+            {
+                return (this->element_ != compare.element_);
+            }
+
+            /**
+                @brief Increments the ObjectListIterator if it points at the given object.
+                @param object The object to compare with
+            */
+            inline void incrementIfEqual(OrxonoxClass* object)
+            {
+                if (this->element_ && this->element_->objectBase_ == object)
+                    this->operator++();
+            }
+
+        private:
+            ObjectListElement<T>* element_;        //!< The element the Iterator points at
+    };
+}
+
+#endif /* _ObjectListIterator_H__ */
Index: /code/branches/rocket2/src/libraries/core/OrxonoxClass.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/OrxonoxClass.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/OrxonoxClass.cc	(revision 6952)
@@ -0,0 +1,132 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the OrxonoxClass Class.
+*/
+
+#include "OrxonoxClass.h"
+
+#include <cassert>
+#include "MetaObjectList.h"
+#include "Identifier.h"
+#include "WeakPtr.h"
+
+namespace orxonox
+{
+    /** @brief Constructor: Sets the default values. */
+    OrxonoxClass::OrxonoxClass()
+    {
+        this->identifier_ = 0;
+        this->parents_ = 0;
+        this->metaList_ = new MetaObjectList();
+        this->referenceCount_ = 0;
+        this->requestedDestruction_ = false;
+        // Optimisation
+        this->objectPointers_.reserve(6);
+    }
+
+    /** @brief Destructor: Deletes, if existing, the list of the parents. */
+    OrxonoxClass::~OrxonoxClass()
+    {
+//        if (!this->requestedDestruction_)
+//            COUT(2) << "Warning: Destroyed object without destroy() (" << this->getIdentifier()->getName() << ')' << std::endl;
+
+        assert(this->referenceCount_ <= 0);
+
+        this->unregisterObject();
+
+        // parents_ exists only if isCreatingHierarchy() of the associated Identifier returned true while creating the class
+        if (this->parents_)
+            delete this->parents_;
+
+        // reset all weak pointers pointing to this object
+        for (std::set<WeakPtr<OrxonoxClass>*>::iterator it = this->weakPointers_.begin(); it != this->weakPointers_.end(); )
+            (*(it++))->objectDeleted();
+    }
+
+    /** @brief Deletes the object if no smart pointers point to this object. Otherwise schedules the object to be deleted as soon as possible. */
+    void OrxonoxClass::destroy()
+    {
+        assert(this); // Just in case someone tries to delete a NULL pointer
+        this->requestedDestruction_ = true;
+        if (this->referenceCount_ == 0)
+        {
+            this->preDestroy();
+            if (this->referenceCount_ == 0)
+                delete this;
+        }
+    }
+
+    void OrxonoxClass::unregisterObject()
+    {
+        if (this->metaList_)
+            delete this->metaList_;
+        this->metaList_ = 0;
+    }
+
+    /** @brief Returns true if the objects class is of the given type or a derivative. */
+    bool OrxonoxClass::isA(const Identifier* identifier)
+        { return this->getIdentifier()->isA(identifier); }
+    /** @brief Returns true if the objects class is exactly of the given type. */
+    bool OrxonoxClass::isExactlyA(const Identifier* identifier)
+        { return this->getIdentifier()->isExactlyA(identifier); }
+    /** @brief Returns true if the objects class is a child of the given type. */
+    bool OrxonoxClass::isChildOf(const Identifier* identifier)
+        { return this->getIdentifier()->isChildOf(identifier); }
+    /** @brief Returns true if the objects class is a direct child of the given type. */
+    bool OrxonoxClass::isDirectChildOf(const Identifier* identifier)
+        { return this->getIdentifier()->isDirectChildOf(identifier); }
+    /** @brief Returns true if the objects class is a parent of the given type. */
+    bool OrxonoxClass::isParentOf(const Identifier* identifier)
+        { return this->getIdentifier()->isParentOf(identifier); }
+    /** @brief Returns true if the objects class is a direct parent of the given type. */
+    bool OrxonoxClass::isDirectParentOf(const Identifier* identifier)
+        { return this->getIdentifier()->isDirectParentOf(identifier); }
+
+
+    /** @brief Returns true if the objects class is of the given type or a derivative. */
+    bool OrxonoxClass::isA(const OrxonoxClass* object)
+        { return this->getIdentifier()->isA(object->getIdentifier()); }
+    /** @brief Returns true if the objects class is exactly of the given type. */
+    bool OrxonoxClass::isExactlyA(const OrxonoxClass* object)
+        { return this->getIdentifier()->isExactlyA(object->getIdentifier()); }
+    /** @brief Returns true if the objects class is a child of the given type. */
+    bool OrxonoxClass::isChildOf(const OrxonoxClass* object)
+        { return this->getIdentifier()->isChildOf(object->getIdentifier()); }
+    /** @brief Returns true if the objects class is a direct child of the given type. */
+    bool OrxonoxClass::isDirectChildOf(const OrxonoxClass* object)
+        { return this->getIdentifier()->isDirectChildOf(object->getIdentifier()); }
+    /** @brief Returns true if the objects class is a parent of the given type. */
+    bool OrxonoxClass::isParentOf(const OrxonoxClass* object)
+        { return this->getIdentifier()->isParentOf(object->getIdentifier()); }
+    /** @brief Returns true if the objects class is a direct child of the given type. */
+    bool OrxonoxClass::isDirectParentOf(const OrxonoxClass* object)
+        { return this->getIdentifier()->isDirectParentOf(object->getIdentifier()); }
+}
Index: /code/branches/rocket2/src/libraries/core/OrxonoxClass.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/OrxonoxClass.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/OrxonoxClass.h	(revision 6952)
@@ -0,0 +1,179 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Declaration of the OrxonoxClass Class.
+
+    All objects and interfaces of the game-logic (not the engine) are derived from OrxonoxClass.
+    It stores the Identifier and the MetaObjectList and has all needed functions to create and use the class-hierarchy.
+*/
+
+#ifndef _OrxonoxClass_H__
+#define _OrxonoxClass_H__
+
+#include "CorePrereqs.h"
+#include "Super.h"
+
+#include <set>
+#include <vector>
+
+/**
+@def CCOUT
+    Acts almost exactly like COUT(x), but prepends "ClassName: "
+*/
+#define CCOUT(level) \
+    COUT(level) << this->getIdentifier()->getName() << ": "
+
+namespace orxonox
+{
+    //! The class all objects and interfaces of the game-logic (not the engine) are derived from.
+    /**
+        The BaseObject and Interfaces are derived with 'virtual public OrxonoxClass' from OrxonoxClass.
+        OrxonoxClass is needed to create the class-hierarchy at startup and to store the Identifier and the MetaObjectList.
+    */
+    class _CoreExport OrxonoxClass
+    {
+        template <class T>
+        friend class ClassIdentifier;
+
+        template <class T>
+        friend class SmartPtr;
+
+        template <class T>
+        friend class WeakPtr;
+
+        public:
+            OrxonoxClass();
+            virtual ~OrxonoxClass();
+
+            void destroy();
+            void unregisterObject();
+
+            /** @brief Function to collect the SetConfigValue-macro calls. */
+            void setConfigValues() {};
+
+            /** @brief Returns the Identifier of the object. @return The Identifier */
+            inline Identifier* getIdentifier() const { return this->identifier_; }
+
+            bool isA(const Identifier* identifier);
+            bool isExactlyA(const Identifier* identifier);
+            bool isChildOf(const Identifier* identifier);
+            bool isDirectChildOf(const Identifier* identifier);
+            bool isParentOf(const Identifier* identifier);
+            bool isDirectParentOf(const Identifier* identifier);
+
+            template <class B> inline bool isA(const SubclassIdentifier<B>* identifier)
+                { return this->isA(*identifier); }
+            template <class B> inline bool isExactlyA(const SubclassIdentifier<B>* identifier)
+                { return this->isExactlyA(*identifier); }
+            template <class B> inline bool isChildOf(const SubclassIdentifier<B>* identifier)
+                { return this->isChildOf(*identifier); }
+            template <class B> inline bool isDirectChildOf(const SubclassIdentifier<B>* identifier)
+                { return this->isDirectChildOf(*identifier); }
+            template <class B> inline bool isParentOf(const SubclassIdentifier<B>* identifier)
+                { return this->isParentOf(*identifier); }
+            template <class B> inline bool isDirectParentOf(const SubclassIdentifier<B>* identifier)
+                { return this->isDirectParentOf(*identifier); }
+
+            bool isA(const OrxonoxClass* object);
+            bool isExactlyA(const OrxonoxClass* object);
+            bool isChildOf(const OrxonoxClass* object);
+            bool isDirectChildOf(const OrxonoxClass* object);
+            bool isParentOf(const OrxonoxClass* object);
+            bool isDirectParentOf(const OrxonoxClass* object);
+            
+            virtual void clone(OrxonoxClass*& item) {}
+
+            inline unsigned int getReferenceCount() const
+                { return this->referenceCount_; }
+
+            /**
+            @brief
+                Returns a valid pointer of any derived type that is
+                registered in the class hierarchy.
+            @return
+                Returns NULL if the no pointer was found.
+            */
+            FORCEINLINE void* getDerivedPointer(unsigned int classID)
+            {
+                for (int i = this->objectPointers_.size() - 1; i >= 0; --i)
+                {
+                    if (this->objectPointers_[i].first == classID)
+                        return this->objectPointers_[i].second;
+                }
+                return NULL;
+            }
+
+            //! Version of getDerivedPointer with template
+            template <class T> 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
+            {   return const_cast<OrxonoxClass*>(this)->getDerivedPointer<T>(classID);   }
+
+        protected:
+            virtual void preDestroy() {}
+
+        private:
+            /** @brief Increments the reference counter (for smart pointers). */
+            inline void incrementReferenceCount()
+                { ++this->referenceCount_; }
+            /** @brief Decrements the reference counter (for smart pointers). */
+            inline void decrementReferenceCount()
+            {
+                --this->referenceCount_;
+                if (this->referenceCount_ == 0 && this->requestedDestruction_)
+                    this->destroy();
+            }
+
+            /** @brief Register a weak pointer which points to this object. */
+            template <class T>
+            inline void registerWeakPtr(WeakPtr<T>* pointer)
+                { this->weakPointers_.insert(reinterpret_cast<WeakPtr<OrxonoxClass>*>(pointer)); }
+            /** @brief Unegister a weak pointer which pointed to this object before. */
+            template <class T>
+            inline void unregisterWeakPtr(WeakPtr<T>* pointer)
+                { this->weakPointers_.erase(reinterpret_cast<WeakPtr<OrxonoxClass>*>(pointer)); }
+
+            Identifier* identifier_;                   //!< The Identifier of the object
+            std::set<const Identifier*>* parents_;     //!< List of all parents of the object
+            MetaObjectList* metaList_;                 //!< MetaObjectList, containing all ObjectLists and ObjectListElements the object is registered in
+            int referenceCount_;                       //!< Counts the references from smart pointers to this object
+            bool requestedDestruction_;                //!< Becomes true after someone called delete on this object
+            std::set<WeakPtr<OrxonoxClass>*> weakPointers_; //!< All weak pointers which point to this object (and like to get notified if it dies)
+
+            //! 'Fast map' that holds this-pointers of all derived types
+            std::vector<std::pair<unsigned int, void*> > objectPointers_;
+    };
+    
+    SUPER_FUNCTION(11, OrxonoxClass, clone, true);
+    
+}
+
+#endif /* _OrxonoxClass_H__ */
Index: /code/branches/rocket2/src/libraries/core/PathConfig.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/PathConfig.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/PathConfig.cc	(revision 6952)
@@ -0,0 +1,327 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "PathConfig.h"
+
+#include <cassert>
+#include <cstdlib>
+#include <cstdio>
+#include <vector>
+#include <boost/version.hpp>
+#include <boost/filesystem.hpp>
+
+#ifdef ORXONOX_PLATFORM_WINDOWS
+#  ifndef WIN32_LEAN_AND_MEAN
+#    define WIN32_LEAN_AND_MEAN
+#  endif
+#  include <windows.h>
+#  undef min
+#  undef max
+#elif defined(ORXONOX_PLATFORM_APPLE)
+#  include <sys/param.h>
+#  include <mach-o/dyld.h>
+#else /* Linux */
+#  include <sys/types.h>
+#  include <unistd.h>
+#endif
+
+#include "SpecialConfig.h"
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "CommandLineParser.h"
+
+// Boost 1.36 has some issues with deprecated functions that have been omitted
+#if (BOOST_VERSION == 103600)
+#  define BOOST_LEAF_FUNCTION filename
+#else
+#  define BOOST_LEAF_FUNCTION leaf
+#endif
+
+namespace orxonox
+{
+    namespace bf = boost::filesystem;
+
+    //! Static pointer to the singleton
+    PathConfig* PathConfig::singletonPtr_s  = 0;
+
+    SetCommandLineArgument(externalDataPath, "").information("Path to the external data files");
+    SetCommandLineOnlyArgument(writingPathSuffix, "").information("Additional subfolder for config and log files");
+
+    PathConfig::PathConfig()
+        : rootPath_(*(new bf::path()))
+        , executablePath_(*(new bf::path()))
+        , modulePath_(*(new bf::path()))
+        , dataPath_(*(new bf::path()))
+        , externalDataPath_(*(new bf::path()))
+        , configPath_(*(new bf::path()))
+        , logPath_(*(new bf::path()))
+        , bDevRun_(false)
+    {
+        //////////////////////////
+        // FIND EXECUTABLE PATH //
+        //////////////////////////
+
+#ifdef ORXONOX_PLATFORM_WINDOWS
+        // get executable module
+        TCHAR buffer[1024];
+        if (GetModuleFileName(NULL, buffer, 1024) == 0)
+            ThrowException(General, "Could not retrieve executable path.");
+
+#elif defined(ORXONOX_PLATFORM_APPLE)
+        char buffer[1024];
+        unsigned long path_len = 1023;
+        if (_NSGetExecutablePath(buffer, &path_len))
+            ThrowException(General, "Could not retrieve executable path.");
+
+#else /* Linux */
+        /* written by Nicolai Haehnle <prefect_@gmx.net> */
+
+        /* Get our PID and build the name of the link in /proc */
+        char linkname[64]; /* /proc/<pid>/exe */
+        if (snprintf(linkname, sizeof(linkname), "/proc/%i/exe", getpid()) < 0)
+        {
+            /* This should only happen on large word systems. I'm not sure
+               what the proper response is here.
+               Since it really is an assert-like condition, aborting the
+               program seems to be in order. */
+            assert(false);
+        }
+
+        /* Now read the symbolic link */
+        char buffer[1024];
+        int ret;
+        ret = readlink(linkname, buffer, 1024);
+        /* In case of an error, leave the handling up to the caller */
+        if (ret == -1)
+            ThrowException(General, "Could not retrieve executable path.");
+
+        /* Ensure proper NUL termination */
+        buffer[ret] = 0;
+#endif
+
+        executablePath_ = bf::path(buffer);
+#ifndef ORXONOX_PLATFORM_APPLE
+        executablePath_ = executablePath_.branch_path(); // remove executable name
+#endif
+
+        /////////////////////
+        // SET MODULE PATH //
+        /////////////////////
+
+        if (bf::exists(executablePath_ / "orxonox_dev_build.keep_me"))
+        {
+            COUT(1) << "Running from the build tree." << std::endl;
+            PathConfig::bDevRun_ = true;
+            modulePath_ = specialConfig::moduleDevDirectory;
+        }
+        else
+        {
+
+#ifdef INSTALL_COPYABLE // --> relative paths
+
+            // Also set the root path
+            bf::path relativeExecutablePath(specialConfig::defaultRuntimePath);
+            rootPath_ = executablePath_;
+            while (!bf::equivalent(rootPath_ / relativeExecutablePath, executablePath_) && !rootPath_.empty())
+                rootPath_ = rootPath_.branch_path();
+            if (rootPath_.empty())
+                ThrowException(General, "Could not derive a root directory. Might the binary installation directory contain '..' when taken relative to the installation prefix path?");
+
+            // Module path is fixed as well
+            modulePath_ = rootPath_ / specialConfig::defaultModulePath;
+
+#else
+
+            // There is no root path, so don't set it at all
+            // Module path is fixed as well
+            modulePath_ = specialConfig::moduleInstallDirectory;
+
+#endif
+        }
+    }
+
+    PathConfig::~PathConfig()
+    {
+        delete &rootPath_;
+        delete &executablePath_;
+        delete &modulePath_;
+        delete &dataPath_;
+        delete &externalDataPath_;
+        delete &configPath_;
+        delete &logPath_;
+    }
+
+    void PathConfig::setConfigurablePaths()
+    {
+        if (bDevRun_)
+        {
+            dataPath_         = specialConfig::dataDevDirectory;
+            configPath_       = specialConfig::configDevDirectory;
+            logPath_          = specialConfig::logDevDirectory;
+
+            // Check for data path override by the command line
+            if (!CommandLineParser::getArgument("externalDataPath")->hasDefaultValue())
+                externalDataPath_ = CommandLineParser::getValue("externalDataPath").getString();
+            else
+                externalDataPath_ = specialConfig::externalDataDevDirectory;
+        }
+        else
+        {
+
+#ifdef INSTALL_COPYABLE // --> relative paths
+
+            // Using paths relative to the install prefix, complete them
+            dataPath_   = rootPath_ / specialConfig::defaultDataPath;
+            configPath_ = rootPath_ / specialConfig::defaultConfigPath;
+            logPath_    = rootPath_ / specialConfig::defaultLogPath;
+
+#else
+
+            dataPath_  = specialConfig::dataInstallDirectory;
+
+            // Get user directory
+#  ifdef ORXONOX_PLATFORM_UNIX /* Apple? */
+            char* userDataPathPtr(getenv("HOME"));
+#  else
+            char* userDataPathPtr(getenv("APPDATA"));
+#  endif
+            if (userDataPathPtr == NULL)
+                ThrowException(General, "Could not retrieve user data path.");
+            bf::path userDataPath(userDataPathPtr);
+            userDataPath /= ".orxonox";
+
+            configPath_ = userDataPath / specialConfig::defaultConfigPath;
+            logPath_    = userDataPath / specialConfig::defaultLogPath;
+
+#endif
+
+        }
+
+        // Option to put all the config and log files in a separate folder
+        if (!CommandLineParser::getArgument("writingPathSuffix")->hasDefaultValue())
+        {
+            const std::string& directory(CommandLineParser::getValue("writingPathSuffix").getString());
+            configPath_ = configPath_ / directory;
+            logPath_    = logPath_    / directory;
+        }
+
+        // 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"));
+
+        for (std::vector<std::pair<bf::path, std::string> >::iterator it = directories.begin();
+            it != directories.end(); ++it)
+        {
+            if (bf::exists(it->first) && !bf::is_directory(it->first))
+            {
+                ThrowException(General, std::string("The ") + it->second + " directory has been preoccupied by a file! \
+                                         Please remove " + it->first.string());
+            }
+            if (bf::create_directories(it->first)) // function may not return true at all (bug?)
+            {
+                COUT(4) << "Created " << it->second << " directory" << std::endl;
+            }
+        }
+    }
+
+    std::vector<std::string> PathConfig::getModulePaths()
+    {
+        std::vector<std::string> modulePaths;
+
+        // We search for helper files with the following extension
+        const std::string& moduleextension = specialConfig::moduleExtension;
+        size_t moduleextensionlength = moduleextension.size();
+
+        // Add that path to the PATH variable in case a module depends on another one
+        std::string pathVariable(getenv("PATH"));
+        putenv(const_cast<char*>(("PATH=" + pathVariable + ';' + modulePath_.string()).c_str()));
+
+        // Make sure the path exists, otherwise don't load modules
+        if (!boost::filesystem::exists(modulePath_))
+            return modulePaths;
+
+        boost::filesystem::directory_iterator file(modulePath_);
+        boost::filesystem::directory_iterator end;
+
+        // Iterate through all files
+        while (file != end)
+        {
+            const std::string& filename = file->BOOST_LEAF_FUNCTION();
+
+            // Check if the file ends with the exension in question
+            if (filename.size() > moduleextensionlength)
+            {
+                if (filename.substr(filename.size() - moduleextensionlength) == moduleextension)
+                {
+                    // We've found a helper file
+                    const std::string& library = filename.substr(0, filename.size() - moduleextensionlength);
+                    modulePaths.push_back((modulePath_ / library).file_string());
+                }
+            }
+            ++file;
+        }
+
+        return modulePaths;
+    }
+
+    /*static*/ std::string PathConfig::getRootPathString()
+    {
+        return getInstance().rootPath_.string() + '/';
+    }
+
+    /*static*/ std::string PathConfig::getExecutablePathString()
+    {
+        return getInstance().executablePath_.string() + '/';
+    }
+
+    /*static*/ std::string PathConfig::getDataPathString()
+    {
+        return getInstance().dataPath_.string() + '/';
+    }
+
+    /*static*/ std::string PathConfig::getExternalDataPathString()
+    {
+        return getInstance().externalDataPath_.string() + '/';
+    }
+
+    /*static*/ std::string PathConfig::getConfigPathString()
+    {
+        return getInstance().configPath_.string() + '/';
+    }
+
+    /*static*/ std::string PathConfig::getLogPathString()
+    {
+        return getInstance().logPath_.string() + '/';
+    }
+
+    /*static*/ std::string PathConfig::getModulePathString()
+    {
+        return getInstance().modulePath_.string() + '/';
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/PathConfig.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/PathConfig.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/PathConfig.h	(revision 6952)
@@ -0,0 +1,140 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PathConfig_H__
+#define _PathConfig_H__
+
+#include "CorePrereqs.h"
+
+#include <string>
+#include <vector>
+#include "util/Singleton.h"
+
+//tolua_begin
+namespace orxonox
+{
+//tolua_end
+    /**
+    @brief
+        The PathConfig class is a singleton used to configure different paths.
+    @details
+        The class provides information about the data, config, log, executable,
+        root and module path.
+        It determines those by the use of platform specific functions.
+    @remarks
+        Not all paths are always available:
+        - root only when installed copyable
+        - externalData only for development builds in the build tree
+    */
+    class _CoreExport PathConfig //tolua_export
+        : public Singleton<PathConfig>
+    { //tolua_export
+        friend class Singleton<PathConfig>;
+        friend class Core;
+
+        public:
+            /**
+            @brief
+                Retrievs the executable path and sets all hard coded fixed paths (currently only the module path)
+                Also checks for "orxonox_dev_build.keep_me" in the executable diretory.
+                If found it means that this is not an installed run, hence we
+                don't write the logs and config files to ~/.orxonox
+            @throw
+                GeneralException
+            */
+            PathConfig();
+            ~PathConfig();
+
+            //! Returns the path to the root folder as boost::filesystem::path
+            static const boost::filesystem::path& getRootPath()
+                { return getInstance().rootPath_; }
+            //! Returns the path to the executable folder as boost::filesystem::path
+            static const boost::filesystem::path& getExecutablePath()
+                { return getInstance().executablePath_; }
+            //! Returns the path to the data files as boost::filesystem::path
+            static const boost::filesystem::path& getDataPath()
+                { return getInstance().dataPath_; }
+            //! Returns the path to the external data files as boost::filesystem::path
+            static const boost::filesystem::path& getExternalDataPath()
+                { return getInstance().externalDataPath_; }
+            //! Returns the path to the config files as boost::filesystem::path
+            static const boost::filesystem::path& getConfigPath()
+                { return getInstance().configPath_; }
+            //! Returns the path to the log files as boost::filesystem::path
+            static const boost::filesystem::path& getLogPath()
+                { return getInstance().logPath_; }
+            //! Returns the path to the modules as boost::filesystem::path
+            static const boost::filesystem::path& getModulePath()
+                { return getInstance().modulePath_; }
+
+            //! Returns the path to the root folder as std::string
+            static std::string getRootPathString();
+            //! Returns the path to the executable folder as std::string
+            static std::string getExecutablePathString();
+            //! Returns the path to the data files as std::string
+            static std::string getDataPathString();
+            //! Returns the path to the external data files as std::string
+            static std::string getExternalDataPathString();
+            //! Returns the path to the config files as std::string
+            static std::string getConfigPathString(); //tolua_export
+            //! Returns the path to the log files as std::string
+            static std::string getLogPathString();
+            //! Returns the path to the modules as std::string
+            static std::string getModulePathString();
+
+            //! Return trrue for runs in the build directory (not installed)
+            static bool isDevelopmentRun() { return getInstance().bDevRun_; }
+
+        private:
+            PathConfig(const PathConfig&); //!< Don't use (undefined symbol)
+
+            /**
+            @brief
+                Sets config, log and media path and creates the folders if necessary.
+            @throws
+                GeneralException
+            */
+            void setConfigurablePaths();
+            //! Returns a list with all modules declared by a *.module file in the module folder.
+            std::vector<std::string> getModulePaths();
+
+            //! Path to the parent directory of the ones above if program was installed with relativ paths
+            boost::filesystem::path& rootPath_;
+            boost::filesystem::path& executablePath_;        //!< Path to the executable
+            boost::filesystem::path& modulePath_;            //!< Path to the modules
+            boost::filesystem::path& dataPath_;              //!< Path to the data files folder
+            boost::filesystem::path& externalDataPath_;      //!< Path to the external data files folder
+            boost::filesystem::path& configPath_;            //!< Path to the config files folder
+            boost::filesystem::path& logPath_;               //!< Path to the log files folder
+
+            bool                     bDevRun_;               //!< True for runs in the build directory (not installed)
+            static PathConfig* singletonPtr_s;
+    }; //tolua_export
+} //tolua_export
+
+#endif /* _PathConfig_H__ */
Index: /code/branches/rocket2/src/libraries/core/Resource.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/Resource.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Resource.cc	(revision 6952)
@@ -0,0 +1,116 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Resource.h"
+
+#include <boost/filesystem/path.hpp>
+#include <OgreException.h>
+#include <OgreFileSystem.h>
+#include <OgreResourceGroupManager.h>
+
+namespace orxonox
+{
+    std::string Resource::DEFAULT_GROUP(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);
+    }
+
+    DataStreamListPtr Resource::openMulti(const std::string& pattern)
+    {
+        DataStreamListPtr resources(new Ogre::DataStreamList());
+        const Ogre::StringVector& groups = Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
+        for (Ogre::StringVector::const_iterator it = groups.begin(); it != groups.end(); ++it)
+        {
+            DataStreamListPtr temp = Ogre::ResourceGroupManager::getSingleton().openResources(pattern, *it);
+            resources->insert(resources->end(), temp->begin(), temp->end());
+        }
+        return resources;
+    }
+
+    bool Resource::exists(const std::string& name)
+    {
+        try
+        {
+            Ogre::ResourceGroupManager::getSingleton().findGroupContainingResource(name);
+            return true;
+        }
+        catch (const Ogre::Exception&)
+        {
+            return false;
+        }
+    }
+
+    shared_ptr<ResourceInfo> Resource::getInfo(const std::string& name)
+    {
+        std::string group;
+        try
+        {
+            group = Ogre::ResourceGroupManager::getSingleton().findGroupContainingResource(name);
+        }
+        catch (const Ogre::Exception&)
+        {
+            return shared_ptr<ResourceInfo>();
+        }
+        Ogre::FileInfoListPtr infos = Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(group, name);
+        for (Ogre::FileInfoList::const_iterator it = infos->begin(); it != infos->end(); ++it)
+        {
+            if (it->filename == name)
+            {
+                shared_ptr<ResourceInfo> ptr(new ResourceInfo());
+                ptr->filename = name;
+                ptr->path = it->path;
+                ptr->basename = it->basename;
+                ptr->group = group;
+                ptr->size = it->uncompressedSize;
+                if (dynamic_cast<Ogre::FileSystemArchive*>(it->archive) != NULL)
+                {
+                    boost::filesystem::path base(it->archive->getName());
+                    base /= it->filename;
+                    ptr->fileSystemPath = base.string();
+                }
+                return ptr;
+            }
+        }
+        return shared_ptr<ResourceInfo>();
+    }
+
+    StringVectorPtr Resource::findResourceNames(const std::string& pattern)
+    {
+        StringVectorPtr resourceNames(new Ogre::StringVector());
+        const Ogre::StringVector& groups = Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
+        for (Ogre::StringVector::const_iterator it = groups.begin(); it != groups.end(); ++it)
+        {
+            StringVectorPtr temp = Ogre::ResourceGroupManager::getSingleton().findResourceNames(*it, pattern);
+            resourceNames->insert(resourceNames->end(), temp->begin(), temp->end());
+        }
+        return resourceNames;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/Resource.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Resource.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Resource.h	(revision 6952)
@@ -0,0 +1,138 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Core_Resource_H__
+#define _Core_Resource_H__
+
+#include "CorePrereqs.h"
+
+#include <boost/shared_ptr.hpp>
+#include <OgreDataStream.h>
+#include <OgreStringVector.h>
+
+namespace orxonox
+{
+    // Import the Ogre::DataStreamList
+    using Ogre::DataStreamList;
+    using Ogre::DataStreamListPtr;
+    using Ogre::StringVector;
+    using Ogre::StringVectorPtr;
+
+    //! Stores basic information about a Resource from Ogre
+    struct ResourceInfo
+    {
+        //! The file's fully qualified name
+        std::string filename;
+        //! Path name; separated by '/' and ending with '/'
+        std::string path;
+        //! Base filename
+        std::string basename;
+        //! Resource group the file is in
+        std::string group;
+        //! Uncompressed size
+        size_t size;
+        //! Absolute file path ("" for files not on filesystem)
+        std::string fileSystemPath;
+    };
+
+    /** Provides simple functions to easily access the Ogre::ResourceGroupManager.
+        The wrapper functions also avoid having to deal with resource groups.
+    */
+    class _CoreExport Resource
+    {
+        // Docs by Ogre::ResourceGroupManager.h
+    public:
+        /**
+        @brief
+            Open a single resource by name and return a DataStream
+            pointing at the source of the data.
+        @param name
+            The name of the resource to locate.
+            Even if resource locations are added recursively, you
+            must provide a fully qualified name to this method.
+        @return
+            Shared pointer to data stream containing the data. Will be
+            destroyed automatically when no longer referenced.
+        */
+        static DataStreamPtr open(const std::string& name);
+
+        //! Similar to open(string, string, bool), but with a fileInfo struct
+        static DataStreamPtr open(shared_ptr<ResourceInfo> fileInfo)
+        {
+            return open(fileInfo->filename);
+        }
+
+        /**
+        @brief
+            Open all resources matching a given pattern (which can contain
+            the character '*' as a wildcard), and return a collection of
+            DataStream objects on them.
+        @param pattern
+            The pattern to look for. If resource locations have been
+            added recursively, subdirectories will be searched too so this
+            does not need to be fully qualified.
+        @return
+            Shared pointer to a data stream list , will be
+            destroyed automatically when no longer referenced
+        */
+        static DataStreamListPtr openMulti(const std::string& pattern);
+
+        /**
+            Find out if the named file exists.
+        @param filename
+            Fully qualified name of the file to test for
+        */
+        static bool exists(const std::string& name);
+
+        /**
+            Get struct with information about path and size.
+        @param filename
+            Fully qualified name of the file to test for
+        */
+        static shared_ptr<ResourceInfo> getInfo(const std::string& name);
+
+        /**
+            Retrieves a list with all resources matching a certain pattern.
+        @param pattern
+            The pattern to look for. If resource locations have been
+            added recursively, subdirectories will be searched too so this
+            does not need to be fully qualified.
+        */
+        static StringVectorPtr findResourceNames(const std::string& pattern);
+
+        //! Name of the default resource group (usually "General")
+        static std::string DEFAULT_GROUP;
+
+    private:
+        Resource();
+        ~Resource();
+        Resource(const Resource& instance);
+    };
+}
+
+#endif /* _Core_Resource_H__ */
Index: /code/branches/rocket2/src/libraries/core/ScopedSingletonManager.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/ScopedSingletonManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ScopedSingletonManager.cc	(revision 6952)
@@ -0,0 +1,49 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ScopedSingletonManager.h"
+
+namespace orxonox
+{
+    /*static*/ std::map<std::string, ScopedSingletonManager*>& ScopedSingletonManager::getManagers()
+    {
+        static std::map<std::string, ScopedSingletonManager*> managers;
+        return managers;
+    }
+    /*static*/ ScopedSingletonManager::ManagerMultiMap& ScopedSingletonManager::getManagersByScope()
+    {
+        static ManagerMultiMap managers;
+        return managers;
+    }
+
+    /*static*/ void ScopedSingletonManager::addManager(ScopedSingletonManager* manager)
+    {
+        getManagers()[manager->className_] = manager;
+        getManagersByScope().insert(std::make_pair(manager->scope_, manager));
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/ScopedSingletonManager.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ScopedSingletonManager.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ScopedSingletonManager.h	(revision 6952)
@@ -0,0 +1,212 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef __ScopedSingletonManager_H__
+#define __ScopedSingletonManager_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include <map>
+#include "util/Exception.h"
+#include "util/Scope.h"
+#include "util/Singleton.h"
+
+#define ManageScopedSingleton(className, scope, allowedToFail) \
+    className* className::singletonPtr_s = NULL; \
+    static ClassScopedSingletonManager<className, scope, allowedToFail> className##ScopedSingletonManager(#className)
+
+namespace orxonox
+{
+    class _CoreExport ScopedSingletonManager
+    {
+        public:
+            ScopedSingletonManager(const std::string& className, ScopeID::Value scope)
+                : className_(className)
+                , scope_(scope)
+            { }
+            virtual ~ScopedSingletonManager() { }
+            static void addManager(ScopedSingletonManager* manager);
+
+            template<ScopeID::Value scope>
+            static void preUpdate(const Clock& time)
+            {
+                assert(Scope<scope>::isActive());
+                for (ManagerMultiMap::iterator it = getManagersByScope().lower_bound(scope); it != getManagersByScope().upper_bound(scope); ++it)
+                    it->second->preUpdate(time);
+            }
+            virtual void preUpdate(const Clock& time) = 0;
+            template<ScopeID::Value scope>
+            static void postUpdate(const Clock& time)
+            {
+                assert(Scope<scope>::isActive());
+                for (ManagerMultiMap::iterator it = getManagersByScope().lower_bound(scope); it != getManagersByScope().upper_bound(scope); ++it)
+                    it->second->postUpdate(time);
+            }
+            virtual void postUpdate(const Clock& time) = 0;
+
+            static std::map<std::string, ScopedSingletonManager*>& getManagers();
+            typedef std::multimap<ScopeID::Value, ScopedSingletonManager*> ManagerMultiMap;
+            static ManagerMultiMap& getManagersByScope();
+
+        protected:
+            const std::string className_;
+            const ScopeID::Value scope_;
+    };
+
+    template <class T, ScopeID::Value scope, bool allowedToFail>
+    class ClassScopedSingletonManager : public ScopedSingletonManager, public ScopeListener
+    {
+    public:
+        ClassScopedSingletonManager(const std::string& className)
+            : ScopedSingletonManager(className, scope)
+            , ScopeListener(scope)
+            , singletonPtr_(NULL)
+        {
+            ScopedSingletonManager::addManager(this);
+        }
+
+        ~ClassScopedSingletonManager()
+        {
+        }
+
+        //! Called if the Scope of the Singleton gets active (creates the instance)
+        void activated()
+        {
+            assert(singletonPtr_ == NULL);
+            singletonPtr_ = new T();
+        }
+
+        //! Called if the Scope of this Singleton gets deactivated (destroys the instance)
+        void deactivated()
+        {
+            assert(singletonPtr_ != NULL);
+            this->destroy(singletonPtr_);
+            singletonPtr_ = NULL;
+        }
+
+        void destroy(OrxonoxClass*)
+        {
+            singletonPtr_->destroy();
+        }
+        void destroy(void*)
+        {
+            delete singletonPtr_;
+        }
+
+        //! Called every frame by the ScopedSingletonManager
+        void preUpdate(const Clock& time)
+        {
+            assert(Scope<scope>::isActive());
+            // assuming T inherits Singleton<T>
+            singletonPtr_->preUpdateSingleton(time);
+        }
+
+        //! Called every frame by the ScopedSingletonManager
+        void postUpdate(const Clock& time)
+        {
+            assert(Scope<scope>::isActive());
+            // assuming T inherits Singleton<T>
+            singletonPtr_->postUpdateSingleton(time);
+        }
+
+    private:
+        T* singletonPtr_;
+    };
+
+    template <class T, ScopeID::Value scope>
+    class ClassScopedSingletonManager<T, scope, true> : public ScopedSingletonManager, public ScopeListener
+    {
+    public:
+        ClassScopedSingletonManager(const std::string& className)
+            : ScopedSingletonManager(className, scope)
+            , ScopeListener(scope)
+            , singletonPtr_(NULL)
+        {
+            ScopedSingletonManager::addManager(this);
+        }
+
+        ~ClassScopedSingletonManager()
+        {
+        }
+
+        //! Called if the Scope of the Singleton gets active (creates the instance)
+        void activated()
+        {
+            assert(singletonPtr_ == NULL);
+            try
+                { singletonPtr_ = new T(); }
+            catch (const InitialisationAbortedException& ex)
+                { COUT(3) << ex.getDescription() << std::endl; }
+            catch (...)
+                { COUT(1) << "Singleton creation failed: " << Exception::handleMessage() << std::endl; }
+        }
+
+        //! Called if the Scope of this Singleton gets deactivated (destroys the instance)
+        void deactivated()
+        {
+            if (singletonPtr_ != NULL)
+            {
+                this->destroy(singletonPtr_);
+                singletonPtr_ = NULL;
+            }
+        }
+
+        void destroy(OrxonoxClass* ptr)
+        {
+            singletonPtr_->destroy();
+        }
+        void destroy(void* ptr)
+        {
+            delete singletonPtr_;
+        }
+
+        //! Called every frame by the ScopedSingletonManager
+        void preUpdate(const Clock& time)
+        {
+            assert(Scope<scope>::isActive());
+            // assuming T inherits Singleton<T>
+            if (singletonPtr_ != NULL)
+                singletonPtr_->preUpdateSingleton(time);
+        }
+
+        //! Called every frame by the ScopedSingletonManager
+        void postUpdate(const Clock& time)
+        {
+            assert(Scope<scope>::isActive());
+            // assuming T inherits Singleton<T>
+            if (singletonPtr_ != NULL)
+                singletonPtr_->postUpdateSingleton(time);
+        }
+
+    private:
+        T* singletonPtr_;
+    };
+}
+
+#endif /* __ScopedSingletonManager_H__ */
Index: /code/branches/rocket2/src/libraries/core/Shell.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/Shell.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Shell.cc	(revision 6952)
@@ -0,0 +1,455 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#include "Shell.h"
+
+#include "util/OutputHandler.h"
+#include "util/StringUtils.h"
+#include "util/SubString.h"
+#include "CommandExecutor.h"
+#include "CoreIncludes.h"
+#include "ConfigFileManager.h"
+#include "ConfigValueIncludes.h"
+#include "ConsoleCommand.h"
+
+namespace orxonox
+{
+    SetConsoleCommandShortcut(OutputHandler, log);
+    SetConsoleCommandShortcut(OutputHandler, error);
+    SetConsoleCommandShortcut(OutputHandler, warning);
+    SetConsoleCommandShortcut(OutputHandler, info);
+    SetConsoleCommandShortcut(OutputHandler, debug);
+
+    Shell::Shell(const std::string& consoleName, bool bScrollable)
+        : OutputListener(consoleName)
+        , inputBuffer_(new InputBuffer())
+        , consoleName_(consoleName)
+        , bScrollable_(bScrollable)
+    {
+        RegisterRootObject(Shell);
+
+        this->scrollPosition_ = 0;
+        this->maxHistoryLength_ = 100;
+        this->historyPosition_ = 0;
+        this->historyOffset_ = 0;
+        this->bFinishedLastLine_ = true;
+
+        this->clearOutput();
+        this->configureInputBuffer();
+
+        // Specify file for the command history
+        ConfigFileManager::getInstance().setFilename(ConfigFileType::CommandHistory, "commandHistory.ini");
+
+        // Use a stringstream object to buffer the output
+        this->outputStream_ = &this->outputBuffer_;
+
+        this->setConfigValues();
+
+        // Get the previous output and add it to the Shell
+        for (OutputHandler::OutputVectorIterator it = OutputHandler::getInstance().getOutputVectorBegin();
+            it != OutputHandler::getInstance().getOutputVectorEnd(); ++it)
+        {
+            if (it->first <= this->getSoftDebugLevel())
+            {
+                this->outputBuffer_ << it->second;
+                this->outputChanged(it->first);
+            }
+        }
+
+        // Register the shell as output listener
+        OutputHandler::getInstance().registerOutputListener(this);
+    }
+
+    Shell::~Shell()
+    {
+        OutputHandler::getInstance().unregisterOutputListener(this);
+        this->inputBuffer_->destroy();
+    }
+
+    void Shell::setConfigValues()
+    {
+        SetConfigValue(maxHistoryLength_, 100)
+            .callback(this, &Shell::commandHistoryLengthChanged);
+        SetConfigValue(historyOffset_, 0)
+            .callback(this, &Shell::commandHistoryOffsetChanged);
+        setConfigValueGeneric(this, &commandHistory_, ConfigFileType::CommandHistory, "Shell", "commandHistory_", std::vector<std::string>());
+
+#ifdef ORXONOX_RELEASE
+        const unsigned int defaultLevel = 1;
+#else
+        const unsigned int defaultLevel = 3;
+#endif
+        setConfigValueGeneric(this, &softDebugLevel_, ConfigFileType::Settings, "OutputHandler", "softDebugLevel" + this->consoleName_, defaultLevel)
+            .description("The maximal level of debug output shown in the Shell");
+        this->setSoftDebugLevel(this->softDebugLevel_);
+    }
+
+    void Shell::commandHistoryOffsetChanged()
+    {
+        if (this->historyOffset_ >= this->maxHistoryLength_)
+            this->historyOffset_ = 0;
+    }
+
+    void Shell::commandHistoryLengthChanged()
+    {
+        this->commandHistoryOffsetChanged();
+
+        while (this->commandHistory_.size() > this->maxHistoryLength_)
+        {
+            unsigned int index = this->commandHistory_.size() - 1;
+            this->commandHistory_.erase(this->commandHistory_.begin() + index);
+            ModifyConfigValue(commandHistory_, remove, index);
+        }
+    }
+
+    void Shell::configureInputBuffer()
+    {
+        this->inputBuffer_->registerListener(this, &Shell::inputChanged, true);
+        this->inputBuffer_->registerListener(this, &Shell::execute,         '\r',   false);
+        this->inputBuffer_->registerListener(this, &Shell::execute,         '\n',   false);
+        this->inputBuffer_->registerListener(this, &Shell::hintAndComplete, '\t',   true);
+        this->inputBuffer_->registerListener(this, &Shell::backspace,       '\b',   true);
+        this->inputBuffer_->registerListener(this, &Shell::backspace,       '\177', true);
+        this->inputBuffer_->registerListener(this, &Shell::exit,            '\033', true); // escape
+        this->inputBuffer_->registerListener(this, &Shell::deleteChar,      KeyCode::Delete);
+        this->inputBuffer_->registerListener(this, &Shell::cursorRight,     KeyCode::Right);
+        this->inputBuffer_->registerListener(this, &Shell::cursorLeft,      KeyCode::Left);
+        this->inputBuffer_->registerListener(this, &Shell::cursorEnd,       KeyCode::End);
+        this->inputBuffer_->registerListener(this, &Shell::cursorHome,      KeyCode::Home);
+        this->inputBuffer_->registerListener(this, &Shell::historyUp,       KeyCode::Up);
+        this->inputBuffer_->registerListener(this, &Shell::historyDown,     KeyCode::Down);
+        if (this->bScrollable_)
+        {
+            this->inputBuffer_->registerListener(this, &Shell::scrollUp,    KeyCode::PageUp);
+            this->inputBuffer_->registerListener(this, &Shell::scrollDown,  KeyCode::PageDown);
+        }
+        else
+        {
+            this->inputBuffer_->registerListener(this, &Shell::historySearchUp,   KeyCode::PageUp);
+            this->inputBuffer_->registerListener(this, &Shell::historySearchDown, KeyCode::PageDown);
+        }
+    }
+
+    /*
+    void Shell::history()
+    {
+        Shell& instance = Shell::getInstance();
+
+        for (unsigned int i = instance.historyOffset_; i < instance.commandHistory_.size(); ++i)
+            instance.addOutput(instance.commandHistory_[i] + '\n', -1);
+        for (unsigned int i =  0; i < instance.historyOffset_; ++i)
+            instance.addOutput(instance.commandHistory_[i] + '\n', -1);
+    }
+    */
+
+    void Shell::registerListener(ShellListener* listener)
+    {
+        this->listeners_.push_back(listener);
+    }
+
+    void Shell::unregisterListener(ShellListener* listener)
+    {
+        for (std::list<ShellListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); )
+        {
+            if ((*it) == listener)
+                it = this->listeners_.erase(it);
+            else
+                ++it;
+        }
+    }
+
+    void Shell::setCursorPosition(unsigned int cursor)
+    {
+        this->inputBuffer_->setCursorPosition(cursor);
+        this->updateListeners<&ShellListener::cursorChanged>();
+    }
+
+    void Shell::addOutput(const std::string& text, LineType type)
+    {
+        this->outputBuffer_ << text;
+        this->outputChanged(type);
+    }
+
+    void Shell::clearOutput()
+    {
+        this->outputLines_.clear();
+        this->scrollIterator_ = this->outputLines_.begin();
+
+        this->scrollPosition_ = 0;
+        this->bFinishedLastLine_ = true;
+
+        this->updateListeners<&ShellListener::linesChanged>();
+    }
+
+    Shell::LineList::const_iterator Shell::getNewestLineIterator() const
+    {
+        if (this->scrollPosition_)
+            return this->scrollIterator_;
+        else
+            return this->outputLines_.begin();
+    }
+
+    Shell::LineList::const_iterator Shell::getEndIterator() const
+    {
+        return this->outputLines_.end();
+    }
+
+    void Shell::addToHistory(const std::string& command)
+    {
+        ModifyConfigValue(commandHistory_, set, this->historyOffset_, command);
+        this->historyPosition_ = 0;
+        ModifyConfigValue(historyOffset_, set, (this->historyOffset_ + 1) % this->maxHistoryLength_);
+    }
+
+    const std::string& Shell::getFromHistory() const
+    {
+        unsigned int index = mod(static_cast<int>(this->historyOffset_) - static_cast<int>(this->historyPosition_), this->maxHistoryLength_);
+        if (index < this->commandHistory_.size() && this->historyPosition_ != 0)
+            return this->commandHistory_[index];
+        else
+            return BLANKSTRING;
+    }
+
+    void Shell::outputChanged(int lineType)
+    {
+        bool newline = false;
+        do
+        {
+            std::string output;
+            std::getline(this->outputBuffer_, output);
+
+            bool eof = this->outputBuffer_.eof();
+            bool fail = this->outputBuffer_.fail();
+            if (eof)
+                this->outputBuffer_.flush();
+            if (eof || fail)
+                this->outputBuffer_.clear();
+            newline = (!eof && !fail);
+
+            if (!newline && output.empty())
+                break;
+
+            if (this->bFinishedLastLine_)
+            {
+                this->outputLines_.push_front(std::make_pair(output, static_cast<LineType>(lineType)));
+
+                if (this->scrollPosition_)
+                    this->scrollPosition_++;
+                else
+                    this->scrollIterator_ = this->outputLines_.begin();
+
+                this->bFinishedLastLine_ = newline;
+
+                if (!this->scrollPosition_)
+                    this->updateListeners<&ShellListener::lineAdded>();
+            }
+            else
+            {
+                this->outputLines_.front().first += output;
+                this->bFinishedLastLine_ = newline;
+                this->updateListeners<&ShellListener::onlyLastLineChanged>();
+            }
+            this->bFinishedLastLine_ = newline;
+
+        } while (newline);
+    }
+
+    void Shell::clearInput()
+    {
+        this->inputBuffer_->clear();
+        this->historyPosition_ = 0;
+        this->updateListeners<&ShellListener::inputChanged>();
+        this->updateListeners<&ShellListener::cursorChanged>();
+    }
+
+    void Shell::setPromptPrefix(const std::string& str)
+    {
+    }
+
+
+    // ##########################################
+    // ###   InputBuffer callback functions   ###
+    // ##########################################
+
+    void Shell::inputChanged()
+    {
+        this->updateListeners<&ShellListener::inputChanged>();
+        this->updateListeners<&ShellListener::cursorChanged>();
+    }
+
+    void Shell::execute()
+    {
+        this->addToHistory(this->inputBuffer_->get());
+        this->updateListeners<&ShellListener::executed>();
+
+        if (!CommandExecutor::execute(this->inputBuffer_->get()))
+        {
+            this->outputBuffer_ << "Error: Can't execute \"" << this->inputBuffer_->get() << "\"." << std::endl;
+            this->outputChanged(Error);
+        }
+
+        this->clearInput();
+    }
+
+    void Shell::hintAndComplete()
+    {
+        this->inputBuffer_->set(CommandExecutor::complete(this->inputBuffer_->get()));
+        this->outputBuffer_ << CommandExecutor::hint(this->inputBuffer_->get()) << std::endl;
+        this->outputChanged(Hint);
+
+        this->inputChanged();
+    }
+
+    void Shell::backspace()
+    {
+        this->inputBuffer_->removeBehindCursor();
+        this->updateListeners<&ShellListener::inputChanged>();
+        this->updateListeners<&ShellListener::cursorChanged>();
+    }
+
+    void Shell::exit()
+    {
+        if (this->inputBuffer_->getSize() > 0)
+        {
+            this->clearInput();
+            return;
+        }
+
+        this->clearInput();
+        this->scrollPosition_ = 0;
+        this->scrollIterator_ = this->outputLines_.begin();
+
+        this->updateListeners<&ShellListener::exit>();
+    }
+
+    void Shell::deleteChar()
+    {
+        this->inputBuffer_->removeAtCursor();
+        this->updateListeners<&ShellListener::inputChanged>();
+    }
+
+    void Shell::cursorRight()
+    {
+        this->inputBuffer_->increaseCursor();
+        this->updateListeners<&ShellListener::cursorChanged>();
+    }
+
+    void Shell::cursorLeft()
+    {
+        this->inputBuffer_->decreaseCursor();
+        this->updateListeners<&ShellListener::cursorChanged>();
+    }
+
+    void Shell::cursorEnd()
+    {
+        this->inputBuffer_->setCursorToEnd();
+        this->updateListeners<&ShellListener::cursorChanged>();
+    }
+
+    void Shell::cursorHome()
+    {
+        this->inputBuffer_->setCursorToBegin();
+        this->updateListeners<&ShellListener::cursorChanged>();
+    }
+
+    void Shell::historyUp()
+    {
+        if (this->historyPosition_ < this->commandHistory_.size())
+        {
+            this->historyPosition_++;
+            this->inputBuffer_->set(this->getFromHistory());
+        }
+    }
+
+    void Shell::historyDown()
+    {
+        if (this->historyPosition_ > 0)
+        {
+            this->historyPosition_--;
+            this->inputBuffer_->set(this->getFromHistory());
+        }
+    }
+
+    void Shell::historySearchUp()
+    {
+        if (this->historyPosition_ == this->historyOffset_)
+            return;
+        unsigned int cursorPosition = this->getCursorPosition();
+        const std::string& input_str(this->getInput().substr(0, cursorPosition)); // only search for the expression from the beginning of the inputline until the cursor position
+        for (unsigned int newPos = this->historyPosition_ + 1; newPos <= this->historyOffset_; newPos++)
+        {
+            if (getLowercase(this->commandHistory_[this->historyOffset_ - newPos]).find(getLowercase(input_str)) == 0) // search case insensitive
+            {
+                this->historyPosition_ = newPos;
+                this->inputBuffer_->set(this->getFromHistory());
+                this->setCursorPosition(cursorPosition);
+                return;
+            }
+        }
+    }
+
+    void Shell::historySearchDown()
+    {
+        if (this->historyPosition_ == 0)
+            return;
+        unsigned int cursorPosition = this->getCursorPosition();
+        const std::string& input_str(this->getInput().substr(0, cursorPosition)); // only search for the expression from the beginning
+        for (unsigned int newPos = this->historyPosition_ - 1; newPos > 0; newPos--)
+        {
+            if (getLowercase(this->commandHistory_[this->historyOffset_ - newPos]).find(getLowercase(input_str)) == 0) // sear$
+            {
+                this->historyPosition_ = newPos;
+                this->inputBuffer_->set(this->getFromHistory());
+                this->setCursorPosition(cursorPosition);
+                return;
+            }
+        }
+    }
+
+    void Shell::scrollUp()
+    {
+        if (this->scrollIterator_ != this->outputLines_.end())
+        {
+            ++this->scrollIterator_;
+            ++this->scrollPosition_;
+
+            this->updateListeners<&ShellListener::linesChanged>();
+        }
+    }
+
+    void Shell::scrollDown()
+    {
+        if (this->scrollIterator_ != this->outputLines_.begin())
+        {
+            --this->scrollIterator_;
+            --this->scrollPosition_;
+
+            this->updateListeners<&ShellListener::linesChanged>();
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/Shell.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Shell.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Shell.h	(revision 6952)
@@ -0,0 +1,172 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#ifndef _Shell_H__
+#define _Shell_H__
+
+#include "CorePrereqs.h"
+
+#include <list>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "util/OutputHandler.h"
+#include "OrxonoxClass.h"
+#include "input/InputBuffer.h"
+
+namespace orxonox
+{
+    class _CoreExport ShellListener
+    {
+        friend class Shell;
+
+        public:
+            virtual ~ShellListener() {}
+
+        private:
+            virtual void linesChanged() {}
+            virtual void onlyLastLineChanged() {}
+            virtual void lineAdded() {}
+            virtual void inputChanged() {}
+            virtual void cursorChanged() {}
+            virtual void executed() {}
+            virtual void exit() {}
+    };
+
+
+    class _CoreExport Shell : virtual public OrxonoxClass, public OutputListener
+    {
+        public:
+            enum LineType
+            {
+                None    = OutputLevel::None,
+                Warning = OutputLevel::Warning,
+                Error   = OutputLevel::Error,
+                Info    = OutputLevel::Info,
+                Debug   = OutputLevel::Debug,
+                Verbose = OutputLevel::Verbose,
+                Ultra   = OutputLevel::Ultra,
+                Input,
+                Command,
+                Hint
+            };
+
+            Shell(const std::string& consoleName, bool bScrollable);
+            ~Shell();
+
+            void setConfigValues();
+            void commandHistoryOffsetChanged();
+            void commandHistoryLengthChanged();
+
+            void registerListener(ShellListener* listener);
+            void unregisterListener(ShellListener* listener);
+
+            inline InputBuffer* getInputBuffer()
+                { return this->inputBuffer_; }
+
+            void setCursorPosition(unsigned int cursor);
+            inline unsigned int getCursorPosition() const
+                { return this->inputBuffer_->getCursorPosition(); }
+
+            inline const std::string& getInput() const
+                { return this->inputBuffer_->get(); }
+
+            typedef std::list<std::pair<std::string, LineType> > LineList;
+            LineList::const_iterator getNewestLineIterator() const;
+            LineList::const_iterator getEndIterator() const;
+
+            void addOutput(const std::string& text, LineType type = None);
+            void clearOutput();
+
+            inline unsigned int getNumLines() const
+                { return this->outputLines_.size(); }
+            inline unsigned int getScrollPosition() const
+                { return this->scrollPosition_; }
+
+            inline const std::string& getPromptPrefix() const { return this->promptPrefix_; }
+            void setPromptPrefix(const std::string& str);
+
+        private:
+            Shell(const Shell& other);
+
+            void addToHistory(const std::string& command);
+            const std::string& getFromHistory() const;
+            void clearInput();
+            // OutputListener
+            void outputChanged(int level);
+
+            void configureInputBuffer();
+
+            // InputBuffer callbacks
+            void inputChanged();
+            void execute();
+            void hintAndComplete();
+            void backspace();
+            void deleteChar();
+            void cursorRight();
+            void cursorLeft();
+            void cursorEnd();
+            void cursorHome();
+            void historyUp();
+            void historyDown();
+            void historySearchUp();
+            void historySearchDown();
+            void scrollUp();
+            void scrollDown();
+            void exit();
+
+            template <void (ShellListener::*F)()>
+            void updateListeners()
+            {
+                for (std::list<ShellListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); )
+                    ((*(it++))->*F)();
+            }
+
+            std::list<ShellListener*> listeners_;
+            InputBuffer*              inputBuffer_;
+            std::stringstream         outputBuffer_;
+            bool                      bFinishedLastLine_;
+            LineList                  outputLines_;
+            LineList::const_iterator  scrollIterator_;
+            unsigned int              scrollPosition_;
+            unsigned int              historyPosition_;
+
+            std::string               promptPrefix_;
+            const std::string         consoleName_;
+            const bool                bScrollable_;
+
+            // Config values
+            unsigned int              maxHistoryLength_;
+            unsigned int              historyOffset_;
+            std::vector<std::string>  commandHistory_;
+            int                       softDebugLevel_;
+    };
+}
+
+#endif /* _Shell_H__ */
Index: /code/branches/rocket2/src/libraries/core/SmartPtr.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/SmartPtr.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/SmartPtr.h	(revision 6952)
@@ -0,0 +1,200 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+// Inspired by boost::intrusive_ptr by Peter Dimov
+
+#ifndef _SmartPtr_H__
+#define _SmartPtr_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+
+#include "OrxonoxClass.h"
+#include "WeakPtr.h"
+
+namespace orxonox
+{
+    template <class T>
+    class SmartPtr
+    {
+        public:
+            inline SmartPtr() : pointer_(0), base_(0)
+            {
+            }
+
+            inline SmartPtr(int) : pointer_(0), base_(0)
+            {
+            }
+
+            inline SmartPtr(T* pointer, bool bAddRef = true) : pointer_(pointer), base_(pointer)
+            {
+                if (this->base_ && bAddRef)
+                    this->base_->incrementReferenceCount();
+            }
+
+            inline SmartPtr(const SmartPtr& other) : pointer_(other.pointer_), base_(other.base_)
+            {
+                if (this->base_)
+                    this->base_->incrementReferenceCount();
+            }
+
+            template <class O>
+            inline SmartPtr(const SmartPtr<O>& other) : pointer_(other.get()), base_(other.base_)
+            {
+                if (this->base_)
+                    this->base_->incrementReferenceCount();
+            }
+
+            template <class O>
+            inline SmartPtr(const WeakPtr<O>& other) : pointer_(other.get()), base_(other.getBase())
+            {
+                if (this->base_)
+                    this->base_->incrementReferenceCount();
+            }
+
+            inline ~SmartPtr()
+            {
+                if (this->base_)
+                    this->base_->decrementReferenceCount();
+            }
+
+            inline const SmartPtr& operator=(int)
+            {
+                SmartPtr(0).swap(*this);
+                return *this;
+            }
+
+            inline const SmartPtr& operator=(T* pointer)
+            {
+                SmartPtr(pointer).swap(*this);
+                return *this;
+            }
+
+            inline const SmartPtr& operator=(const SmartPtr& other)
+            {
+                SmartPtr(other).swap(*this);
+                return *this;
+            }
+
+            template <class O>
+            inline const SmartPtr& operator=(const SmartPtr<O>& other)
+            {
+                SmartPtr(other).swap(*this);
+                return *this;
+            }
+
+            template <class O>
+            inline const SmartPtr& operator=(const WeakPtr<O>& other)
+            {
+                SmartPtr(other).swap(*this);
+                return *this;
+            }
+
+            inline T* get() const
+            {
+                return this->pointer_;
+            }
+
+            inline OrxonoxClass* getBase() const
+            {
+                return this->base_;
+            }
+
+            inline operator T*() const
+            {
+                return this->pointer_;
+            }
+
+            inline T* operator->() const
+            {
+                assert(this->pointer_ != 0);
+                return this->pointer_;
+            }
+
+            inline T& operator*() const
+            {
+                assert(this->pointer_ != 0);
+                return *this->pointer_;
+            }
+
+            inline bool operator!() const
+            {
+                return (this->pointer_ == 0);
+            }
+
+            inline void swap(SmartPtr& other)
+            {
+                {
+                    T* temp = this->pointer_;
+                    this->pointer_ = other.pointer_;
+                    other.pointer_ = temp;
+                }
+                {
+                    OrxonoxClass* temp = this->base_;
+                    this->base_ = other.base_;
+                    other.base_ = temp;
+                }
+            }
+
+            inline void reset()
+            {
+                SmartPtr().swap(*this);
+            }
+
+        private:
+            T* pointer_;
+            OrxonoxClass* base_;
+    };
+
+    template <class T>
+    void swap(SmartPtr<T>& a, SmartPtr<T>& b)
+    {
+        a.swap(b);
+    }
+
+    template <class T, class U>
+    SmartPtr<T> static_pointer_cast(const SmartPtr<U>& p)
+    {
+        return static_cast<T*>(p.get());
+    }
+
+    template <class T, class U>
+    SmartPtr<T> const_pointer_cast(const SmartPtr<U>& p)
+    {
+        return const_cast<T*>(p.get());
+    }
+
+    template <class T, class U>
+    SmartPtr<T> dynamic_pointer_cast(const SmartPtr<U>& p)
+    {
+        return dynamic_cast<T*>(p.get());
+    }
+}
+
+#endif /* _SmartPtr_H__ */
Index: /code/branches/rocket2/src/libraries/core/SubclassIdentifier.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/SubclassIdentifier.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/SubclassIdentifier.h	(revision 6952)
@@ -0,0 +1,192 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of SubclassIdentifier.
+
+    SubclassIdentifier is a separated class, acting like an Identifier, but has a given class.
+    You can only assign Identifiers of exactly the given class or of a derivative to a SubclassIdentifier.
+*/
+
+#ifndef _SubclassIdentifier_H__
+#define _SubclassIdentifier_H__
+
+#include "CorePrereqs.h"
+
+#include <cstdlib>
+#include "util/Debug.h"
+#include "Identifier.h"
+
+namespace orxonox
+{
+    // ###############################
+    // ###   SubclassIdentifier    ###
+    // ###############################
+    //! The SubclassIdentifier acts almost like an Identifier, but has some prerequisites.
+    /**
+        You can only assign an Identifier that belongs to a class T (or derived) to a SubclassIdentifier<T>.
+        If you assign something else, the program aborts.
+        Because we know the minimum type, a dynamic_cast is done, which makes it easier to create a new object.
+    */
+    template <class T>
+    class SubclassIdentifier
+    {
+        public:
+            /**
+                @brief Constructor: Automaticaly assigns the Identifier of the given class.
+            */
+            SubclassIdentifier()
+            {
+                this->identifier_ = ClassIdentifier<T>::getIdentifier();
+            }
+
+            /**
+                @brief Constructor: Assigns the given Identifier.
+                @param identifier The Identifier
+            */
+            SubclassIdentifier(Identifier* identifier)
+            {
+                this->operator=(identifier);
+            }
+
+            /**
+                @brief Copyconstructor: Assigns the identifier of the other SubclassIdentifier.
+                @param identifier The other SublcassIdentifier
+            */
+            template <class O>
+            SubclassIdentifier(const SubclassIdentifier<O>& identifier)
+            {
+                this->operator=(identifier.getIdentifier());
+            }
+
+            /**
+                @brief Overloading of the = operator: assigns the identifier and checks its type.
+                @param identifier The Identifier to assign
+                @return The SubclassIdentifier itself
+            */
+            const SubclassIdentifier<T>& operator=(Identifier* identifier)
+            {
+                if (!identifier || !identifier->isA(ClassIdentifier<T>::getIdentifier()))
+                {
+                    COUT(1) << "An error occurred in SubclassIdentifier (Identifier.h):" << std::endl;
+                    if (identifier)
+                    {
+                        COUT(1) << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<T>::getIdentifier()->getName() << '!' << std::endl;
+                        COUT(1) << "Error: SubclassIdentifier<" << ClassIdentifier<T>::getIdentifier()->getName() << "> = Class(" << identifier->getName() << ") is forbidden." << std::endl;
+                    }
+                    else
+                    {
+                        COUT(1) << "Error: Can't assign NULL identifier" << std::endl;
+                    }
+                }
+                else
+                {
+                    this->identifier_ = identifier;
+                }
+                return *this;
+            }
+
+            /**
+                @brief Overloading of the = operator: assigns the identifier of the other SubclassIdentifier.
+                @param identifier The other SublcassIdentifier
+            */
+            template <class O>
+            const SubclassIdentifier<T>& operator=(const SubclassIdentifier<O>& identifier)
+            {
+                return this->operator=(identifier.getIdentifier());
+            }
+
+            /**
+                @brief Overloading of the * operator: returns the assigned identifier.
+            */
+            inline Identifier* operator*() const
+            {
+                return this->identifier_;
+            }
+
+            /**
+                @brief Overloading of the -> operator: returns the assigned identifier.
+            */
+            inline Identifier* operator->() const
+            {
+                return this->identifier_;
+            }
+
+            /**
+                @brief Returns the assigned identifier. This allows you to assign a SubclassIdentifier to a normal Identifier*.
+            */
+            inline operator Identifier*() const
+            {
+                return this->identifier_;
+            }
+
+            /**
+                @brief Creates a new object of the type of the assigned Identifier and dynamic_casts it to the minimal type given by T.
+                @return The new object
+            */
+            T* fabricate(BaseObject* creator) const
+            {
+                BaseObject* newObject = this->identifier_->fabricate(creator);
+
+                // Check if the creation was successful
+                if (newObject)
+                {
+                    return orxonox_cast<T*>(newObject);
+                }
+                else
+                {
+                    // Something went terribly wrong
+                    if (this->identifier_)
+                    {
+                        COUT(1) << "An error occurred in SubclassIdentifier (Identifier.h):" << std::endl;
+                        COUT(1) << "Error: Class " << this->identifier_->getName() << " is not a " << ClassIdentifier<T>::getIdentifier()->getName() << '!' << std::endl;
+                        COUT(1) << "Error: Couldn't fabricate a new Object." << std::endl;
+                    }
+                    else
+                    {
+                        COUT(1) << "An error occurred in SubclassIdentifier (Identifier.h):" << std::endl;
+                        COUT(1) << "Error: Couldn't fabricate a new Object - Identifier is undefined." << std::endl;
+                    }
+
+                    COUT(1) << "Aborting..." << std::endl;
+                    abort();
+                    return 0;
+                }
+            }
+
+            /** @brief Returns the assigned identifier. @return The identifier */
+            inline Identifier* getIdentifier() const
+                { return this->identifier_; }
+
+        private:
+            Identifier* identifier_;            //!< The assigned identifier
+    };
+}
+
+#endif /* _SubclassIdentifier_H__ */
Index: /code/branches/rocket2/src/libraries/core/Super.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Super.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Super.h	(revision 6952)
@@ -0,0 +1,611 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of all super-function related macros.
+
+    This file defines all macros needed to add a new "super-function".
+    If you add a super-function, you can call SUPER(myclass, functionname) inside your
+    code and the function of the parentclass gets called. This is comparable with
+    super.functionname() in Java or other languages.
+
+    This works only with virtual functions that return nothing (void) and belong to
+    classes that have an Identifier. Arguments however are supported.
+
+    To add a new super-function, you have process 4 steps:
+
+    1) Add a new SUPER macro
+       This allows you to call the super-function in your code.
+       Location: This file (Super.h), marked with --> HERE <-- comments (1/3)
+
+    2) Call the SUPER_FUNCTION_GLOBAL_DECLARATION_PART1/2 macros.
+       This defines some global classes and templates, needed to create and call the super-functions.
+       Location: This file (Super.h), marked with --> HERE <-- comments (2/3)
+
+    3) Call the SUPER_INTRUSIVE_DECLARATION macro.
+       This will be included into the declaration of ClassIdentifier<T>.
+       Location: This file (Super.h), marked with --> HERE <-- comments (3/3)
+
+    4) Call the SUPER_FUNCTION macro.
+       This defines a partially specialized template that will decide if a class is "super" to another class.
+       If the check returns true, a SuperFunctionCaller gets created, which will be used by the SUPER macro.
+       You have to add this into the header-file of the baseclass of the super-function (the class that first
+       implements the function), below the class declaration. You can't call it directly in this file, because
+       otherwise you had to include the headerfile right here, which would cause some ugly backdependencies,
+       include loops and slower compilation.
+       Dont forget to include Super.h in the header-file.
+       Location: The header-file of the baseclass (Baseclass.h), below the class declaration
+*/
+
+#ifndef _Super_H__
+#define _Super_H__
+
+#include "CorePrereqs.h"
+
+#include "util/Debug.h"
+#include "Event.h"
+
+///////////////////////
+// Macro definitions //
+///////////////////////
+
+//// Common macros ////
+
+    /**
+        @brief Declares a new super-function by creating a specialized template. Add this below the class declaration of the baseclass.
+        @param functionnumber Each super-function needs a unique number, starting with zero, increasing by one
+        @param baseclass The baseclass of the super-function (~the root)
+        @param functionname The name of the super-function
+        @param purevirtualbase "true" if the function is pure virtual in the baseclass, "false" if the function is implemented (without "")
+    */
+    #define SUPER_FUNCTION(functionnumber, baseclass, functionname, purevirtualbase) \
+        template <class T, int templatehack2> \
+        struct SuperFunctionCondition<functionnumber, T, 0, templatehack2> \
+        { \
+            static void check() \
+            { \
+                SuperFunctionCondition<functionnumber, T, 0, templatehack2>::apply(static_cast<T*>(0)); \
+                SuperFunctionCondition<functionnumber + 1, T, 0, templatehack2>::check(); \
+            } \
+            \
+            static void apply(void* temp) {} \
+            \
+            static void apply(baseclass* temp) \
+            { \
+                ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier(); \
+                for (std::set<const Identifier*>::iterator it = identifier->getDirectChildrenIntern().begin(); it != identifier->getDirectChildrenIntern().end(); ++it) \
+                { \
+                    if (((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ && ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_) \
+                    { \
+                        delete ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_; \
+                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = 0; \
+                        ((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ = false; \
+                    } \
+                    \
+                    if (!((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_) \
+                    { \
+                        COUT(5) << "Added SuperFunctionCaller for " << #functionname << ": " << ClassIdentifier<T>::getIdentifier()->getName() << " <- " << ((ClassIdentifier<T>*)(*it))->getName() << std::endl; \
+                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_##functionname <T>; \
+                    } \
+                } \
+            } \
+        }; \
+        \
+        SUPER_FUNCTION_PUREVIRTUAL_WORKAROUND##purevirtualbase(functionnumber, baseclass)
+
+    #define SUPER_FUNCTION_PUREVIRTUAL_WORKAROUND0(functionnumber, baseclass) SUPER_FUNCTION_PUREVIRTUAL_WORKAROUNDfalse(functionnumber, baseclass)
+    #define SUPER_FUNCTION_PUREVIRTUAL_WORKAROUND1(functionnumber, baseclass) SUPER_FUNCTION_PUREVIRTUAL_WORKAROUNDtrue(functionnumber, baseclass)
+    #define SUPER_FUNCTION_PUREVIRTUAL_WORKAROUNDfalse(functionnumber, baseclass)
+    #define SUPER_FUNCTION_PUREVIRTUAL_WORKAROUNDtrue(functionnumber, baseclass) \
+        template <int templatehack2> \
+        struct SuperFunctionCondition<functionnumber, baseclass, 0, templatehack2> \
+        { \
+            static void check() \
+            { \
+                SuperFunctionCondition<functionnumber + 1, baseclass, 0, templatehack2>::check(); \
+            } \
+        };
+
+
+    /*
+    //// Comments about the macro ////
+
+        // Partially specialized template (templatehack is now specialized too).
+        //
+        // This ensures the compiler takes THIS template if the header-file of the super-function
+        // is included. In any other case, the compiler just uses the fallback template which is
+        // defined in this file.
+        template <class T, templatehack2>
+        struct SuperFunctionCondition<functionnumber, T, 0, templatehack2>
+        {
+            static void check()
+            {
+                // This call to the apply-function is the whole check. By calling the function with
+                // a T* pointer, the right function get's called.
+                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();
+            }
+
+            // This function gets called if T is not a child of the baseclass.
+            // The function does nothing.
+            static void apply(void* temp) {}
+
+            // This function gets called if T is a child of the baseclass and can therefore be converted.
+            // The function adds a SuperFunctionCaller to the Identifier of all subclasses of T.
+            static void apply(baseclass* temp)
+            {
+                ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier();
+
+                // Iterate through all children
+                for (std::set<const Identifier*>::iterator it = identifier->getDirectChildrenIntern().begin(); it != identifier->getDirectChildrenIntern().end(); ++it)
+                {
+                    // Check if the caller is a fallback-caller
+                    if (((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ && ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_)
+                    {
+                        // Delete the fallback caller an prepare to get a real caller
+                        delete ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_;
+                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = 0;
+                        ((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ = false;
+                    }
+
+                    // Check if there's not already a caller
+                    if (!((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_)
+                    {
+                        // Add the SuperFunctionCaller
+                        COUT(5) << "adding functionpointer to " << ((ClassIdentifier<T>*)(*it))->getName() << std::endl;
+                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_##functionname <T>;
+                    }
+                }
+            }
+        };
+        SUPER_FUNCTION_PUREVIRTUAL_WORKAROUND##purevirtualbase
+
+
+        // The following piece of code is only added if purevirtualbase = true
+
+        // Explicit specialization of the Condition template for the baseclass to avoid
+        // errors if the function is pure virtual in the baseclass.
+        template <int templatehack2> \
+        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(); \
+            } \
+        };
+    */
+
+    // SUPER-macro: Calls Parent::functionname() where Parent is the direct parent of classname
+    #ifdef ORXONOX_COMPILER_MSVC
+        #define SUPER(classname, functionname, ...) \
+            __super::functionname(__VA_ARGS__)
+    #else
+        #define SUPER(classname, functionname, ...) \
+            SUPER_##functionname(classname, functionname, __VA_ARGS__)
+    #endif
+
+    // helper macro: for functions without arguments
+    #define SUPER_NOARGS(classname, functionname) \
+        (*ClassIdentifier<classname>::getIdentifier()->superFunctionCaller_##functionname##_)(this)
+
+    // helper macro: for functions with arguments
+    #define SUPER_ARGS(classname, functionname, ...) \
+        (*ClassIdentifier<classname>::getIdentifier()->superFunctionCaller_##functionname##_)(this, __VA_ARGS__)
+
+
+//// Function-specific macros ////
+
+    /*
+        Add a macro for each super-function
+
+        Example (no arguments):
+        #define SUPER_myfunction(classname, functionname, ...) \
+            SUPER_NOARGS(classname, functionname)
+
+        Example (with arguments):
+        #define SUPER_myfunction(classname, functionname, ...) \
+            SUPER_ARGS(classname, functionname, __VA_ARGS__)
+    */
+
+    // (1/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
+    #define SUPER_XMLPort(classname, functionname, ...) \
+        SUPER_ARGS(classname, functionname, __VA_ARGS__)
+
+    #define SUPER_tick(classname, functionname, ...) \
+        SUPER_ARGS(classname, functionname, __VA_ARGS__)
+
+    #define SUPER_changedActivity(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_changedVisibility(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_XMLEventPort(classname, functionname, ...) \
+        SUPER_ARGS(classname, functionname, __VA_ARGS__)
+
+    #define SUPER_changedScale(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_changedOwner(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_changedOverlayGroup(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_changedName(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+
+    #define SUPER_changedGametype(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+        
+    #define SUPER_changedUsed(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+        
+    #define SUPER_clone(classname, functionname, ...) \
+        SUPER_ARGS(classname, functionname, __VA_ARGS__)
+        
+    #define SUPER_changedCarrier(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+        
+    #define SUPER_changedPickedUp(classname, functionname, ...) \
+        SUPER_NOARGS(classname, functionname)
+        
+    // (1/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
+
+
+namespace orxonox
+{
+    /////////////////////////////////////////////////////////////////////////////////////////////////////
+    // This code gets included by Identifier.h and every other header file that needs a super-function //
+    /////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    //// Common code ////
+
+        // Base templates
+        /**
+            @brief Creates the SuperFunctionCaller if T is a child of the super-functions baseclass.
+        */
+        template <int functionnumber, class T, int templatehack1, int templatehack2>
+        struct SuperFunctionCondition
+        {
+            static void check() {}
+        };
+
+        /**
+            @brief Initializes the SuperFunctionCaller-pointer with zero.
+        */
+        template <int functionnumber, class T>
+        struct SuperFunctionInitialization
+        {
+            static void initialize(ClassIdentifier<T>* identifier) {}
+        };
+
+        /**
+            @brief Deletes the SuperFunctionCaller.
+        */
+        template <int functionnumber, class T>
+        struct SuperFunctionDestruction
+        {
+            static void destroy(ClassIdentifier<T>* identifier) {}
+        };
+
+
+    //// Function-specific code ////
+
+        /**
+            @brief Creates the needed objects and templates to call a super-function.
+            @param functionnumber Each super-function needs a unique number, starting with zero, increasing by one
+            @param functionname The name of the super-function
+            @param hasarguments "false" if the function doesn't take any arguments, "true" if it does (without "")
+            @param ... Variadic: If the function takes arguments, add them here with type and name. Example: int myvalue, float myothervalue
+        */
+        #define SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(functionnumber, functionname, hasarguments, ...) \
+            template <class T, int templatehack1, int templatehack2> \
+            struct SuperFunctionCondition<functionnumber, T, templatehack1, templatehack2> \
+            { \
+                static void check() \
+                { \
+                    SuperFunctionCondition<functionnumber + 1, T, templatehack1, templatehack2>::check(); \
+                } \
+            }; \
+            \
+            class _CoreExport SuperFunctionCaller_##functionname \
+            { \
+                public: \
+                    virtual void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) = 0; \
+                    virtual ~SuperFunctionCaller_##functionname () {} \
+            }; \
+            \
+            template <class T> \
+            class SuperFunctionClassCaller_purevirtualfallback_##functionname : public SuperFunctionCaller_##functionname \
+            { \
+                public: \
+                    inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) \
+                    { \
+                    } \
+            }; \
+            \
+            template <class T> \
+            struct SuperFunctionInitialization<functionnumber, T> \
+            { \
+                static void initialize(ClassIdentifier<T>* identifier) \
+                { \
+                    identifier->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_purevirtualfallback_##functionname <T>; \
+                    identifier->bSuperFunctionCaller_##functionname##_isFallback_ = true; \
+                    SuperFunctionInitialization<functionnumber + 1, T>::initialize(identifier); \
+                } \
+            }; \
+            \
+            template <class T> \
+            struct SuperFunctionDestruction<functionnumber, T> \
+            { \
+                static void destroy(ClassIdentifier<T>* identifier) \
+                { \
+                    if (identifier->superFunctionCaller_##functionname##_) \
+                        delete identifier->superFunctionCaller_##functionname##_; \
+                    SuperFunctionDestruction<functionnumber + 1, T>::destroy(identifier); \
+                } \
+            }; \
+            \
+            template <class T> \
+            class SuperFunctionClassCaller_##functionname : public SuperFunctionCaller_##functionname \
+            { \
+                public: \
+                    inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) \
+                    { \
+                        (dynamic_cast<T*>(object))->T:: functionname
+
+        /*
+            JUST ADD THE FUNCTION ARGUMENTS BETWEEN BOTH MACROS, ENCLOSED BY BRACKETS
+            EXAMPLE:
+
+              SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(0, myfunction, true, int myvalue, float myothervalue) <-- !!! DONT ADD A SEMICOLON HERE !!!
+                (myvalue, myothervalue)
+              SUPER_FUNCTION_GLOBAL_DECLARATION_PART2
+        */
+
+        #define SUPER_FUNCTION_GLOBAL_DECLARATION_PART2 \
+                                                        ; \
+                    } \
+            };
+
+        #define SUPER_CALL_ARGUMENTSfalse(...) OrxonoxClass* object
+        #define SUPER_CALL_ARGUMENTS0(...)     OrxonoxClass* object
+        #define SUPER_CALL_ARGUMENTStrue(...) OrxonoxClass* object, __VA_ARGS__
+        #define SUPER_CALL_ARGUMENTS1(...)    OrxonoxClass* object, __VA_ARGS__
+
+
+    /*
+    //// COMMENTS ABOUT THE MACRO ////
+
+        // Partially specialized template (templatehack not yet specialized, this
+        // will be done by the real condition in the header-file of the super-function)
+        // Only used as fallback
+        template <class T, int templatehack1, int templatehack2>
+        struct SuperFunctionCondition<functionnumber, T, templatehack1, templatehack2>
+        {
+            // 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()
+            {
+                // Calls the condition-check of the next super-function (functionnumber + 1)
+                SuperFunctionCondition<functionnumber + 1, T, templatehack1, templatehack2>::check();
+            }
+        };
+
+        // Baseclass of the super-function caller. The real call will be done by a
+        // templatized subclass through the virtual () operator.
+        class _CoreExport SuperFunctionCaller_##functionname
+        {
+            public:
+                virtual void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) = 0;
+                virtual ~SuperFunctionCaller_##functionname () {}
+        };
+
+        // Fallback if the base is pure virtual
+        template <class T>
+        class SuperFunctionClassCaller_purevirtualfallback_##functionname : public SuperFunctionCaller_##functionname
+        {
+            public:
+                // Fallback does nothing
+                inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) )
+                {
+                }
+        };
+
+        // Initializes the SuperFunctionCaller-pointer with a fallback caller in case the base function is pure virtual
+        template <class T>
+        struct SuperFunctionInitialization<functionnumber, T>
+        {
+            static void initialize(ClassIdentifier<T>* identifier)
+            {
+                identifier->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_purevirtualfallback_##functionname <T>;
+                identifier->bSuperFunctionCaller_##functionname##_isFallback_ = true;
+
+                // Calls the initialization of the next super-function (functionnumber + 1)
+                SuperFunctionInitialization<functionnumber + 1, T>::initialize(identifier);
+            }
+        };
+
+        // Deletes the SuperFunctionCaller.
+        template <class T>
+        struct SuperFunctionDestruction<functionnumber, T>
+        {
+            static void destroy(ClassIdentifier<T>* identifier)
+            {
+                if (identifier->superFunctionCaller_##functionname##_)
+                    delete identifier->superFunctionCaller_##functionname##_;
+
+                // Calls the destruction of the next super-function (functionnumber + 1)
+                SuperFunctionDestruction<functionnumber + 1, T>::destroy(identifier);
+            }
+        };
+
+        // The real super-function caller: Calls T::functionname()
+        // T should be the parent, but this will be done by the spezialized condition template
+        template <class T>
+        class SuperFunctionClassCaller_##functionname : public SuperFunctionCaller_##functionname
+        {
+            public:
+                // @brief Calls the function.
+                // @param object The object to call the function on
+                // @param ... The arguments of the function
+                inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) )
+                {
+                    (dynamic_cast<T*>(object))->T:: functionname ( Call the function with it's arguments );
+                }
+        }
+    */
+
+
+    //// Execute the code for each super-function ////
+
+        // (2/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(0, XMLPort, true, Element& xmlelement, XMLPort::Mode mode)
+            (xmlelement, mode)
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(1, tick, true, float dt)
+            (dt)
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(2, changedActivity, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(3, changedVisibility, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(4, XMLEventPort, true, Element& xmlelement, XMLPort::Mode mode)
+            (xmlelement, mode)
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(5, changedScale, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(6, changedOwner, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(7, changedOverlayGroup, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(8, changedName, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(9, changedGametype, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+        
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(10, changedUsed, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(11, clone, true, OrxonoxClass* item)
+            (item)
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+        
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(12, changedCarrier, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+        
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(13, changedPickedUp, false)
+            ()
+        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
+
+        // (2/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
+
+}
+
+#else /* _Super_H__ */
+  #ifdef SUPER_INTRUSIVE_DECLARATION_INCLUDE
+
+//////////////////////////////////////////////////////////////////////////
+// This code gets included within the declaration of ClassIdentifier<T> //
+//////////////////////////////////////////////////////////////////////////
+
+//// Common code ////
+
+    private:
+
+        template <int functionnumber, class TT, int templatehack1, int templatehack2>
+        friend struct SuperFunctionCondition;
+
+        // Creates the super-function-callers by calling the first SuperFunctionCondition check
+        // This get's called within the initialization of an Identifier
+        virtual void createSuperFunctionCaller() const
+        {
+            SuperFunctionCondition<0, T, 0, 0>::check();
+        }
+
+
+//// Function-specific code ////
+
+    public:
+        /**
+            @brief Adds a pointer to the SuperFunctionCaller as a member of ClassIdentifier.
+            @param functionname The name of the super-function
+        */
+        #ifndef SUPER_INTRUSIVE_DECLARATION
+          #define SUPER_INTRUSIVE_DECLARATION(functionname) \
+            SuperFunctionCaller_##functionname * superFunctionCaller_##functionname##_; \
+            bool bSuperFunctionCaller_##functionname##_isFallback_
+        #endif
+
+
+//// Execute the code for each super-function ////
+
+    // (3/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
+    SUPER_INTRUSIVE_DECLARATION(XMLPort);
+    SUPER_INTRUSIVE_DECLARATION(tick);
+    SUPER_INTRUSIVE_DECLARATION(changedActivity);
+    SUPER_INTRUSIVE_DECLARATION(changedVisibility);
+    SUPER_INTRUSIVE_DECLARATION(XMLEventPort);
+    SUPER_INTRUSIVE_DECLARATION(changedScale);
+    SUPER_INTRUSIVE_DECLARATION(changedOwner);
+    SUPER_INTRUSIVE_DECLARATION(changedOverlayGroup);
+    SUPER_INTRUSIVE_DECLARATION(changedName);
+    SUPER_INTRUSIVE_DECLARATION(changedGametype);
+    SUPER_INTRUSIVE_DECLARATION(changedUsed);
+    SUPER_INTRUSIVE_DECLARATION(clone);
+    SUPER_INTRUSIVE_DECLARATION(changedCarrier);
+    SUPER_INTRUSIVE_DECLARATION(changedPickedUp);
+    // (3/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
+
+
+    #undef SUPER_INTRUSIVE_DECLARATION_INCLUDE
+  #endif /* SUPER_INTRUSIVE_DECLARATION_INCLUDE */
+#endif /* _Super_H__ */
Index: /code/branches/rocket2/src/libraries/core/TclBind.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/TclBind.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/TclBind.cc	(revision 6952)
@@ -0,0 +1,203 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "TclBind.h"
+
+#include <exception>
+#include <string>
+#include <cpptcl/cpptcl.h>
+
+#include "SpecialConfig.h"
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/StringUtils.h"
+#include "CommandExecutor.h"
+#include "ConsoleCommand.h"
+#include "PathConfig.h"
+#include "TclThreadManager.h"
+
+namespace orxonox
+{
+    SetConsoleCommandShortcut(TclBind, tcl);
+    SetConsoleCommandShortcut(TclBind, bgerror);
+
+    TclBind* TclBind::singletonPtr_s = 0;
+
+    TclBind::TclBind(const std::string& datapath)
+    {
+        this->interpreter_ = 0;
+        this->bSetTclDataPath_ = false;
+        this->setDataPath(datapath);
+    }
+
+    TclBind::~TclBind()
+    {
+        if (this->interpreter_)
+            delete this->interpreter_;
+    }
+
+    void TclBind::setDataPath(const std::string& datapath)
+    {
+        // String has POSIX slashes
+        this->tclDataPath_ = datapath + "tcl" + '/';
+        this->bSetTclDataPath_ = true;
+
+        this->initializeTclInterpreter();
+    }
+
+    void TclBind::initializeTclInterpreter()
+    {
+        if (this->bSetTclDataPath_ && !this->interpreter_)
+        {
+            this->interpreter_ = this->createTclInterpreter();
+
+            this->interpreter_->def("::orxonox::query", TclBind::tcl_query, Tcl::variadic());
+            this->interpreter_->def("::orxonox::crossquery", TclThreadManager::tcl_crossquery, Tcl::variadic());
+            this->interpreter_->def("execute", TclBind::tcl_execute, Tcl::variadic());
+            this->interpreter_->def("::orxonox::crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
+
+            try
+            {
+                this->interpreter_->eval("proc query        {args}    { ::orxonox::query $args }");
+                this->interpreter_->eval("proc crossquery   {id args} { ::orxonox::crossquery 0 $id $args }");
+                this->interpreter_->eval("proc crossexecute {id args} { ::orxonox::crossquery 0 $id $args }");
+                this->interpreter_->eval("proc running      {}        { return 1 }");
+                this->interpreter_->eval("set id 0");
+                this->interpreter_->eval("rename exit ::tcl::exit; proc exit {} { execute exit }");
+            }
+            catch (Tcl::tcl_error const &e)
+            {   COUT(1) << "Tcl error while creating Tcl-interpreter: " << e.what() << std::endl;   }
+            catch (...)
+            {   COUT(1) << "Error while creating Tcl-interpreter: " << Exception::handleMessage() << std::endl;   }
+        }
+    }
+
+    Tcl::interpreter* TclBind::createTclInterpreter()
+    {
+        Tcl::interpreter* interpreter = new Tcl::interpreter();
+        const std::string& libpath = TclBind::getTclLibraryPath();
+
+        try
+        {
+            if (!libpath.empty())
+                interpreter->eval("set tcl_library \"" + libpath + '"');
+
+            Tcl_Init(interpreter->get());
+
+            interpreter->eval("source \"" + TclBind::getInstance().tclDataPath_ + "/init.tcl\"");
+        }
+        catch (Tcl::tcl_error const &e)
+        {   COUT(1) << "Tcl error while creating Tcl-interpreter: " << e.what() << std::endl; COUT(1) << "Error: Tcl isn't properly initialized. Orxonox might possibly not work like that." << std::endl;   }
+        catch (...)
+        {   COUT(1) << "Error while creating Tcl-interpreter: " << Exception::handleMessage() << std::endl; COUT(1) << "Error: Tcl isn't properly initialized. Orxonox might possibly not work like that." << std::endl;   }
+
+        return interpreter;
+    }
+
+    std::string TclBind::getTclLibraryPath()
+    {
+#ifdef DEPENDENCY_PACKAGE_ENABLE
+        if (PathConfig::isDevelopmentRun())
+            return (std::string(specialConfig::dependencyLibraryDirectory) + "/tcl");
+        else
+            return (PathConfig::getRootPathString() + "lib/tcl");
+#else
+        return "";
+#endif
+    }
+
+    std::string TclBind::tcl_query(Tcl::object const &args)
+    {
+        COUT(4) << "Tcl_query: " << args.get() << std::endl;
+
+        const std::string& command = stripEnclosingBraces(args.get());
+
+        if (!CommandExecutor::execute(command, false))
+        {
+            COUT(1) << "Error: Can't execute command \"" << command << "\"!" << std::endl;
+        }
+
+        if (CommandExecutor::getLastEvaluation().hasReturnvalue())
+            return CommandExecutor::getLastEvaluation().getReturnvalue().getString();
+
+        return "";
+    }
+
+    void TclBind::tcl_execute(Tcl::object const &args)
+    {
+        COUT(4) << "Tcl_execute: " << args.get() << std::endl;
+        const std::string& command = stripEnclosingBraces(args.get());
+
+        if (!CommandExecutor::execute(command, false))
+        {
+            COUT(1) << "Error: Can't execute command \"" << command << "\"!" << std::endl;
+        }
+    }
+
+    std::string TclBind::tcl(const std::string& tclcode)
+    {
+        if (TclBind::getInstance().interpreter_)
+        {
+            try
+            {
+                const std::string& output = TclBind::getInstance().interpreter_->eval("uplevel #0 " + tclcode);
+                if (!output.empty())
+                {
+                    COUT(0) << "tcl> " << output << std::endl;
+                }
+                return output;
+            }
+            catch (Tcl::tcl_error const &e)
+            {   COUT(1) << "tcl> Error: " << e.what() << std::endl;   }
+            catch (...)
+            {   COUT(1) << "Error while executing Tcl: " << Exception::handleMessage() << std::endl;   }
+        }
+
+        return "";
+    }
+
+    void TclBind::bgerror(const std::string& error)
+    {
+        COUT(1) << "Tcl background error: " << stripEnclosingBraces(error) << std::endl;
+    }
+
+    bool TclBind::eval(const std::string& tclcode)
+    {
+        try
+        {
+            TclBind::getInstance().interpreter_->eval(tclcode);
+            return true;
+        }
+        catch (Tcl::tcl_error const &e)
+        {   COUT(1) << "Tcl error: " << e.what() << std::endl;   }
+        catch (...)
+        {   COUT(1) << "Error while executing Tcl: " << Exception::handleMessage() << std::endl;   }
+
+        return false;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/TclBind.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/TclBind.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/TclBind.h	(revision 6952)
@@ -0,0 +1,74 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TclBind_H__
+#define _TclBind_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include <string>
+#include "util/Singleton.h"
+
+namespace orxonox
+{
+    class _CoreExport TclBind : public Singleton<TclBind>
+    {
+        friend class Singleton<TclBind>;
+        public:
+            TclBind(const std::string& datapath);
+            ~TclBind();
+
+            static std::string tcl(const std::string& tclcode);
+            static void bgerror(const std::string& error);
+
+            void setDataPath(const std::string& datapath);
+            const std::string& getTclDataPath() const { return this->tclDataPath_; }
+            static std::string getTclLibraryPath();
+
+            void initializeTclInterpreter();
+            static Tcl::interpreter* createTclInterpreter();
+            Tcl::interpreter* getTclInterpreter() const { return this->interpreter_; }
+
+            static std::string tcl_query(Tcl::object const &args);
+            static void tcl_execute(Tcl::object const &args);
+
+            static bool eval(const std::string& tclcode);
+
+        private:
+            TclBind(const TclBind& other);
+
+            Tcl::interpreter* interpreter_;
+            std::string tclDataPath_;
+            bool bSetTclDataPath_;
+
+            static TclBind* singletonPtr_s;
+    };
+}
+
+#endif /* _TclBind_H__ */
Index: /code/branches/rocket2/src/libraries/core/TclThreadList.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/TclThreadList.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/TclThreadList.h	(revision 6952)
@@ -0,0 +1,263 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TclThreadList_H__
+#define _TclThreadList_H__
+
+#include "CorePrereqs.h"
+
+#include <list>
+
+#include <boost/thread/condition_variable.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <boost/thread/locks.hpp>
+
+namespace orxonox
+{
+    template <class T>
+    class TclThreadList
+    {
+        public:
+            void push_front(const T& value);
+            void push_back(const T& value);
+            template <class InputIterator> void insert(typename std::list<T>::iterator position, InputIterator begin, InputIterator end);
+
+            void wait_and_pop_front(T* value);
+            void wait_and_pop_back(T* value);
+            bool try_pop_front(T* value);
+            bool try_pop_back(T* value);
+            void clear();
+
+            size_t size() const;
+            bool empty() const;
+            bool is_in(const T& value) const;
+
+            /**
+                @brief Returns a reference to the list. Don't forget to lock the mutex (see @ref getMutex).
+            */
+            inline std::list<T>& getList()
+                { return this->list_; }
+
+            /**
+                @brief Returns a reference to the list. Don't forget to lock the mutex (see @ref getMutex).
+            */
+            inline const std::list<T>& getList() const
+                { return this->list_; }
+
+            /**
+                @brief Returns a reference to the mutex which might be useful if you want to iterate through the list (see @ref begin and @ref end).
+            */
+            inline boost::shared_mutex& getMutex() const
+                { return this->mutex_; }
+
+        private:
+            std::list<T>                  list_;        ///< A standard list for type T
+            mutable boost::shared_mutex   mutex_;       ///< A mutex to grant exclusive access to the list
+            boost::condition_variable_any condition_;   ///< A condition variable to wake threads waiting for the mutex to become ready
+    };
+
+    /**
+        @brief Pushes a new element to the front of the list. A unique_lock is needed.
+    */
+    template <class T>
+    void TclThreadList<T>::push_front(const T& value)
+    {
+        boost::unique_lock<boost::shared_mutex> lock(this->mutex_);
+        this->list_.push_front(value);
+        lock.unlock();                  // unlock the mutex...
+        this->condition_.notify_all();  // ...then call notify_all to wake threads waiting in wait_and_pop_front/back
+    }
+
+    /**
+        @brief Pushes a new element to the back of the list. A unique_lock is needed.
+    */
+    template <class T>
+    void TclThreadList<T>::push_back(const T& value)
+    {
+        boost::unique_lock<boost::shared_mutex> lock(this->mutex_);
+        this->list_.push_back(value);
+        lock.unlock();                  // unlock the mutex...
+        this->condition_.notify_all();  // ...then call notify_all to wake threads waiting in wait_and_pop_front/back
+    }
+
+    /**
+        @brief Inserts new elements into the list. A unique_lock is needed.
+    */
+    template <class T>
+    template <class InputIterator> void TclThreadList<T>::insert(typename std::list<T>::iterator position, InputIterator begin, InputIterator end)
+    {
+        boost::unique_lock<boost::shared_mutex> lock(this->mutex_);
+        this->list_.insert(position, begin, end);
+        lock.unlock();                  // unlock the mutex...
+        this->condition_.notify_all();  // ...then call notify_all to wake threads waiting in wait_and_pop_front/back
+    }
+
+    /**
+        @brief Waits until the list contains at least one element and then pops and returns the front element.
+        @param value The front value will be stored in the variable referenced by this pointer.
+    */
+    template <class T>
+    void TclThreadList<T>::wait_and_pop_front(T* value)
+    {
+        boost::unique_lock<boost::shared_mutex> lock(this->mutex_);
+
+        while (this->list_.empty())       // check if there's an element in the list
+            this->condition_.wait(lock);  // wait until the condition becomes true (a notification comes from push_front, push_back or insert
+
+        *value = this->list_.front();
+        this->list_.pop_front();
+    }
+
+    /**
+        @brief Waits until the list contains at least one element and then pops and returns the back element.
+        @param value The back value will be stored in the variable referenced by this pointer.
+    */
+    template <class T>
+    void TclThreadList<T>::wait_and_pop_back(T* value)
+    {
+        boost::unique_lock<boost::shared_mutex> lock(this->mutex_);
+
+        while (this->list_.empty())       // check if there's an element in the list
+            this->condition_.wait(lock);  // wait until the condition becomes true (a notification comes from push_front, push_back or insert
+
+        *value = this->list_.back();
+        this->list_.pop_back();
+    }
+
+    /**
+        @brief Pops and returns the front element if there's at least one element in the list.
+        @param value The front value will be stored in the variable referenced by this pointer.
+        @return Returns true if there was at least one element in the list (which got poped). If the list was empty, false is returned immediately.
+
+        Needs a unique_lock if there's an element to pop. If not, shared_lock is sufficient.
+    */
+    template <class T>
+    bool TclThreadList<T>::try_pop_front(T* value)
+    {
+        boost::upgrade_lock<boost::shared_mutex> lock(this->mutex_); // gain shared lock
+
+        if (this->list_.empty())
+        {
+            // No elements - return immediately
+            return false;
+        }
+        else
+        {
+            // At least one element - write it into the passed variable and pop it from the list
+            boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(lock); // upgrade to unique lock to modify the list
+            *value = this->list_.front();
+            this->list_.pop_front();
+        }
+        return true;
+    }
+
+    /**
+        @brief Pops and returns the back element if there's at least one element in the list.
+        @param value The back value will be stored in the variable referenced by this pointer.
+        @return Returns true if there was at least one element in the list (which got poped). If the list was empty, false is returned immediately.
+
+        Needs a unique_lock if there's an element to pop. If not, shared_lock is sufficient.
+    */
+    template <class T>
+    bool TclThreadList<T>::try_pop_back(T* value)
+    {
+        boost::upgrade_lock<boost::shared_mutex> lock(this->mutex_); // gain shared lock
+
+        if (this->list_.empty())
+        {
+            // No elements - return immediately
+            return false;
+        }
+        else
+        {
+            // At least one element - write it into the passed variable and pop it from the list
+            boost::upgrade_to_unique_lock<boost::shared_mutex> unique_lock(lock); // upgrade to unique lock to modify the list
+            *value = this->list_.back();
+            this->list_.pop_back();
+        }
+        return true;
+    }
+
+    /**
+        @brief Clears the list. A unique_lock is needed.
+    */
+    template <class T>
+    void TclThreadList<T>::clear()
+    {
+        boost::unique_lock<boost::shared_mutex> lock(this->mutex_);
+        this->list_.clear();
+    }
+
+    /**
+        @brief Returns the size of the list. A shared_lock is needed.
+
+        Warning: Don't change the list based on the result of size(). Use an atomic function instead. Other threads may change the list
+        beween your call to size() and your further actions, so be careful and use this function only if you really want nothing else than
+        just the size of the list.
+    */
+    template <class T>
+    size_t TclThreadList<T>::size() const
+    {
+        boost::shared_lock<boost::shared_mutex> lock(this->mutex_);
+        return this->list_.size();
+    }
+
+    /**
+        @brief Returns true if the list is empty, false otherwise. A shared_lock is needed.
+
+        Warning: Don't change the list based on the result of empty(). Use an atomic function instead. Other threads may change the list
+        beween your call to empty() and your further actions, so be careful and use this function only if you really want nothing else than
+        just if the list is empty or not.
+    */
+    template <class T>
+    bool TclThreadList<T>::empty() const
+    {
+        boost::shared_lock<boost::shared_mutex> lock(this->mutex_);
+        return this->list_.empty();
+    }
+
+    /**
+        @brief Returns true if a given element is in the list, false otherwise. A shared_lock is needed.
+
+        Warning: The result of this function might be wrong just one instruction after the call. Use this function just to get information
+        about a temporary snapshot and don't change the list based on the result of this function.
+    */
+    template <class T>
+    bool TclThreadList<T>::is_in(const T& value) const
+    {
+        boost::shared_lock<boost::shared_mutex> lock(this->mutex_);
+
+        for (typename std::list<T>::const_iterator it = this->list_.begin(); it != this->list_.end(); ++it)
+            if (*it == value)
+                return true;
+
+        return false;
+    }
+}
+
+#endif /* _TclThreadList_H__ */
Index: /code/branches/rocket2/src/libraries/core/TclThreadManager.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/TclThreadManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/TclThreadManager.cc	(revision 6952)
@@ -0,0 +1,672 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "TclThreadManager.h"
+
+#include <boost/bind.hpp>
+#include <boost/thread/thread.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <OgreTimer.h>
+#include <cpptcl/cpptcl.h>
+
+#include "util/Clock.h"
+#include "util/Convert.h"
+#include "util/Exception.h"
+#include "util/StringUtils.h"
+#include "CommandExecutor.h"
+#include "ConsoleCommand.h"
+#include "CoreIncludes.h"
+#include "TclBind.h"
+#include "TclThreadList.h"
+
+namespace orxonox
+{
+    const float TCLTHREADMANAGER_MAX_CPU_USAGE = 0.50f;
+
+    SetConsoleCommandShortcutAlias(TclThreadManager, execute, "tclexecute").argumentCompleter(0, autocompletion::tclthreads());
+    SetConsoleCommandShortcutAlias(TclThreadManager, query,   "tclquery"  ).argumentCompleter(0, autocompletion::tclthreads());
+    SetConsoleCommand(TclThreadManager, create,  false);
+    SetConsoleCommand(TclThreadManager, destroy, false).argumentCompleter(0, autocompletion::tclthreads());
+    SetConsoleCommand(TclThreadManager, execute, false).argumentCompleter(0, autocompletion::tclthreads());
+    SetConsoleCommand(TclThreadManager, query,   false).argumentCompleter(0, autocompletion::tclthreads());
+    SetConsoleCommand(TclThreadManager, source,  false).argumentCompleter(0, autocompletion::tclthreads());
+
+    /**
+        @brief A struct containing all information about a Tcl-interpreter
+    */
+    struct TclInterpreterBundle
+    {
+        TclInterpreterBundle()
+        {
+            this->lock_ = new boost::unique_lock<boost::mutex>(this->mutex_, boost::defer_lock);
+            this->bRunning_ = true;
+        }
+
+        ~TclInterpreterBundle()
+        {
+            delete this->lock_;
+        }
+
+        unsigned int                      id_;             ///< The id of the interpreter
+        Tcl::interpreter*                 interpreter_;    ///< The Tcl-interpreter
+        boost::mutex                      mutex_;          ///< A mutex to lock the interpreter while it's being used
+        boost::unique_lock<boost::mutex>* lock_;           ///< The corresponding lock for the mutex
+        TclThreadList<std::string>        queue_;          ///< The command queue for commands passed by execute(command)
+        TclThreadList<unsigned int>       queriers_;       ///< A list containing the id's of all other threads sending a query to this interpreter (to avoid circular queries and deadlocks)
+        bool                              bRunning_;       ///< This variable stays true until destroy() gets called
+    };
+
+    TclThreadManager* TclThreadManager::singletonPtr_s = 0;
+
+    /**
+        @brief Constructor
+        @param interpreter A pointer to the standard Tcl-interpreter (see @ref TclBind)
+    */
+    TclThreadManager::TclThreadManager(Tcl::interpreter* interpreter)
+    {
+        RegisterRootObject(TclThreadManager);
+
+        this->numInterpreterBundles_ = 0;
+
+        this->interpreterBundlesMutex_ = new boost::shared_mutex();
+        this->mainInterpreterMutex_ = new boost::mutex();
+        this->messageQueue_ = new TclThreadList<std::string>();
+
+        TclInterpreterBundle* newbundle = new TclInterpreterBundle();
+        newbundle->id_ = 0;
+        newbundle->interpreter_ = interpreter;
+        newbundle->lock_->lock();
+
+        {
+            boost::unique_lock<boost::shared_mutex> lock(*this->interpreterBundlesMutex_);
+            this->interpreterBundles_[0] = newbundle;
+        }
+    }
+
+    /**
+        @brief Destructor
+    */
+    TclThreadManager::~TclThreadManager()
+    {
+        delete this->interpreterBundlesMutex_;
+//        delete this->mainInterpreterMutex_; // <-- temporary disabled to avoid crash if a thread is still actively queriyng
+        delete this->messageQueue_;
+    }
+
+    /**
+        @brief The "main loop" of the TclThreadManager. Creates new threads if needed and handles queries and queued commands for the main interpreter.
+    */
+    void TclThreadManager::preUpdate(const Clock& time)
+    {
+        // Get the bundle of the main interpreter (0)
+        TclInterpreterBundle* bundle = this->getInterpreterBundle(0);
+        if (bundle)
+        {
+            // Unlock the mutex to allow other threads accessing the main interpreter
+            bundle->lock_->unlock();
+
+            // Lock the main interpreter mutex once to synchronize with threads that want to query the main interpreter
+            {
+                boost::unique_lock<boost::mutex> lock(*this->mainInterpreterMutex_);
+            }
+
+            // Lock the mutex again to gain exclusive access to the interpreter for the rest of the mainloop
+            bundle->lock_->lock();
+
+            // Execute commands in the queues of the threaded interpreters
+            {
+                boost::shared_lock<boost::shared_mutex> lock(*this->interpreterBundlesMutex_);
+                for (std::map<unsigned int, TclInterpreterBundle*>::const_iterator it = this->interpreterBundles_.begin(); it != this->interpreterBundles_.end(); ++it)
+                {
+                    if (it->first == 0)
+                        continue; // We'll handle the default interpreter later (and without threads of course)
+
+                    TclInterpreterBundle* bundle = it->second;
+                    if (!bundle->queue_.empty())
+                    {
+                        // There are commands in the queue
+                        try
+                        {
+                            if (!bundle->lock_->owns_lock() && bundle->lock_->try_lock())
+                            {
+                                // We sucessfully obtained a lock for the interpreter
+                                std::string command;
+                                if (bundle->queue_.try_pop_front(&command))
+                                {
+                                    // Start a thread to execute the command
+                                    boost::thread(boost::bind(&tclThread, bundle, command));
+                                }
+                                else
+                                {
+                                    // Somehow the queue become empty (maybe multiple consumers) - unlock the mutex
+                                    bundle->lock_->unlock();
+                                }
+                            }
+                        }
+                        catch (...)
+                        {
+                            // A lock error occurred - this is possible if the lock gets locked between !bundle->lock_->owns_lock() and bundle->lock_->try_lock()
+                            // This isn't too bad, just continue
+                        }
+                    }
+                }
+            }
+
+            // Execute commands in the message queue
+            if (!this->messageQueue_->empty())
+            {
+                std::string command;
+                while (true)
+                {
+                    // Pop the front value from the list (break the loop if there are no elements in the list)
+                    if (!this->messageQueue_->try_pop_front(&command))
+                        break;
+
+                    // Execute the command
+                    CommandExecutor::execute(command, false);
+                }
+            }
+
+            // Execute commands in the queue of the main interpreter
+            if (!bundle->queue_.empty())
+            {
+                // Calculate the time we have until we reach the maximal cpu usage
+                unsigned long maxtime = (unsigned long)(time.getDeltaTime() * 1000000 * TCLTHREADMANAGER_MAX_CPU_USAGE);
+
+                Ogre::Timer timer;
+                std::string command;
+
+                while (timer.getMicroseconds() < maxtime)
+                {
+                    // Pop the front value from the list (break the loop if there are no elements in the list)
+                    if (!bundle->queue_.try_pop_front(&command))
+                        break;
+
+                    // Execute the command
+                    CommandExecutor::execute(command, false);
+                }
+            }
+        }
+    }
+
+    /**
+        @brief Creates a new Tcl-interpreter.
+    */
+    unsigned int TclThreadManager::create()
+    {
+        TclThreadManager::getInstance().numInterpreterBundles_++;
+        TclThreadManager::createWithId(TclThreadManager::getInstance().numInterpreterBundles_);
+        COUT(0) << "Created new Tcl-interpreter with ID " << TclThreadManager::getInstance().numInterpreterBundles_ << std::endl;
+        return TclThreadManager::getInstance().numInterpreterBundles_;
+    }
+
+    /**
+        @brief Creates a new Tcl-interpreter with a given id.
+
+        Use with caution - if the id collides with an already existing interpreter, this call will fail.
+        This will also be a problem, if the auto-numbered interpreters (by using create()) reach an id
+        which was previously used in this function. Use high numbers to be safe.
+    */
+    Tcl::interpreter* TclThreadManager::createWithId(unsigned int id)
+    {
+        TclInterpreterBundle* newbundle = new TclInterpreterBundle();
+        newbundle->id_ = id;
+        newbundle->interpreter_ = TclBind::createTclInterpreter();
+
+        TclThreadManager::initialize(newbundle);
+
+        {
+            // Add the new bundle to the map
+            boost::unique_lock<boost::shared_mutex> lock(*TclThreadManager::getInstance().interpreterBundlesMutex_);
+            TclThreadManager::getInstance().interpreterBundles_[id] = newbundle;
+        }
+
+        return newbundle->interpreter_;
+    }
+
+    void TclThreadManager::initialize(TclInterpreterBundle* bundle)
+    {
+        const std::string& id_string = getConvertedValue<unsigned int, std::string>(bundle->id_);
+
+        // Initialize the new interpreter
+        try
+        {
+            // Define the functions which are implemented in C++
+            bundle->interpreter_->def("::orxonox::execute",      TclThreadManager::tcl_execute,      Tcl::variadic());
+            bundle->interpreter_->def("::orxonox::crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
+            bundle->interpreter_->def("::orxonox::query",        TclThreadManager::tcl_query,        Tcl::variadic());
+            bundle->interpreter_->def("::orxonox::crossquery",   TclThreadManager::tcl_crossquery,   Tcl::variadic());
+            bundle->interpreter_->def("::orxonox::running",      TclThreadManager::tcl_running);
+
+            // Create threadspecific shortcuts for the functions above
+            bundle->interpreter_->def("execute",      TclThreadManager::tcl_execute,      Tcl::variadic());
+            bundle->interpreter_->def("crossexecute", TclThreadManager::tcl_crossexecute, Tcl::variadic());
+            bundle->interpreter_->eval("proc query      {args}    { ::orxonox::query " + id_string + " $args }");
+            bundle->interpreter_->eval("proc crossquery {id args} { ::orxonox::crossquery " + id_string + " $id $args }");
+            bundle->interpreter_->eval("proc running    {}        { return [::orxonox::running " + id_string + "] }");
+
+            // Define a variable containing the thread id
+            bundle->interpreter_->eval("set id " + id_string);
+
+            // Use our own exit function to avoid shutting down the whole program instead of just the interpreter
+            bundle->interpreter_->eval("rename exit ::tcl::exit");
+            bundle->interpreter_->eval("proc exit {} { execute TclThreadManager destroy " + id_string + " }");
+
+            // Redefine some native functions
+            bundle->interpreter_->eval("rename while ::tcl::while");
+            bundle->interpreter_->eval("rename ::orxonox::while while");
+            bundle->interpreter_->eval("rename for ::tcl::for");
+            bundle->interpreter_->eval("rename ::orxonox::for for");
+        }
+        catch (const Tcl::tcl_error& e)
+        {   bundle->interpreter_ = 0; COUT(1) << "Tcl error while creating Tcl-interpreter (" << id_string << "): " << e.what() << std::endl;   }
+        catch (...)
+        {   bundle->interpreter_ = 0; COUT(1) << "Error while creating Tcl-interpreter (" << id_string << "): " << Exception::handleMessage() << std::endl;   }
+    }
+
+    /**
+        @brief Stops and destroys a given Tcl-interpreter
+    */
+    void TclThreadManager::destroy(unsigned int id)
+    {
+        // TODO
+        // Not yet implemented
+        TclInterpreterBundle* bundle = TclThreadManager::getInstance().getInterpreterBundle(id);
+        if (bundle)
+        {
+            bundle->bRunning_ = false;
+        }
+    }
+
+    /**
+        @brief Sends a command to the queue of a given Tcl-interpreter
+        @param id The id of the target interpreter
+        @param command The command to be sent
+    */
+    void TclThreadManager::execute(unsigned int target_id, const std::string& command)
+    {
+        TclThreadManager::getInstance()._execute(target_id, command);
+    }
+
+    /**
+        @brief This function can be called from Tcl to execute a console command.
+
+        Commands which shall be executed are put into a queue and processed as soon as the
+        main thread feels ready to do so. The queue may also be full which results in a temporary
+        suspension of the calling thread until the queue gets ready again.
+    */
+    void TclThreadManager::tcl_execute(const Tcl::object& args)
+    {
+        TclThreadManager::getInstance()._execute(0, stripEnclosingBraces(args.get()));
+    }
+
+    /**
+        @brief This function can be called from Tcl to send a command to the queue of any interpreter.
+        @param target_id The id of the target thread
+    */
+    void TclThreadManager::tcl_crossexecute(int target_id, const Tcl::object& args)
+    {
+        TclThreadManager::getInstance()._execute(static_cast<unsigned int>(target_id), stripEnclosingBraces(args.get()));
+    }
+
+    /**
+        @brief Sends a command to the queue of a given Tcl-interpreter
+        @param id The id of the target interpreter
+        @param command The command to be sent
+    */
+    void TclThreadManager::_execute(unsigned int target_id, const std::string& command)
+    {
+        TclInterpreterBundle* bundle = this->getInterpreterBundle(target_id);
+        if (bundle)
+            bundle->queue_.push_back(command);
+    }
+
+
+    /**
+        @brief Sends a query to a given Tcl-interpreter and waits for the result
+        @param id The id of the target interpreter
+        @param command The command to be sent
+        @return The result of the command
+    */
+    std::string TclThreadManager::query(unsigned int target_id, const std::string& command)
+    {
+        return TclThreadManager::getInstance()._query(0, target_id, command);
+    }
+
+    /**
+        @brief This function can be called from Tcl to send a query to the main thread.
+        @param source_id The id of the calling thread
+
+        A query waits for the result of the command. This means, the calling thread will be blocked until
+        the main thread answers the query. In return, the main thread sends the result of the console
+        command back to Tcl.
+    */
+    std::string TclThreadManager::tcl_query(int source_id, const Tcl::object& args)
+    {
+        return TclThreadManager::getInstance()._query(static_cast<unsigned int>(source_id), 0, stripEnclosingBraces(args.get()), true);
+    }
+
+    /**
+        @brief This function can be called from Tcl to send a query to another thread.
+        @param source_id The id of the calling thread
+        @param target_id The id of the target thread
+    */
+    std::string TclThreadManager::tcl_crossquery(int source_id, int target_id, const Tcl::object& args)
+    {
+        return TclThreadManager::getInstance()._query(static_cast<unsigned int>(source_id), static_cast<unsigned int>(target_id), stripEnclosingBraces(args.get()));
+    }
+
+    /**
+        @brief This function performs a query to any Tcl interpreter
+        @param source_id The id of the calling thread
+        @param target_id The id of the target thread
+        @param command The command to send as a query
+        @param bUseCommandExecutor Only used if the target_id is 0 (which references the main interpreter). In this case it means if the command should be passed to the CommandExecutor (true) or to the main Tcl interpreter (false). This is true when called by tcl_query and false when called by tcl_crossquery.
+    */
+    std::string TclThreadManager::_query(unsigned int source_id, unsigned int target_id, const std::string& command, bool bUseCommandExecutor)
+    {
+        TclInterpreterBundle* source_bundle = this->getInterpreterBundle(source_id);
+        TclInterpreterBundle* target_bundle = this->getInterpreterBundle(target_id);
+        std::string output;
+
+        if (source_bundle && target_bundle)
+        {
+            // At this point we assume the mutex of source_bundle to be locked (because it's executing this query right now an waits for the return value)
+            // We can safely use it's querier list (because there's no other place in the code using the list except this query - and the interpreter can't start more than one query)
+
+            if ((source_bundle->id_ == target_bundle->id_) || source_bundle->queriers_.is_in(target_bundle->id_))
+            {
+                // This query would lead to a deadlock - return with an error
+                TclThreadManager::error("Error: Circular query (" + this->dumpList(source_bundle->queriers_.getList()) + ' ' + getConvertedValue<unsigned int, std::string>(source_bundle->id_) \
+                            + " -> " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) \
+                            + "), couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) \
+                            + " from other interpreter with ID " + getConvertedValue<unsigned int, std::string>(source_bundle->id_) + '.');
+            }
+            else
+            {
+                boost::unique_lock<boost::mutex> lock(target_bundle->mutex_, boost::try_to_lock);
+                boost::unique_lock<boost::mutex> mainlock(*this->mainInterpreterMutex_, boost::defer_lock);
+
+                if (!lock.owns_lock() && source_bundle->id_ != 0)
+                {
+                    // We couldn't obtain the try_lock immediately and we're not the main interpreter - wait until the lock becomes possible (note: the main interpreter won't wait and instead returns an error - see below)
+                    if (target_bundle->id_ == 0)
+                    {
+                        // We're querying the main interpreter - use the main interpreter mutex to synchronize
+                        mainlock.lock();
+                        lock.lock();
+                    }
+                    else
+                    {
+                        // We're querying a threaded interpreter - no synchronization needed
+                        lock.lock();
+                    }
+                }
+
+                if (lock.owns_lock())
+                {
+                    // Now the mutex of target_bundle is also locked an we can update the querier list
+                    target_bundle->queriers_.insert(target_bundle->queriers_.getList().begin(), source_bundle->queriers_.getList().begin(), source_bundle->queriers_.getList().end());
+                    target_bundle->queriers_.push_back(source_bundle->id_);
+
+                    // Perform the query (note: this happens in the main thread because we need the returnvalue)
+                    if (target_bundle->id_ == 0 && bUseCommandExecutor)
+                    {
+                        // It's a query to the CommandExecutor
+                        TclThreadManager::debug("TclThread_query -> CE: " + command);
+                        if (!CommandExecutor::execute(command, false))
+                            TclThreadManager::error("Error: Can't execute command \"" + command + "\"!");
+
+                        if (CommandExecutor::getLastEvaluation().hasReturnvalue())
+                            output = CommandExecutor::getLastEvaluation().getReturnvalue().getString();
+                    }
+                    else
+                    {
+                        // It's a query to a Tcl interpreter
+                        TclThreadManager::debug("TclThread_query: " + command);
+
+                        output = TclThreadManager::eval(target_bundle, command, "query");
+                    }
+
+                    // Clear the queriers list of the target
+                    target_bundle->queriers_.clear();
+
+                    // Unlock the mutex of the target_bundle
+                    lock.unlock();
+
+                    // Finally unlock the main interpreter lock if necessary
+                    if (mainlock.owns_lock())
+                        mainlock.unlock();
+                }
+                else
+                {
+                    // This happens if the main thread tries to query a busy interpreter
+                    // To avoid a lock of the main thread, we simply don't proceed with the query in this case
+                    TclThreadManager::error("Error: Couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) + ", interpreter is busy right now.");
+                }
+            }
+
+        }
+
+        return output;
+    }
+
+    /**
+        @brief Creates a non-interactive Tcl-interpreter which executes a file.
+    */
+    void TclThreadManager::source(const std::string& file)
+    {
+        boost::thread(boost::bind(&sourceThread, file));
+    }
+
+    /**
+        @brief This function can be called from Tcl to ask if the thread is still suposed to be running.
+        @param id The id of the thread in question
+    */
+    bool TclThreadManager::tcl_running(int id)
+    {
+        TclInterpreterBundle* bundle = TclThreadManager::getInstance().getInterpreterBundle(static_cast<unsigned int>(id));
+        if (bundle)
+            return bundle->bRunning_;
+        else
+            return false;
+    }
+
+    /**
+        @brief Returns the interpreter bundle with the given id.
+        @param id The id of the interpreter
+        @return The interpreter or 0 if the id doesn't exist
+    */
+    TclInterpreterBundle* TclThreadManager::getInterpreterBundle(unsigned int id)
+    {
+        boost::shared_lock<boost::shared_mutex> lock(*this->interpreterBundlesMutex_);
+
+        std::map<unsigned int, TclInterpreterBundle*>::const_iterator it = this->interpreterBundles_.find(id);
+        if (it != this->interpreterBundles_.end())
+        {
+            return it->second;
+        }
+        else
+        {
+            TclThreadManager::error("Error: No Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(id) + " existing.");
+            return 0;
+        }
+    }
+
+    /**
+        @brief Returns a string containing all elements of a unsigned-integer-list separated by spaces.
+    */
+    std::string TclThreadManager::dumpList(const std::list<unsigned int>& list)
+    {
+        std::string output;
+        for (std::list<unsigned int>::const_iterator it = list.begin(); it != list.end(); ++it)
+        {
+            if (it != list.begin())
+                output += ' ';
+
+            output += getConvertedValue<unsigned int, std::string>(*it);
+        }
+        return output;
+    }
+
+    /**
+        @brief Returns a list with the numbers of all existing Tcl-interpreters.
+
+        This function is used by the auto completion function.
+    */
+    std::list<unsigned int> TclThreadManager::getThreadList() const
+    {
+        boost::shared_lock<boost::shared_mutex> lock(*this->interpreterBundlesMutex_);
+
+        std::list<unsigned int> threads;
+        for (std::map<unsigned int, TclInterpreterBundle*>::const_iterator it = this->interpreterBundles_.begin(); it != this->interpreterBundles_.end(); ++it)
+            if (it->first > 0 && it->first <= this->numInterpreterBundles_) // only list autonumbered interpreters (created with create()) - exclude the default interpreter 0 and all manually numbered interpreters)
+                threads.push_back(it->first);
+        return threads;
+    }
+
+    /**
+        @brief A helper function to print errors in a thread safe manner.
+    */
+    void TclThreadManager::error(const std::string& error)
+    {
+        TclThreadManager::getInstance().messageQueue_->push_back("error " + error);
+    }
+
+    /**
+        @brief A helper function to print debug information in a thread safe manner.
+    */
+    void TclThreadManager::debug(const std::string& error)
+    {
+        TclThreadManager::getInstance().messageQueue_->push_back("debug " + error);
+    }
+
+    /**
+        @brief Evaluates a Tcl command without throwing exceptions (which may rise problems on certain machines).
+        @return The Tcl return value
+
+        Errors are reported through the @ref error function.
+    */
+    std::string TclThreadManager::eval(TclInterpreterBundle* bundle, const std::string& command, const std::string& action)
+    {
+        Tcl_Interp* interpreter = bundle->interpreter_->get();
+        int cc = Tcl_Eval(interpreter, command.c_str());
+
+        Tcl::details::result result(interpreter);
+
+        if (cc != TCL_OK)
+        {
+            TclThreadManager::error("Tcl error (" + action + ", ID " + getConvertedValue<unsigned int, std::string>(bundle->id_) + "): " + static_cast<std::string>(result));
+            return "";
+        }
+        else
+        {
+            return result;
+        }
+    }
+
+    ////////////////
+    // The Thread //
+    ////////////////
+
+    /**
+        @brief The main function of the thread. Executes a Tcl command.
+        @param bundle The interpreter bundle containing all necessary variables
+        @param command the Command to execute
+    */
+    void tclThread(TclInterpreterBundle* bundle, const std::string& command)
+    {
+        TclThreadManager::debug("TclThread_execute: " + command);
+
+        TclThreadManager::eval(bundle, command, "execute");
+
+        bundle->lock_->unlock();
+    }
+
+    /**
+        @brief The main function of a non-interactive source thread. Executes the file.
+        @param file The name of the file that should be executed by the non-interactive interpreter.
+    */
+    void sourceThread(const std::string& file)
+    {
+        TclThreadManager::debug("TclThread_source: " + file);
+
+        // Prepare the command-line arguments
+        const int argc = 2;
+        char* argv[argc];
+        argv[0] = "tclthread";
+        argv[1] = const_cast<char*>(file.c_str());
+
+        // Start the Tcl-command Tcl_Main with the Tcl_OrxonoxAppInit hook
+        Tcl_Main(argc, argv, Tcl_OrxonoxAppInit);
+
+//        Tcl::object object(file);
+//        int cc = Tcl_FSEvalFile(bundle->interpreter_->get(), object.get_object());
+//        Tcl::details::result result(bundle->interpreter_->get());
+//        if (cc != TCL_OK)
+//            TclThreadManager::error("Tcl error (source, ID " + getConvertedValue<unsigned int, std::string>(bundle->id_) + "): " + static_cast<std::string>(result));
+//
+//        // Unlock the mutex
+//        bundle->lock_->unlock();
+    }
+
+    /**
+        @brief A tcl-init hook to inject the non-interactive Tcl-interpreter into the TclThreadManager.
+    */
+    int Tcl_OrxonoxAppInit(Tcl_Interp* interp)
+    {
+        // Create a new interpreter bundle
+        unsigned int id = TclThreadManager::create();
+        TclInterpreterBundle* bundle = TclThreadManager::getInstance().getInterpreterBundle(id);
+
+        // Replace the default interpreter in the bundle with the non-interactive one (passed as an argument to this function)
+        if (bundle->interpreter_)
+            delete bundle->interpreter_;
+        bundle->interpreter_ = new Tcl::interpreter(interp, true);
+
+        // Initialize the non-interactive interpreter (like in @ref TclBind::createTclInterpreter but exception safe)
+        const std::string& libpath = TclBind::getTclLibraryPath();
+        if (!libpath.empty())
+            TclThreadManager::eval(bundle, "set tcl_library \"" + libpath + '"', "source");
+        int cc = Tcl_Init(interp);
+        TclThreadManager::eval(bundle, "source \"" + TclBind::getInstance().getTclDataPath() + "/init.tcl\"", "source");
+
+        // Initialize the non-interactive interpreter also with the thread-specific stuff
+        TclThreadManager::initialize(bundle);
+
+        // Lock the mutex (this will be locked until the thread finishes - no chance to interact with the interpreter)
+        bundle->lock_->lock();
+
+        // Return to Tcl_Main
+        if (!bundle->interpreter_)
+            return TCL_ERROR;
+        else
+            return cc;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/TclThreadManager.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/TclThreadManager.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/TclThreadManager.h	(revision 6952)
@@ -0,0 +1,102 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TclThreadManager_H__
+#define _TclThreadManager_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include <list>
+#include <map>
+#include <string>
+
+#include "util/Singleton.h"
+#include "OrxonoxClass.h"
+
+struct Tcl_Interp;
+
+namespace orxonox
+{
+    class _CoreExport TclThreadManager : public Singleton<TclThreadManager>, public OrxonoxClass
+    {
+        friend class Singleton<TclThreadManager>;
+        friend class TclBind;
+        friend _CoreExport void tclThread(TclInterpreterBundle* bundle, const std::string& command);
+        friend _CoreExport void sourceThread(const std::string& file);
+        friend _CoreExport int Tcl_OrxonoxAppInit(Tcl_Interp* interp);
+
+        public:
+            TclThreadManager(Tcl::interpreter* interpreter);
+            virtual ~TclThreadManager();
+
+            static unsigned int      create();
+            static Tcl::interpreter* createWithId(unsigned int id);
+            static void              destroy(unsigned int id);
+            static void              execute(unsigned int target_id, const std::string& command);
+            static std::string       query(unsigned int target_id, const std::string& command);
+            static void              source(const std::string& file);
+
+            static void error(const std::string& error);
+            static void debug(const std::string& error);
+
+            void preUpdate(const Clock& time);
+
+            std::list<unsigned int> getThreadList() const;
+
+        private:
+            static void tcl_execute(const Tcl::object& args);
+            static void tcl_crossexecute(int target_id, const Tcl::object& args);
+            static std::string tcl_query(int source_id, const Tcl::object& args);
+            static std::string tcl_crossquery(int source_id, int target_id, const Tcl::object& args);
+            static bool tcl_running(int id);
+
+            void _execute(unsigned int target_id, const std::string& command);
+            std::string _query(unsigned int source_id, unsigned int target_id, const std::string& command, bool bUseCommandExecutor = false);
+
+            TclInterpreterBundle* getInterpreterBundle(unsigned int id);
+            std::string dumpList(const std::list<unsigned int>& list);
+
+            static void initialize(TclInterpreterBundle* bundle);
+            static std::string eval(TclInterpreterBundle* bundle, const std::string& command, const std::string& action);
+
+            static TclThreadManager* singletonPtr_s;                            ///< Singleton pointer
+
+            unsigned int numInterpreterBundles_;                                ///< Number of created Tcl-interpreters (only used for auto-numbered interpreters, not affected by @ref createWithId)
+            std::map<unsigned int, TclInterpreterBundle*> interpreterBundles_;  ///< A map containing all Tcl-interpreters
+            boost::shared_mutex* interpreterBundlesMutex_;                      ///< A mutex used to synchronize threads when accessing @ref interpreterBundles_
+            TclThreadList<std::string>* messageQueue_;                          ///< A queue to pass messages from Tcl-threads to the main thread
+            boost::mutex* mainInterpreterMutex_;                                ///< A mutex to synchronize queries to the main interpreter
+    };
+
+    _CoreExport void tclThread(TclInterpreterBundle* bundle, const std::string& command);
+    _CoreExport void sourceThread(const std::string& file);
+    _CoreExport int Tcl_OrxonoxAppInit(Tcl_Interp* interp);
+}
+
+#endif /* _TclThreadManager_H__ */
Index: /code/branches/rocket2/src/libraries/core/Template.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/Template.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Template.cc	(revision 6952)
@@ -0,0 +1,183 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Template.h"
+
+#include <tinyxml/tinyxml.h>
+#include <tinyxml/ticpp.h>
+
+#include "util/Debug.h"
+#include "CoreIncludes.h"
+#include "XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(Template);
+
+    Template::Template(BaseObject* creator) : BaseObject(creator)
+    {
+        this->xmlelement_ = new TiXmlElement("");
+
+        RegisterObject(Template);
+
+        this->bIsLink_ = false;
+        this->bLoadDefaults_ = true;
+        this->bIsReturningXMLElement_ = false;
+        this->baseclassIdentifier_ = 0;
+    }
+
+    Template::~Template()
+    {
+        Template::getTemplateMap().erase(this->getName());
+        delete this->xmlelement_;
+    }
+
+    void Template::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Template, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Template, "link",      setLink,         getLink,         xmlelement, mode);
+        XMLPortParam(Template, "baseclass", setBaseclass,    getBaseclass,    xmlelement, mode);
+        XMLPortParam(Template, "defaults",  setLoadDefaults, getLoadDefaults, xmlelement, mode).defaultValues(true);
+
+        Element* element = xmlelement.FirstChildElement(false);
+        if (element)
+        {
+            TiXmlElement* tixmlelement = static_cast<TiXmlElement*>(element->GetTiXmlPointer());
+            if (tixmlelement)
+                this->setXMLElement(*tixmlelement);
+        }
+    }
+
+    void Template::changedName()
+    {
+        SUPER(Template, changedName);
+
+        if (!this->getName().empty())
+        {
+            std::map<std::string, Template*>::iterator it;
+            it = Template::getTemplateMap().find(this->getOldName());
+            if (it != Template::getTemplateMap().end())
+                Template::getTemplateMap().erase(it);
+
+            it = Template::getTemplateMap().find(this->getName());
+            if (it != Template::getTemplateMap().end())
+                COUT(2) << "Warning: Template with name \"" << this->getName() << "\" already exists." << std::endl;
+            else
+                Template::getTemplateMap()[this->getName()] = this;
+        }
+    }
+
+    void Template::setXMLElement(const TiXmlElement& xmlelement)
+    {
+        *this->xmlelement_ = xmlelement;
+    }
+
+    const TiXmlElement& Template::getXMLElement()
+    {
+        if (this->bIsLink_)
+        {
+            Template* temp = Template::getTemplate(this->link_);
+            if (temp)
+            {
+                this->bLoadDefaults_ = temp->bLoadDefaults_;
+                
+                if (!temp->bIsReturningXMLElement_)
+                {
+                    this->bIsReturningXMLElement_ = true;
+                    const TiXmlElement& element = temp->getXMLElement();
+                    this->bIsReturningXMLElement_ = false;
+                    return element;
+                }
+                else
+                {
+                    COUT(2) << "Warning: Linking from " << this->getName() << " to " << this->link_ << " leads to an infinite loop. Returning own element." << std::endl;
+                }
+            }
+            else
+            {
+                COUT(2) << "Warning: " << this->link_ << " is not an existing Template name. Returning own element." << std::endl;
+            }
+        }
+
+        return *this->xmlelement_;
+    }
+
+    void Template::setBaseclass(const std::string& baseclass)
+    {
+        this->baseclassIdentifier_ = ClassByString(baseclass);
+        if (this->baseclassIdentifier_)
+            this->baseclass_ = baseclass;
+    }
+
+    void Template::applyOn(BaseObject* object)
+    {
+        if (this->baseclassIdentifier_)
+        {
+            if (!object->isA(this->baseclassIdentifier_))
+            {
+                COUT(1) << "Error: Can't apply template (name: " << this->getName() << "), object (name: " << object->getName() << ", class: " << object->getIdentifier()->getName() << ") is not a " << this->baseclassIdentifier_->getName() << std::endl;
+                return;
+            }
+        }
+
+        COUT(4) << object->getLoaderIndentation() << " aplying Template \"" << this->getName() << "\"..." << std::endl;
+
+        Element temp = &const_cast<TiXmlElement&>(this->getXMLElement());
+
+        if (this->bLoadDefaults_)
+            object->XMLPort(temp, XMLPort::LoadObject);
+        else
+            object->XMLPort(temp, XMLPort::ExpandObject);
+    }
+
+    std::map<std::string, Template*>& Template::getTemplateMap()
+    {
+        static std::map<std::string, Template*> templateMap;
+        return templateMap;
+    }
+
+    Template* Template::getTemplate(const std::string& name)
+    {
+        std::map<std::string, Template*>::iterator it = Template::getTemplateMap().find(name);
+        if (it != Template::getTemplateMap().end())
+            return it->second;
+        else
+        {
+            COUT(2) << "Warning: Template with name " << name << " doesn't exist." << std::endl;
+            return 0;
+        }
+    }
+
+    void Template::apply(const std::string& name, BaseObject* object)
+    {
+        std::map<std::string, Template*>::iterator it = Template::getTemplateMap().find(name);
+        if (it != Template::getTemplateMap().end())
+            it->second->applyOn(object);
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/Template.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Template.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Template.h	(revision 6952)
@@ -0,0 +1,85 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Template_H__
+#define _Template_H__
+
+#include "CorePrereqs.h"
+
+#include <map>
+#include <string>
+#include "BaseObject.h"
+
+namespace orxonox
+{
+    class _CoreExport Template : public BaseObject
+    {
+        public:
+            Template(BaseObject* creator);
+            virtual ~Template();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void changedName();
+
+            inline void setLink(const std::string& link)
+                { this->link_ = link; this->bIsLink_ = !link.empty(); }
+            inline const std::string& getLink() const
+                { return this->link_; }
+
+            inline void setLoadDefaults(bool bLoadDefaults)
+                { this->bLoadDefaults_ = bLoadDefaults; }
+            inline bool getLoadDefaults() const
+                { return this->bLoadDefaults_; }
+
+            void setXMLElement(const TiXmlElement& xmlelement);
+            const TiXmlElement& getXMLElement();
+
+            void setBaseclass(const std::string& baseclass);
+            inline const std::string& getBaseclass() const
+                { return this->baseclass_; }
+            inline Identifier* getBaseclassIdentifier() const
+                { return this->baseclassIdentifier_; }
+
+            void applyOn(BaseObject* object);
+
+            static std::map<std::string, Template*>& getTemplateMap();
+            static Template* getTemplate(const std::string& name);
+            static void apply(const std::string& name, BaseObject* object);
+
+        private:
+            TiXmlElement* xmlelement_;
+            std::string link_;
+            std::string baseclass_;
+            Identifier* baseclassIdentifier_;
+            bool bIsLink_;
+            bool bLoadDefaults_;
+            mutable bool bIsReturningXMLElement_;
+    };
+}
+
+#endif /* _Template_H__ */
Index: /code/branches/rocket2/src/libraries/core/Thread.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/Thread.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Thread.cc	(revision 6952)
@@ -0,0 +1,129 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Thread.h"
+
+#include <cassert>
+#include <boost/thread/thread.hpp>
+#include <boost/bind.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread_time.hpp>
+
+#include "util/Sleep.h"
+#include "Executor.h"
+
+namespace orxonox
+{
+    boost::posix_time::millisec THREAD_WAIT_BEFORE_DETACH(1000);
+
+
+    Thread::Thread():
+        executor_(0),
+        isWorking_(false),
+        stopThread_(false)
+    {
+        this->executorMutex_ = new boost::mutex;
+        this->isWorkingMutex_ = new boost::mutex;
+        this->stopThreadMutex_ = new boost::mutex;
+        this->workerThread_ = new boost::thread( boost::bind(&Thread::threadLoop, this) );
+    }
+
+    Thread::~Thread()
+    {
+        this->stopThreadMutex_->lock();
+        this->stopThread_ = true;
+        this->stopThreadMutex_->unlock();
+        if( !this->workerThread_->timed_join( THREAD_WAIT_BEFORE_DETACH ) )
+            assert(0); // this should not happen
+        delete this->workerThread_;
+        delete this->executorMutex_;
+        delete this->stopThreadMutex_;
+        delete this->isWorkingMutex_;
+    }
+
+    bool Thread::isWorking()
+    {
+      this->isWorkingMutex_->lock();
+      bool isWorking = this->isWorking_;
+      this->isWorkingMutex_->unlock();
+      return isWorking;
+    }
+
+    bool Thread::evaluateExecutor( Executor* executor )
+    {
+        this->isWorkingMutex_->lock();
+        this->isWorking_=true;
+        this->isWorkingMutex_->unlock();
+        this->executorMutex_->lock();
+        this->executor_ = executor;
+        this->executorMutex_->unlock();
+        return true;
+    }
+
+    void Thread::threadLoop()
+    {
+        bool stopThread = false;
+        while( !stopThread )
+        {
+            //this->executorMutex_->lock();
+            Executor* executor = this->executor_;
+            //this->executorMutex_->unlock();
+            if( executor )
+            {
+                (*executor)();
+                this->executorMutex_->lock();
+                delete this->executor_;
+                this->executor_ = 0;
+                this->executorMutex_->unlock();
+                this->isWorkingMutex_->lock();
+                this->isWorking_=false;
+                this->isWorkingMutex_->unlock();
+            }
+            else
+            {
+                this->workerThread_->yield();
+            }
+            //this->stopThreadMutex_->lock();
+            stopThread = this->stopThread_;
+            //this->stopThreadMutex_->unlock();
+        }
+    }
+
+    void Thread::waitUntilFinished()
+    {
+        bool stillWorking = true;
+        while( stillWorking )
+        {
+            this->isWorkingMutex_->lock();
+            stillWorking = this->isWorking_;
+            this->isWorkingMutex_->unlock();
+            if( stillWorking )
+                msleep( 1 );
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/Thread.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/Thread.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/Thread.h	(revision 6952)
@@ -0,0 +1,64 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Thread_H__
+#define _Thread_H__
+
+#include "CorePrereqs.h"
+
+namespace boost{
+  class recursive_mutex;
+}
+
+ namespace orxonox
+{
+    class _CoreExport Thread
+    {
+    public:
+        Thread();
+        virtual ~Thread();
+
+        bool isWorking();
+        void waitUntilFinished();
+        bool evaluateExecutor( Executor* executor );
+
+    private:
+        void            threadLoop();
+
+        Executor*       executor_;
+        bool            isWorking_;
+        bool            stopThread_;
+        boost::thread*  workerThread_;
+        boost::mutex*   executorMutex_;
+        boost::mutex*     isWorkingMutex_;
+        boost::mutex*   stopThreadMutex_;
+    };
+
+ }
+
+#endif /* _Thread_H__ */
Index: /code/branches/rocket2/src/libraries/core/ThreadPool.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/ThreadPool.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ThreadPool.cc	(revision 6952)
@@ -0,0 +1,115 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ThreadPool.h"
+#include "Thread.h"
+#include <cassert>
+
+namespace orxonox
+{
+
+    ThreadPool::ThreadPool()
+    {
+    }
+
+    ThreadPool::~ThreadPool()
+    {
+        unsigned int a = this->setNrOfThreads(0);
+        assert(a == 0);
+    }
+
+    void ThreadPool::addThreads( unsigned int nr )
+    {
+        for( unsigned int i=0; i<nr; i++ )
+            this->threadPool_.push_back(new Thread());
+    }
+    unsigned int ThreadPool::removeThreads( unsigned int nr )
+    {
+        unsigned int i=0;
+        std::vector<Thread*>::iterator it;
+        for( it = this->threadPool_.begin(); it != threadPool_.end() && i<nr; )
+        {
+            if( ! (*it)->isWorking() )
+            {
+                Thread* temp = *it;
+                it=this->threadPool_.erase( it );
+                delete temp;
+                ++i;
+            }
+            else
+              ++it;
+        }
+        return i;
+    }
+    unsigned int ThreadPool::setNrOfThreads( unsigned int nr )
+    {
+        unsigned int currentsize = this->threadPool_.size();
+        if ( nr < currentsize )
+            return currentsize - removeThreads( currentsize - nr );
+        else if ( nr == currentsize )
+            return currentsize;
+        else
+        {
+            addThreads( nr - currentsize );
+            return nr;
+        }
+    }
+
+    bool ThreadPool::passFunction( Executor* executor, bool addThread )
+    {
+        std::vector<Thread*>::iterator it;
+        for ( it=this->threadPool_.begin(); it!=this->threadPool_.end(); ++it )
+        {
+            if ( ! (*it)->isWorking() )
+            {
+                bool b = (*it)->evaluateExecutor( executor );
+                assert(b); // if b is false then there is some code error
+                return true;
+            }
+        }
+        if ( addThread )
+        {
+            addThreads( 1 );
+            bool b = this->threadPool_.back()->evaluateExecutor( executor ); // access the last element
+            assert(b);
+            return true;
+        }
+        else
+            return false;
+    }
+
+    void ThreadPool::synchronise()
+    {
+        std::vector<Thread*>::iterator it;
+        for ( it=this->threadPool_.begin(); it!=this->threadPool_.end(); ++it )
+        {
+            (*it)->waitUntilFinished();
+        }
+    }
+
+}
Index: /code/branches/rocket2/src/libraries/core/ThreadPool.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ThreadPool.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ThreadPool.h	(revision 6952)
@@ -0,0 +1,57 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ThreadPool_H__
+#define _ThreadPool_H__
+
+#include "CorePrereqs.h"
+
+#include <vector>
+
+ namespace orxonox
+{
+    class _CoreExport ThreadPool
+    {
+    public:
+        ThreadPool();
+        virtual ~ThreadPool();
+
+        void addThreads( unsigned int nr );
+        unsigned int removeThreads( unsigned int nr );
+        unsigned int setNrOfThreads( unsigned int nr );
+
+        bool passFunction( Executor* executor, bool addThread=false );
+        void synchronise();
+
+    private:
+        std::vector<Thread*> threadPool_;
+
+    };
+}
+
+#endif /* _ThreadPool_H__ */
Index: /code/branches/rocket2/src/libraries/core/ToluaInterface.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/ToluaInterface.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/ToluaInterface.h	(revision 6952)
@@ -0,0 +1,45 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+    This is required because tolua would parse this macro in LuaState.h and fail
+*/
+
+#ifndef _ToluaInterface_H__
+#define _ToluaInterface_H__
+
+#include "CorePrereqs.h"
+#include <boost/preprocessor/cat.hpp>
+
+// Macro for declaring a tolua interface of a library/module
+#define DeclareToluaInterface(libraryName) \
+    static bool BOOST_PP_CAT(bDummy##libraryName, __LINE__) = orxonox::LuaState::addToluaInterface(&tolua_##libraryName##_open, #libraryName); \
+    static Loki::ScopeGuardImpl1<bool (*)(const std::string&), std::string> BOOST_PP_CAT(dummy##libraryName, __LINE__)(&orxonox::LuaState::removeToluaInterface, #libraryName)
+
+#endif /* _ToluaInterface_H__ */
Index: /code/branches/rocket2/src/libraries/core/WeakPtr.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/WeakPtr.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/WeakPtr.h	(revision 6952)
@@ -0,0 +1,219 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+// Inspired by boost::intrusive_ptr by Peter Dimov
+
+#ifndef _WeakPtr_H__
+#define _WeakPtr_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include "OrxonoxClass.h"
+#include "Functor.h"
+
+namespace orxonox
+{
+    template <class T>
+    class WeakPtr
+    {
+        friend class OrxonoxClass;
+
+        public:
+            inline WeakPtr() : pointer_(0), base_(0), callback_(0)
+            {
+            }
+
+            inline WeakPtr(int) : pointer_(0), base_(0), callback_(0)
+            {
+            }
+
+            inline WeakPtr(T* pointer) : pointer_(pointer), base_(pointer), callback_(0)
+            {
+                if (this->base_)
+                    this->base_->registerWeakPtr(this);
+            }
+
+            inline WeakPtr(const WeakPtr& other) : pointer_(other.pointer_), base_(other.base_), callback_(0)
+            {
+                if (this->base_)
+                    this->base_->registerWeakPtr(this);
+            }
+
+            template <class O>
+            inline WeakPtr(const WeakPtr<O>& other) : pointer_(other.get()), base_(other.base_), callback_(0)
+            {
+                if (this->base_)
+                    this->base_->registerWeakPtr(this);
+            }
+
+            inline ~WeakPtr()
+            {
+                if (this->base_)
+                    this->base_->unregisterWeakPtr(this);
+                if (this->callback_)
+                    delete this->callback_;
+
+            }
+
+            inline const WeakPtr& operator=(int)
+            {
+                WeakPtr(0).swap(*this);
+                return *this;
+            }
+
+            inline const WeakPtr& operator=(T* pointer)
+            {
+                WeakPtr(pointer).swap(*this);
+                return *this;
+            }
+
+            inline const WeakPtr& operator=(const WeakPtr& other)
+            {
+                WeakPtr(other).swap(*this);
+                return *this;
+            }
+
+            template <class O>
+            inline const WeakPtr& operator=(const WeakPtr<O>& other)
+            {
+                WeakPtr(other).swap(*this);
+                return *this;
+            }
+
+            inline T* get() const
+            {
+                return this->pointer_;
+            }
+
+            inline OrxonoxClass* getBase() const
+            {
+                return this->base_;
+            }
+
+            inline operator T*() const
+            {
+                return this->pointer_;
+            }
+
+            inline T* operator->() const
+            {
+                assert(this->pointer_ != 0);
+                return this->pointer_;
+            }
+
+            inline T& operator*() const
+            {
+                assert(this->pointer_ != 0);
+                return *this->pointer_;
+            }
+
+            inline bool operator!() const
+            {
+                return (this->pointer_ == 0);
+            }
+
+            inline void swap(WeakPtr& other)
+            {
+                if (this->base_)
+                    this->base_->unregisterWeakPtr(this);
+                if (other.base_)
+                    other.base_->unregisterWeakPtr(&other);
+
+                {
+                    T* temp = this->pointer_;
+                    this->pointer_ = other.pointer_;
+                    other.pointer_ = temp;
+                }
+                {
+                    OrxonoxClass* temp = this->base_;
+                    this->base_ = other.base_;
+                    other.base_ = temp;
+                }
+
+                if (this->base_)
+                    this->base_->registerWeakPtr(this);
+                if (other.base_)
+                    other.base_->registerWeakPtr(&other);
+            }
+
+            inline void reset()
+            {
+                WeakPtr().swap(*this);
+            }
+
+            inline void setCallback(Functor* callback)
+            {
+                this->callback_ = callback;
+            }
+
+            inline Functor* getFunctor() const
+            {
+                return this->callback_;
+            }
+
+        private:
+            inline void objectDeleted()
+            {
+                this->base_ = 0;
+                this->pointer_ = 0;
+                if (this->callback_)
+                    (*this->callback_)();
+            }
+
+            T* pointer_;
+            OrxonoxClass* base_;
+            Functor* callback_;
+    };
+
+    template <class T>
+    void swap(WeakPtr<T>& a, WeakPtr<T>& b)
+    {
+        a.swap(b);
+    }
+
+    template <class T, class U>
+    WeakPtr<T> static_pointer_cast(const WeakPtr<U>& p)
+    {
+        return static_cast<T*>(p.get());
+    }
+
+    template <class T, class U>
+    WeakPtr<T> const_pointer_cast(const WeakPtr<U>& p)
+    {
+        return const_cast<T*>(p.get());
+    }
+
+    template <class T, class U>
+    WeakPtr<T> dynamic_pointer_cast(const WeakPtr<U>& p)
+    {
+        return dynamic_cast<T*>(p.get());
+    }
+}
+
+#endif /* _WeakPtr_H__ */
Index: /code/branches/rocket2/src/libraries/core/WindowEventListener.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/WindowEventListener.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/WindowEventListener.cc	(revision 6952)
@@ -0,0 +1,64 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "WindowEventListener.h"
+#include "CoreIncludes.h"
+
+namespace orxonox
+{
+    unsigned int WindowEventListener::windowWidth_s  = 0;
+    unsigned int WindowEventListener::windowHeight_s = 0;
+
+    WindowEventListener::WindowEventListener()
+    {
+        RegisterRootObject(WindowEventListener);
+    }
+
+    //! Calls all registered objects
+    /*static*/ void WindowEventListener::moveWindow()
+    {
+        for (ObjectList<WindowEventListener>::iterator it = ObjectList<WindowEventListener>::begin(); it; ++it)
+            it->windowMoved();
+    }
+
+    //! Calls all registered objects and sets the static variables
+    /*static*/ void WindowEventListener::resizeWindow(unsigned int newWidth, unsigned int newHeight)
+    {
+        windowWidth_s = newWidth;
+        windowHeight_s = newHeight;
+        for (ObjectList<WindowEventListener>::iterator it = ObjectList<WindowEventListener>::begin(); it; ++it)
+            it->windowResized(newWidth, newHeight);
+    }
+
+    //! Calls all registered objects
+    /*static*/ void WindowEventListener::changeWindowFocus()
+    {
+        for (ObjectList<WindowEventListener>::iterator it = ObjectList<WindowEventListener>::begin(); it; ++it)
+            it->windowFocusChanged();
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/WindowEventListener.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/WindowEventListener.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/WindowEventListener.h	(revision 6952)
@@ -0,0 +1,71 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _WindowEventListener_H__
+#define _WindowEventListener_H__
+
+#include "CorePrereqs.h"
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    //! Interface for receiving window events like resize, moved and focusChanged
+    class _CoreExport WindowEventListener : virtual public OrxonoxClass
+    {
+        friend class OgreWindowEventListener;
+
+        protected:
+            WindowEventListener();
+            virtual ~WindowEventListener() { }
+
+            //! Returns the current render window width
+            unsigned int getWindowWidth() const { return windowWidth_s; }
+            //! Returns the current render window height
+            unsigned int getWindowHeight() const { return windowHeight_s; }
+
+        private:
+            //! Window has been moved
+            virtual void windowMoved() { }
+
+            //! Window has resized
+            virtual void windowResized(unsigned int newWidth, unsigned int newHeight) { }
+
+            //! Window has lost/gained focus
+            virtual void windowFocusChanged() { }
+
+            static void moveWindow();
+            static void resizeWindow(unsigned int newWidth, unsigned int newHeight);
+            static void changeWindowFocus();
+
+            //! Static variable that holds the latest distributed information
+            static unsigned int windowWidth_s;
+            static unsigned int windowHeight_s;
+    };
+}
+
+#endif /* _WindowEventListener_H__ */
Index: /code/branches/rocket2/src/libraries/core/XMLFile.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/XMLFile.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/XMLFile.h	(revision 6952)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _XMLFile_H__
+#define _XMLFile_H__
+
+#include "CorePrereqs.h"
+
+#include <string>
+#include "ClassTreeMask.h"
+
+namespace orxonox
+{
+    class _CoreExport XMLFile
+    {
+        public:
+            XMLFile(const std::string& filename)
+                : filename_(filename)
+                , bLuaSupport_(true)
+            { }
+            XMLFile(const ClassTreeMask& mask, const std::string& filename)
+                : filename_(filename)
+                , mask_(mask)
+                , bLuaSupport_(true)
+            { }
+
+            void setLuaSupport(bool val) { bLuaSupport_ = val; }
+
+            const std::string& getFilename() const { return this->filename_; }
+            const ClassTreeMask& getMask() const { return this->mask_; }
+            bool getLuaSupport() const { return this->bLuaSupport_; }
+
+        private:
+            std::string filename_;
+            ClassTreeMask mask_;
+            bool bLuaSupport_; // Default is true
+    };
+}
+
+#endif /* _XMLFile_H__ */
Index: /code/branches/rocket2/src/libraries/core/XMLNameListener.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/XMLNameListener.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/XMLNameListener.cc	(revision 6952)
@@ -0,0 +1,38 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "XMLNameListener.h"
+#include "CoreIncludes.h"
+
+namespace orxonox
+{
+    XMLNameListener::XMLNameListener()
+    {
+        RegisterRootObject(XMLNameListener);
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/XMLNameListener.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/XMLNameListener.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/XMLNameListener.h	(revision 6952)
@@ -0,0 +1,47 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _XMLNameListener_H__
+#define _XMLNameListener_H__
+
+#include "CorePrereqs.h"
+#include "OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _CoreExport XMLNameListener : virtual public OrxonoxClass
+    {
+        public:
+            XMLNameListener();
+            virtual ~XMLNameListener() {}
+
+            virtual void loadedNewXMLName(BaseObject* object) = 0;
+    };
+}
+
+#endif /* _XMLNameListener_H__ */
Index: /code/branches/rocket2/src/libraries/core/XMLPort.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/XMLPort.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/XMLPort.cc	(revision 6952)
@@ -0,0 +1,43 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "XMLPort.h"
+
+#include "Loader.h"
+#include "Namespace.h"
+
+namespace orxonox
+{
+    // ################################
+    // ###  XMLPortObjectContainer  ###
+    // ################################
+    bool XMLPortObjectContainer::identifierIsIncludedInLoaderMask(const Identifier* identifier)
+    {
+        return ((!this->bApplyLoaderMask_) || identifier->isA(ClassIdentifier<Namespace>::getIdentifier()) || Loader::currentMask_s.isIncluded(identifier));
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/XMLPort.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/XMLPort.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/XMLPort.h	(revision 6952)
@@ -0,0 +1,688 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Declaration of the XMLPort helper classes and macros.
+
+    XMLPort is a virtual function of every BaseObject. Every object can change this function.
+    The XMLPort function gets called with an XMLElement, containing all attributes and
+    subclasses the object gets from the levelfile.
+
+    This file declares classes and macros to simplify XML-parsing.
+*/
+
+#ifndef _XMLPort_H__
+#define _XMLPort_H__
+
+#include "CorePrereqs.h"
+
+#include <cassert>
+#include <string>
+#include <tinyxml/ticpp.h>
+
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "util/MultiType.h"
+#include "util/OrxAssert.h"
+#include "util/StringUtils.h"
+#include "Identifier.h"
+#include "Executor.h"
+#include "BaseObject.h"
+
+// ------------
+// XMLPortParam
+
+/**
+    @brief Declares an XML attribute with a name, which will be set through load- and savefunctions.
+    @param classname The name of the class owning this param
+    @param paramname The name of the attribute
+    @param loadfunction A function to set the param in the object with a given value (~a set-function)
+    @param savefunction A function to get the value of the param from the object (~a get-function)
+    @param xmlelement The XMLElement, you get this from the XMLPort function
+    @param mode The mode (load or save), you get this from the XMLPort function
+
+    In the XML file, a param or attribute will be set like this:
+    <classname paramname="value" />
+
+    The macro will then call loadfunction(value) to set the given value (or call savefunction() to
+    write an existing value to an XML file).
+*/
+#define XMLPortParam(classname, paramname, loadfunction, savefunction, xmlelement, mode) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
+    XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, classname, this, paramname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode)
+
+/**
+    @brief Declares an XML attribute with a name, which will be set through a variable.
+    @param classname The name of the class owning this param
+    @param paramname The name of the attribute
+    @param variable Name of the variable used to save and load the value
+    @param xmlelement The XMLElement, you get this from the XMLPort function
+    @param mode The mode (load or save), you get this from the XMLPort function
+
+    In the XML file, a param or attribute will be set like this:
+    <classname paramname="value" />
+
+    The macro will then store "value" in the variable or read it when saving.
+*/
+#define XMLPortParamVariable(classname, paramname, variable, xmlelement, mode) \
+    XMLPortVariableHelperClass xmlcontainer##variable##dummy(static_cast<void*>(&variable)); \
+    static ExecutorMember<orxonox::XMLPortVariableHelperClass>* xmlcontainer##variable##loadexecutor = static_cast<ExecutorMember<orxonox::XMLPortVariableHelperClass>*>(orxonox::createExecutor(orxonox::createFunctor(orxonox::XMLPortVariableHelperClass::getLoader(variable)), std::string( #classname ) + "::" + #variable + "loader")); \
+    static ExecutorMember<orxonox::XMLPortVariableHelperClass>* xmlcontainer##variable##saveexecutor = static_cast<ExecutorMember<orxonox::XMLPortVariableHelperClass>*>(orxonox::createExecutor(orxonox::createFunctor(orxonox::XMLPortVariableHelperClass::getSaver (variable)), std::string( #classname ) + "::" + #variable + "saver" )); \
+    XMLPortParamGeneric(xmlcontainer##variable, classname, orxonox::XMLPortVariableHelperClass, &xmlcontainer##variable##dummy, paramname, xmlcontainer##variable##loadexecutor, xmlcontainer##variable##saveexecutor, xmlelement, mode)
+
+/**
+    @brief This is the same as XMLPortParam, but you can set the template arguments needed to store the loadfunction.
+
+    Sometimes the name of the loadfunction is ambiguous (example: setPosition(Vector3) or
+    setPosition(float, float, float)). In this case, you can choose the right function by
+    telling the types of the functionparams. In our example, this would be either
+    > XMLPortParamTemplate(classname, paramname, loadfunction, savefunction, xmlelement, mode, Vector3);
+    or
+    > XMLPortParamTemplate(classname, paramname, loadfunction, savefunction, xmlelement, mode, float, float, float);
+    You don't have to use this, if there exist only one function with the given name.
+*/
+#define XMLPortParamTemplate(classname, paramname, loadfunction, savefunction, xmlelement, mode, ...) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
+    XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, classname, this, paramname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode)
+
+// --------------------
+// XMLPortParamLoadOnly
+
+/**
+    @brief Declares an XML attribute with a name, which can be set through a loadfunction.
+
+    This is the same as XMLPortParam, but you don't need a savefunction (get-function). Therefore,
+    this param won't be saved in an XML file, but you can add the attribute manually an it will be
+    loaded.
+
+    This might be helpful in cases, when you have several options to set a value, for example the
+    rotation. You can set the rotation with a quaternion, but you could also use three angles.
+    When saving the object, only one of both options has to be saved; this is, where this macro helps.
+*/
+#define XMLPortParamLoadOnly(classname, paramname, loadfunction, xmlelement, mode) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##0##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    XMLPortParamGeneric(xmlcontainer##loadfunction##0, classname, classname, this, paramname, xmlcontainer##loadfunction##0##loadexecutor, 0, xmlelement, mode)
+/**
+    @brief This is the same as XMLPortParamTemplate, but for load-only attributes (see XMLPortParamLoadOnly).
+*/
+#define XMLPortParamLoadOnlyTemplate(classname, paramname, loadfunction, xmlelement, mode, ...) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##0##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    XMLPortParamGeneric(xmlcontainer##loadfunction##0, classname, classname, this, paramname, xmlcontainer##loadfunction##0##loadexecutor, 0, xmlelement, mode)
+
+// ------------------
+// XMLPortParamExtern
+
+/**
+    @brief This is the same as XMLPortParam, but for attributes in an extern class.
+    @param classname The name of the class owning the object owning the attribute
+    @param externclass The name of the extern class (the objects class)
+    @param object The name of the object of the extern class (a member of the main class)
+    @param paramname The name of the attribute
+    @param loadfunction The function to set the attribute inside of the member object.
+    @param loadfunction The function to get the attribute from the member object
+
+    Sometimes you'll have a member object in your class, which has it's own load- and savefunctions.
+    With this macro, you can simply use them instead of writing your own functions.
+
+    @example
+    Your class is called SpaceShip and this class has an object (myPilot_) of class Pilot. Pilot has a name
+    and two functions, setName(name) and getName(). Now you want an attribute "pilotname" in your
+    SpaceShip class. Instead of writing wrapper functions, you can simply use the XMLPortParamExtern
+    macro:
+    > XMLPortParamExtern(SpaceShip, Pilot, myPilot_, "pilotname", setName, getName, xmlelement, mode);
+*/
+#define XMLPortParamExtern(classname, externclass, object, paramname, loadfunction, savefunction, xmlelement, mode) \
+    static ExecutorMember<externclass>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&externclass::loadfunction), std::string( #externclass ) + "::" + #loadfunction); \
+    static ExecutorMember<externclass>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&externclass::savefunction), std::string( #externclass ) + "::" + #savefunction); \
+    XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, externclass, object, paramname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode);
+/**
+    @brief This is the same as XMLPortParamTemplate, but for extern attributes (see XMLPortParamExtern).
+*/
+#define XMLPortParamExternTemplate(classname, externclass, object, paramname, loadfunction, savefunction, xmlelement, mode, ...) \
+    static ExecutorMember<externclass>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<externclass, __VA_ARGS__ >(&externclass::loadfunction), std::string( #externclass ) + "::" + #loadfunction); \
+    static ExecutorMember<externclass>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&externclass::savefunction), std::string( #externclass ) + "::" + #savefunction); \
+    XMLPortParamGeneric(xmlcontainer##loadfunction##savefunction, classname, externclass, object, paramname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode);
+
+// -------------------
+// XMLPortParamGeneric
+
+/**
+    @brief This is the generic XMLPort param macro, which is used by all six specialized macros above.
+*/
+#define XMLPortParamGeneric(containername, classname, objectclass, object, paramname, loadexecutor, saveexecutor, xmlelement, mode) \
+    orxonox::XMLPortClassParamContainer<objectclass>* containername = static_cast<orxonox::XMLPortClassParamContainer<objectclass>*>(ClassIdentifier<classname>::getIdentifier()->getXMLPortParamContainer(paramname)); \
+    if (!containername) \
+    { \
+        containername = new orxonox::XMLPortClassParamContainer<objectclass>(std::string(paramname), ClassIdentifier<classname>::getIdentifier(), loadexecutor, saveexecutor); \
+        ClassIdentifier<classname>::getIdentifier()->addXMLPortParamContainer(paramname, containername); \
+    } \
+    containername->port(dynamic_cast<BaseObject*>(this), object, xmlelement, mode)
+
+// --------------------
+// XMLPortObjectExtended
+
+/**
+    @brief Declares a possible sub-object that can be added in the XML file.
+    @param classname The name of the class that uses this macro
+    @param objectclass The baseclass of objects that can be added
+    @param sectionname The name of the subsection in the XML file that encloses the sub-objects ("" means no subsection)
+    @param loadfunction The function to add a new object to the class
+    @param loadfunction The function to get all added objects from the class
+    @param xmlelement The XMLElement (recieved through the XMLPort function)
+    @param mode The mode (load/save) (received through the XMLPort function)
+    @param bApplyLoaderMask If this is true, an added sub-object gets loaded only if it's class is included in the Loaders ClassTreeMask (this is usually false)
+    @param bLoadBefore If this is true, the sub-object gets loaded (through XMLPort) BEFORE it gets added to the main class (this is usually true)
+
+    bApplyLoaderMask is usually false for the following reason:
+    If the loaders mask says, for example, "load only SpaceShips" and you added weapons to the
+    SpaceShips, then the Weapons will still be loaded (which is most probably what you want).
+    Of course, if there are "standalone" weapons in the level, they wont be loaded.
+
+    If bLoadBefore is true, an added object already has all attributes set (like it's name). This is most
+    likely the best option, so this is usually true.
+
+    @note
+    The load- and savefunctions have to follow an exactly defined protocol.
+    Loadfunction:
+      The loadfunction gets a pointer to the object.
+      > void loadfunction(objectclass* pointer);
+
+    Savefunction:
+      The savefunction gets an index, starting with 0. For every returnvalue != 0, the savefunction
+      gets called again, but with index + 1. It's the functions responsibility to do something smart
+      with the index and to return 0 if all objects were returned.
+      > objectclass* savefunction(unsigned int index) const;
+
+      Possible implementation:
+        objectclass* savefunction(unsigned int index) const
+        {
+          if (index < number_of_added_objects_)
+            return my_added_objects[index];
+          else
+            return 0;
+        }
+
+    @example
+    Possible usage of the macro:
+    > XMLPortObject(SpaceShip, Weapon, "weapons", addWeapon, getWeapon, xmlelement, mode, false, true);
+
+    Now you can add weapons through the XML file:
+    <SpaceShip someattribute="..." ...>
+      <weapons>
+        <Weapon someattribute="..." ... />
+        <Weapon someattribute="..." ... />
+        <Weapon someattribute="..." ... />
+      </weapons>
+    </SpaceShip>
+
+    Note that "weapons" is the subsection. This allows you to add more types of sub-objects. In our example,
+    you could add pilots, blinking lights or other stuff. If you don't want a subsection, just use "" (an
+    empty string). Then you can add sub-objects directly into the mainclass.
+*/
+#define XMLPortObjectExtended(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, mode, bApplyLoaderMask, bLoadBefore) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
+    XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode, bApplyLoaderMask, bLoadBefore)
+/**
+    @brief This is the same as XMLPortObjectExtended, but you can specify the loadfunction by adding the param types. See XMLPortParamTemplate for more details about the types.
+*/
+#define XMLPortObjectExtendedTemplate(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, mode, bApplyLoaderMask, bLoadBefore, ...) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
+    XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode, bApplyLoaderMask, bLoadBefore)
+
+// -------------
+// XMLPortObject
+
+/**
+    @brief This is the same as XMLPortObjectExtended, but bApplyLoaderMask is false and bLoadBefore is true by default.
+*/
+#define XMLPortObject(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, mode) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
+    XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode, false, true)
+/**
+    @brief This is the same as XMLPortObject, but you can specify the loadfunction by adding the param types. See XMLPortParamTemplate for more details about the types.
+*/
+#define XMLPortObjectTemplate(classname, objectclass, sectionname, loadfunction, savefunction, xmlelement, mode, ...) \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##loadexecutor = orxonox::createExecutor(orxonox::createFunctor<classname, __VA_ARGS__ >(&classname::loadfunction), std::string( #classname ) + "::" + #loadfunction); \
+    static ExecutorMember<classname>* xmlcontainer##loadfunction##savefunction##saveexecutor = orxonox::createExecutor(orxonox::createFunctor(&classname::savefunction), std::string( #classname ) + "::" + #savefunction); \
+    XMLPortObjectGeneric(xmlcontainer##loadfunction##savefunction, classname, objectclass, sectionname, xmlcontainer##loadfunction##savefunction##loadexecutor, xmlcontainer##loadfunction##savefunction##saveexecutor, xmlelement, mode, false, true)
+
+// --------------------
+// XMLPortObjectGeneric
+
+/**
+    @brief Generic XMLPortObject macro, that gets called by all other XMLPortObject macros above.
+*/
+#define XMLPortObjectGeneric(containername, classname, objectclass, sectionname, loadexecutor, saveexecutor, xmlelement, mode, bApplyLoaderMask, bLoadBefore) \
+    orxonox::XMLPortClassObjectContainer<classname, objectclass>* containername = (orxonox::XMLPortClassObjectContainer<classname, objectclass>*)(ClassIdentifier<classname>::getIdentifier()->getXMLPortObjectContainer(sectionname)); \
+    if (!containername) \
+    { \
+        containername = new orxonox::XMLPortClassObjectContainer<classname, objectclass>(std::string(sectionname), ClassIdentifier<classname>::getIdentifier(), loadexecutor, saveexecutor, bApplyLoaderMask, bLoadBefore); \
+        ClassIdentifier<classname>::getIdentifier()->addXMLPortObjectContainer(sectionname, containername); \
+    } \
+    containername->port(this, xmlelement, mode)
+
+
+namespace orxonox
+{
+    // ###############################
+    // ###  XMLPortParamContainer  ###
+    // ###############################
+    class _CoreExport XMLPortParamContainer
+    {
+    public:
+        enum ParseResult
+        {
+            PR_not_started,
+            PR_finished,
+            PR_waiting_for_default_values
+        };
+
+        public:
+            XMLPortParamContainer()
+                { this->parseResult_ = PR_not_started; }
+            virtual ~XMLPortParamContainer() {}
+
+            inline const std::string& getName() const
+                { return this->paramname_; }
+
+            virtual XMLPortParamContainer& description(const std::string& description) = 0;
+            virtual const std::string& getDescription() = 0;
+
+            virtual XMLPortParamContainer& defaultValue(unsigned int index, const MultiType& param) = 0;
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1) = 0;
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2) = 0;
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3) = 0;
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4) = 0;
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) = 0;
+
+        protected:
+            std::string paramname_;
+            ParseResult parseResult_;
+            Identifier* identifier_;
+            BaseObject* owner_;
+    };
+
+    template <class T>
+    class XMLPortClassParamContainer : public XMLPortParamContainer
+    {
+        struct ParseParams
+        {
+            T* object;
+            Element* xmlelement;
+            XMLPort::Mode mode;
+        };
+
+        public:
+            XMLPortClassParamContainer(const std::string& paramname, Identifier* identifier, ExecutorMember<T>* loadexecutor, ExecutorMember<T>* saveexecutor)
+            {
+                this->paramname_ = paramname;
+                this->identifier_ = identifier;
+                this->loadexecutor_ = loadexecutor;
+                this->saveexecutor_ = saveexecutor;
+            }
+
+            ~XMLPortClassParamContainer()
+            {
+                assert(this->loadexecutor_);
+                delete this->loadexecutor_;
+                if (this->saveexecutor_)
+                    delete this->saveexecutor_;
+            }
+
+            XMLPortParamContainer& port(BaseObject* owner, T* object, Element& xmlelement, XMLPort::Mode mode)
+            {
+                OrxAssert(owner, "XMLPortParamContainer must have a BaseObject as owner.");
+                this->owner_ = owner;
+                this->parseParams_.object = object;
+                this->parseParams_.xmlelement = &xmlelement;
+                this->parseParams_.mode = mode;
+
+                if ((mode == XMLPort::LoadObject) || (mode == XMLPort::ExpandObject))
+                {
+                    try
+                    {
+                        if (this->owner_->lastLoadedXMLElement_ != &xmlelement)
+                        {
+                            this->owner_->xmlAttributes_.clear();
+                            // Iterate through the attributes manually in order to make them case insensitive
+                            ticpp::Attribute* attribute = xmlelement.FirstAttribute(false);
+                            while (attribute != 0)
+                            {
+                                this->owner_->xmlAttributes_[getLowercase(attribute->Name())] = attribute->Value();
+                                attribute = attribute->Next(false);
+                            }
+                            this->owner_->lastLoadedXMLElement_ = &xmlelement;
+                        }
+                        std::map<std::string, std::string>::const_iterator it = this->owner_->xmlAttributes_.find(getLowercase(this->paramname_));
+                        std::string attributeValue;
+                        if (it != this->owner_->xmlAttributes_.end())
+                            attributeValue = it->second;
+
+                        // TODO: Checking the iterator would be better since then we can have strings with value "" as well.
+                        //       Unfortunately this does not seem to work with the Executor parser yet.
+                        if ((!attributeValue.empty()) || ((mode != XMLPort::ExpandObject) && this->loadexecutor_->allDefaultValuesSet()))
+                        {
+                            COUT(5) << this->owner_->getLoaderIndentation() << "Loading parameter " << this->paramname_ << " in " << this->identifier_->getName() << " (objectname " << this->owner_->getName() << ")." << std::endl << this->owner_->getLoaderIndentation();
+                            if (this->loadexecutor_->parse(object, attributeValue, ",") || (mode  == XMLPort::ExpandObject))
+                                this->parseResult_ = PR_finished;
+                            else
+                                this->parseResult_ = PR_waiting_for_default_values;
+                        }
+                        else if (mode == XMLPort::ExpandObject)
+                            this->parseResult_ = PR_finished;
+                        else
+                            this->parseResult_ = PR_waiting_for_default_values;
+                    }
+                    catch (ticpp::Exception& ex)
+                    {
+                        COUT(1) << std::endl;
+                        COUT(1) << "An error occurred in XMLPort.h while loading attribute '" << this->paramname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << this->owner_->getName() << ") in " << this->owner_->getFilename() << ':' << std::endl;
+                        COUT(1) << ex.what() << std::endl;
+                    }
+                }
+                else if (mode == XMLPort::SaveObject)
+                {
+                    if (this->saveexecutor_)
+                    {
+//                        xmlelement.SetAttribute(this->paramname_, "...");
+                    }
+                }
+
+                return (*this);
+            }
+
+            XMLPortParamContainer& port(BaseObject* owner, const ParseParams& parseParams)
+            {
+                return this->port(owner, parseParams.object, *parseParams.xmlelement, parseParams.mode);
+            }
+
+            XMLPortParamContainer& portIfWaitingForDefaultValues(const ParseResult& result, const ParseParams& params)
+            {
+                if (result == PR_waiting_for_default_values)
+                    return this->port(this->owner_, params);
+                else
+                    return (*this);
+            }
+
+            virtual XMLPortParamContainer& description(const std::string& description)
+                { this->loadexecutor_->setDescription(description); return (*this); }
+            virtual const std::string& getDescription()
+                { return this->loadexecutor_->getDescription(); }
+
+            virtual XMLPortParamContainer& defaultValue(unsigned int index, const MultiType& param)
+            {
+                if (!this->loadexecutor_->defaultValueSet(index))
+                    this->loadexecutor_->setDefaultValue(index, param);
+                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
+            }
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1)
+            {
+                if (!this->loadexecutor_->defaultValueSet(0))
+                    this->loadexecutor_->setDefaultValues(param1);
+                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
+            }
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2)
+            {
+                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)))
+                    this->loadexecutor_->setDefaultValues(param1, param2);
+                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
+            }
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3)
+            {
+                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2)))
+                    this->loadexecutor_->setDefaultValues(param1, param2, param3);
+                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
+            }
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4)
+            {
+                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2)) || (!this->loadexecutor_->defaultValueSet(3)))
+                    this->loadexecutor_->setDefaultValues(param1, param2, param3, param4);
+                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
+            }
+            virtual XMLPortParamContainer& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5)
+            {
+                if ((!this->loadexecutor_->defaultValueSet(0)) || (!this->loadexecutor_->defaultValueSet(1)) || (!this->loadexecutor_->defaultValueSet(2)) || (!this->loadexecutor_->defaultValueSet(3)) || (!this->loadexecutor_->defaultValueSet(4)))
+                    this->loadexecutor_->setDefaultValues(param1, param2, param3, param4, param5);
+                return this->portIfWaitingForDefaultValues(this->parseResult_, this->parseParams_);
+            }
+
+        private:
+            ExecutorMember<T>* loadexecutor_;
+            ExecutorMember<T>* saveexecutor_;
+            ParseParams parseParams_;
+    };
+
+
+    // ################################
+    // ###  XMLPortObjectContainer  ###
+    // ################################
+    class _CoreExport XMLPortObjectContainer
+    {
+        public:
+            XMLPortObjectContainer()
+                { this->bApplyLoaderMask_ = false; }
+            virtual ~XMLPortObjectContainer() {}
+
+            inline const std::string& getName() const
+                { return this->sectionname_; }
+
+            virtual XMLPortObjectContainer& description(const std::string& description) = 0;
+            virtual const std::string& getDescription() = 0;
+
+            bool identifierIsIncludedInLoaderMask(const Identifier* identifier);
+
+        protected:
+            std::string sectionname_;
+            bool bApplyLoaderMask_;
+            bool bLoadBefore_;
+            Identifier* identifier_;
+    };
+
+    template <class T, class O>
+    class XMLPortClassObjectContainer : public XMLPortObjectContainer
+    {
+        public:
+            XMLPortClassObjectContainer(const std::string& sectionname, Identifier* identifier, ExecutorMember<T>* loadexecutor, ExecutorMember<T>* saveexecutor, bool bApplyLoaderMask, bool bLoadBefore)
+            {
+                this->sectionname_ = sectionname;
+                this->identifier_ = identifier;
+                this->loadexecutor_ = loadexecutor;
+                this->saveexecutor_ = saveexecutor;
+                this->bApplyLoaderMask_ = bApplyLoaderMask;
+                this->bLoadBefore_ = bLoadBefore;
+            }
+
+            ~XMLPortClassObjectContainer()
+            {
+                assert(this->loadexecutor_);
+                delete this->loadexecutor_;
+                if (this->saveexecutor_)
+                    delete this->saveexecutor_;
+            }
+
+            XMLPortObjectContainer& port(T* object, Element& xmlelement, XMLPort::Mode mode)
+            {
+                if ((mode == XMLPort::LoadObject) || (mode == XMLPort::ExpandObject))
+                {
+                    try
+                    {
+                        Element* xmlsubelement;
+                        if (!this->sectionname_.empty())
+                            xmlsubelement = xmlelement.FirstChildElement(this->sectionname_, false);
+                        else
+                            xmlsubelement = &xmlelement;
+
+                        if (xmlsubelement)
+                        {
+                            for (ticpp::Iterator<ticpp::Element> child = xmlsubelement->FirstChildElement(false); child != child.end(); child++)
+                            {
+                                Identifier* identifier = Identifier::getIdentifierByString(child->Value());
+                                if (identifier)
+                                {
+                                    if (identifier->isA(ClassIdentifier<O>::getIdentifier()))
+                                    {
+                                        if (identifier->isLoadable())
+                                        {
+                                            if (this->identifierIsIncludedInLoaderMask(identifier))
+                                            {
+                                                try
+                                                {
+                                                    COUT(4) << object->getLoaderIndentation() << "fabricating " << child->Value() << "..." << std::endl;
+
+                                                    BaseObject* newObject = identifier->fabricate(static_cast<BaseObject*>(object));
+                                                    assert(newObject);
+                                                    newObject->setLoaderIndentation(object->getLoaderIndentation() + "  ");
+
+                                                    O* castedObject = orxonox_cast<O*>(newObject);
+                                                    assert(castedObject);
+
+                                                    if (this->bLoadBefore_)
+                                                    {
+                                                        newObject->XMLPort(*child, XMLPort::LoadObject);
+                                                        COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->identifier_->getName() << " (objectname " << static_cast<BaseObject*>(object)->getName() << ')' << std::endl;
+                                                    }
+                                                    else
+                                                    {
+                                                        COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << this->identifier_->getName() << " (objectname " << static_cast<BaseObject*>(object)->getName() << ')' << std::endl;
+                                                    }
+
+                                                    COUT(5) << object->getLoaderIndentation();
+                                                    (*this->loadexecutor_)(object, castedObject);
+
+                                                    if (!this->bLoadBefore_)
+                                                        newObject->XMLPort(*child, XMLPort::LoadObject);
+
+                                                    COUT(5) << object->getLoaderIndentation() << "...fabricated " << child->Value() << " (objectname " << newObject->getName() << ")." << std::endl;
+                                                }
+                                                catch (AbortLoadingException& ex)
+                                                {
+                                                    COUT(1) << "An error occurred while loading object, abort loading..." << std::endl;
+                                                    throw ex;
+                                                }
+                                                catch (...)
+                                                {
+                                                    COUT(1) << "An error occurred while loading object:" << std::endl;
+                                                    COUT(1) << Exception::handleMessage() << std::endl;
+                                                }
+                                            }
+                                        }
+                                        else
+                                        {
+                                            COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not loadable." << std::endl;
+                                        }
+                                    }
+                                    else
+                                    {
+                                        COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a '" << ClassIdentifier<O>::getIdentifier()->getName() << "'." << std::endl;
+                                    }
+                                }
+                                else
+                                {
+                                    if (!this->sectionname_.empty())
+                                    {
+                                        COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a valid classname." << std::endl;
+                                    }
+                                    else
+                                    {
+                                        // It's probably just another subsection
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    catch (ticpp::Exception& ex)
+                    {
+                        COUT(1) << std::endl;
+                        COUT(1) << "An error occurred in XMLPort.h while loading a '" << ClassIdentifier<O>::getIdentifier()->getName() << "' in '" << this->sectionname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << object->getName() << ") in " << object->getFilename() << ':' << std::endl;
+                        COUT(1) << ex.what() << std::endl;
+                    }
+                }
+                else if (mode == XMLPort::SaveObject)
+                {
+                }
+
+                return (*this);
+            }
+
+            virtual XMLPortObjectContainer& description(const std::string& description)
+                { this->loadexecutor_->setDescription(description); return (*this); }
+            virtual const std::string& getDescription()
+                { return this->loadexecutor_->getDescription(); }
+
+        private:
+            ExecutorMember<T>* loadexecutor_;
+            ExecutorMember<T>* saveexecutor_;
+    };
+
+
+    // ####################################
+    // ###  XMLPortVariableHelperClass  ###
+    // ####################################
+    /**
+    @brief
+        Helper class to load and save simple variables with XMLPort.
+
+        getLoader and getSaver were necessary to get the type T with
+        the help of template function type deduction (const T& is unused).
+        These functions return the adress of save<T> or load<T>.
+    */
+    class XMLPortVariableHelperClass
+    {
+        public:
+            XMLPortVariableHelperClass(void* var)
+                : variable_(var)
+                { }
+
+            template <class T>
+            void load(const T& value)
+                { *static_cast<T*>(this->variable_) = value; }
+
+            template <class T>
+            const T& save()
+                { return *static_cast<T*>(this->variable_); }
+
+            template <class T>
+            static void (XMLPortVariableHelperClass::*getLoader(const T& var))(const T& value)
+                { return &XMLPortVariableHelperClass::load<T>; }
+
+            template <class T>
+            static const T& (XMLPortVariableHelperClass::*getSaver(const T& var))()
+                { return &XMLPortVariableHelperClass::save<T>; }
+
+        private:
+            void* variable_;
+    };
+}
+
+#endif /* _XMLPort_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/Button.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/Button.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/Button.cc	(revision 6952)
@@ -0,0 +1,262 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of the different input handlers.
+*/
+
+#include "Button.h"
+
+#include "util/Convert.h"
+#include "util/SubString.h"
+#include "util/StringUtils.h"
+#include "util/Debug.h"
+#include "core/ConsoleCommand.h"
+#include "core/CommandEvaluation.h"
+#include "core/CommandExecutor.h"
+#include "core/ConfigFileManager.h"
+
+namespace orxonox
+{
+    /**
+    @note
+        bButtonThresholdUser_: We set it to true so that setConfigValues in KeyBinder sets the value
+        correctly the first time. It is then set to false first and changed later in Button::parse().
+    */
+    Button::Button()
+        : bButtonThresholdUser_(false)
+        , paramCommandBuffer_(0)
+    {
+        nCommands_[0]=0;
+        nCommands_[1]=0;
+        nCommands_[2]=0;
+    }
+
+    Button::~Button()
+    {
+        this->clear();
+    }
+
+    void Button::clear()
+    {
+        for (unsigned int j = 0; j < 3; j++)
+        {
+            if (nCommands_[j])
+            {
+                // delete all commands and the command pointer array
+                for (unsigned int i = 0; i < nCommands_[j]; i++)
+                    delete commands_[j][i];
+                delete[] commands_[j];
+                commands_[j] = 0;
+                nCommands_[j] = 0;
+            }
+        }
+        this->bindingString_.clear();
+    }
+
+    void Button::readBinding(ConfigFile* configFile, ConfigFile* fallbackFile)
+    {
+        std::string binding = configFile->getOrCreateValue(groupName_, name_, "", true);
+        if (binding.empty() && fallbackFile)
+            binding = fallbackFile->getValue(groupName_, name_, true);
+        this->parse(binding);
+    }
+
+    void Button::setBinding(ConfigFile* configFile, ConfigFile* fallbackFile, const std::string& binding, bool bTemporary)
+    {
+        if (!bTemporary)
+            configFile->setValue(groupName_, name_, binding, true);
+        this->parse(binding);
+    }
+
+    void Button::parse(const std::string& binding)
+    {
+        if (binding == this->bindingString_)
+            return;
+
+        // delete all commands
+        clear();
+        this->bindingString_ = binding;
+
+        if (isEmpty(bindingString_) || removeTrailingWhitespaces(getLowercase(binding)) == "nobinding")
+            return;
+
+        // reset this to false first when parsing (was true before when parsing for the first time)
+        bButtonThresholdUser_ = false;
+
+        // use std::vector for a temporary dynamic array
+        std::vector<BaseCommand*> commands[3];
+
+        // separate the commands
+        SubString commandStrings(bindingString_, "|", SubString::WhiteSpaces, false,
+            '\\', false, '"', false, '(', ')', false, '\0');
+
+        for (unsigned int iCommand = 0; iCommand < commandStrings.size(); iCommand++)
+        {
+            if (!commandStrings[iCommand].empty())
+            {
+                SubString tokens(commandStrings[iCommand], " ", SubString::WhiteSpaces, false,
+                    '\\', false, '"', false, '(', ')', false, '\0');
+
+                KeybindMode::Value mode = KeybindMode::None;
+                float paramModifier = 1.0f;
+                std::string commandStr;
+
+                for (unsigned int iToken = 0; iToken < tokens.size(); ++iToken)
+                {
+                    const std::string& token = getLowercase(tokens[iToken]);
+
+                    if (token == "onpress")
+                        mode = KeybindMode::OnPress;
+                    else if (token == "onrelease")
+                        mode = KeybindMode::OnRelease;
+                    else if (token == "onhold")
+                        mode = KeybindMode::OnHold;
+                    else if (token == "buttonthreshold")
+                    {
+                        // for real axes, we can feed a ButtonThreshold argument
+                        ++iToken;
+                        if (iToken == tokens.size())
+                            continue;
+                        // may fail, but doesn't matter (default value already set)
+                        if (!convertValue(&buttonThreshold_, tokens[iToken + 1]))
+                            parseError("Could not parse 'ButtonThreshold' argument. \
+                                Switching to default value.", true);
+                        else
+                            this->bButtonThresholdUser_ = true;
+                    }
+                    else if (token == "scale")
+                    {
+                        ++iToken;
+                        if (iToken == tokens.size() || !convertValue(&paramModifier, tokens[iToken]))
+                            parseError("Could not parse 'scale' argument. Switching to default value.", true);
+                    }
+                    else
+                    {
+                        // no input related argument
+                        // we interpret everything from here as a command string
+                        while (iToken != tokens.size())
+                            commandStr += tokens[iToken++] + ' ';
+                    }
+                }
+
+                if (commandStr.empty())
+                {
+                    parseError("No command string given.", false);
+                    continue;
+                }
+
+                // evaluate the command
+                const CommandEvaluation& eval = CommandExecutor::evaluate(commandStr);
+                if (!eval.isValid())
+                {
+                    parseError("Command evaluation of \"" + commandStr + "\"failed.", true);
+                    continue;
+                }
+
+                // check for param command
+                int paramIndex = eval.getConsoleCommand()->getInputConfiguredParam_();
+                if (paramIndex >= 0)
+                {
+                    // parameter supported command
+                    ParamCommand* cmd = new ParamCommand();
+                    cmd->scale_ = paramModifier;
+
+                    // add command to the buffer if not yet existing
+                    for (unsigned int iParamCmd = 0; iParamCmd < paramCommandBuffer_->size(); iParamCmd++)
+                    {
+                        if ((*paramCommandBuffer_)[iParamCmd]->evaluation_.getConsoleCommand()
+                            == eval.getConsoleCommand())
+                        {
+                            // already in list
+                            cmd->paramCommand_ = (*paramCommandBuffer_)[iParamCmd];
+                            break;
+                        }
+                    }
+                    if (cmd->paramCommand_ == 0)
+                    {
+                        cmd->paramCommand_ = new BufferedParamCommand();
+                        paramCommandBuffer_->push_back(cmd->paramCommand_);
+                        cmd->paramCommand_->evaluation_ = eval;
+                        cmd->paramCommand_->paramIndex_ = paramIndex;
+                    }
+
+
+                    // we don't know whether this is an actual axis or just a button
+                    if (mode == KeybindMode::None)
+                    {
+                        if (!addParamCommand(cmd))
+                        {
+                            mode = eval.getConsoleCommand()->getKeybindMode();
+                            commands[mode].push_back(cmd);
+                        }
+                    }
+                }
+                else
+                {
+                    SimpleCommand* cmd = new SimpleCommand();
+                    cmd->evaluation_ = eval;
+
+                    if (mode == KeybindMode::None)
+                        mode = eval.getConsoleCommand()->getKeybindMode();
+
+                    commands[mode].push_back(cmd);
+                }
+            }
+        }
+
+        for (unsigned int j = 0; j < 3; j++)
+        {
+            nCommands_[j] = commands[j].size();
+            if (nCommands_[j])
+            {
+                commands_[j] = new BaseCommand*[nCommands_[j]];
+                for (unsigned int i = 0; i < commands[j].size(); i++)
+                    commands_[j][i] = commands[j][i];
+            }
+            else
+                commands_[j] = 0;
+        }
+    }
+
+    inline void Button::parseError(const std::string& message, bool serious)
+    {
+        if (serious)
+        {
+            COUT(2) << "Error while parsing binding for button/axis " << this->name_ << ". "
+                << message << std::endl;
+        }
+        else
+        {
+            COUT(3) << "Warning while parsing binding for button/axis " << this->name_ << ". "
+                << message << std::endl;
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/input/Button.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/Button.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/Button.h	(revision 6952)
@@ -0,0 +1,89 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Different definitions of input processing.
+*/
+
+#ifndef _Button_H__
+#define _Button_H__
+
+#include "InputPrereqs.h"
+
+#include <string>
+#include <vector>
+#include "InputCommands.h"
+
+namespace orxonox
+{
+    class _CoreExport Button
+    {
+    public:
+        Button();
+        virtual ~Button();
+        virtual void clear();
+        virtual bool addParamCommand(ParamCommand* command) { return false; }
+        void parse(const std::string& binding);
+        void readBinding(ConfigFile* configFile, ConfigFile* fallbackFile);
+        void setBinding(ConfigFile* configFile, ConfigFile* fallbackFile, const std::string& binding, bool bTemporary);
+        bool execute(KeybindMode::Value mode, float abs = 1.0f, float rel = 1.0f);
+
+        //! The configured string value
+        std::string bindingString_;
+        //! Name of the trigger as strings
+        std::string name_;
+        //! Name of the group of input triggers
+        std::string groupName_;
+        //! Basic commands for OnPress, OnHold and OnRelease
+        BaseCommand** commands_[3];
+        //! Number of basic commands
+        unsigned int nCommands_[3];
+        //! Says how much it takes for an analog axis to trigger a button
+        //! Note: This variable is here to have only one parse() function.
+        float buttonThreshold_;
+        bool bButtonThresholdUser_;
+        //! Pointer to the list of parametrised commands
+        std::vector<BufferedParamCommand*>* paramCommandBuffer_;
+
+    private:
+        void parseError(const std::string& message, bool serious);
+    };
+
+    inline bool Button::execute(KeybindMode::Value mode, float abs, float rel)
+    {
+        // execute all the parsed commands in the string
+        for (unsigned int iCommand = 0; iCommand < nCommands_[mode]; iCommand++)
+            commands_[mode][iCommand]->execute(abs, rel);
+        return true;
+    }
+
+}
+
+#endif /* _Button_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,15 @@
+ADD_SOURCE_FILES(CORE_SRC_FILES
+  Button.cc
+  HalfAxis.cc
+  InputBuffer.cc
+  InputCommands.cc
+  InputManager.cc
+  InputState.cc
+  JoyStick.cc
+  JoyStickQuantityListener.cc
+  KeyBinder.cc
+  KeyBinderManager.cc
+  Keyboard.cc
+  KeyDetector.cc
+  Mouse.cc
+)
Index: /code/branches/rocket2/src/libraries/core/input/HalfAxis.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/HalfAxis.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/HalfAxis.cc	(revision 6952)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of the different input handlers.
+*/
+
+#include "HalfAxis.h"
+#include "core/CommandEvaluation.h"
+
+namespace orxonox
+{
+    void HalfAxis::clear()
+    {
+        Button::clear();
+        if (nParamCommands_)
+        {
+            // delete all commands and the command pointer array
+            for (unsigned int i = 0; i < nParamCommands_; i++)
+                delete paramCommands_[i];
+            delete[] paramCommands_;
+            nParamCommands_ = 0;
+        }
+    }
+
+    bool HalfAxis::addParamCommand(ParamCommand* command)
+    {
+        ParamCommand** cmds = paramCommands_;
+        paramCommands_ = new ParamCommand*[++nParamCommands_];
+        unsigned int i;
+        for (i = 0; i < nParamCommands_ - 1; i++)
+            paramCommands_[i] = cmds[i];
+        paramCommands_[i] = command;
+        if (nParamCommands_ > 1)
+            delete[] cmds;
+        return true;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/input/HalfAxis.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/HalfAxis.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/HalfAxis.h	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Different definitions of input processing.
+*/
+
+#ifndef _HalfAxis_H__
+#define _HalfAxis_H__
+
+#include "InputPrereqs.h"
+
+#include "Button.h"
+#include "InputCommands.h"
+
+namespace orxonox
+{
+    class _CoreExport HalfAxis : public Button
+    {
+    public:
+        HalfAxis()
+            : relVal_(0.0f)
+            , absVal_(0.0f)
+            , paramCommands_(0)
+            , nParamCommands_(0)
+            , pressed_(false)
+            , hasChanged_(false)
+        { }
+        using Button::execute;
+        bool execute();
+        bool addParamCommand(ParamCommand* command);
+        void clear();
+
+        // axis related
+        float relVal_;
+        float absVal_;
+        ParamCommand** paramCommands_;
+        unsigned int nParamCommands_;
+
+        // button related
+        bool pressed_;
+        bool hasChanged_;
+    };
+
+    inline bool HalfAxis::execute()
+    {
+        bool success = true;
+        for (unsigned int i = 0; i < nParamCommands_; i++)
+            success = paramCommands_[i]->execute(absVal_, relVal_) && success;
+        return success;
+    }
+}
+
+#endif /* _HalfAxis_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/InputBuffer.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/InputBuffer.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/InputBuffer.cc	(revision 6952)
@@ -0,0 +1,272 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#include "InputBuffer.h"
+
+#include "util/Clipboard.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+
+namespace orxonox
+{
+    InputBuffer::InputBuffer()
+    {
+        RegisterRootObject(InputBuffer);
+
+        this->cursor_ = 0;
+        this->maxLength_ = 1024;
+        this->allowedChars_ = "abcdefghijklmnopqrstuvwxyz \
+                               ABCDEFGHIJKLMNOPQRSTUVWXYZ \
+                               äëïöüÄËÏÖÜáâàéêèíîìóôòúûù \
+                               0123456789 \
+                               \\\"(){}[]<>.:,;_-+*/=!?|$&%^~#";
+
+        this->lastKey_ = KeyCode::Unassigned;
+        this->timeSinceKeyPressed_ = 0.0f;
+        this->timeSinceKeyRepeated_ = 0.0f;
+        this->keysToRepeat_ = 0;
+
+        setConfigValues();
+    }
+
+    InputBuffer::InputBuffer(const std::string& allowedChars)
+    {
+        RegisterRootObject(InputBuffer);
+
+        this->maxLength_ = 1024;
+        this->allowedChars_ = allowedChars;
+        this->cursor_ = 0;
+
+        this->lastKey_ = KeyCode::Unassigned;
+        this->timeSinceKeyPressed_ = 0.0f;
+        this->timeSinceKeyRepeated_ = 0.0f;
+        this->keysToRepeat_ = 0;
+
+        setConfigValues();
+    }
+
+    InputBuffer::~InputBuffer()
+    {
+        for (std::list<BaseInputBufferListenerTuple*>::const_iterator it = this->listeners_.begin();
+            it != this->listeners_.end(); ++it)
+            delete *it;
+    }
+
+    void InputBuffer::setConfigValues()
+    {
+        SetConfigValue(keyRepeatDeleay_, 0.4).description("Key repeat delay of the input buffer");
+        SetConfigValue(keyRepeatTime_, 0.022).description("Key repeat time of the input buffer");
+
+        if (keyRepeatDeleay_ < 0.0)
+        {
+            ResetConfigValue(keyRepeatDeleay_);
+        }
+        if (keyRepeatTime_ < 0.0)
+        {
+            ResetConfigValue(keyRepeatTime_);
+        }
+    }
+
+    void InputBuffer::setMaxLength(unsigned int length)
+    {
+        this->maxLength_ = length;
+        if (this->buffer_.size() > length)
+            this->buffer_.resize(length);
+    }
+
+    void InputBuffer::set(const std::string& input, bool update)
+    {
+        this->clear(false);
+        this->insert(input, update);
+    }
+
+    void InputBuffer::insert(const std::string& input, bool update)
+    {
+        for (unsigned int i = 0; i < input.size(); ++i)
+        {
+            this->insert(input[i], false);
+
+            if (update)
+                this->updated(input[i], false);
+        }
+
+        if (update)
+            this->updated();
+    }
+
+    void InputBuffer::insert(const char& input, bool update)
+    {
+        if (this->charIsAllowed(input))
+        {
+            if (this->buffer_.size() >= this->maxLength_)
+                return;
+            this->buffer_.insert(this->cursor_, 1, input);
+            ++this->cursor_;
+        }
+
+        if (update)
+            this->updated(input, true);
+    }
+
+    void InputBuffer::clear(bool update)
+    {
+        this->buffer_.clear();
+        this->cursor_ = 0;
+
+        if (update)
+            this->updated();
+    }
+
+    void InputBuffer::removeBehindCursor(bool update)
+    {
+        if (this->cursor_ > 0)
+        {
+            --this->cursor_;
+            this->buffer_.erase(this->cursor_, 1);
+
+            if (update)
+                this->updated();
+        }
+    }
+
+    void InputBuffer::removeAtCursor(bool update)
+    {
+        if (this->cursor_ < this->buffer_.size())
+        {
+            this->buffer_.erase(this->cursor_, 1);
+
+            if (update)
+                this->updated();
+        }
+    }
+
+    void InputBuffer::updated()
+    {
+        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        {
+            if ((*it)->bListenToAllChanges_)
+                (*it)->callFunction();
+        }
+    }
+
+    void InputBuffer::updated(const char& update, bool bSingleInput)
+    {
+        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        {
+            if ((!(*it)->trueKeyFalseChar_) && ((*it)->bListenToAllChanges_ || ((*it)->char_ == update)) && (!(*it)->bOnlySingleInput_ || bSingleInput))
+                (*it)->callFunction();
+        }
+    }
+
+    bool InputBuffer::charIsAllowed(const char& input)
+    {
+        if (this->allowedChars_.empty())
+            return true;
+        else
+            return (this->allowedChars_.find(input) != std::string::npos);
+    }
+
+
+    void InputBuffer::processKey(const KeyEvent& evt)
+    {
+        // Prevent disaster when switching applications
+        if (evt.isModifierDown(KeyboardModifier::Alt) && evt.getKeyCode() == KeyCode::Tab)
+            return;
+
+        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        {
+            if ((*it)->trueKeyFalseChar_ && ((*it)->key_ == evt.getKeyCode()))
+                (*it)->callFunction();
+        }
+
+        if (evt.isModifierDown(KeyboardModifier::Ctrl))
+        {
+            if (evt.getKeyCode() == KeyCode::V)
+                this->insert(fromClipboard());
+            else if (evt.getKeyCode() == KeyCode::C)
+                toClipboard(this->buffer_);
+            else if (evt.getKeyCode() == KeyCode::X)
+            {
+                toClipboard(this->buffer_);
+                this->clear();
+            }
+        }
+        else if (evt.isModifierDown(KeyboardModifier::Shift))
+        {
+            if (evt.getKeyCode() == KeyCode::Insert)
+                this->insert(fromClipboard());
+            else if (evt.getKeyCode() == KeyCode::Delete)
+            {
+                toClipboard(this->buffer_);
+                this->clear();
+            }
+        }
+
+        this->insert(static_cast<char>(evt.getText()));
+    }
+
+    /**
+        @brief This update() function is called by the InputState if the InputBuffer is active.
+        @param dt Delta time
+    */
+    void InputBuffer::keyboardUpdated(float dt)
+    {
+        timeSinceKeyPressed_ += dt;
+        if (keysToRepeat_ < 10 && timeSinceKeyPressed_ > keyRepeatDeleay_)
+        {
+            // initial time out has gone by, start repeating keys
+            while (timeSinceKeyPressed_ - timeSinceKeyRepeated_ > keyRepeatTime_)
+            {
+                timeSinceKeyRepeated_ += keyRepeatTime_;
+                keysToRepeat_++;
+            }
+        }
+    }
+
+    void InputBuffer::buttonPressed(const KeyEvent& evt)
+    {
+        lastKey_ = evt.getKeyCode();
+        timeSinceKeyPressed_ = 0.0;
+        timeSinceKeyRepeated_ = keyRepeatDeleay_;
+        keysToRepeat_ = 0;
+
+        processKey(evt);
+    }
+
+    void InputBuffer::buttonHeld(const KeyEvent& evt)
+    {
+        if (evt.getKeyCode() == lastKey_)
+        {
+            while (keysToRepeat_)
+            {
+                processKey(evt);
+                keysToRepeat_--;
+            }
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/input/InputBuffer.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/InputBuffer.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/InputBuffer.h	(revision 6952)
@@ -0,0 +1,193 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#ifndef _InputBuffer_H__
+#define _InputBuffer_H__
+
+#include "InputPrereqs.h"
+
+#include <list>
+#include <string>
+#include "core/OrxonoxClass.h"
+#include "InputHandler.h"
+
+namespace orxonox
+{
+    class BaseInputBufferListenerTuple
+    {
+    public:
+        BaseInputBufferListenerTuple(bool bListenToAllChanges, bool bOnlySingleInput,
+            bool trueKeyFalseChar, char _char, KeyCode::ByEnum key)
+            : bListenToAllChanges_(bListenToAllChanges), bOnlySingleInput_(bOnlySingleInput),
+              trueKeyFalseChar_(trueKeyFalseChar), char_(_char), key_(key)
+        { }
+        virtual ~BaseInputBufferListenerTuple() { }
+        virtual void callFunction() = 0;
+        bool bListenToAllChanges_;
+        bool bOnlySingleInput_;
+        bool trueKeyFalseChar_;
+        char char_;
+        KeyCode::ByEnum key_;
+    };
+
+    template <class T>
+    class InputBufferListenerTuple : public BaseInputBufferListenerTuple
+    {
+    public:
+        InputBufferListenerTuple(T* listener, void (T::*function)(), bool bListenToAllChanges,
+            bool bOnlySingleInput, bool trueKeyFalseChar, char _char, KeyCode::ByEnum key)
+            : BaseInputBufferListenerTuple(bListenToAllChanges, bOnlySingleInput, trueKeyFalseChar, _char, key),
+              listener_(listener), function_(function)
+        { }
+        virtual ~InputBufferListenerTuple() { }
+        void callFunction()
+        {
+            (listener_->*function_)();
+        }
+        T* listener_;
+        void (T::*function_)();
+    };
+
+    class _CoreExport InputBuffer : public InputHandler, public OrxonoxClass
+    {
+        public:
+            InputBuffer();
+            ~InputBuffer();
+            InputBuffer(const std::string& allowedChars);
+
+            void setConfigValues();
+
+            unsigned int getMaxLength() const { return this->maxLength_; }
+            void setMaxLength(unsigned int length);
+
+            template <class T>
+            void registerListener(T* listener, void (T::*function)(), bool bOnlySingleInput)
+            {
+                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, true, bOnlySingleInput, false, '\0', KeyCode::Unassigned);
+                this->listeners_.insert(this->listeners_.end(), newTuple);
+            }
+            template <class T>
+            void registerListener(T* listener, void (T::*function)() const, bool bOnlySingleInput)
+            {
+                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, true, bOnlySingleInput, false, '\0', KeyCode::Unassigned);
+                this->listeners_.insert(this->listeners_.end(), newTuple);
+            }
+            template <class T>
+            void registerListener(T* listener, void (T::*function)(), char _char, bool bOnlySingleInput)
+            {
+                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, false, bOnlySingleInput, false, _char, KeyCode::Unassigned);
+                this->listeners_.insert(this->listeners_.end(), newTuple);
+            }
+            template <class T>
+            void registerListener(T* listener, void (T::*function)() const, char _char, bool bOnlySingleInput)
+            {
+                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, false, bOnlySingleInput, false, _char, KeyCode::Unassigned);
+                this->listeners_.insert(this->listeners_.end(), newTuple);
+            }
+
+            template <class T>
+            void registerListener(T* listener, void (T::*function)(), KeyCode::ByEnum key)
+            {
+                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, false, true, true, '\0', key);
+                this->listeners_.insert(this->listeners_.end(), newTuple);
+            }
+            template <class T>
+            void registerListener(T* listener, void (T::*function)() const, KeyCode::ByEnum key)
+            {
+                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, false, true, true, '\0', key);
+                this->listeners_.insert(this->listeners_.end(), newTuple);
+            }
+
+            template <class T>
+            void unregisterListener(T* listener)
+            {
+                for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); )
+                {
+                    InputBufferListenerTuple<T>* refListener = static_cast<InputBufferListenerTuple<T>*>(*it);
+                    if (refListener && refListener->listener_ == listener)
+                        this->listeners_.erase(it++);
+                    else
+                        it++;
+                }
+            }
+
+            void set(const std::string& input, bool update = true);
+            void insert(const std::string& input, bool update = true);
+            void insert(const char& input, bool update = true);
+            void clear(bool update = true);
+            void removeAtCursor(bool update = true);
+            void removeBehindCursor(bool update = true);
+
+            void updated();
+            void updated(const char& update, bool bSingleInput);
+
+            inline const std::string& get() const
+                { return this->buffer_; }
+            inline unsigned int getSize() const
+                { return this->buffer_.size(); }
+
+            inline unsigned int getCursorPosition() const
+                { return this->cursor_; }
+            inline void setCursorPosition(unsigned int cursor)
+                { if (cursor <= this->buffer_.size()) { this->cursor_ = cursor; } }
+            inline void setCursorToEnd()
+                { this->cursor_ = this->buffer_.size(); }
+            inline void setCursorToBegin()
+                { this->cursor_ = 0; }
+            inline void increaseCursor()
+                { if (this->cursor_ < this->buffer_.size()) { ++this->cursor_; } }
+            inline void decreaseCursor()
+                { if (this->cursor_ > 0) { --this->cursor_; } }
+
+            void buttonPressed(const KeyEvent& evt);
+
+        private:
+            bool charIsAllowed(const char& input);
+
+            void buttonHeld   (const KeyEvent& evt);
+            void processKey   (const KeyEvent& evt);
+
+            void keyboardUpdated(float dt);
+
+            std::string buffer_;
+            std::list<BaseInputBufferListenerTuple*> listeners_;
+            std::string allowedChars_;
+            unsigned int maxLength_;
+            unsigned int cursor_;
+
+            KeyCode::ByEnum lastKey_;
+            float timeSinceKeyPressed_;
+            float timeSinceKeyRepeated_;
+            int keysToRepeat_;
+
+            float keyRepeatDeleay_;
+            float keyRepeatTime_;
+    };
+}
+
+#endif /* _InputBuffer_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/InputCommands.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/InputCommands.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/InputCommands.cc	(revision 6952)
@@ -0,0 +1,97 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of the different input handlers.
+*/
+
+#include "InputCommands.h"
+#include "util/Math.h"
+
+namespace orxonox
+{
+    // ###############################
+    // ###  BufferedParamCommand   ###
+    // ###############################
+
+    /**
+    @brief
+        Executes a buffered command. This is used for commands with additional
+        parameters.
+    @return
+        True if command execution was successful or value was zero.
+    */
+    bool BufferedParamCommand::execute()
+    {
+        if (this->abs_ != 0.0f || this->rel_ != 0.0f)
+        {
+            evaluation_.setEvaluatedParameter(paramIndex_, Vector2(abs_, rel_));
+            // reset
+            rel_ = 0.0;
+            abs_ = 0.0;
+            return evaluation_.execute();
+        }
+        else
+            return true;
+    }
+
+    // ###############################
+    // #####    ParamCommand     #####
+    // ###############################
+
+    /**
+    @brief
+        Executes a parameter command. The commmand string is not directly executed,
+        but instead stored in a buffer list so that values can be combined.
+    @return
+        Always true.
+    */
+    bool ParamCommand::execute(float abs, float rel)
+    {
+        BufferedParamCommand& cmd = *paramCommand_;
+        // command has an additional parameter
+        if (rel != 0.0f)
+        {
+            // calculate relative movement.
+            // scale_ says how much one keystroke is
+            cmd.rel_ += scale_ * rel;
+        }
+
+        if (abs != 0.0f)
+        {
+            cmd.abs_ += scale_ * abs;
+            if (cmd.abs_ > 1.0)
+                cmd.abs_ = 1.0;
+            if (cmd.abs_ < -1.0)
+                cmd.abs_ = -1.0;
+        }
+        return true;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/input/InputCommands.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/InputCommands.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/InputCommands.h	(revision 6952)
@@ -0,0 +1,92 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Different definitions of input processing.
+*/
+
+#ifndef _InputCommands_H__
+#define _InputCommands_H__
+
+#include "InputPrereqs.h"
+#include "core/CommandEvaluation.h"
+
+namespace orxonox
+{
+    class _CoreExport BufferedParamCommand
+    {
+    public:
+        BufferedParamCommand() : abs_(0.0f), rel_(0.0), paramIndex_(-1) { }
+        bool execute();
+
+        float abs_;
+        float rel_;
+        int paramIndex_;
+        CommandEvaluation evaluation_;
+    };
+
+    class _CoreExport BaseCommand
+    {
+    public:
+        virtual ~BaseCommand() { }
+        virtual bool execute(float abs = 1.0f, float rel = 1.0f) = 0;
+    };
+
+    class _CoreExport SimpleCommand : public BaseCommand
+    {
+    public:
+        bool execute(float abs = 1.0f, float rel = 1.0f);
+
+        CommandEvaluation evaluation_;
+    };
+
+    /**
+    @brief
+        Executes a simple command with no additional paramters.
+    @return
+        True if command execution was successful, false otherwise.
+    */
+    inline bool SimpleCommand::execute(float abs, float rel)
+    {
+        return evaluation_.execute();
+    }
+
+    class _CoreExport ParamCommand : public BaseCommand
+    {
+    public:
+        ParamCommand() : scale_(1.0f), paramCommand_(0) { }
+        bool execute(float abs = 1.0f, float rel = 1.0f);
+
+        float scale_;
+        BufferedParamCommand* paramCommand_;
+    };
+}
+
+#endif /* _InputCommands_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/InputDevice.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/InputDevice.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/InputDevice.h	(revision 6952)
@@ -0,0 +1,239 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of InputDevice and InputDeviceTemplated
+*/
+
+#ifndef _InputDevice_H__
+#define _InputDevice_H__
+
+#include "InputPrereqs.h"
+
+#include <vector>
+#include <ois/OISInputManager.h>
+
+#include "util/Clock.h"
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "InputState.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Abstract base class for all input devices (mouse, keyboard and joy sticks).
+
+        It provides common virtual functions to be used by the InputManager.
+    */
+    class InputDevice
+    {
+    public:
+        //! Only resets the members
+        InputDevice(unsigned int id) : bCalibrating_(false), deviceID_(id) { }
+        virtual ~InputDevice() { }
+        //! Returns the device class (derived) name as string
+        virtual std::string getClassName() const = 0;
+        //! Updates the device which should in turn distribute events
+        virtual void update(const Clock& time) = 0;
+        //! Clear all button related buffers
+        virtual void clearBuffers() = 0;
+
+        //! Start calibrating (only useful for joy sticks)
+        void startCalibration()
+        {
+            bCalibrating_ = true;
+            this->calibrationStarted();
+        }
+
+        //! Stop calibrating and evaluate the data (only useful for joy sticks)
+        void stopCalibration()
+        {
+            this->calibrationStopped();
+            bCalibrating_ = false;
+        }
+
+        //! Returns a reference to the internal input state vector. Use with care!
+        std::vector<InputState*>& getStateListRef() { return this->inputStates_; }
+        //! Returns the ID of the device (the same as in InputDeviceEnumerator for mouse and keyboard)
+        unsigned int getDeviceID() const { return this->deviceID_; }
+        //! Tells whether the device is in calibration mode
+        bool isCalibrating() const { return bCalibrating_; }
+
+    protected:
+        //! To be ovrridden by the subclass
+        virtual void calibrationStarted() { }
+        //! To be ovrridden by the subclass
+        virtual void calibrationStopped() { }
+
+        //! List of all input states that receive events from this device
+        std::vector<InputState*> inputStates_;
+
+    private:
+        InputDevice(const InputDevice& rhs); //!< Don't use!
+
+        bool bCalibrating_;                  //!< Whether the device is in calibration mode
+        const unsigned int deviceID_;        //!< ID of the device (the same as in InputDeviceEnumerator for mouse and keyboard)
+    };
+
+    /**
+    @brief
+        Heavily templated base class for all three input devices.
+
+        The purpose of this class is not to provide an interface but rather
+        to reduce code redundancy. This concerns device creation and destruction
+        as well as common code for button events (press, release, hold).
+
+        In order to derive from this class you have to supply it with a struct
+        as template parameter that contains the necessary type traits.
+    */
+    template <class Traits>
+    class InputDeviceTemplated : public InputDevice
+    {
+        typedef typename Traits::DeviceClass DeviceClass;
+        typedef typename Traits::OISDeviceClass OISDeviceClass;
+        typedef typename Traits::ButtonType ButtonType;
+        typedef typename Traits::ButtonTypeParam ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = Traits::OISDeviceValue;
+
+    public:
+        //! Creates the OIS device
+        InputDeviceTemplated(unsigned int id, OIS::InputManager* oisInputManager)
+            : InputDevice(id)
+            , oisInputManager_(oisInputManager)
+        {
+            oisDevice_ = static_cast<OISDeviceClass*>(oisInputManager_->createInputObject(OISDeviceValue, true));
+            // Note: after the static_cast here, the casted this pointer becomes
+            //       invalid right until the subclass has been constructed!
+            oisDevice_->setEventCallback(static_cast<DeviceClass*>(this));
+            COUT(4) << "Instantiated a " << this->getClassName() << std::endl;
+        }
+
+        //! Destroys the OIS device
+        virtual ~InputDeviceTemplated()
+        {
+            try
+            {
+                oisInputManager_->destroyInputObject(oisDevice_);
+            }
+            catch (...)
+            {
+                COUT(1) << this->getClassName() << " destruction failed: " << Exception::handleMessage() << std::endl
+                        << "    Potential resource leak!" << std::endl;
+            }
+        }
+
+        //! Captures OIS events (which then get distributed to the derived class) and creates the button held events
+        void update(const Clock& time)
+        {
+            oisDevice_->capture();
+
+            // Call all the states with the held button event
+            for (unsigned int iB = 0; iB < pressedButtons_.size(); ++iB)
+                for (unsigned int iS = 0; iS < inputStates_.size(); ++iS)
+                    inputStates_[iS]->buttonEvent<ButtonEvent::THold, typename Traits::ButtonTypeParam>(
+                        this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(pressedButtons_[iB]));
+
+            // Call states with device update events
+            for (unsigned int i = 0; i < inputStates_.size(); ++i)
+                inputStates_[i]->update(time.getDeltaTime(), this->getDeviceID());
+
+            static_cast<DeviceClass*>(this)->updateImpl(time);
+        }
+
+        //! Clears the list of pressed buttons and calls the derived class's method
+        void clearBuffers()
+        {
+            pressedButtons_.clear();
+            static_cast<DeviceClass*>(this)->clearBuffersImpl();
+        }
+
+        // Returns a pointer to the OIS device
+        OISDeviceClass* getOISDevice()   { return this->oisDevice_; }
+        // Returns the name of the derived class as string
+        std::string getClassName() const { return DeviceClass::getClassNameImpl(); }
+
+    protected:
+        //! Common code for all button pressed events (updates pressed buttons list and calls the input states)
+        FORCEINLINE void buttonPressed(ButtonTypeParam button)
+        {
+            // check whether the button already is in the list (can happen when focus was lost)
+            unsigned int iButton = 0;
+            while (iButton < pressedButtons_.size() && pressedButtons_[iButton] != button)
+                iButton++;
+            if (iButton == pressedButtons_.size())
+                pressedButtons_.push_back(button);
+            else
+                return; // Button already pressed
+
+            // Call states
+            for (unsigned int i = 0; i < inputStates_.size(); ++i)
+                inputStates_[i]->buttonEvent<ButtonEvent::TPress, typename Traits::ButtonTypeParam>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
+        }
+
+        //! Common code for all button released events (updates pressed buttons list and calls the input states)
+        FORCEINLINE void buttonReleased(ButtonTypeParam button)
+        {
+            // remove the button from the pressedButtons_ list
+            bool found = false;
+            for (unsigned int iButton = 0; iButton < pressedButtons_.size(); iButton++)
+            {
+                if (pressedButtons_[iButton] == button)
+                {
+                    pressedButtons_.erase(pressedButtons_.begin() + iButton);
+                    found = true;
+                    break;
+                }
+            }
+            if (!found)
+                return; // We ignore release strokes when the press was not captured
+
+            // Call states
+            for (unsigned int i = 0; i < inputStates_.size(); ++i)
+                inputStates_[i]->buttonEvent<ButtonEvent::TRelease, typename Traits::ButtonTypeParam>(this->getDeviceID(), static_cast<DeviceClass*>(this)->getButtonEventArg(button));
+        }
+
+        //! Managed pointer to the OIS device
+        OISDeviceClass* oisDevice_;
+
+    private:
+        //!< Fallback dummy function for static polymorphism
+        void clearBuffersImpl() { }
+        //!< Fallback dummy function for static polymorphism
+        void updateImpl(const Clock& time) { }
+        //!< Fallback dummy function for static polymorphism
+        ButtonType& getButtonEventArg(ButtonType& button) { return button; }
+
+        std::vector<ButtonType> pressedButtons_; //!< List of all buttons that are currently pressed down
+        OIS::InputManager* oisInputManager_;     //!< Pointer to the OIS InputManager that can create and destroy devices
+    };
+}
+
+#endif /* _InputDevice_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/InputHandler.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/InputHandler.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/InputHandler.h	(revision 6952)
@@ -0,0 +1,154 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _InputHandler_H__
+#define _InputHandler_H__
+
+#include "InputPrereqs.h"
+#include "util/Math.h"
+
+namespace orxonox
+{
+    namespace ButtonEvent
+    {
+        //! Helper enum to deploy events with the help of templates
+        enum Value
+        {
+            Press,
+            Release,
+            Hold
+        };
+
+        //! Enables function overloading with integer values
+        template <ButtonEvent::Value Event>
+        struct EnumToType { };
+        typedef EnumToType<Press>   TPress;
+        typedef EnumToType<Release> TRelease;
+        typedef EnumToType<Hold>    THold;
+    }
+
+    namespace KeyboardModifier
+    {
+        //! Keyboard modifiers (shift, ctrl and alt)
+        enum Enum
+        {
+            Shift = 0x0000001,
+            Ctrl  = 0x0000010,
+            Alt   = 0x0000100
+        };
+    }
+
+    //! Event argument for key events
+    class _CoreExport KeyEvent
+    {
+    public:
+        KeyEvent(const OIS::KeyEvent& evt)
+            : key_(static_cast<KeyCode::ByEnum>(evt.key))
+            , text_(evt.text)
+            , modifiers_(0)
+        { }
+        KeyEvent(KeyCode::ByEnum key, unsigned int text, int modifiers)
+            : key_(key)
+            , text_(text)
+            , modifiers_(modifiers)
+        { }
+        bool operator==(const KeyEvent& rhs) const
+            { return rhs.key_ == key_; }
+        bool operator!=(const KeyEvent& rhs) const
+            { return rhs.key_ != key_; }
+        void setModifiers(int modifiers)
+            { modifiers_ = modifiers; }
+
+        bool isModifierDown(KeyboardModifier::Enum modifier) const
+            { return static_cast<KeyboardModifier::Enum>(modifier & modifiers_); }
+        KeyCode::ByEnum getKeyCode() const
+            { return key_; }
+        unsigned int getText() const { return text_; }
+
+    private:
+        KeyCode::ByEnum key_;
+        unsigned int text_;
+        int modifiers_;
+    };
+
+    /**
+    @brief
+        Base class for all input handlers like KeyBinder, InputBuffer, etc.
+
+        Derive from this class if you wish to receive input events.
+        But keep in mind that this is pointless without first having an InputState.
+    @note
+        The definitions for the button events with the weird arguments are simply
+        to avoid redundant code in the input devices.
+    */
+    class _CoreExport InputHandler
+    {
+    public:
+        virtual ~InputHandler() { }
+
+        template<class T> void buttonEvent(unsigned int device, T button, ButtonEvent::TPress)
+            { this->buttonPressed(button); }
+        template<class T> void buttonEvent(unsigned int device, T button, ButtonEvent::TRelease)
+            { this->buttonReleased(button); }
+        template<class T> void buttonEvent(unsigned int device, T button, ButtonEvent::THold)
+            { this->buttonHeld(button); }
+
+        virtual void buttonPressed (const KeyEvent& evt) { }
+        virtual void buttonReleased(const KeyEvent& evt) { }
+        virtual void buttonHeld    (const KeyEvent& evt) { }
+
+        virtual void buttonPressed (MouseButtonCode::ByEnum button) { }
+        virtual void buttonReleased(MouseButtonCode::ByEnum button) { }
+        virtual void buttonHeld    (MouseButtonCode::ByEnum button) { }
+        virtual void mouseMoved    (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) { }
+        virtual void mouseScrolled (int abs, int rel) { }
+
+        virtual void buttonPressed (unsigned int joyStick, JoyStickButtonCode::ByEnum button) { }
+        virtual void buttonReleased(unsigned int joyStick, JoyStickButtonCode::ByEnum button) { }
+        virtual void buttonHeld    (unsigned int joyStick, JoyStickButtonCode::ByEnum button) { }
+        virtual void axisMoved     (unsigned int joyStick, unsigned int axis, float value){ }
+
+        virtual void keyboardUpdated(float dt) { }
+        virtual void mouseUpdated   (float dt) { }
+        virtual void joyStickUpdated(unsigned int joyStick, float dt) { }
+
+        virtual void allDevicesUpdated(float dt) { }
+
+        //! Use this input handler if you want to occupy a device in an input state.
+        static InputHandler EMPTY;
+    };
+
+    template<> inline void InputHandler::buttonEvent<JoyStickButtonCode::ByEnum>(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TPress)
+        { this->buttonPressed(device - InputDeviceEnumerator::FirstJoyStick, button); }
+    template<> inline void InputHandler::buttonEvent<JoyStickButtonCode::ByEnum>(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::TRelease)
+        { this->buttonReleased(device - InputDeviceEnumerator::FirstJoyStick, button); }
+    template<> inline void InputHandler::buttonEvent<JoyStickButtonCode::ByEnum>(unsigned int device, JoyStickButtonCode::ByEnum button, ButtonEvent::THold)
+        { this->buttonHeld(device - InputDeviceEnumerator::FirstJoyStick, button); }
+}
+
+#endif /* _InputHandler_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/InputManager.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/InputManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/InputManager.cc	(revision 6952)
@@ -0,0 +1,646 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of the InputManager and a static variable from the InputHandler.
+*/
+
+#include "InputManager.h"
+
+#include <cassert>
+#include <climits>
+#include <ois/OISException.h>
+#include <ois/OISInputManager.h>
+#include <boost/foreach.hpp>
+
+#include "util/Clock.h"
+#include "util/Convert.h"
+#include "util/Exception.h"
+#include "util/ScopeGuard.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/ConsoleCommand.h"
+#include "core/CommandLineParser.h"
+#include "core/Functor.h"
+#include "core/GraphicsManager.h"
+
+#include "InputBuffer.h"
+#include "JoyStick.h"
+#include "JoyStickQuantityListener.h"
+#include "Mouse.h"
+#include "Keyboard.h"
+
+namespace orxonox
+{
+    SetCommandLineSwitch(keyboard_no_grab).information("Whether not to exclusively grab the keyboard");
+
+    // Abuse of this source file for the InputHandler
+    InputHandler InputHandler::EMPTY;
+
+    InputManager* InputManager::singletonPtr_s = 0;
+
+    //! Defines the |= operator for easier use.
+    inline InputManager::State operator|=(InputManager::State& lval, InputManager::State rval)
+    {
+        return (lval = (InputManager::State)(lval | rval));
+    }
+
+    //! Defines the &= operator for easier use.
+    inline InputManager::State operator&=(InputManager::State& lval, int rval)
+    {
+        return (lval = (InputManager::State)(lval & rval));
+    }
+
+    // ############################################################
+    // #####                  Initialisation                  #####
+    // ##########                                        ##########
+    // ############################################################
+    InputManager::InputManager()
+        : internalState_(Bad)
+        , oisInputManager_(0)
+        , devices_(2)
+        , exclusiveMouse_(TriBool::False)
+        , emptyState_(0)
+        , calibratorCallbackHandler_(0)
+    {
+        RegisterRootObject(InputManager);
+
+        CCOUT(4) << "Constructing..." << std::endl;
+
+        // Allocate space for the function call buffer
+        this->callBuffer_.reserve(16);
+
+        this->setConfigValues();
+
+        if (GraphicsManager::getInstance().isFullScreen())
+            exclusiveMouse_ = TriBool::True;
+        this->loadDevices();
+
+        // Lowest priority empty InputState
+        emptyState_ = createInputState("empty", false, false, InputStatePriority::Empty);
+        emptyState_->setHandler(&InputHandler::EMPTY);
+        activeStates_[emptyState_->getPriority()] = emptyState_;
+
+        // Joy stick calibration helper callback
+        InputState* calibrator = createInputState("calibrator", false, false, InputStatePriority::Calibrator);
+        calibrator->setHandler(&InputHandler::EMPTY);
+        calibratorCallbackHandler_ = new InputBuffer();
+        calibratorCallbackHandler_->registerListener(this, &InputManager::stopCalibration, '\r', true);
+        calibrator->setKeyHandler(calibratorCallbackHandler_);
+
+        this->updateActiveStates();
+
+        // calibrate console command
+        this->getIdentifier()->addConsoleCommand(createConsoleCommand(createFunctor(&InputManager::calibrate, this), "calibrate"), true);
+        // reload console command
+        this->getIdentifier()->addConsoleCommand(createConsoleCommand(createFunctor(&InputManager::reload, this), "reload"), false);
+
+        CCOUT(4) << "Construction complete." << std::endl;
+        internalState_ = Nothing;
+    }
+
+    void InputManager::setConfigValues()
+    {
+    }
+
+    /**
+    @brief
+        Creates the OIS::InputMananger, the keyboard, the mouse and
+        the joys ticks. If either of the first two fail, this method throws an exception.
+    @param windowWidth
+        The width of the render window
+    @param windowHeight
+        The height of the render window
+    */
+    void InputManager::loadDevices()
+    {
+        CCOUT(4) << "Loading input devices..." << std::endl;
+
+        // When loading the devices they should not already be loaded
+        assert(internalState_ & Bad);
+        assert(devices_[InputDeviceEnumerator::Mouse] == 0);
+        assert(devices_[InputDeviceEnumerator::Keyboard] == 0);
+        assert(devices_.size() == InputDeviceEnumerator::FirstJoyStick);
+
+        // Fill parameter list
+        OIS::ParamList paramList;
+        size_t windowHnd = GraphicsManager::getInstance().getRenderWindowHandle();
+        paramList.insert(std::make_pair("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"));
+        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"));
+#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"));
+
+        if (exclusiveMouse_ == TriBool::True || GraphicsManager::getInstance().isFullScreen())
+        {
+            if (CommandLineParser::getValue("keyboard_no_grab").getBool())
+                paramList.insert(std::make_pair("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"));
+        }
+#endif
+
+        try
+        {
+            oisInputManager_ = OIS::InputManager::createInputSystem(paramList);
+            // Exception-safety
+            Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, oisInputManager_);
+            CCOUT(4) << "Created OIS input manager." << std::endl;
+
+            if (oisInputManager_->getNumberOfDevices(OIS::OISKeyboard) > 0)
+                devices_[InputDeviceEnumerator::Keyboard] = new Keyboard(InputDeviceEnumerator::Keyboard, oisInputManager_);
+            else
+                ThrowException(InitialisationFailed, "InputManager: No keyboard found, cannot proceed!");
+
+            // Successful initialisation
+            guard.Dismiss();
+        }
+        catch (const std::exception& ex)
+        {
+            oisInputManager_ = NULL;
+            internalState_ |= Bad;
+            ThrowException(InitialisationFailed, "Could not initialise the input system: " << ex.what());
+        }
+
+        this->loadMouse();
+        this->loadJoySticks();
+
+        // Reorder states in case some joy sticks were added/removed
+        this->updateActiveStates();
+
+        CCOUT(4) << "Input devices loaded." << std::endl;
+    }
+
+    //! Creates a new orxonox::Mouse
+    void InputManager::loadMouse()
+    {
+        if (oisInputManager_->getNumberOfDevices(OIS::OISMouse) > 0)
+        {
+            try
+            {
+                devices_[InputDeviceEnumerator::Mouse] = new Mouse(InputDeviceEnumerator::Mouse, oisInputManager_);
+            }
+            catch (const std::exception& ex)
+            {
+                CCOUT(2) << "Warning: Failed to create Mouse:" << ex.what() << std::endl
+                         << "Proceeding without mouse support." << std::endl;
+            }
+        }
+        else
+            CCOUT(2) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
+    }
+
+    //! Creates as many joy sticks as are available.
+    void InputManager::loadJoySticks()
+    {
+        for (int i = 0; i < oisInputManager_->getNumberOfDevices(OIS::OISJoyStick); i++)
+        {
+            try
+            {
+                devices_.push_back(new JoyStick(InputDeviceEnumerator::FirstJoyStick + i, oisInputManager_));
+            }
+            catch (const std::exception& ex)
+            {
+                CCOUT(2) << "Warning: Failed to create joy stick: " << ex.what() << std::endl;
+            }
+        }
+
+        // inform all JoyStick Device Number Listeners
+        std::vector<JoyStick*> joyStickList;
+        for (unsigned int i = InputDeviceEnumerator::FirstJoyStick; i < devices_.size(); ++i)
+            joyStickList.push_back(static_cast<JoyStick*>(devices_[i]));
+        JoyStickQuantityListener::changeJoyStickQuantity(joyStickList);
+    }
+
+    // ############################################################
+    // #####                    Destruction                   #####
+    // ##########                                        ##########
+    // ############################################################
+
+    InputManager::~InputManager()
+    {
+        CCOUT(3) << "Destroying..." << std::endl;
+
+        // Leave all active InputStates (except "empty")
+        while (this->activeStates_.size() > 1)
+            this->leaveState(this->activeStates_.rbegin()->second->getName());
+        this->activeStates_.clear();
+
+        // Destroy calibrator helper handler and state
+        this->destroyState("calibrator");
+        // Destroy KeyDetector and state
+        calibratorCallbackHandler_->destroy();
+        // Destroy the empty InputState
+        this->destroyStateInternal(this->emptyState_);
+
+        // Destroy all user InputStates
+        while (statesByName_.size() > 0)
+            this->destroyStateInternal(statesByName_.rbegin()->second);
+
+        if (!(internalState_ & Bad))
+            this->destroyDevices();
+
+        CCOUT(3) << "Destruction complete." << std::endl;
+    }
+
+    /**
+    @brief
+        Destoys all input devices (joy sticks, mouse, keyboard and OIS::InputManager)
+    @throw
+        Method does not throw
+    */
+    void InputManager::destroyDevices()
+    {
+        CCOUT(4) << "Destroying devices..." << std::endl;
+
+        BOOST_FOREACH(InputDevice*& device, devices_)
+        {
+            if (device == NULL)
+                continue;
+            const std::string& className = device->getClassName();
+            try
+            {
+                delete device;
+                device = 0;
+                CCOUT(4) << className << " destroyed." << std::endl;
+            }
+            catch (...)
+            {
+                COUT(1) << className << " destruction failed: " << Exception::handleMessage() << std::endl
+                        << "    Potential resource leak!" << std::endl;
+            }
+        }
+        devices_.resize(InputDeviceEnumerator::FirstJoyStick);
+
+        assert(oisInputManager_ != NULL);
+        try
+        {
+            OIS::InputManager::destroyInputSystem(oisInputManager_);
+        }
+        catch (...)
+        {
+            COUT(1) << "OIS::InputManager destruction failed" << Exception::handleMessage() << std::endl
+                    << "    Potential resource leak!" << std::endl;
+        }
+        oisInputManager_ = NULL;
+
+        internalState_ |= Bad;
+        CCOUT(4) << "Destroyed devices." << std::endl;
+    }
+
+    // ############################################################
+    // #####                     Reloading                    #####
+    // ##########                                        ##########
+    // ############################################################
+
+    void InputManager::reload()
+    {
+        if (internalState_ & Calibrating)
+            CCOUT(2) << "Warning: Cannot reload input system. Joy sticks are currently being calibrated." << std::endl;
+        else
+            reloadInternal();
+    }
+
+    //! Internal reload method. Destroys the OIS devices and loads them again.
+    void InputManager::reloadInternal()
+    {
+        CCOUT(4) << "Reloading ..." << std::endl;
+
+        this->destroyDevices();
+        this->loadDevices();
+
+        internalState_ &= ~Bad;
+        CCOUT(4) << "Reloading complete." << std::endl;
+    }
+
+    // ############################################################
+    // #####                  Runtime Methods                 #####
+    // ##########                                        ##########
+    // ############################################################
+
+    void InputManager::preUpdate(const Clock& time)
+    {
+        if (internalState_ & Bad)
+            ThrowException(General, "InputManager was not correctly reloaded.");
+
+        // check whether a state has changed its EMPTY situation
+        bool bUpdateRequired = false;
+        for (std::map<int, InputState*>::iterator it = activeStates_.begin(); it != activeStates_.end(); ++it)
+        {
+            if (it->second->hasExpired())
+            {
+                it->second->resetExpiration();
+                bUpdateRequired = true;
+            }
+        }
+        if (bUpdateRequired)
+            updateActiveStates();
+
+        // Capture all the input and collect the function calls
+        // No event gets triggered here yet!
+        BOOST_FOREACH(InputDevice* device, devices_)
+            if (device != NULL)
+                device->update(time);
+
+        // Collect function calls for the update
+        for (unsigned int i = 0; i < activeStatesTicked_.size(); ++i)
+            activeStatesTicked_[i]->update(time.getDeltaTime());
+
+        // Execute all cached function calls in order
+        // Why so complicated? The problem is that an InputHandler could trigger
+        // a reload that would destroy the OIS devices or it could even leave and
+        // then destroy its own InputState. That would of course lead to access
+        // violations.
+        // If we delay the calls, then OIS and and the InputStates are not anymore
+        // in the call stack and can therefore be edited.
+        for (size_t i = 0; i < this->callBuffer_.size(); ++i)
+            this->callBuffer_[i]();
+
+        this->callBuffer_.clear();
+    }
+
+    /**
+    @brief
+        Updates the currently active states (according to activeStates_) for each device.
+        Also, a list of all active states (no duplicates!) is compiled for the general preUpdate().
+    */
+    void InputManager::updateActiveStates()
+    {
+        // Calculate the stack of input states
+        // and assign it to the corresponding device
+        for (unsigned int i = 0; i < devices_.size(); ++i)
+        {
+            if (devices_[i] == NULL)
+                continue;
+            std::vector<InputState*>& states = devices_[i]->getStateListRef();
+            bool occupied = false;
+            states.clear();
+            for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin(); rit != activeStates_.rend(); ++rit)
+            {
+                if (rit->second->isInputDeviceEnabled(i) && (!occupied || rit->second->bAlwaysGetsInput_))
+                {
+                    states.push_back(rit->second);
+                    if (!rit->second->bTransparent_)
+                        occupied = true;
+                }
+            }
+        }
+
+        // See that we only update each InputState once for each device
+        // Using an std::set to avoid duplicates
+        std::set<InputState*> tempSet;
+        for (unsigned int i = 0; i < devices_.size(); ++i)
+            if (devices_[i] != NULL)
+                for (unsigned int iState = 0; iState < devices_[i]->getStateListRef().size(); ++iState)
+                    tempSet.insert(devices_[i]->getStateListRef()[iState]);
+
+        // Copy the content of the std::set back to the actual vector
+        activeStatesTicked_.clear();
+        for (std::set<InputState*>::const_iterator it = tempSet.begin();it != tempSet.end(); ++it)
+            activeStatesTicked_.push_back(*it);
+
+        // Check whether we have to change the mouse mode
+        TriBool::Value requestedMode = TriBool::Dontcare;
+        std::vector<InputState*>& mouseStates = devices_[InputDeviceEnumerator::Mouse]->getStateListRef();
+        if (mouseStates.empty())
+            requestedMode = TriBool::False;
+        else
+            requestedMode = mouseStates.front()->getMouseExclusive();
+        if (requestedMode != TriBool::Dontcare && exclusiveMouse_ != requestedMode)
+        {
+            exclusiveMouse_ = requestedMode;
+            if (!GraphicsManager::getInstance().isFullScreen())
+                this->reloadInternal();
+        }
+    }
+
+    void InputManager::clearBuffers()
+    {
+        BOOST_FOREACH(InputDevice* device, devices_)
+            if (device != NULL)
+                device->clearBuffers();
+    }
+
+    void InputManager::calibrate()
+    {
+        COUT(0) << "Move all joy stick axes fully in all directions." << std::endl
+                << "When done, put the axex in the middle position and press enter." << std::endl;
+
+        BOOST_FOREACH(InputDevice* device, devices_)
+            if (device != NULL)
+                device->startCalibration();
+
+        internalState_ |= Calibrating;
+        enterState("calibrator");
+    }
+
+    //! Tells all devices to stop the calibration and evaluate it. Buffers are being cleared as well!
+    void InputManager::stopCalibration()
+    {
+        BOOST_FOREACH(InputDevice* device, devices_)
+            if (device != NULL)
+                device->stopCalibration();
+
+        // restore old input state
+        leaveState("calibrator");
+        internalState_ &= ~Calibrating;
+        // Clear buffers to prevent button hold events
+        this->clearBuffers();
+
+        COUT(0) << "Calibration has been stored." << std::endl;
+    }
+
+    //! Gets called by WindowEventListener upon focus change --> clear buffers
+    void InputManager::windowFocusChanged()
+    {
+        this->clearBuffers();
+    }
+
+    std::pair<int, int> InputManager::getMousePosition() const
+    {
+        Mouse* mouse = static_cast<Mouse*>(devices_[InputDeviceEnumerator::Mouse]);
+        if (mouse != NULL)
+        {
+            const OIS::MouseState state = mouse->getOISDevice()->getMouseState();
+            return std::make_pair(state.X.abs, state.Y.abs);
+        }
+        else
+            return std::make_pair(0, 0);
+    }
+
+    // ############################################################
+    // #####                    Input States                  #####
+    // ##########                                        ##########
+    // ############################################################
+
+    InputState* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
+    {
+        if (name.empty())
+            return 0;
+        if (statesByName_.find(name) == statesByName_.end())
+        {
+            if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
+            {
+                // Make sure we don't add two high priority states with the same priority
+                for (std::map<std::string, InputState*>::const_iterator it = this->statesByName_.begin();
+                    it != this->statesByName_.end(); ++it)
+                {
+                    if (it->second->getPriority() == priority)
+                    {
+                        COUT(2) << "Warning: Could not add an InputState with the same priority '"
+                            << static_cast<int>(priority) << "' != 0." << std::endl;
+                        return 0;
+                    }
+                }
+            }
+            InputState* state = new InputState(name, bAlwaysGetsInput, bTransparent, priority);
+            statesByName_[name] = state;
+
+            return state;
+        }
+        else
+        {
+            COUT(2) << "Warning: Could not add an InputState with the same name '" << name << "'." << std::endl;
+            return 0;
+        }
+    }
+
+    InputState* InputManager::getState(const std::string& name)
+    {
+        std::map<std::string, InputState*>::iterator it = statesByName_.find(name);
+        if (it != statesByName_.end())
+            return it->second;
+        else
+            return 0;
+    }
+
+    bool InputManager::enterState(const std::string& name)
+    {
+        // get pointer from the map with all stored handlers
+        std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name);
+        if (it != statesByName_.end() && activeStates_.find(it->second->getPriority()) == activeStates_.end())
+        {
+            // exists and not active
+            if (it->second->getPriority() == 0)
+            {
+                // Get smallest possible priority between 1 and maxStateStackSize_s
+                for (std::map<int, InputState*>::reverse_iterator rit = activeStates_.rbegin();
+                    rit != activeStates_.rend(); ++rit)
+                {
+                    if (rit->first < InputStatePriority::HighPriority)
+                    {
+                        it->second->setPriority(rit->first + 1);
+                        break;
+                    }
+                }
+                // In case no normal handler was on the stack
+                if (it->second->getPriority() == 0)
+                    it->second->setPriority(1);
+            }
+            activeStates_[it->second->getPriority()] = it->second;
+            updateActiveStates();
+            it->second->entered();
+
+            return true;
+        }
+        return false;
+    }
+
+    bool InputManager::leaveState(const std::string& name)
+    {
+        if (name == "empty")
+        {
+            COUT(2) << "InputManager: Leaving the empty state is not allowed!" << std::endl;
+            return false;
+        }
+        // get pointer from the map with all stored handlers
+        std::map<std::string, InputState*>::const_iterator it = statesByName_.find(name);
+        if (it != statesByName_.end() && activeStates_.find(it->second->getPriority()) != activeStates_.end())
+        {
+            // exists and active
+
+            it->second->left();
+
+            activeStates_.erase(it->second->getPriority());
+            if (it->second->getPriority() < InputStatePriority::HighPriority)
+                it->second->setPriority(0);
+            updateActiveStates();
+
+            return true;
+        }
+        return false;
+    }
+
+    bool InputManager::destroyState(const std::string& name)
+    {
+        if (name == "empty")
+        {
+            COUT(2) << "InputManager: Removing the empty state is not allowed!" << std::endl;
+            return false;
+        }
+        std::map<std::string, InputState*>::iterator it = statesByName_.find(name);
+        if (it != statesByName_.end())
+        {
+            this->leaveState(name);
+            destroyStateInternal(it->second);
+
+            return true;
+        }
+        return false;
+    }
+
+    //! Destroys an InputState internally.
+    void InputManager::destroyStateInternal(InputState* state)
+    {
+        assert(state && this->activeStates_.find(state->getPriority()) == this->activeStates_.end());
+        statesByName_.erase(state->getName());
+        state->destroy();
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/input/InputManager.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/InputManager.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/InputManager.h	(revision 6952)
@@ -0,0 +1,223 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _InputManager_H__
+#define _InputManager_H__
+
+#include "InputPrereqs.h"
+
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include <boost/function.hpp>
+
+#include "util/Singleton.h"
+#include "util/TriBool.h"
+#include "core/WindowEventListener.h"
+
+// tolua_begin
+namespace orxonox
+{
+    /**
+    @brief
+        Manages the input devices (mouse, keyboard, joy sticks) and the input states.
+
+        Every input device has its own wrapper class which does the actually input event
+        distribution. The InputManager only creates reloads (on request) those devices.
+
+        The other functionality concerns handling InputStates. They act as a layer
+        between InputHandlers (like the KeyBinder or the GUIManager) and InputDevices.
+        InputStates are memory managed by the IputManager. You cannot create or destroy
+        them on your own. Therefore all states get destroyed with the InputManager d'tor.
+    @note
+        - The actual lists containing all the InputStates for a specific device are stored
+          in the InputDevices themselves.
+        - The devices_ vector always has at least two elements: Keyboard (first) and mouse.
+          You best access them internally with InputDeviceEnumerator::Keyboard/Mouse
+          The first joy stick is accessed with InputDeviceEnumerator::FirstJoyStick.
+        - Keyboard construction is mandatory , mouse and joy sticks are not.
+          If the OIS::InputManager or the Keyboard fail, an exception is thrown.
+    */
+    class _CoreExport InputManager
+// tolua_end
+        : public Singleton<InputManager>, public WindowEventListener
+    { // tolua_export
+        friend class Singleton<InputManager>;
+    public:
+        //! Represents internal states of the InputManager.
+        enum State
+        {
+            Nothing       = 0x00,
+            Bad           = 0x02,
+            Calibrating   = 0x04,
+        };
+
+        /**
+        @brief
+            Loads the devices and initialises the KeyDetector and the Calibrator.
+
+            If either the OIS input system and/or the keyboard could not be created,
+            the constructor fails with an std::exception.
+        */
+        InputManager();
+        //! Destroys all devices AND all input states!
+        ~InputManager();
+        void setConfigValues();
+
+        /**
+        @brief
+            Updates the devices (which distribute the input events) and the input states.
+
+            Any InpuStates changes (destroy, enter, leave) and happens here. If a reload request
+            was submitted while updating, the request will be postponed until the next update call.
+        */
+        void preUpdate(const Clock& time);
+        //! Clears all input device buffers. This usually only includes the pressed button list.
+        void clearBuffers();
+        //! Starts joy stick calibration.
+        void calibrate();
+        /**
+        @brief
+            Reloads all the input devices. Use this method to initialise new joy sticks.
+        @note
+            Only reloads immediately if the call stack doesn't include the preUpdate() method.
+        */
+        void reload();
+
+        //-------------------------------
+        // Input States
+        //-------------------------------
+        /**
+        @brief
+            Creates a new InputState that gets managed by the InputManager.
+        @remarks
+            The InputManager will take care of the state completely. That also
+            means it gets deleted when the InputManager is destroyed!
+        @param name
+            Unique name of the InputState when referenced as string
+        @param priority
+            Priority matters when multiple states are active. You can specify any
+            number, but 1 - 99 is preferred (99 means high priority).
+        */
+        InputState* createInputState(const std::string& name, bool bAlwaysGetsInput = false, bool bTransparent = false, InputStatePriority priority = InputStatePriority::Dynamic);
+        /**
+        @brief
+            Returns a pointer to a InputState referenced by name.
+        @return
+            Returns NULL if state was not found.
+        */
+        InputState* getState(const std::string& name);
+        /**
+        @brief
+            Activates a specific input state.
+            It might not actually be activated if the priority is too low!
+        @return
+            False if name was not found, true otherwise.
+        */
+        bool enterState(const std::string& name); // tolua_export
+        /**
+        @brief
+            Deactivates a specific input state.
+        @return
+            False if name was not found, true otherwise.
+        */
+        bool leaveState(const std::string& name); // tolua_export
+        /**
+        @brief
+            Removes and destroys an input state.
+        @return
+            True if removal was successful, false if name was not found.
+        @remarks
+            - You can't remove the internal states "empty", "calibrator" and "detector".
+            - The removal process is being postponed if InputManager::preUpdate() is currently running.
+        */
+        bool destroyState(const std::string& name); // tolua_export
+
+        //-------------------------------
+        // Various getters and setters
+        //-------------------------------
+        //! Returns the number of joy stick that have been created since the c'tor or last call to reload().
+        unsigned int getJoyStickQuantity() const
+            { return devices_.size() - InputDeviceEnumerator::FirstJoyStick; }
+        //! Returns a pointer to the OIS InputManager. Only you if you know what you're doing!
+        OIS::InputManager* getOISInputManager() { return this->oisInputManager_; }
+        //! Returns the position of the cursor as std::pair of ints
+        std::pair<int, int> getMousePosition() const;
+        //! Tells whether the mouse is used exclusively to the game
+        bool isMouseExclusive() const { return this->exclusiveMouse_; } // tolua_export
+
+        //-------------------------------
+        // Function call caching
+        //-------------------------------
+        void pushCall(const boost::function<void ()>& function)
+            { this->callBuffer_.push_back(function); }
+
+        static InputManager& getInstance() { return Singleton<InputManager>::getInstance(); } // tolua_export
+
+    private: // functions
+        // don't mess with a Singleton
+        InputManager(const InputManager&);
+
+        // Internal methods
+        void loadDevices();
+        void loadMouse();
+        void loadJoySticks();
+        void destroyDevices();
+
+        void stopCalibration();
+        void reloadInternal();
+
+        void destroyStateInternal(InputState* state);
+        void updateActiveStates();
+
+        // From WindowEventListener
+        void windowFocusChanged();
+
+    private: // variables
+        State                               internalState_;        //!< Current internal state
+        OIS::InputManager*                  oisInputManager_;      //!< OIS input manager
+        std::vector<InputDevice*>           devices_;              //!< List of all input devices (keyboard, mouse, joy sticks)
+        TriBool::Value                      exclusiveMouse_;       //!< Currently applied mouse mode
+
+        // some internally handled states and handlers
+        InputState*                         emptyState_;           //!< Lowest priority states (makes handling easier)
+        //! InputBuffer that reacts to the Enter key when calibrating the joy sticks
+        InputBuffer*                        calibratorCallbackHandler_;
+
+        std::map<std::string, InputState*>  statesByName_;         //!< Contains all the created input states by name
+        std::map<int, InputState*>          activeStates_;         //!< Contains all active input states by priority (std::map is sorted!)
+        std::vector<InputState*>            activeStatesTicked_;   //!< Like activeStates_, but only contains the ones that currently receive events
+
+        std::vector<boost::function<void ()> > callBuffer_;        //!< Caches all calls from InputStates to be executed afterwards (see preUpdate)
+
+        static InputManager*                singletonPtr_s;        //!< Pointer reference to the singleton
+    }; // tolua_export
+} // tolua_export
+
+#endif /* _InputManager_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/InputPrereqs.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/InputPrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/InputPrereqs.h	(revision 6952)
@@ -0,0 +1,467 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Declarations of all key/button/axis code enumeration and string literals
+    and an input device enumeration.
+*/
+
+#ifndef _InputPrereqs_H__
+#define _InputPrereqs_H__
+
+#include "core/CorePrereqs.h"
+
+#include <ois/OISKeyboard.h>
+#include <ois/OISMouse.h>
+#include <ois/OISJoyStick.h>
+#include "util/OrxEnum.h"
+
+namespace orxonox
+{
+    //-----------------------------------------------------------------------
+    // Code enumerations
+    //-----------------------------------------------------------------------
+
+    namespace KeyCode
+    {
+        const unsigned int numberOfKeys = 0xEE; // 238
+
+        //! Key codes as enumeration
+        enum ByEnum
+        {
+            Unassigned    = OIS::KC_UNASSIGNED,
+            Escape        = OIS::KC_ESCAPE,
+            NumRow1       = OIS::KC_1,
+            NumRow2       = OIS::KC_2,
+            NumRow3       = OIS::KC_3,
+            NumRow4       = OIS::KC_4,
+            NumRow5       = OIS::KC_5,
+            NumRow6       = OIS::KC_6,
+            NumRow7       = OIS::KC_7,
+            NumRow8       = OIS::KC_8,
+            NumRow9       = OIS::KC_9,
+            NumRow0       = OIS::KC_0,
+            Minus         = OIS::KC_MINUS,           // - on main keyboard
+            Equals        = OIS::KC_EQUALS,
+            Back          = OIS::KC_BACK,            // backspace
+            Tab           = OIS::KC_TAB,
+            Q             = OIS::KC_Q,
+            W             = OIS::KC_W,
+            E             = OIS::KC_E,
+            R             = OIS::KC_R,
+            T             = OIS::KC_T,
+            Y             = OIS::KC_Y,
+            U             = OIS::KC_U,
+            I             = OIS::KC_I,
+            O             = OIS::KC_O,
+            P             = OIS::KC_P,
+            LeftBracket   = OIS::KC_LBRACKET,
+            RightBracket  = OIS::KC_RBRACKET,
+            Return        = OIS::KC_RETURN,          // Enter on main keyboard
+            LeftControl   = OIS::KC_LCONTROL,
+            A             = OIS::KC_A,
+            S             = OIS::KC_S,
+            D             = OIS::KC_D,
+            F             = OIS::KC_F,
+            G             = OIS::KC_G,
+            H             = OIS::KC_H,
+            J             = OIS::KC_J,
+            K             = OIS::KC_K,
+            L             = OIS::KC_L,
+            Semicolon     = OIS::KC_SEMICOLON,
+            Apostrophe    = OIS::KC_APOSTROPHE,
+            Grave         = OIS::KC_GRAVE,           // accent
+            LeftShift     = OIS::KC_LSHIFT,
+            Backslash     = OIS::KC_BACKSLASH,
+            Z             = OIS::KC_Z,
+            X             = OIS::KC_X,
+            C             = OIS::KC_C,
+            V             = OIS::KC_V,
+            B             = OIS::KC_B,
+            N             = OIS::KC_N,
+            M             = OIS::KC_M,
+            Comma         = OIS::KC_COMMA,
+            Period        = OIS::KC_PERIOD,          // . on main keyboard
+            Slash         = OIS::KC_SLASH,           // / on main keyboard
+            RightShift    = OIS::KC_RSHIFT,
+            Multiply      = OIS::KC_MULTIPLY,        // * on numeric keypad
+            LeftAlt       = OIS::KC_LMENU,           // left Alt
+            Space         = OIS::KC_SPACE,
+            CapsLock      = OIS::KC_CAPITAL,
+            F1            = OIS::KC_F1,
+            F2            = OIS::KC_F2,
+            F3            = OIS::KC_F3,
+            F4            = OIS::KC_F4,
+            F5            = OIS::KC_F5,
+            F6            = OIS::KC_F6,
+            F7            = OIS::KC_F7,
+            F8            = OIS::KC_F8,
+            F9            = OIS::KC_F9,
+            F10           = OIS::KC_F10,
+            NumLock       = OIS::KC_NUMLOCK,
+            ScrollLock    = OIS::KC_SCROLL,          // Scroll Lock
+            Numpad7       = OIS::KC_NUMPAD7,
+            Numpad8       = OIS::KC_NUMPAD8,
+            Numpad9       = OIS::KC_NUMPAD9,
+            NumpadSubtract= OIS::KC_SUBTRACT,        // - on numeric keypad
+            Numpad4       = OIS::KC_NUMPAD4,
+            Numpad5       = OIS::KC_NUMPAD5,
+            Numpad6       = OIS::KC_NUMPAD6,
+            NumpadAdd     = OIS::KC_ADD,             // + on numeric keypad
+            Numpad1       = OIS::KC_NUMPAD1,
+            Numpad2       = OIS::KC_NUMPAD2,
+            Numpad3       = OIS::KC_NUMPAD3,
+            Numpad0       = OIS::KC_NUMPAD0,
+            NumpadPeriod  = OIS::KC_DECIMAL,         // . on numeric keypad
+            LessThan      = OIS::KC_OEM_102,         // < > | on UK/Germany keyboards
+            F11           = OIS::KC_F11,
+            F12           = OIS::KC_F12,
+            F13           = OIS::KC_F13,             //                     (NEC PC98)
+            F14           = OIS::KC_F14,             //                     (NEC PC98)
+            F15           = OIS::KC_F15,             //                     (NEC PC98)
+            Kana          = OIS::KC_KANA,            // (Japanese keyboard)
+            ABNT_C1       = OIS::KC_ABNT_C1,         // / ? on Portugese (Brazilian) keyboards
+            Convert       = OIS::KC_CONVERT,         // (Japanese keyboard)
+            NoConvert     = OIS::KC_NOCONVERT,       // (Japanese keyboard)
+            Yen           = OIS::KC_YEN,             // (Japanese keyboard)
+            ABNT_C2       = OIS::KC_ABNT_C2,         // Numpad . on Portugese (Brazilian) keyboards
+            NumpadEquals  = OIS::KC_NUMPADEQUALS,    // = on numeric keypad (NEC PC98)
+            PreviousTrack = OIS::KC_PREVTRACK,       // Previous Track (KC_CIRCUMFLEX on Japanese keyboard)
+            AT            = OIS::KC_AT,              //                     (NEC PC98)
+            Colon         = OIS::KC_COLON,           //                     (NEC PC98)
+            Underline     = OIS::KC_UNDERLINE,       //                     (NEC PC98)
+            Kanji         = OIS::KC_KANJI,           // (Japanese keyboard)
+            Stop          = OIS::KC_STOP,            //                     (NEC PC98)
+            AX            = OIS::KC_AX,              //                     (Japan AX)
+            Unlabeled     = OIS::KC_UNLABELED,       //                        (J3100)
+            NextTrack     = OIS::KC_NEXTTRACK,       // Next Track
+            NumpadEnter   = OIS::KC_NUMPADENTER,     // Enter on numeric keypad
+            RightControl  = OIS::KC_RCONTROL,
+            Mute          = OIS::KC_MUTE,            // Mute
+            Calculator    = OIS::KC_CALCULATOR,      // Calculator
+            PlayPause     = OIS::KC_PLAYPAUSE,       // Play / Pause
+            MediaStop     = OIS::KC_MEDIASTOP,       // Media Stop
+            VolumeDown    = OIS::KC_VOLUMEDOWN,      // Volume -
+            VolumeUp      = OIS::KC_VOLUMEUP,        // Volume +
+            WebHome       = OIS::KC_WEBHOME,         // Web home
+            NumpadComma   = OIS::KC_NUMPADCOMMA,     // , on numeric keypad (NEC PC98)
+            Divide        = OIS::KC_DIVIDE,          // / on numeric keypad
+            SystemRequest = OIS::KC_SYSRQ,
+            RightAlt      = OIS::KC_RMENU,           // right Alt
+            Pause         = OIS::KC_PAUSE,           // Pause
+            Home          = OIS::KC_HOME,            // Home on arrow keypad
+            Up            = OIS::KC_UP,              // UpArrow on arrow keypad
+            PageUp        = OIS::KC_PGUP,            // PgUp on arrow keypad
+            Left          = OIS::KC_LEFT,            // LeftArrow on arrow keypad
+            Right         = OIS::KC_RIGHT,           // RightArrow on arrow keypad
+            End           = OIS::KC_END,             // End on arrow keypad
+            Down          = OIS::KC_DOWN,            // DownArrow on arrow keypad
+            PageDown      = OIS::KC_PGDOWN,          // PgDn on arrow keypad
+            Insert        = OIS::KC_INSERT,          // Insert on arrow keypad
+            Delete        = OIS::KC_DELETE,          // Delete on arrow keypad
+            LeftWindows   = OIS::KC_LWIN,            // Left Windows key
+            RightWindows  = OIS::KC_RWIN,            // Right Windows key
+            Apps          = OIS::KC_APPS,            // AppMenu key
+            Power         = OIS::KC_POWER,           // System Power
+            Sleep         = OIS::KC_SLEEP,           // System Sleep
+            Wake          = OIS::KC_WAKE,            // System Wake
+            WebSearch     = OIS::KC_WEBSEARCH,       // Web Search
+            WebFavorites  = OIS::KC_WEBFAVORITES,    // Web Favorites
+            WebRefresh    = OIS::KC_WEBREFRESH,      // Web Refresh
+            WebStop       = OIS::KC_WEBSTOP,         // Web Stop
+            WebForward    = OIS::KC_WEBFORWARD,      // Web Forward
+            WebBack       = OIS::KC_WEBBACK,         // Web Back
+            MyComputer    = OIS::KC_MYCOMPUTER,      // My Computer
+            Mail          = OIS::KC_MAIL,            // Mail
+            MediaSelect   = OIS::KC_MEDIASELECT      // Media Select
+        };
+
+        //! Key codes as strings
+        const char* const ByString[] =
+        {
+            "Unassigned",
+            "Escape",
+            "NumRow1", "NumRow2", "NumRow3", "NumRow4", "NumRow5",
+            "NumRow6", "NumRow7", "NumRow8", "NumRow9", "NumRow0",
+            "Minus", "Equals", "Back", "Tab",
+            "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",
+            "LeftBracket", "RightBracket",
+            "Return", "LeftControl",
+            "A", "S", "D", "F", "G", "H", "J", "K", "L",
+            "Semicolon", "Apostrophe", "Grave",
+            "LeftShift", "Backslash",
+            "Z", "X", "C", "V", "B", "N", "M",
+            "Comma", "Period", "Slash",
+            "RightShift",
+            "Multiply",
+            "LeftAlt",
+            "Space",
+            "CapsLock",
+            "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",
+            "NumLock", "ScrollLock",
+            "Numpad7", "Numpad8", "Numpad9",
+            "NumpadSubtract",
+            "Numpad4", "Numpad5", "Numpad6",
+            "NumpadAdd",
+            "Numpad1", "Numpad2", "Numpad3", "Numpad0",
+            "NumpadPeriod",
+            "","",
+            "LessThan",
+            "F11", "F12",
+            "","","","","","","","","","","",
+            "F13", "F14", "F15",
+            "","","","","","","","","","",
+            "Kana",
+            "","",
+            "ABNT_C1",
+            "","","","","",
+            "Convert",
+            "",
+            "NoConvert",
+            "",
+            "Yen",
+            "ABNT_C2",
+            "","","","","","","","","","","","","","",
+            "NumpadEquals",
+            "","",
+            "PreviousTrack",
+            "AT",
+            "Colon", "Underline",
+            "Kanji",
+            "Stop",
+            "AX",
+            "Unlabeled",
+            "NextTrack",
+            "","",
+            "NumpadEnter",
+            "RightControl",
+            "","",
+            "Mute",
+            "Calculator",
+            "PlayPause",
+            "",
+            "MediaStop",
+            "","","","","","","","","",
+            "VolumeDown",
+            "",
+            "VolumeUp",
+            "",
+            "WebHome",
+            "NumpadComma",
+            "",
+            "Divide",
+            "",
+            "SystemRequest",
+            "RightAlt",
+            "","","","","","","","","","","","",
+            "Pause",
+            "",
+            "Home",
+            "UP",
+            "PageUp",
+            "",
+            "Left",
+            "",
+            "Right",
+            "",
+            "End", "Down", "PageDown", "Insert", "Delete",
+            "","","","","","","",
+            "LeftWindows", "RightWindows", "Apps",
+            "Power", "Sleep",
+            "","","",
+            "Wake",
+            "",
+            "WebSearch", "WebFavorites", "WebRefresh", "WebStop", "WebForward", "WebBack",
+            "MyComputer", "Mail", "MediaSelect"
+        };
+    }
+
+
+    namespace MouseButtonCode
+    {
+        const unsigned int numberOfButtons = 8;
+
+        //! Mouse button codes as enumeration
+        enum ByEnum
+        {
+            Left    = OIS::MB_Left,
+            Right   = OIS::MB_Right,
+            Middle  = OIS::MB_Middle,
+            Button3 = OIS::MB_Button3,
+            Button4 = OIS::MB_Button4,
+            Button5 = OIS::MB_Button5,
+            Button6 = OIS::MB_Button6,
+            Button7 = OIS::MB_Button7,
+        };
+
+        // Mouse button codes as strings
+        const char* const ByString[] =
+        {
+            "Left",
+            "Right",
+            "Middle",
+            "Button3",
+            "Button4",
+            "Button5",
+            "Button6",
+            "Button7",
+        };
+    }
+
+    namespace MouseAxisCode
+    {
+        const unsigned int numberOfAxes = 2;
+
+        // Mouse axis codes as enumeration
+        enum ByEnum
+        {
+            X,
+            Y
+        };
+
+        // Mouse axis codes as strings
+        const char* const ByString[] =
+        {
+            "X",
+            "Y"
+        };
+    }
+
+
+    namespace JoyStickButtonCode
+    {
+        const unsigned int numberOfButtons = 64;
+
+        // Joy stick button codes as enumeration
+        enum ByEnum
+        {
+            Button0       =  0, Button1       =  1, Button2       =  2, Button3       =  3,
+            Button4       =  4, Button5       =  5, Button6       =  6, Button7       =  7,
+            Button8       =  8, Button9       =  9, Button10      = 10, Button11      = 11,
+            Button12      = 12, Button13      = 13, Button14      = 14, Button15      = 15,
+            Button16      = 16, Button17      = 17, Button18      = 18, Button19      = 19,
+            Button20      = 20, Button21      = 21, Button22      = 22, Button23      = 23,
+            Button24      = 24, Button25      = 25, Button26      = 26, Button27      = 27,
+            Button28      = 28, Button29      = 29, Button30      = 30, Button31      = 31,
+
+            POV0North     = 32, POV0South     = 33, POV0East      = 34, POV0West      = 35,
+            POV0NorthEast = 36, POV0SouthEast = 37, POV0NorthWest = 38, POV0SouthWest = 39,
+
+            POV1North     = 40, POV1South     = 41, POV1East      = 42, POV1West      = 43,
+            POV1NorthEast = 44, POV1SouthEast = 45, POV1NorthWest = 46, POV1SouthWest = 47,
+
+            POV2North     = 48, POV2South     = 49, POV2East      = 50, POV2West      = 51,
+            POV2NorthEast = 52, POV2SouthEast = 53, POV2NorthWest = 54, POV2SouthWest = 55,
+
+            POV3North     = 56, POV3South     = 57, POV3East      = 58, POV3West      = 59,
+            POV3NorthEast = 60, POV3SouthEast = 61, POV3NorthWest = 62, POV3SouthWest = 63,
+        };
+
+        // Joy stick button codes as strings
+        const char* const ByString[] =
+        {
+            "Button00",      "Button01",      "Button02",      "Button03",
+            "Button04",      "Button05",      "Button06",      "Button07",
+            "Button08",      "Button09",      "Button10",      "Button11",
+            "Button12",      "Button13",      "Button14",      "Button15",
+            "Button16",      "Button17",      "Button18",      "Button19",
+            "Button20",      "Button21",      "Button22",      "Button23",
+            "Button24",      "Button25",      "Button26",      "Button27",
+            "Button28",      "Button29",      "Button30",      "Button31",
+            "POV0North",     "POV0South",     "POV0East",      "POV0West",
+            "POV0NorthEast", "POV0SouthEast", "POV0NorthWest", "POV0SouthWest",
+            "POV1North",     "POV1South",     "POV1East",      "POV1West",
+            "POV1NorthEast", "POV1SouthEast", "POV1NorthWest", "POV1SouthWest",
+            "POV2North",     "POV2South",     "POV2East",      "POV2West",
+            "POV2NorthEast", "POV2SouthEast", "POV2NorthWest", "POV2SouthWest",
+            "POV3North",     "POV3South",     "POV3East",      "POV3West",
+            "POV3NorthEast", "POV3SouthEast", "POV3NorthWest", "POV3SouthWest"
+        };
+    }
+
+    namespace JoyStickAxisCode
+    {
+        const unsigned int numberOfAxes = 24;
+
+        // Joy stick axis codes as enumeration
+        enum ByEnum
+        {
+            Slider0 =  0, Slider1 =  1, Slider2 =  2, Slider3 =  3,
+            Slider4 =  4, Slider5 =  5, Slider6 =  6, Slider7 =  7,
+            Axis0   =  8, Axis1   =  9, Axis2   = 10, Axis3   = 11,
+            Axis4   = 12, Axis5   = 13, Axis6   = 14, Axis7   = 15,
+            Axis8   = 16, Axis9   = 17, Axis10  = 18, Axis11  = 19,
+            Axis12  = 20, Axis13  = 21, Axis14  = 22, Axis15  = 23
+        };
+
+        // Joy stick axis codes as strings
+        const char* const ByString[] =
+        {
+            "Slider0", "Slider1", "Slider2", "Slider3",
+            "Slider4", "Slider5", "Slider6", "Slider7",
+            "Axis00",  "Axis01",  "Axis02",  "Axis03",
+            "Axis04",  "Axis05",  "Axis06",  "Axis07",
+            "Axis08",  "Axis09",  "Axis10",  "Axis11",
+            "Axis12",  "Axis13",  "Axis14",  "Axis15"
+        };
+    }
+
+
+    //-----------------------------------------------------------------------
+    // Miscellaneous
+    //-----------------------------------------------------------------------
+
+    namespace InputDeviceEnumerator
+    {
+        //! Used to access the devices in an array
+        enum Value
+        {
+            Keyboard = 0,
+            Mouse = 1,
+            FirstJoyStick = 2
+        };
+    }
+
+    //! Enumeration wrapper for input state priorities
+    struct InputStatePriority : OrxEnum<InputStatePriority>
+    {
+        OrxEnumConstructors(InputStatePriority);
+
+        static const int Empty        = -1;
+        static const int Dynamic      = 0;
+
+        static const int HighPriority = 1000;
+        static const int Console      = HighPriority + 0;
+        static const int Calibrator   = HighPriority + 1;
+        static const int Detector     = HighPriority + 2;
+    };
+}
+
+#endif /* _InputPrereqs_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/InputState.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/InputState.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/InputState.cc	(revision 6952)
@@ -0,0 +1,112 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "InputState.h"
+#include "core/Functor.h"
+
+namespace orxonox
+{
+    //! Sets priority of it's a high priority and resizes the handler list
+    InputState::InputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
+        : name_(name)
+        , bAlwaysGetsInput_(bAlwaysGetsInput)
+        , bTransparent_(bTransparent)
+        , exclusiveMouse_(TriBool::Dontcare)
+        , bExpired_(true)
+        , handlers_(2)
+        , joyStickHandlerAll_(0)
+        , enterFunctor_(0)
+        , leaveFunctor_(0)
+    {
+        if (priority >= InputStatePriority::HighPriority || priority == InputStatePriority::Empty)
+            priority_ = priority;
+        else
+            priority_ = 0;
+
+        handlers_.resize(InputDeviceEnumerator::FirstJoyStick + this->getJoyStickList().size(), NULL);
+    }
+
+    bool InputState::isInputDeviceEnabled(unsigned int device)
+    {
+        if (device < handlers_.size())
+            return handlers_[device] != NULL;
+        else
+            return false;
+    }
+
+    //! Called by JoyStickQuantityListener upon joy stick adding/removal
+    void InputState::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList)
+    {
+        unsigned int oldSize = handlers_.size();
+        handlers_.resize(InputDeviceEnumerator::FirstJoyStick + joyStickList.size(), NULL);
+
+        for (unsigned int i = oldSize; i < handlers_.size(); ++i)
+            handlers_[i] = joyStickHandlerAll_;
+
+        bExpired_ = true;
+    }
+
+    bool InputState::setJoyStickHandler(InputHandler* handler, unsigned int joyStick)
+    {
+        unsigned device = joyStick + firstJoyStickIndex_s;
+        if (joyStick >= handlers_.size() - device)
+            return false;
+
+        handlers_[device] = handler;
+        bExpired_ = true;
+        return true;
+    }
+
+    void InputState::setJoyStickHandler(InputHandler* handler)
+    {
+        joyStickHandlerAll_ = handler;
+        for (unsigned int i = firstJoyStickIndex_s; i < handlers_.size(); ++i)
+            handlers_[i] = handler;
+        bExpired_ = true;
+    }
+
+    void InputState::setHandler(InputHandler* handler)
+    {
+        setKeyHandler(handler);
+        setMouseHandler(handler);
+        setJoyStickHandler(handler);
+    }
+
+    void InputState::entered()
+    {
+        if (enterFunctor_)
+            (*enterFunctor_)();
+
+    }
+
+    void InputState::left()
+    {
+        if (leaveFunctor_)
+            (*leaveFunctor_)();
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/input/InputState.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/InputState.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/InputState.h	(revision 6952)
@@ -0,0 +1,238 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _InputState_H__
+#define _InputState_H__
+
+#include "InputPrereqs.h"
+
+#include <cassert>
+#include <string>
+#include <vector>
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+
+#include "util/TriBool.h"
+#include "InputHandler.h"
+#include "InputManager.h"
+#include "JoyStickQuantityListener.h"
+
+#define INPUT_STATE_PUSH_CALL(deviceIndex, functionName, ...) \
+    InputManager::getInstance().pushCall(boost::function<void ()>(boost::bind(&InputHandler::functionName, handlers_[deviceIndex], __VA_ARGS__)))
+
+namespace orxonox
+{
+    /**
+    @brief
+        InputStates allow you to customise the input event targets at runtime.
+
+        The general idea is a stack: Every activated InputState will be pushed on
+        that stack and only the top one gets the input events. This is done for
+        every device (keyboard, mouse, all joy sticks) separately to allow
+        for instance keyboard input capturing for the console while you can still
+        steer a ship with the mouse.
+        There are two exceptions to this behaviour though:
+        - If an InputState is created with the 'Transparent' parameter on, the
+          state will not prevent input from getting to the state below it on the stack.
+          This can be useful for instance if you need to deploy input to multiple
+          handlers: Simply create two InputStates and make the high priority one transparent.
+        - If an InputState is created with the 'AlwaysGetsInput' parameter on, then
+          the state will always receive input as long as it is activated.
+        - Note: If you mark an InputState with both parameters on, then it will
+          not influence only other InputState at all.
+
+    @par Priorities
+        Every InputState has a priority when on the stack, but mostly this
+        priority is dynamic (InputStatePriority::Dynamic) which means that a state
+        pushed onto the stack will simply have a higher priority than the top one.
+        This behaviour really only applies to normal states that don't have
+        a high priority (InputStatePriority::HighPriority). These 'special' ones
+        are used for features like the KeyDetector or the console. Use with care!
+
+    @par Exclusive/Non-Exclusive mouse Mode
+        You can select a specific mouse mode that tells whether the application
+        should have exclusive access to it or not.
+        When in non-exclusive mode, you can move the mouse out of the window
+        like with any other normal window (only for windowed mode!).
+        The setting is dictated by the topmost InputState that gets mouse events.
+    */
+    class _CoreExport InputState : public JoyStickQuantityListener
+    {
+        friend class InputManager;
+
+        //! Marks the index in the handler vector for the keyboard handler
+        static const InputDeviceEnumerator::Value keyboardIndex_s = InputDeviceEnumerator::Keyboard;
+        //! Marks the index in the handler vector for the mouse handler
+        static const InputDeviceEnumerator::Value mouseIndex_s = InputDeviceEnumerator::Mouse;
+        //! Marks the index in the handler vector for the first joy stick handler
+        static const InputDeviceEnumerator::Value firstJoyStickIndex_s = InputDeviceEnumerator::FirstJoyStick;
+
+    public:
+        //! Sets the keyboard event handler (overwrites if there already was one!)
+        void setKeyHandler     (InputHandler* handler)
+            { handlers_[keyboardIndex_s] = handler; bExpired_ = true; }
+        //! Sets the mouse event handler (overwrites if there already was one!)
+        void setMouseHandler   (InputHandler* handler)
+            { handlers_[mouseIndex_s]    = handler; bExpired_ = true; }
+        /**
+        @brief
+            Sets the joy stick event handler for one specific joy stick (overwrites if there already was one!)
+        @return
+            Returns false if the specified device was not found
+        */
+        bool setJoyStickHandler(InputHandler* handler, unsigned int joyStick);
+        //! Sets the joy stick event handler for all joy sticks (overwrites if there already was one!)
+        void setJoyStickHandler(InputHandler* handler);
+        //! Sets an InputHandler to be used for all devices
+        void setHandler        (InputHandler* handler);
+
+        void setMouseExclusive(TriBool::Value value) { exclusiveMouse_ = value; this->bExpired_ = true; }
+        TriBool::Value getMouseExclusive() const { return exclusiveMouse_; }
+
+        //! Returns the name of the state (which is unique!)
+        const std::string& getName() const { return name_; }
+        //! Returns the priority of the state (which is unique if != 0)
+        int getPriority()            const { return priority_; }
+
+        //! Tells whether there a handler installed for a specific device
+        bool isInputDeviceEnabled(unsigned int device);
+
+        //! Returns true if the handler situation has changed
+        bool hasExpired()      { return this->bExpired_; }
+        //! Call this if you have applied the changes resulting from changed handlers
+        void resetExpiration() { bExpired_ = false; }
+
+        //! Updates one specific device handler with #device#Updated
+        void update(float dt, unsigned int device);
+        //! Updates all handlers with allDevicesUpdated
+        void update(float dt);
+
+        //! Generic function that distributes all 9 button events
+        template <typename EventType, class ButtonTypeParam>
+        void buttonEvent(unsigned int device, ButtonTypeParam button);
+
+        //! Event handler
+        void mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
+        //! Event handler
+        void mouseScrolled(int abs, int rel);
+        //! Event handler
+        void joyStickAxisMoved(unsigned int device, unsigned int axis, float value);
+
+        // Functors
+        //! Called when the state is being activated (even if it doesn't get any events afterwards!)
+        void entered();
+        //! Called upon deactivation of the state
+        void left();
+        //! Sets a functor to be called upon activation of the state
+        void setEnterFunctor(Functor* functor) { this->enterFunctor_ = functor; }
+        //! Sets a functor to be called upon deactivation of the state
+        void setLeaveFunctor(Functor* functor) { this->leaveFunctor_ = functor; }
+
+    private:
+        InputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority);
+        ~InputState() { }
+
+        void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList);
+
+        //! Sets the priority (only to be used by the InputManager!)
+        void setPriority(int priority) { priority_ = priority; }
+
+        const std::string           name_;                  //!< Name of the state
+        const bool                  bAlwaysGetsInput_;      //!< See class declaration for explanation
+        const bool                  bTransparent_;          //!< See class declaration for explanation
+        TriBool::Value              exclusiveMouse_;        //!< See class declaration for explanation
+        int                         priority_;              //!< Current priority (might change)
+        bool                        bExpired_;              //!< See hasExpired()
+        std::vector<InputHandler*>  handlers_;              //!< Vector with all handlers where the index is the device ID
+        //! Handler to be used for all joy sticks (needs to be saved in case another joy stick gets attached)
+        InputHandler*               joyStickHandlerAll_;
+        Functor*                    enterFunctor_;          //!< Functor to be executed on enter
+        Functor*                    leaveFunctor_;          //!< Functor to be executed on leave
+    };
+
+    FORCEINLINE void InputState::update(float dt)
+    {
+        for (unsigned int i = 0; i < handlers_.size(); ++i)
+            if (handlers_[i] != NULL)
+                INPUT_STATE_PUSH_CALL(i, allDevicesUpdated, dt);
+    }
+
+    FORCEINLINE void InputState::update(float dt, unsigned int device)
+    {
+        switch (device)
+        {
+        case InputDeviceEnumerator::Keyboard:
+            if (handlers_[keyboardIndex_s] != NULL)
+                INPUT_STATE_PUSH_CALL(keyboardIndex_s, keyboardUpdated, dt);
+            break;
+
+        case InputDeviceEnumerator::Mouse:
+            if (handlers_[mouseIndex_s] != NULL)
+                INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseUpdated, dt);
+            break;
+
+        default: // joy sticks
+            if (handlers_[device] != NULL)
+                INPUT_STATE_PUSH_CALL(device, joyStickUpdated, device - firstJoyStickIndex_s, dt);
+            break;
+        }
+    }
+
+    template <typename EventType, class ButtonTypeParam>
+    FORCEINLINE void InputState::buttonEvent(unsigned int device, ButtonTypeParam button)
+    {
+        assert(device < handlers_.size());
+        if (handlers_[device] != NULL)
+        {
+            // We have to store the function pointer to tell the compiler about its actual type because of overloading
+            void (InputHandler::*function)(unsigned int, ButtonTypeParam, EventType) = &InputHandler::buttonEvent<ButtonTypeParam>;
+            InputManager::getInstance().pushCall(boost::function<void ()>(boost::bind(function, handlers_[device], device, button, EventType())));
+        }
+    }
+
+    FORCEINLINE void InputState::mouseMoved(IntVector2 abs, IntVector2 rel, IntVector2 clippingSize)
+    {
+        if (handlers_[mouseIndex_s] != NULL)
+            INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseMoved, abs, rel, clippingSize);
+    }
+
+    FORCEINLINE void InputState::mouseScrolled(int abs, int rel)
+    {
+        if (handlers_[mouseIndex_s] != NULL)
+            INPUT_STATE_PUSH_CALL(mouseIndex_s, mouseScrolled, abs, rel);
+    }
+
+    FORCEINLINE void InputState::joyStickAxisMoved(unsigned int device, unsigned int axis, float value)
+    {
+        assert(device < handlers_.size());
+        if (handlers_[device] != NULL)
+            INPUT_STATE_PUSH_CALL(device, axisMoved, device - firstJoyStickIndex_s, axis, value);
+    }
+}
+
+#endif /* _InputState_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/JoyStick.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/JoyStick.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/JoyStick.cc	(revision 6952)
@@ -0,0 +1,262 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "JoyStick.h"
+
+#include <climits>
+#include <ois/OISJoyStick.h>
+#include <boost/foreach.hpp>
+
+#include "util/StringUtils.h"
+#include "core/ConfigFileManager.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
+#include "util/Convert.h"
+#include "InputState.h"
+
+namespace orxonox
+{
+    //! Helper function that loads the config value vector of one coefficient
+    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue);
+
+    std::vector<std::string> JoyStick::deviceNames_s;
+
+    JoyStick::JoyStick(unsigned int id, OIS::InputManager* oisInputManager)
+        : super(id, oisInputManager)
+    {
+        RegisterRootObject(JoyStick);
+        this->setConfigValues();
+        // Initialise POV and Slider states
+        this->clearBuffersImpl();
+
+        // Generate unique name
+        if (oisDevice_->vendor().empty())
+            deviceName_ = "Unknown_";
+        else
+        {
+            std::string name = oisDevice_->vendor();
+            replaceCharacters(name, ' ', '_');
+            deviceName_ = name + '_';
+        }
+        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Button))  + '_';
+        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis))    + '_';
+        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Slider))  + '_';
+        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_POV));
+        //deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Vector3));
+
+        BOOST_FOREACH(std::string& idString, deviceNames_s)
+        {
+            if (deviceName_ == idString)
+            {
+                // Make the ID unique for this execution time.
+                deviceName_ += '_' + multi_cast<std::string>(this->getDeviceName());
+                break;
+            }
+        }
+
+        COUT(4) << "Created OIS joy stick with ID " << deviceName_ << std::endl;
+
+        // Load calibration
+        size_t axes = sliderAxes_s + static_cast<size_t>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis));
+        loadCalibration(configMinValues_,  deviceName_, "MinValue",  axes,  -32768);
+        loadCalibration(configMaxValues_,  deviceName_, "MaxValue",  axes,   32768);
+        loadCalibration(configZeroValues_, deviceName_, "ZeroValue", axes, 0);
+        this->evaluateCalibration();
+    }
+
+    //! Callback for the joy stick calibration config file.
+    void JoyStick::calibrationFileCallback()
+    {
+        ConfigFileManager::getInstance().setFilename(ConfigFileType::JoyStickCalibration, calibrationFilename_);
+    }
+
+    void JoyStick::setConfigValues()
+    {
+        SetConfigValue(calibrationFilename_, "joystick_calibration.ini")
+            .description("Ini filename for the the joy stick calibration data.")
+            .callback(this, &JoyStick::calibrationFileCallback);
+    }
+
+    void loadCalibration(std::vector<int>& list, const std::string& sectionName, const std::string& valueName, size_t size, int defaultValue)
+    {
+        list.resize(size);
+        unsigned int configValueVectorSize = ConfigFileManager::getInstance().getConfigFile(ConfigFileType::JoyStickCalibration)->getVectorSize(sectionName, valueName);
+        if (configValueVectorSize > size)
+            configValueVectorSize = size;
+
+        for (unsigned int i = 0; i < configValueVectorSize; ++i)
+        {
+            list[i] = multi_cast<int>(ConfigFileManager::getInstance().getConfigFile(ConfigFileType::JoyStickCalibration)
+                ->getOrCreateValue(sectionName, valueName, i, multi_cast<std::string>(defaultValue), false));
+        }
+
+        // fill the rest with default values
+        for (unsigned int i = configValueVectorSize; i < size; ++i)
+            list[i] = defaultValue;
+    }
+
+    //! Called by InputDevice when calibration mode has started
+    void JoyStick::calibrationStarted()
+    {
+        // Set initial values
+        BOOST_FOREACH(int& minVal, configMinValues_)
+            minVal = INT_MAX;
+        BOOST_FOREACH(int& minVal, configMaxValues_)
+            minVal = INT_MIN;
+        BOOST_FOREACH(int& zeroVal, configZeroValues_)
+            zeroVal = 0;
+    }
+
+    //! Called by InputDevice when calibration mode has stopped
+    void JoyStick::calibrationStopped()
+    {
+        // Get the middle positions now
+        unsigned int iAxis = 0;
+        for (unsigned int i = 0; i < sliderAxes_s/2; ++i)
+        {
+            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mSliders[i].abX;
+            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mSliders[i].abY;
+        }
+        // Note: joyStickZeroValues_[iJoyStick] was already correctly resised in loadCalibration()
+        assert(oisDevice_->getJoyStickState().mAxes.size() == configZeroValues_.size() - sliderAxes_s);
+        for (unsigned int i = 0; i < configZeroValues_.size() - sliderAxes_s; ++i)
+            configZeroValues_[iAxis++] = oisDevice_->getJoyStickState().mAxes[i].abs;
+
+        for (unsigned int i = 0; i < configMinValues_.size(); ++i)
+        {
+            // Minimum values
+            if (configMinValues_[i] == INT_MAX)
+                configMinValues_[i] = -32768;
+            ConfigFileManager::getInstance().getConfigFile(ConfigFileType::JoyStickCalibration)
+                ->getOrCreateValue(deviceName_, "MinValue", i, multi_cast<std::string>(configMinValues_[i]), false);
+
+            // Maximum values
+            if (configMaxValues_[i] == INT_MIN)
+                configMaxValues_[i] = 32767;
+            ConfigFileManager::getInstance().getConfigFile(ConfigFileType::JoyStickCalibration)
+                ->getOrCreateValue(deviceName_, "MaxValue", i, multi_cast<std::string>(configMaxValues_[i]), false);
+
+            // Middle values
+            ConfigFileManager::getInstance().getConfigFile(ConfigFileType::JoyStickCalibration)
+                ->getOrCreateValue(deviceName_, "ZeroValue", i, multi_cast<std::string>(configZeroValues_[i]), false);
+        }
+
+        this->evaluateCalibration();
+    }
+
+    //! Evaluates the accumulated values during calibration
+    void JoyStick::evaluateCalibration()
+    {
+        for (unsigned int i = 0; i < configMinValues_.size(); i++)
+        {
+            zeroValues_[i] = configZeroValues_[i];
+            negativeCoeffs_[i] = - 1.0f / (configMinValues_[i] - configZeroValues_[i]);
+            positiveCoeffs_[i] =   1.0f / (configMaxValues_[i] - configZeroValues_[i]);
+        }
+    }
+
+    //! Resets the pov states
+    void JoyStick::clearBuffersImpl()
+    {
+        for (int j = 0; j < 4; ++j)
+            povStates_[j] = 0;
+    }
+
+    //! Generic method to forward axis events
+    void JoyStick::fireAxis(int axis, int value)
+    {
+        if (this->isCalibrating())
+        {
+            if (value < configMinValues_[axis])
+                configMinValues_[axis] = value;
+            if (value > configMaxValues_[axis])
+                configMaxValues_[axis] = value;
+        }
+        else
+        {
+            float fValue = static_cast<float>(value - zeroValues_[axis]);
+            if (fValue > 0.0f)
+                fValue *= positiveCoeffs_[axis];
+            else
+                fValue *= negativeCoeffs_[axis];
+
+            BOOST_FOREACH(InputState* state, inputStates_)
+                state->joyStickAxisMoved(this->getDeviceID(), axis, fValue);
+        }
+    }
+
+    //! OIS joy stick axis event handler
+    bool JoyStick::axisMoved(const OIS::JoyStickEvent &arg, int axis)
+    {
+        // keep in mind that the first 8 axes are reserved for the sliders
+        this->fireAxis(axis + sliderAxes_s, arg.state.mAxes[axis].abs);
+
+        return true;
+    }
+
+    //! A Slider always has an X and an Y direction!
+    bool JoyStick::sliderMoved(const OIS::JoyStickEvent &arg, int id)
+    {
+        if (sliderStates_[id][0] != arg.state.mSliders[id].abX)
+            fireAxis(id * 2, arg.state.mSliders[id].abX);
+        else if (sliderStates_[id][1] != arg.state.mSliders[id].abY)
+            fireAxis(id * 2 + 1, arg.state.mSliders[id].abY);
+
+        return true;
+    }
+
+    //! A POV is the big button that can point in all directions (but only in one at once)
+    bool JoyStick::povMoved(const OIS::JoyStickEvent &arg, int id)
+    {
+        // translate the POV into 8 simple buttons
+
+        int lastState = povStates_[id];
+        if (lastState & OIS::Pov::North)
+            buttonReleased(arg, 32 + id * 4 + 0);
+        if (lastState & OIS::Pov::South)
+            buttonReleased(arg, 32 + id * 4 + 1);
+        if (lastState & OIS::Pov::East)
+            buttonReleased(arg, 32 + id * 4 + 2);
+        if (lastState & OIS::Pov::West)
+            buttonReleased(arg, 32 + id * 4 + 3);
+
+        povStates_[id] = arg.state.mPOV[id].direction;
+
+        int currentState = povStates_[id];
+        if (currentState & OIS::Pov::North)
+            buttonPressed(arg, 32 + id * 4 + 0);
+        if (currentState & OIS::Pov::South)
+            buttonPressed(arg, 32 + id * 4 + 1);
+        if (currentState & OIS::Pov::East)
+            buttonPressed(arg, 32 + id * 4 + 2);
+        if (currentState & OIS::Pov::West)
+            buttonPressed(arg, 32 + id * 4 + 3);
+
+        return true;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/input/JoyStick.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/JoyStick.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/JoyStick.h	(revision 6952)
@@ -0,0 +1,132 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Core_JoyStick_H__
+#define _Core_JoyStick_H__
+
+#include "InputPrereqs.h"
+
+#include <string>
+#include <vector>
+#include "InputDevice.h"
+
+namespace orxonox
+{
+    //! Template parameter collection for the base class
+    struct JoyStickTraits
+    {
+        typedef JoyStick DeviceClass;
+        typedef OIS::JoyStick OISDeviceClass;
+        typedef JoyStickButtonCode::ByEnum ButtonType;
+        typedef JoyStickButtonCode::ByEnum ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = OIS::OISJoyStick;
+    };
+
+    /**
+    @brief
+        Wraps around an OIS::JoyStick and forwards the input events to
+        a list of input states.
+
+        The class also supports joy stick calibration and stores the values
+        in an ini-file.
+    */
+    class _CoreExport JoyStick
+        : public OrxonoxClass
+        , public InputDeviceTemplated<JoyStickTraits>
+        , public OIS::JoyStickListener
+    {
+        friend class InputDeviceTemplated<JoyStickTraits>;
+        //! Super class alias
+        typedef InputDeviceTemplated<JoyStickTraits> super;
+
+    public:
+        //! Assigns a generated ID string and loads the calibration (if present)
+        JoyStick(unsigned int id, OIS::InputManager* oisInputManager);
+        ~JoyStick() { }
+        void setConfigValues();
+
+        //! Returns the name generated from the number of knobs and the device name
+        const std::string& getDeviceName() const { return this->deviceName_; }
+
+    private:
+        void calibrationStarted();
+        void calibrationStopped();
+        void evaluateCalibration();
+
+        void clearBuffersImpl();
+        void calibrationFileCallback();
+        void fireAxis(int axis, int value);
+
+        //! OIS event handler
+        bool buttonPressed (const OIS::JoyStickEvent &arg, int button)
+        {
+            super::buttonPressed(static_cast<JoyStickButtonCode::ByEnum>(button));
+            return true;
+        }
+
+        //! OIS event handler
+        bool buttonReleased(const OIS::JoyStickEvent &arg, int button)
+        {
+            super::buttonReleased(static_cast<JoyStickButtonCode::ByEnum>(button));
+            return true;
+        }
+
+        bool axisMoved     (const OIS::JoyStickEvent &arg, int axis);
+        bool sliderMoved   (const OIS::JoyStickEvent &arg, int id);
+        bool povMoved      (const OIS::JoyStickEvent &arg, int id);
+        //! OIS event handler (don't remove that because of OIS version issues!)
+        bool vector3Moved  (const OIS::JoyStickEvent &arg, int id) { return true; }
+
+        //! Returns the class name as string
+        static std::string getClassNameImpl() { return "JoyStick"; }
+
+        std::string deviceName_;              //!< Name generated by the number of knobs and the device name
+        int povStates_[4];                    //!< Internal states for the POVs
+        int sliderStates_[4][2];              //!< Internal states for the Sliders (each slider has X and Y!)
+
+        // calibration
+        int zeroValues_[24];                  //!< Axes values when the knob is in the middle
+        float positiveCoeffs_[24];            //!< Maps the negative part of an axis to a 0.0 to 1.0 floating range
+        float negativeCoeffs_[24];            //!< Maps the positive part of an axis to a 0.0 to 1.0 floating range
+
+        std::vector<int> configZeroValues_;   //!< Config file stored axis values when the knob is in the middle
+        std::vector<int> configMinValues_;    //!< Config file stored minimum axis values
+        std::vector<int> configMaxValues_;    //!< Config file stored maximum axis values
+
+        // ConfigValues
+        std::string calibrationFilename_;     //!< Joy stick calibration ini filename
+
+        //! Contains a list of all names to avoid duplicates
+        static std::vector<std::string> deviceNames_s;
+
+        //!< Maximum number of slider axes
+        static const unsigned int sliderAxes_s = 8;
+    };
+}
+
+#endif /* _Core_JoyStick_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/JoyStickQuantityListener.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/JoyStickQuantityListener.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/JoyStickQuantityListener.cc	(revision 6952)
@@ -0,0 +1,50 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "JoyStickQuantityListener.h"
+
+#include "core/CoreIncludes.h"
+#include "core/ObjectList.h"
+
+namespace orxonox
+{
+    std::vector<JoyStick*> JoyStickQuantityListener::joyStickList_s;
+
+    JoyStickQuantityListener::JoyStickQuantityListener()
+    {
+        RegisterObject(JoyStickQuantityListener);
+    }
+
+    //! Calls all registered objects and sets the static variable
+    /*static*/ void JoyStickQuantityListener::changeJoyStickQuantity(const std::vector<JoyStick*>& joyStickList)
+    {
+        joyStickList_s = joyStickList;
+        for (ObjectList<JoyStickQuantityListener>::iterator it = ObjectList<JoyStickQuantityListener>::begin(); it; ++it)
+            it->JoyStickQuantityChanged(joyStickList);
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/input/JoyStickQuantityListener.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/JoyStickQuantityListener.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/JoyStickQuantityListener.h	(revision 6952)
@@ -0,0 +1,64 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+*/
+
+#ifndef _JoyStickQuantityListener_H__
+#define _JoyStickQuantityListener_H__
+
+#include "InputPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    //! Derive from this class to get informed when joy sticks get added/removed
+    class _CoreExport JoyStickQuantityListener : virtual public OrxonoxClass
+    {
+        friend class InputManager;
+    protected:
+        JoyStickQuantityListener();
+        virtual ~JoyStickQuantityListener() { }
+
+        //! Returns a list with all JoySticks currently loaded
+        const std::vector<JoyStick*>& getJoyStickList() const { return joyStickList_s; }
+
+    private:
+        //! Called whenever joy sticks get added/removed
+        virtual void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList) = 0;
+
+        static void changeJoyStickQuantity(const std::vector<JoyStick*>& joyStickList);
+
+        //! Static variable that holds the latest distributed information
+        static std::vector<JoyStick*> joyStickList_s;
+    };
+}
+
+#endif /* _JoyStickQuantityListener_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/KeyBinder.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/KeyBinder.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/KeyBinder.cc	(revision 6952)
@@ -0,0 +1,597 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "KeyBinder.h"
+
+#include <algorithm>
+#include <sstream>
+#include "util/Convert.h"
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigFileManager.h"
+#include "core/PathConfig.h"
+#include "InputCommands.h"
+#include "JoyStick.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Constructor that does as little as necessary.
+    */
+    KeyBinder::KeyBinder(const std::string& filename)
+        : deriveTime_(0.0f)
+        , filename_(filename)
+        , configFile_(NULL)
+        , fallbackConfigFile_(NULL)
+    {
+        mouseRelative_[0] = 0;
+        mouseRelative_[1] = 0;
+        mousePosition_[0] = 0.0;
+        mousePosition_[1] = 0.0;
+
+        RegisterRootObject(KeyBinder);
+
+        // initialise all buttons and half axes to avoid creating everything with 'new'
+        // keys
+        for (unsigned int i = 0; i < KeyCode::numberOfKeys; i++)
+        {
+            const std::string& keyname = KeyCode::ByString[i];
+            if (!keyname.empty())
+                keys_[i].name_ = std::string("Key") + keyname;
+            else
+                keys_[i].name_.clear();
+            keys_[i].paramCommandBuffer_ = &paramCommandBuffer_;
+            keys_[i].groupName_ = "Keys";
+        }
+        // mouse buttons plus 4 mouse wheel buttons only 'generated' by KeyBinder
+        const char* const mouseWheelNames[] = { "Wheel1Down", "Wheel1Up", "Wheel2Down", "Wheel2Up" };
+        for (unsigned int i = 0; i < numberOfMouseButtons_; i++)
+        {
+            std::string nameSuffix;
+            if (i < MouseButtonCode::numberOfButtons)
+                nameSuffix = MouseButtonCode::ByString[i];
+            else
+                nameSuffix = mouseWheelNames[i - MouseButtonCode::numberOfButtons];
+            mouseButtons_[i].name_ = nameSuffix;
+            mouseButtons_[i].paramCommandBuffer_ = &paramCommandBuffer_;
+            mouseButtons_[i].groupName_ = "MouseButtons";
+        }
+        // mouse axes
+        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
+        {
+            mouseAxes_[i].name_ = MouseAxisCode::ByString[i / 2];
+            if (i & 1)
+                mouseAxes_[i].name_ += "Pos";
+            else
+                mouseAxes_[i].name_ += "Neg";
+            mouseAxes_[i].paramCommandBuffer_ = &paramCommandBuffer_;
+            mouseAxes_[i].groupName_ = "MouseAxes";
+        }
+
+        // initialise joy sticks separatly to allow for reloading
+        this->JoyStickQuantityChanged(this->getJoyStickList());
+
+        // set them here to use allHalfAxes_
+        setConfigValues();
+
+        // Load the bindings if filename was given
+        if (!this->filename_.empty())
+            this->loadBindings();
+    }
+
+    /**
+    @brief
+        Destructor
+    */
+    KeyBinder::~KeyBinder()
+    {
+        // almost no destructors required because most of the arrays are static.
+        clearBindings(); // does some destruction work
+        if (this->configFile_)
+            delete this->configFile_;
+        if (this->fallbackConfigFile_)
+            delete this->fallbackConfigFile_;
+    }
+
+    /**
+    @brief
+        Loader for the key bindings, managed by config values.
+    */
+    void KeyBinder::setConfigValues()
+    {
+        SetConfigValue(analogThreshold_, 0.05f)
+            .description("Threshold for analog axes until which the state is 0.");
+        SetConfigValue(bFilterAnalogNoise_, false)
+            .description("Specifies whether to filter small analog values like joy stick fluctuations.");
+        SetConfigValue(mouseSensitivity_, 3.0f)
+            .description("Mouse sensitivity.");
+        this->totalMouseSensitivity_ = this->mouseSensitivity_ / this->mouseClippingSize_;
+        SetConfigValue(bDeriveMouseInput_, false)
+            .description("Whether or not to derive moues movement for the absolute value.");
+        SetConfigValue(derivePeriod_, 0.05f)
+            .description("Accuracy of the mouse input deriver. The higher the more precise, but laggier.");
+        SetConfigValue(mouseSensitivityDerived_, 1.0f)
+            .description("Mouse sensitivity if mouse input is derived.");
+        SetConfigValue(mouseWheelStepSize_, 120)
+            .description("Equals one step of the mousewheel.");
+        SetConfigValue(buttonThreshold_, 0.80f)
+            .description("Threshold for analog axes until which the button is not pressed.")
+            .callback(this, &KeyBinder::buttonThresholdChanged);
+    }
+
+    void KeyBinder::buttonThresholdChanged()
+    {
+        for (unsigned int i = 0; i < allHalfAxes_.size(); i++)
+            if (!allHalfAxes_[i]->bButtonThresholdUser_)
+                allHalfAxes_[i]->buttonThreshold_ = this->buttonThreshold_;
+    }
+
+    void KeyBinder::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList)
+    {
+        unsigned int oldValue = joySticks_.size();
+        joySticks_ = joyStickList;
+
+        // initialise joy stick bindings
+        initialiseJoyStickBindings();
+
+        // collect all Buttons and HalfAxes again
+        compilePointerLists();
+
+        // load the bindings if required
+        if (configFile_ != NULL)
+        {
+            for (unsigned int iDev = oldValue; iDev < joySticks_.size(); ++iDev)
+            {
+                for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; ++i)
+                    (*joyStickButtons_[iDev])[i].readBinding(this->configFile_, this->fallbackConfigFile_);
+                for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; ++i)
+                    (*joyStickAxes_[iDev])[i].readBinding(this->configFile_, this->fallbackConfigFile_);
+            }
+        }
+
+        // Set the button threshold for potential new axes
+        buttonThresholdChanged();
+    }
+
+    void KeyBinder::initialiseJoyStickBindings()
+    {
+        while (joyStickAxes_.size() < joySticks_.size())
+            joyStickAxes_.push_back(shared_ptr<JoyStickAxisVector>(new JoyStickAxisVector()));
+        while (joyStickButtons_.size() < joySticks_.size())
+            joyStickButtons_.push_back(shared_ptr<JoyStickButtonVector>(new JoyStickButtonVector()));
+        // For the case the new size is smaller
+        this->joyStickAxes_.resize(joySticks_.size());
+        this->joyStickButtons_.resize(joySticks_.size());
+
+        // reinitialise all joy stick bindings (doesn't overwrite the old ones)
+        for (unsigned int iDev = 0; iDev < joySticks_.size(); iDev++)
+        {
+            const std::string& deviceName = joySticks_[iDev]->getDeviceName();
+            // joy stick buttons
+            for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
+            {
+                (*joyStickButtons_[iDev])[i].name_ = JoyStickButtonCode::ByString[i];
+                (*joyStickButtons_[iDev])[i].paramCommandBuffer_ = &paramCommandBuffer_;
+                (*joyStickButtons_[iDev])[i].groupName_ = "JoyStickButtons_" + deviceName;
+            }
+            // joy stick axes
+            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+            {
+                (*joyStickAxes_[iDev])[i].name_ = JoyStickAxisCode::ByString[i / 2];
+                if (i & 1)
+                    (*joyStickAxes_[iDev])[i].name_ += "Pos";
+                else
+                    (*joyStickAxes_[iDev])[i].name_ += "Neg";
+                (*joyStickAxes_[iDev])[i].paramCommandBuffer_ = &paramCommandBuffer_;
+                (*joyStickAxes_[iDev])[i].groupName_ = "JoyStickAxes_" + deviceName;
+            }
+        }
+    }
+
+    void KeyBinder::compilePointerLists()
+    {
+        allButtons_.clear();
+        allHalfAxes_.clear();
+
+        // Note: Don't include the dummy keys which don't actually exist in OIS but have a number
+        for (unsigned int i = 0; i < KeyCode::numberOfKeys; i++)
+            if (!keys_[i].name_.empty())
+                allButtons_[keys_[i].groupName_ + '.' + keys_[i].name_] = keys_ + i;
+        for (unsigned int i = 0; i < numberOfMouseButtons_; i++)
+            allButtons_[mouseButtons_[i].groupName_ + '.' + mouseButtons_[i].name_] = mouseButtons_ + i;
+        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
+        {
+            allButtons_[mouseAxes_[i].groupName_ + '.' + mouseAxes_[i].name_] = mouseAxes_ + i;
+            allHalfAxes_.push_back(mouseAxes_ + i);
+        }
+        for (unsigned int iDev = 0; iDev < joySticks_.size(); iDev++)
+        {
+            for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
+                allButtons_[(*joyStickButtons_[iDev])[i].groupName_ + '.' + (*joyStickButtons_[iDev])[i].name_] = &((*joyStickButtons_[iDev])[i]);
+            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+            {
+                allButtons_[(*joyStickAxes_[iDev])[i].groupName_ + '.' + (*joyStickAxes_[iDev])[i].name_] = &((*joyStickAxes_[iDev])[i]);
+                allHalfAxes_.push_back(&((*joyStickAxes_[iDev])[i]));
+            }
+        }
+    }
+
+    /**
+    @brief
+        Loads the key and button bindings.
+    */
+    void KeyBinder::loadBindings()
+    {
+        COUT(3) << "KeyBinder: Loading key bindings..." << std::endl;
+
+        this->configFile_ = new ConfigFile(this->filename_, !PathConfig::isDevelopmentRun());
+        this->configFile_->load();
+
+        if (PathConfig::isDevelopmentRun())
+        {
+            // Dev users should have combined key bindings files
+            std::string defaultFilepath(PathConfig::getDataPathString() + ConfigFile::DEFAULT_CONFIG_FOLDER + '/' + this->filename_);
+            std::ifstream file(defaultFilepath.c_str());
+            if (file.is_open())
+            {
+                file.close();
+                // Open the default file for later use (use absolute path!)
+                this->fallbackConfigFile_ = new ConfigFile(defaultFilepath, false);
+                this->fallbackConfigFile_->load();
+            }
+        }
+
+        // Parse bindings and create the ConfigValueContainers if necessary
+        for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
+        {
+            it->second->readBinding(this->configFile_, this->fallbackConfigFile_);
+            addButtonToCommand(it->second->bindingString_, it->second);
+        }
+
+        COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
+    }
+
+    bool KeyBinder::setBinding(const std::string& binding, const std::string& name, bool bTemporary)
+    {
+        std::map<std::string, Button*>::iterator it = allButtons_.find(name);
+        if (it != allButtons_.end())
+        {
+            addButtonToCommand(binding, it->second);
+            std::string str = binding;
+            if (PathConfig::isDevelopmentRun() && binding.empty())
+                str = "NoBinding";
+            it->second->setBinding(this->configFile_, this->fallbackConfigFile_, binding, bTemporary);
+            return true;
+        }
+        else
+        {
+            COUT(2) << "Could not find key/button/axis with name '" << name << "'." << std::endl;
+            return false;
+        }
+    }
+
+     void KeyBinder::addButtonToCommand(const std::string& command, Button* button)
+     {
+        std::ostringstream stream;
+        stream << button->groupName_  << '.' << button->name_;
+
+        std::vector<std::string>& oldKeynames = this->allCommands_[button->bindingString_];
+        std::vector<std::string>::iterator it = std::find(oldKeynames.begin(), oldKeynames.end(), stream.str());
+        if (it != oldKeynames.end())
+            oldKeynames.erase(it);
+
+        if (!command.empty())
+        {
+            std::vector<std::string>& keynames = this->allCommands_[command];
+            if (std::find(keynames.begin(), keynames.end(), stream.str()) == keynames.end())
+                this->allCommands_[command].push_back(stream.str());
+        }
+     }
+
+    /**
+    @brief
+        Return the first key name for a specific command
+    */
+    const std::string& KeyBinder::getBinding(const std::string& commandName)
+    {
+        if (this->allCommands_.find(commandName) != this->allCommands_.end())
+        {
+            std::vector<std::string>& keynames = this->allCommands_[commandName];
+            return keynames.front();
+        }
+
+        return BLANKSTRING;
+    }
+
+    /**
+    @brief
+        Return the key name for a specific command at a given index.
+    @param commandName
+        The command name the key name is returned for.
+    @param index
+        The index at which the key name is returned for.
+    */
+    const std::string& KeyBinder::getBinding(const std::string& commandName, unsigned int index)
+    {
+        if (this->allCommands_.find(commandName) != this->allCommands_.end())
+        {
+            std::vector<std::string>& keynames = this->allCommands_[commandName];
+            if (index < keynames.size())
+                return keynames[index];
+
+            return BLANKSTRING;
+        }
+
+        return BLANKSTRING;
+    }
+
+    /**
+    @brief
+        Get the number of different key bindings of a specific command.
+    @param commandName
+        The command.
+    */
+    unsigned int KeyBinder::getNumberOfBindings(const std::string& commandName)
+    {
+        if (this->allCommands_.find(commandName) != this->allCommands_.end())
+        {
+            std::vector<std::string>& keynames = this->allCommands_[commandName];
+            return keynames.size();
+        }
+
+        return 0;
+    }
+
+    /**
+    @brief
+        Overwrites all bindings with ""
+    */
+    void KeyBinder::clearBindings()
+    {
+        for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
+            it->second->clear();
+
+        for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
+            delete paramCommandBuffer_[i];
+        paramCommandBuffer_.clear();
+    }
+
+    void KeyBinder::resetJoyStickAxes()
+    {
+        for (unsigned int iDev = 0; iDev < joySticks_.size(); ++iDev)
+        {
+            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+            {
+                (*joyStickAxes_[iDev])[i].absVal_ = 0.0f;
+                (*joyStickAxes_[iDev])[i].relVal_ = 0.0f;
+            }
+        }
+    }
+
+    void KeyBinder::mouseUpdated(float dt)
+    {
+        if (bDeriveMouseInput_)
+        {
+            // only update when derivation dt has passed
+            if (deriveTime_ > derivePeriod_)
+            {
+                for (int i = 0; i < 2; i++)
+                {
+                    if (mouseRelative_[i] < 0)
+                    {
+                        mouseAxes_[2*i + 0].absVal_
+                            = -mouseRelative_[i] / deriveTime_ * 0.0005f * mouseSensitivityDerived_;
+                        mouseAxes_[2*i + 1].absVal_ = 0.0f;
+                    }
+                    else if (mouseRelative_[i] > 0)
+                    {
+                        mouseAxes_[2*i + 0].absVal_ = 0.0f;
+                        mouseAxes_[2*i + 1].absVal_
+                            =  mouseRelative_[i] / deriveTime_ * 0.0005f * mouseSensitivityDerived_;
+                    }
+                    else
+                    {
+                        mouseAxes_[2*i + 0].absVal_ = 0.0f;
+                        mouseAxes_[2*i + 1].absVal_ = 0.0f;
+                    }
+                    mouseRelative_[i] = 0;
+                    mouseAxes_[2*i + 0].hasChanged_ = true;
+                    mouseAxes_[2*i + 1].hasChanged_ = true;
+                }
+                deriveTime_ = 0.0f;
+            }
+            else
+                deriveTime_ += dt;
+        }
+
+        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
+        {
+            // Why dividing relative value by dt? The reason lies in the simple fact, that when you
+            // press a button that has relative movement, that value has to be multiplied by dt to be
+            // frame rate independent. This can easily (and only) be done in updateInput(float).
+            // Hence we need to divide by dt here for the mouse to compensate, because the relative
+            // move movements have nothing to do with dt.
+            if (dt != 0.0f)
+            {
+                // just ignore if dt == 0.0 because we have multiplied by 0.0 anyway..
+                mouseAxes_[i].relVal_ /= dt;
+            }
+
+            tickHalfAxis(mouseAxes_[i]);
+        }
+    }
+
+    void KeyBinder::joyStickUpdated(unsigned int joyStick, float dt)
+    {
+        for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
+        {
+            tickHalfAxis((*joyStickAxes_[joyStick])[i]);
+        }
+    }
+
+    void KeyBinder::tickHalfAxis(HalfAxis& halfAxis)
+    {
+        // button mode
+        // TODO: optimize out all the half axes that don't act as a button at the moment
+        if (halfAxis.hasChanged_)
+        {
+            if (!halfAxis.pressed_ && halfAxis.absVal_ > halfAxis.buttonThreshold_)
+            {
+                // key pressed event
+                halfAxis.pressed_ = true;
+                if (halfAxis.nCommands_[KeybindMode::OnPress])
+                    halfAxis.execute(KeybindMode::OnPress);
+            }
+            else if (halfAxis.pressed_ && halfAxis.absVal_ < halfAxis.buttonThreshold_)
+            {
+                // key released event
+                halfAxis.pressed_ = false;
+                if (halfAxis.nCommands_[KeybindMode::OnRelease])
+                    halfAxis.execute(KeybindMode::OnRelease);
+            }
+            halfAxis.hasChanged_ = false;
+        }
+
+        if (halfAxis.pressed_)
+        {
+            // key held event
+            if (halfAxis.nCommands_[KeybindMode::OnHold])
+                halfAxis.execute(KeybindMode::OnHold);
+        }
+
+        // these are the actually useful axis bindings for analog input
+        halfAxis.execute();
+    }
+
+    /**
+    @brief
+        Event handler for the mouseMoved Event.
+    @param e
+        Mouse state information
+    */
+    void KeyBinder::mouseMoved(IntVector2 abs_, IntVector2 rel_, IntVector2 clippingSize)
+    {
+        // y axis of mouse input is inverted
+        int rel[] = { rel_.x, -rel_.y };
+
+        if (bDeriveMouseInput_)
+        {
+            mouseRelative_[0] += rel[0];
+            mouseRelative_[1] += rel[1];
+        }
+        else
+        {
+            for (int i = 0; i < 2; i++)
+            {
+                if (rel[i]) // performance opt. for the case that rel[i] == 0
+                {
+                    // write absolute values
+                    mouseAxes_[2*i + 0].hasChanged_ = true;
+                    mouseAxes_[2*i + 1].hasChanged_ = true;
+                    mousePosition_[i] += rel[i] * totalMouseSensitivity_;
+
+                    // clip absolute position
+                    if (mousePosition_[i] > 1.0)
+                        mousePosition_[i] =  1.0;
+                    if (mousePosition_[i] < -1.0)
+                        mousePosition_[i] = -1.0;
+
+                    if (mousePosition_[i] < 0.0)
+                    {
+                        mouseAxes_[2*i + 0].absVal_ = -mousePosition_[i];
+                        mouseAxes_[2*i + 1].absVal_ = 0.0f;
+                    }
+                    else
+                    {
+                        mouseAxes_[2*i + 0].absVal_ = 0.0f;
+                        mouseAxes_[2*i + 1].absVal_ =  mousePosition_[i];
+                    }
+                }
+            }
+        }
+
+        // relative
+        for (int i = 0; i < 2; i++)
+        {
+            if (rel[i] < 0)
+                mouseAxes_[0 + 2*i].relVal_ = -rel[i] * totalMouseSensitivity_;
+            else
+                mouseAxes_[1 + 2*i].relVal_ =  rel[i] * totalMouseSensitivity_;
+        }
+    }
+
+    /**
+    @brief Event handler for the mouseScrolled Event.
+    @param e Mouse state information
+    */
+    void KeyBinder::mouseScrolled(int abs, int rel)
+    {
+        if (rel < 0)
+            for (int i = 0; i < -rel/mouseWheelStepSize_; i++)
+                mouseButtons_[8].execute(KeybindMode::OnPress, static_cast<float>(abs)/mouseWheelStepSize_);
+        else
+            for (int i = 0; i < rel/mouseWheelStepSize_; i++)
+                mouseButtons_[9].execute(KeybindMode::OnPress, static_cast<float>(abs)/mouseWheelStepSize_);
+    }
+
+    void KeyBinder::axisMoved(unsigned int device, unsigned int axisID, float value)
+    {
+        // Filter analog noise
+        if (this->bFilterAnalogNoise_ && std::abs(value) < this->analogThreshold_)
+            value = 0.0;
+        int i = axisID * 2;
+        JoyStickAxisVector& axis = *joyStickAxes_[device];
+        if (value < 0)
+        {
+            axis[i].absVal_ = -value;
+            axis[i].relVal_ = -value;
+            axis[i].hasChanged_ = true;
+            if (axis[i + 1].absVal_ > 0.0f)
+            {
+                axis[i + 1].absVal_ = -0.0f;
+                axis[i + 1].relVal_ = -0.0f;
+                axis[i + 1].hasChanged_ = true;
+            }
+        }
+        else
+        {
+            axis[i + 1].absVal_ = value;
+            axis[i + 1].relVal_ = value;
+            axis[i + 1].hasChanged_ = true;
+            if (axis[i].absVal_ > 0.0f)
+            {
+                axis[i].absVal_ = -0.0f;
+                axis[i].relVal_ = -0.0f;
+                axis[i].hasChanged_ = true;
+            }
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/input/KeyBinder.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/KeyBinder.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/KeyBinder.h	(revision 6952)
@@ -0,0 +1,237 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _KeyBinder_H__
+#define _KeyBinder_H__
+
+#include "InputPrereqs.h"
+
+#include <cassert>
+#include <string>
+#include <vector>
+#include <map>
+#include <boost/shared_ptr.hpp>
+
+#include "InputHandler.h"
+#include "Button.h"
+#include "HalfAxis.h"
+#include "InputCommands.h"
+#include "JoyStickQuantityListener.h"
+
+// tolua_begin
+namespace orxonox
+{
+    // tolua_end
+    /**
+    @brief
+        Maps mouse, keyboard and joy stick input to command strings and executes them.
+
+        The bindings are stored in ini-files (like the one for configValues) in the config Path.
+    @remarks
+        You cannot change the filename because the KeyBinderManager maps these filenames to the
+        KeyBinders. If you need to load other bindings, just create a new one.
+    */
+    class _CoreExport KeyBinder // tolua_export
+        : public InputHandler, public JoyStickQuantityListener
+    { // tolua_export
+    public:
+        KeyBinder (const std::string& filename);
+        virtual ~KeyBinder();
+
+        void clearBindings();
+        bool setBinding(const std::string& binding, const std::string& name, bool bTemporary = false);
+        const std::string& getBinding(const std::string& commandName); //tolua_export
+        const std::string& getBinding(const std::string& commandName, unsigned int index); //tolua_export
+        unsigned int getNumberOfBindings(const std::string& commandName); //tolua_export
+
+        const std::string& getBindingsFilename()
+            { return this->filename_; }
+        void setConfigValues();
+        void resetJoyStickAxes();
+
+    protected: // functions
+        void loadBindings();
+        void buttonThresholdChanged();
+        void initialiseJoyStickBindings();
+        void compilePointerLists();
+        // from JoyStickQuantityListener interface
+        virtual void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList);
+
+        void allDevicesUpdated(float dt);
+        void mouseUpdated(float dt);
+        void joyStickUpdated(unsigned int joyStick, float dt);
+        // internal
+        void tickHalfAxis(HalfAxis& halfAxis);
+
+        void buttonPressed (const KeyEvent& evt);
+        void buttonReleased(const KeyEvent& evt);
+        void buttonHeld    (const KeyEvent& evt);
+
+        void buttonPressed (MouseButtonCode::ByEnum button);
+        void buttonReleased(MouseButtonCode::ByEnum button);
+        void buttonHeld    (MouseButtonCode::ByEnum button);
+        void mouseMoved    (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize);
+        void mouseScrolled (int abs, int rel);
+
+        void buttonPressed (unsigned int device, JoyStickButtonCode::ByEnum button);
+        void buttonReleased(unsigned int device, JoyStickButtonCode::ByEnum button);
+        void buttonHeld    (unsigned int device, JoyStickButtonCode::ByEnum button);
+        void axisMoved     (unsigned int device, unsigned int axis, float value);
+
+    protected: // variables
+        //! Currently active joy sticks
+        std::vector<JoyStick*>  joySticks_;
+
+        //! Actual key bindings for keys on the keyboard
+        Button keys_            [KeyCode::numberOfKeys];
+        //! Number of mouse buttons in KeyBinder (+4)
+        static const unsigned int numberOfMouseButtons_ = MouseButtonCode::numberOfButtons + 4;
+        //! Actual key bindings for mouse buttons including the wheel(s)
+        Button mouseButtons_    [numberOfMouseButtons_];
+        //! Actual key bindings for mouse axes
+        HalfAxis mouseAxes_     [MouseAxisCode::numberOfAxes * 2];
+
+        //! Helper class to use something like std:vector<Button[64]>
+        struct JoyStickButtonVector
+        {
+            Button& operator[](unsigned int index) { return buttons[index]; }
+            Button buttons[JoyStickButtonCode::numberOfButtons];
+        };
+        //! Actual key bindings for joy stick buttons
+        std::vector<shared_ptr<JoyStickButtonVector> > joyStickButtons_;
+        //! Helper class to use something like std:vector<HalfAxis[48]>
+        struct JoyStickAxisVector
+        {
+            HalfAxis& operator[](unsigned int index) { return halfAxes[index]; }
+            HalfAxis halfAxes[JoyStickAxisCode::numberOfAxes * 2];
+        };
+        //! Actual key bindings for joy stick axes (and sliders)
+        std::vector<shared_ptr<JoyStickAxisVector> > joyStickAxes_;
+
+        //! Pointer map with all Buttons, including half axes
+        std::map<std::string, Button*> allButtons_;
+        //! Pointer list with all half axes
+        std::vector<HalfAxis*> allHalfAxes_;
+        //! Maps input commands to all Button names, including half axes
+        std::map< std::string, std::vector<std::string> > allCommands_;
+
+        /**
+        @brief
+            Commands that have additional parameters (axes) are executed at the end of
+            update() so that all values can be buffered for single execution.
+        */
+        std::vector<BufferedParamCommand*> paramCommandBuffer_;
+
+        //! Keeps track of the absolute mouse value
+        float mousePosition_[2];
+        //! Used to derive mouse input if requested
+        int mouseRelative_[2];
+        float deriveTime_;
+
+        //! Name of the file used in this KeyBinder (constant!)
+        const std::string filename_;
+        //! Config file used. NULL in case of KeyDetector. Also indicates whether we've already loaded.
+        ConfigFile* configFile_;
+        //! Config file from the data directory that only serves as fallback
+        ConfigFile* fallbackConfigFile_;
+
+    private:
+        void addButtonToCommand(const std::string& command, Button* button);
+
+        //##### ConfigValues #####
+        //! Whether to filter small value analog input
+        bool bFilterAnalogNoise_;
+        //! Threshold for analog triggers until which the state is 0.
+        float analogThreshold_;
+        //! Threshold for analog triggers until which the button is not pressed.
+        float buttonThreshold_;
+        //! Derive mouse input for absolute values?
+        bool bDeriveMouseInput_;
+        //! Accuracy of the mouse input deriver. The higher the more precise, but laggier.
+        float derivePeriod_;
+        //! mouse sensitivity
+        float mouseSensitivity_;
+        //! mouse sensitivity if mouse input is derived
+        float mouseSensitivityDerived_;
+        //! Equals one step of the mouse wheel
+        int mouseWheelStepSize_;
+
+        //! Multiplication of mouse sensitivity and clipping size
+        float totalMouseSensitivity_;
+
+        //##### Constant config variables #####
+        // Use some value at about 1000. This can be configured with mouseSensitivity_ anyway.
+        static const int mouseClippingSize_ = 1024;
+    };// tolua_export
+
+
+    inline void KeyBinder::buttonPressed (const KeyEvent& evt)
+    { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnPress); }
+
+    inline void KeyBinder::buttonReleased(const KeyEvent& evt)
+    { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnRelease); }
+
+    inline void KeyBinder::buttonHeld    (const KeyEvent& evt)
+    { assert(!keys_[evt.getKeyCode()].name_.empty()); keys_[evt.getKeyCode()].execute(KeybindMode::OnHold); }
+
+
+    inline void KeyBinder::buttonPressed (MouseButtonCode::ByEnum button)
+    { mouseButtons_[button].execute(KeybindMode::OnPress); }
+
+    inline void KeyBinder::buttonReleased(MouseButtonCode::ByEnum button)
+    { mouseButtons_[button].execute(KeybindMode::OnRelease); }
+
+    inline void KeyBinder::buttonHeld    (MouseButtonCode::ByEnum button)
+    { mouseButtons_[button].execute(KeybindMode::OnHold); }
+
+
+    inline void KeyBinder::buttonPressed (unsigned int device, JoyStickButtonCode::ByEnum button)
+    { (*joyStickButtons_[device])[button].execute(KeybindMode::OnPress); }
+
+    inline void KeyBinder::buttonReleased(unsigned int device, JoyStickButtonCode::ByEnum button)
+    { (*joyStickButtons_[device])[button].execute(KeybindMode::OnRelease); }
+
+    inline void KeyBinder::buttonHeld    (unsigned int device, JoyStickButtonCode::ByEnum button)
+    { (*joyStickButtons_[device])[button].execute(KeybindMode::OnHold); }
+
+    inline void KeyBinder::allDevicesUpdated(float dt)
+    {
+        // execute all buffered bindings (additional parameter)
+        for (unsigned int i = 0; i < paramCommandBuffer_.size(); i++)
+        {
+            paramCommandBuffer_[i]->rel_ *= dt;
+            paramCommandBuffer_[i]->execute();
+        }
+
+        // always reset the relative movement of the mouse
+        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
+            mouseAxes_[i].relVal_ = 0.0f;
+    }
+}// tolua_export
+
+#endif /* _KeyBinder_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/KeyBinderManager.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/KeyBinderManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/KeyBinderManager.cc	(revision 6952)
@@ -0,0 +1,189 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "KeyBinderManager.h"
+
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/ConsoleCommand.h"
+#include "core/CoreIncludes.h"
+#include "core/ScopedSingletonManager.h"
+#include "InputManager.h"
+#include "KeyDetector.h"
+
+namespace orxonox
+{
+    ManageScopedSingleton(KeyBinderManager, ScopeID::Graphics, false);
+
+    KeyBinderManager::KeyBinderManager()
+        : currentBinder_(NULL)
+        , bDefaultFileLoaded_(true)
+        , bBinding_(false)
+    {
+        RegisterObject(KeyBinderManager);
+        this->setConfigValues();
+
+        // keybind console commands
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&KeyBinderManager::keybind,  this), "keybind" ))
+            .defaultValues("");
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&KeyBinderManager::tkeybind, this), "tkeybind"))
+            .defaultValues("");
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&KeyBinderManager::unbind, this), "unbind"))
+            .defaultValues("");
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&KeyBinderManager::tunbind, this), "tunbind"))
+            .defaultValues("");
+
+        // Load default key binder
+        this->setCurrent(defaultFilename_);
+    }
+
+    KeyBinderManager::~KeyBinderManager()
+    {
+        // Delete all remaining KeyBinders
+        for (std::map<std::string, KeyBinder*>::const_iterator it = this->binders_.begin(); it != this->binders_.end(); ++it)
+            delete it->second;
+    }
+
+    void KeyBinderManager::setConfigValues()
+    {
+        SetConfigValue(defaultFilename_, "keybindings.ini")
+            .description("Filename for the default keybindings file.")
+            .callback(this, &KeyBinderManager::defaultFilenameChanged);
+    }
+
+    void KeyBinderManager::defaultFilenameChanged()
+    {
+        if (this->bDefaultFileLoaded_)
+            this->setCurrent(this->defaultFilename_);
+    }
+
+    void KeyBinderManager::setCurrent(const std::string& filename)
+    {
+        this->currentBinder_ = this->get(filename);
+        if (filename == this->defaultFilename_)
+            this->bDefaultFileLoaded_ = true;
+        else
+            this->bDefaultFileLoaded_ = false;
+    }
+
+    inline void KeyBinderManager::unbind(const std::string& binding)
+    {
+        this->currentBinder_->setBinding("", binding, false);
+    }
+
+    inline void KeyBinderManager::tunbind(const std::string& binding)
+    {
+        this->currentBinder_->setBinding("", binding, true);
+    }
+
+    void KeyBinderManager::load(const std::string& filename)
+    {
+        std::map<std::string, KeyBinder*>::const_iterator it = this->binders_.find(filename);
+        if (it != this->binders_.end())
+            return;
+
+        KeyBinder* binder = new KeyBinder(filename);
+        this->binders_[filename] = binder;
+    }
+
+    void KeyBinderManager::unload(const std::string& filename)
+    {
+        if (filename == this->defaultFilename_)
+            ThrowException(General, "KeyBinderManager: Cannot unload the default file");
+        if (filename == this->currentBinder_->getBindingsFilename())
+        {
+            // unloading current file --> set default file
+            this->setCurrent(this->defaultFilename_);
+        }
+        std::map<std::string, KeyBinder*>::iterator it = this->binders_.find(filename);
+        if (it != this->binders_.end())
+        {
+            delete it->second;
+            this->binders_.erase(it);
+        }
+    }
+
+    KeyBinder* KeyBinderManager::get(const std::string& name)
+    {
+        this->load(name);
+        return this->binders_[name];
+    }
+
+    InputHandler* KeyBinderManager::getCurrentAsHandler()
+    {
+        return this->getCurrent();
+    }
+
+    InputHandler* KeyBinderManager::getDefaultAsHandler()
+    {
+        return this->getDefault();
+    }
+
+    InputHandler* KeyBinderManager::getAsHandler(const std::string& name)
+    {
+        return this->get(name);
+    }
+
+    void KeyBinderManager::keybindInternal(const std::string& command, bool bTemporary)
+    {
+        if (!this->bBinding_)
+        {
+            COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
+            KeyDetector::getInstance().setCallback(shared_ptr<Functor>(createFunctor(&KeyBinderManager::keybindKeyPressed, this)));
+            InputManager::getInstance().enterState("detector");
+            this->command_ = command;
+            this->bTemporary_ = bTemporary;
+            this->bBinding_ = true;
+        }
+        // else: We're still in a keybind command. Ignore this call.
+    }
+
+    // Gets called by the KeyDetector (registered with a Functor)
+    void KeyBinderManager::keybindKeyPressed(const std::string& keyName)
+    {
+        if (this->bBinding_)
+        {
+            if (keyName == "Keys.KeyEscape")
+            {
+                COUT(0) << "Keybinding aborted." << std::endl;
+            }
+            else
+            {
+                COUT(0) << "Binding string \"" << command_ << "\" on key '" << keyName << "'" << std::endl;
+                this->currentBinder_->setBinding(command_, keyName, bTemporary_);
+            }
+            InputManager::getInstance().leaveState("detector");
+            // inform whatever was calling the command
+            if (this->callbackFunction_)
+                (*this->callbackFunction_)();
+            this->bBinding_ = false;
+        }
+        // else: A key was probably pressed within the same tick, ignore it.
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/input/KeyBinderManager.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/KeyBinderManager.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/KeyBinderManager.h	(revision 6952)
@@ -0,0 +1,125 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _KeyBinderManager_H__
+#define _KeyBinderManager_H__
+
+#include "InputPrereqs.h"
+
+#include <map>
+#include <string>
+#include <boost/shared_ptr.hpp>
+
+#include "util/Singleton.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox //tolua_export
+{ //tolua_export
+    /**
+    @brief
+        Handles the KeyBinders and supplies them throughout the game.
+
+        This interface merely serves to provide a static "keybind" command that always
+        maps to the currently active KeyBinder. You can set that with setCurrent().
+        There is also a default one, retrieved with getDefault(). The idea is that
+        mostly the default KeyBinder is active except for special situations (mini-game for inst).
+    @remarks
+        You are not forced to use the KeyBinder imposed by getCurrent(). But be aware that "keybind"
+        will not work as expected!
+    */
+    class _CoreExport KeyBinderManager //tolua_export
+        : public Singleton<KeyBinderManager>, public OrxonoxClass
+    { //tolua_export
+        friend class Singleton<KeyBinderManager>;
+    public:
+        KeyBinderManager();
+        ~KeyBinderManager();
+        void setConfigValues();
+
+        static KeyBinderManager& getInstance() { return Singleton<KeyBinderManager>::getInstance(); } //tolua_export
+        //! Returns the currently selected KeyBinder
+        KeyBinder* getCurrent() { return this->currentBinder_; } //tolua_export
+        //! Like getCurrent(), but returns it as InputHandler* (so you don't have to include KeyBinder.h)
+        InputHandler* getCurrentAsHandler();
+        //! Selects the current KeyBinder and creates it if not yet loaded.
+        void setCurrent(const std::string& filename);
+
+        //! Returns the default KeyBinder
+        KeyBinder* getDefault()
+            { return binders_[this->defaultFilename_]; }
+        //! Returns the default KeyBinder as InputHandler* (so you don't have to include KeyBinder.h)
+        InputHandler* getDefaultAsHandler();
+        //! Returns the filename of the default key bindings
+        const std::string& getDefaultFilename()
+            { return defaultFilename_; }
+        //! Selects the default KeyBinder as current one
+        void setToDefault()
+            { this->setCurrent(this->defaultFilename_); }
+
+        //! Returns a pointer to a KeyBinder (creates it if not yet loaded)
+        KeyBinder* get(const std::string& name);
+        //! Like get() but return value is of type InputHandler* (so you don't have to include KeyBinder.h)
+        InputHandler* getAsHandler(const std::string& name);
+
+        //! Loads a KeyBinder by creating it (no different from get() except for the return value)
+        void load(const std::string& filename);
+        //! Destroys a KeyBinder completely (does nothing if not yet loaded)
+        void unload(const std::string& filename);
+
+        //! Bind 'command' to any key pressed after this call (use with care!)
+        inline void keybind(const std::string& command) { this->keybindInternal(command, false); } //tolua_export
+        //! Bind 'command' to any key pressed after this call (use with care!), but temporarily (no file save)
+        inline void tkeybind(const std::string& command)
+            { this->keybindInternal(command, true); }
+        void unbind(const std::string& binding); //tolua_export
+        void tunbind(const std::string& binding);
+        inline void registerKeybindCallback(Functor* function) { this->callbackFunction_.reset(function); } // tolua_export
+
+    private:
+        KeyBinderManager(const KeyBinderManager&);
+        void keybindInternal(const std::string& command, bool bTemporary);
+        void keybindKeyPressed(const std::string& keyName);
+        void defaultFilenameChanged();
+
+        // KeyBinder management
+        KeyBinder* currentBinder_;                   //! Currently selected KeyBinder (never NULL!)
+        std::map<std::string, KeyBinder*> binders_;  //! All loaded KeyBinders
+        bool bDefaultFileLoaded_;                    //! Tells whether the default one is loaded
+        std::string defaultFilename_;                //! Name of the file with the default key bindings
+
+        // keybind command related
+        shared_ptr<Functor> callbackFunction_;       //! Function to be called when key was pressed after "keybind" command
+        bool bBinding_;                              //! Tells whether a key binding process is active
+        bool bTemporary_;                            //! Stores tkeybind/keybind value
+        std::string command_;                        //! Stores the command received by (t)keybind
+
+        static KeyBinderManager* singletonPtr_s;
+    }; //tolua_export
+} //tolua_export
+
+#endif /* _KeyBinderManager_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/KeyDetector.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/KeyDetector.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/KeyDetector.cc	(revision 6952)
@@ -0,0 +1,82 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "KeyDetector.h"
+
+#include "core/ConsoleCommand.h"
+#include "core/CoreIncludes.h"
+#include "core/ScopedSingletonManager.h"
+#include "Button.h"
+#include "InputManager.h"
+#include "InputState.h"
+
+namespace orxonox
+{
+    std::string KeyDetector::callbackCommand_s = "KeyDetectorKeyPressed";
+    ManageScopedSingleton(KeyDetector, ScopeID::Graphics, false);
+
+    KeyDetector::KeyDetector()
+        : KeyBinder("")
+    {
+        RegisterObject(KeyDetector);
+
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&KeyDetector::callback,  this), callbackCommand_s));
+        this->assignCommands();
+
+        inputState_ = InputManager::getInstance().createInputState("detector", false, false, InputStatePriority::Detector);
+        // Create a callback to avoid buttonHeld events after the key has been detected
+        inputState_->setLeaveFunctor(createFunctor(&InputManager::clearBuffers, &InputManager::getInstance()));
+        inputState_->setHandler(this);
+    }
+
+    KeyDetector::~KeyDetector()
+    {
+        inputState_->setHandler(NULL);
+        InputManager::getInstance().destroyState("detector");
+    }
+
+    void KeyDetector::assignCommands()
+    {
+        // Assign every button/axis the same command, but with its name as argument
+        for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
+            it->second->parse(callbackCommand_s + ' ' + it->second->groupName_ + "." + it->second->name_);
+    }
+
+    void KeyDetector::callback(const std::string& name)
+    {
+        // Call the registered function
+        if (this->callbackFunction_)
+            (*this->callbackFunction_)(name);
+    }
+
+    void KeyDetector::JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList)
+    {
+        KeyBinder::JoyStickQuantityChanged(joyStickList);
+        this->assignCommands();
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/input/KeyDetector.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/KeyDetector.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/KeyDetector.h	(revision 6952)
@@ -0,0 +1,64 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _KeyDetector_H__
+#define _KeyDetector_H__
+
+#include "InputPrereqs.h"
+
+#include <boost/shared_ptr.hpp>
+#include "util/Singleton.h"
+#include "KeyBinder.h"
+
+namespace orxonox
+{
+    class _CoreExport KeyDetector : public KeyBinder, public Singleton<KeyDetector>
+    {
+        friend class Singleton<KeyDetector>;
+
+    public:
+        KeyDetector();
+        ~KeyDetector();
+
+        void setCallback(const shared_ptr<Functor>& function) { this->callbackFunction_ = function; }
+
+    private:
+        KeyDetector(const KeyDetector&);
+
+        void callback(const std::string& name);
+        void JoyStickQuantityChanged(const std::vector<JoyStick*>& joyStickList);
+        void assignCommands();
+
+        shared_ptr<Functor> callbackFunction_;
+        InputState* inputState_;
+        static std::string callbackCommand_s;
+        static KeyDetector* singletonPtr_s;
+    };
+}
+
+#endif /* _KeyDetector_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/Keyboard.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/Keyboard.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/Keyboard.cc	(revision 6952)
@@ -0,0 +1,69 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Keyboard.h"
+#include "InputState.h"
+
+namespace orxonox
+{
+    //! OIS event handler
+    bool Keyboard::keyPressed(const OIS::KeyEvent& arg)
+    {
+        // update modifiers
+        if (arg.key == OIS::KC_RMENU    || arg.key == OIS::KC_LMENU)
+            modifiers_ |= KeyboardModifier::Alt;   // alt key
+        if (arg.key == OIS::KC_RCONTROL || arg.key == OIS::KC_LCONTROL)
+            modifiers_ |= KeyboardModifier::Ctrl;  // ctrl key
+        if (arg.key == OIS::KC_RSHIFT   || arg.key == OIS::KC_LSHIFT)
+            modifiers_ |= KeyboardModifier::Shift; // shift key
+
+        // Do not distribute the alt+tab event (messes with the operating system)
+        if ((modifiers_ & KeyboardModifier::Alt) != 0 && arg.key == OIS::KC_TAB)
+            return true;
+
+        KeyEvent evt(arg);
+        super::buttonPressed(evt);
+        return true;
+    }
+
+    //! OIS event handler
+    bool Keyboard::keyReleased(const OIS::KeyEvent& arg)
+    {
+        // update modifiers
+        if (arg.key == OIS::KC_RMENU    || arg.key == OIS::KC_LMENU)
+            modifiers_ &= ~KeyboardModifier::Alt;   // alt key
+        if (arg.key == OIS::KC_RCONTROL || arg.key == OIS::KC_LCONTROL)
+            modifiers_ &= ~KeyboardModifier::Ctrl;  // ctrl key
+        if (arg.key == OIS::KC_RSHIFT   || arg.key == OIS::KC_LSHIFT)
+            modifiers_ &= ~KeyboardModifier::Shift; // shift key
+
+        KeyEvent evt(arg);
+        super::buttonReleased(evt);
+        return true;
+    }
+}
Index: /code/branches/rocket2/src/libraries/core/input/Keyboard.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/Keyboard.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/Keyboard.h	(revision 6952)
@@ -0,0 +1,90 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Core_Keyboard_H__
+#define _Core_Keyboard_H__
+
+#include "InputPrereqs.h"
+
+#include "InputHandler.h"
+#include "InputDevice.h"
+
+namespace orxonox
+{
+    //! Template parameter collection for the base class
+    struct KeyboardTraits
+    {
+        typedef Keyboard DeviceClass;
+        typedef OIS::Keyboard OISDeviceClass;
+        typedef KeyEvent ButtonType;
+        typedef KeyEvent& ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = OIS::OISKeyboard;
+    };
+
+    /**
+    @brief
+        Wraps around an OIS::Mouse and forwards the input events to
+        a list of input states.
+
+        It also saves the state of the keyboard modifiers (like shift, etc.)
+    */
+    class _CoreExport Keyboard
+        : public InputDeviceTemplated<KeyboardTraits>
+        , public OIS::KeyListener
+    {
+        friend class InputDeviceTemplated<KeyboardTraits>;
+        //! Super class alias
+        typedef InputDeviceTemplated<KeyboardTraits> super;
+
+    public:
+        //! Only resets the keyboard modifiers. Initialising is done in the base class.
+        Keyboard(unsigned int id, OIS::InputManager* oisInputManager) : super(id, oisInputManager), modifiers_(0) { }
+        ~Keyboard() { }
+
+    private:
+        //! Resets the keyboard modifiers
+        void clearBuffersImpl() { this->modifiers_ = 0; }
+        //! Translates the KeyHandle to a KeyEvent
+        KeyEvent& getButtonEventArg(KeyEvent& button)
+        {
+            button.setModifiers(modifiers_);
+            return button;
+        }
+
+        bool keyPressed(const OIS::KeyEvent& arg);
+        bool keyReleased(const OIS::KeyEvent& arg);
+
+        //! Returns the class name as string
+        static std::string getClassNameImpl() { return "Keyboard"; }
+
+        //! Bit mask representing keyboard modifiers
+        int modifiers_;
+    };
+}
+
+#endif /* _Core_Keyboard_H__ */
Index: /code/branches/rocket2/src/libraries/core/input/Mouse.cc
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/Mouse.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/Mouse.cc	(revision 6952)
@@ -0,0 +1,101 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Mouse.h"
+
+#include <ois/OISMouse.h>
+#include "core/ConsoleCommand.h"
+#include "core/CoreIncludes.h"
+#include "InputState.h"
+
+#ifdef ORXONOX_PLATFORM_LINUX
+// include this as last, X11 seems to define some macros...
+#include <ois/linux/LinuxMouse.h>
+#endif
+
+namespace orxonox
+{
+    Mouse::Mouse(unsigned int id, OIS::InputManager* oisInputManager)
+        : super(id, oisInputManager)
+    {
+        RegisterRootObject(Mouse);
+        this->windowResized(this->getWindowWidth(), this->getWindowHeight());
+
+#ifdef ORXONOX_PLATFORM_LINUX
+        // Mouse grab console command
+        this->getIdentifier()->addConsoleCommand(createConsoleCommand(createFunctor(&Mouse::grab, this), "grab"), false);
+        // Mouse ungrab console command
+        this->getIdentifier()->addConsoleCommand(createConsoleCommand(createFunctor(&Mouse::ungrab, this), "ungrab"), false);
+#endif
+    }
+
+    //! OIS event handler
+    bool Mouse::mouseMoved(const OIS::MouseEvent &e)
+    {
+        // check for actual moved event
+        if (e.state.X.rel != 0 || e.state.Y.rel != 0)
+        {
+            IntVector2 abs(e.state.X.abs, e.state.Y.abs);
+            IntVector2 rel(e.state.X.rel, e.state.Y.rel);
+            IntVector2 clippingSize(e.state.width, e.state.height);
+            for (unsigned int i = 0; i < inputStates_.size(); ++i)
+                inputStates_[i]->mouseMoved(abs, rel, clippingSize);
+        }
+
+        // check for mouse scrolled event
+        if (e.state.Z.rel != 0)
+        {
+            for (unsigned int i = 0; i < inputStates_.size(); ++i)
+                inputStates_[i]->mouseScrolled(e.state.Z.abs, e.state.Z.rel);
+        }
+
+        return true;
+    }
+
+    void Mouse::windowResized(unsigned int newWidth, unsigned int newHeight)
+    {
+        oisDevice_->getMouseState().width  = newWidth;
+        oisDevice_->getMouseState().height = newHeight;
+    }
+
+#ifdef ORXONOX_PLATFORM_LINUX
+    void Mouse::grab()
+    {
+        OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(oisDevice_);
+        assert(linuxMouse);
+        linuxMouse->grab(true);
+    }
+
+    void Mouse::ungrab()
+    {
+        OIS::LinuxMouse* linuxMouse = dynamic_cast<OIS::LinuxMouse*>(oisDevice_);
+        assert(linuxMouse);
+        linuxMouse->grab(false);
+    }
+#endif
+}
Index: /code/branches/rocket2/src/libraries/core/input/Mouse.h
===================================================================
--- /code/branches/rocket2/src/libraries/core/input/Mouse.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/core/input/Mouse.h	(revision 6952)
@@ -0,0 +1,98 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Core_Mouse_H__
+#define _Core_Mouse_H__
+
+#include "InputPrereqs.h"
+
+#include "InputDevice.h"
+#include "core/WindowEventListener.h"
+
+namespace orxonox
+{
+    //! Template parameter collection for the base class
+    struct MouseTraits
+    {
+        typedef Mouse DeviceClass;
+        typedef OIS::Mouse OISDeviceClass;
+        typedef MouseButtonCode::ByEnum ButtonType;
+        typedef MouseButtonCode::ByEnum ButtonTypeParam;
+        static const OIS::Type OISDeviceValue = OIS::OISMouse;
+    };
+
+    /**
+    @brief
+        Wraps around an OIS::Mouse and forwards the input events to
+        a list of input states.
+    */
+    class _CoreExport Mouse
+        : public InputDeviceTemplated<MouseTraits>
+        , public OIS::MouseListener
+        , public WindowEventListener
+    {
+        friend class InputDeviceTemplated<MouseTraits>;
+        //! Super class alias
+        typedef InputDeviceTemplated<MouseTraits> super;
+
+    public:
+        //! Only sets the clipping size. Initialising is done in the base class.
+        Mouse(unsigned int id, OIS::InputManager* oisInputManager);
+        ~Mouse() { }
+
+#ifdef ORXONOX_PLATFORM_LINUX
+        // TODO: Make this a feature rather than a hack
+        void grab();
+        void ungrab();
+#endif
+
+    private:
+        //! OIS event handler
+        bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
+        {
+            super::buttonPressed(static_cast<MouseButtonCode::ByEnum>(id));
+            return true;
+        }
+
+        //! OIS event handler
+        bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
+        {
+            super::buttonReleased(static_cast<MouseButtonCode::ByEnum>(id));
+            return true;
+        }
+
+        bool mouseMoved(const OIS::MouseEvent &arg);
+
+        void windowResized(unsigned int newWidth, unsigned int newHeight);
+
+        // Returns the class name as string
+        static std::string getClassNameImpl() { return "Mouse"; }
+    };
+}
+
+#endif /* _Core_Mouse_H__ */
Index: /code/branches/rocket2/src/libraries/network/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/libraries/network/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,74 @@
+ #
+ #             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.
+ #
+
+SET_SOURCE_FILES(NETWORK_SRC_FILES
+  ChatListener.cc
+  Client.cc
+  ClientConnection.cc
+  ClientInformation.cc
+  ClientConnectionListener.cc
+  Connection.cc
+  FunctionCallManager.cc
+  GamestateManager.cc
+  GamestateClient.cc
+  GamestateHandler.cc
+  NetworkFunction.cc
+  Host.cc
+  Server.cc
+  ServerConnection.cc
+  TrafficControl.cc
+)
+
+SET_SOURCE_FILES(NETWORK_HDR_FILES
+  ChatListener.h
+  Client.h
+  ClientConnection.h
+  ClientConnectionListener.h
+  ClientInformation.h
+  Connection.h
+  FunctionCallManager.h
+  GamestateClient.h
+  GamestateHandler.h
+  GamestateManager.h
+  Host.h
+  NetworkFunction.h
+  NetworkPrecompiledHeaders.h
+  NetworkPrereqs.h
+  Server.h
+  ServerConnection.h
+  TrafficControl.h
+)
+
+ADD_SUBDIRECTORY(packet)
+ADD_SUBDIRECTORY(synchronisable)
+
+ORXONOX_ADD_LIBRARY(network
+  DEFINE_SYMBOL
+    "NETWORK_SHARED_BUILD"
+  PCH_FILE
+    NetworkPrecompiledHeaders.h
+  LINK_LIBRARIES
+    ${ZLIB_LIBRARY}
+    ${ENET_LIBRARY}
+    ${Boost_THREAD_LIBRARY}
+    util
+    core
+  SOURCE_FILES
+    ${NETWORK_SRC_FILES} ${NETWORK_HDR_FILES}
+)
Index: /code/branches/rocket2/src/libraries/network/ChatListener.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/ChatListener.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/ChatListener.cc	(revision 6952)
@@ -0,0 +1,50 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ChatListener.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    ChatListener::ChatListener()
+    {
+        RegisterRootObject(ChatListener);
+    }
+
+    //void ChatListener::incomingChat( const std::string& message,
+      //unsigned int senderID )
+    //{
+      //COUT(0) << "Chat: \"" << message << "\"\n";
+
+
+    //}
+
+
+}
+
+
Index: /code/branches/rocket2/src/libraries/network/ChatListener.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/ChatListener.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/ChatListener.h	(revision 6952)
@@ -0,0 +1,49 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NETWORK_ChatListener__
+#define _NETWORK_ChatListener__
+
+#include "NetworkPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _NetworkExport ChatListener : virtual public OrxonoxClass
+    {
+        public:
+	    /* constructor, destructor */
+            ChatListener();
+            virtual ~ChatListener() {}
+
+            /* What to do with incoming chat */
+            virtual void incomingChat(const std::string& message, unsigned int senderID) = 0;
+    };
+}
+
+#endif /* _NETWORK_ChatListener__ */
Index: /code/branches/rocket2/src/libraries/network/Client.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/Client.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/Client.cc	(revision 6952)
@@ -0,0 +1,186 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Implementation: Client
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "Client.h"
+
+#include <cassert>
+
+#include "util/Clock.h"
+#include "util/Debug.h"
+#include "synchronisable/Synchronisable.h"
+#include "packet/Chat.h"
+#include "packet/Gamestate.h"
+#include "FunctionCallManager.h"
+#include "core/CoreIncludes.h"
+#include "core/Game.h"
+
+namespace orxonox
+{
+
+
+  /**
+  * Constructor for the Client class
+  * initializes the address and the port to default localhost:NETWORK_PORT
+  */
+  Client::Client():
+      isSynched_(false),
+      gameStateFailure_(false),
+      timeSinceLastUpdate_(0)
+  {
+  }
+
+  /**
+  * Constructor for the Client class
+  * @param address the server address
+  * @param port port of the application on the server
+  */
+  Client::Client(const std::string& address, int port):
+      isSynched_(false),
+      gameStateFailure_(false),
+      timeSinceLastUpdate_(0)
+  {
+      setPort( port );
+      setServerAddress( address );
+  }
+
+  Client::~Client(){
+    if ( ClientConnection::isConnected() )
+      closeConnection();
+  }
+
+  /**
+  * Establish the Connection to the Server
+  * @return true/false
+  */
+  bool Client::establishConnection(){
+    Synchronisable::setClient(true);
+    return ClientConnection::establishConnection();
+  }
+
+  /**
+  * closes the Connection to the Server
+  * @return true/false
+  */
+  bool Client::closeConnection(){
+    return ClientConnection::closeConnection();
+  }
+
+  bool Client::queuePacket(ENetPacket *packet, int clientID){
+    bool b = ClientConnection::addPacket(packet);
+    assert(b);
+    return b;
+  }
+
+  bool Client::processChat(const std::string& message, unsigned int playerID){
+//    COUT(1) << "Player " << playerID << ": " << message << std::endl;
+    return true;
+  }
+
+  void Client::printRTT(){
+    COUT(0) << "Round trip time to server is " << ClientConnection::getRTT() << " ms" << endl;
+  }
+
+  /**
+   * This function implements the method of sending a chat message to the server
+   * @param message message to be sent
+   * @return result(true/false)
+   */
+  bool Client::chat(const std::string& message){
+    packet::Chat *m = new packet::Chat(message, Host::getPlayerID());
+    return m->send();
+  }
+
+
+  /**
+   * Processes incoming packets, sends a gamestate to the server and does the cleanup
+   * @param time
+   */
+  void Client::update(const Clock& time){
+    //this steers our network frequency
+    timeSinceLastUpdate_+=time.getDeltaTime();
+    if(timeSinceLastUpdate_>=NETWORK_PERIOD)
+    {
+      timeSinceLastUpdate_ -= static_cast<unsigned int>( timeSinceLastUpdate_ / NETWORK_PERIOD ) * NETWORK_PERIOD;
+      //     COUT(3) << '.';
+      if ( isConnected() && isSynched_ )
+      {
+        COUT(4) << "popping partial gamestate: " << std::endl;
+        packet::Gamestate *gs = gamestate.getGamestate();
+        //assert(gs); <--- there might be the case that no data has to be sent, so its commented out now
+        if(gs){
+          COUT(4) << "client tick: sending gs " << gs << std::endl;
+          if( !gs->send() )
+            COUT(3) << "Problem adding partial gamestate to queue" << std::endl;
+        // gs gets automatically deleted by enet callback
+        }
+        FunctionCallManager::sendCalls();
+      }
+    }
+    sendPackets(); // flush the enet queue
+
+    Connection::processQueue();
+    if(gamestate.processGamestates())
+    {
+      if(!isSynched_)
+        isSynched_=true;
+    }
+    gamestate.cleanup();
+    Connection::sendPackets();
+
+    return;
+  }
+
+  void Client::connectionClosed()
+  {
+    ObjectList<Synchronisable>::iterator it;
+    for(it = ObjectList<Synchronisable>::begin(); it; )
+    {
+      if( it->getSyncMode() != 0x0 )
+        (it++)->destroy();
+      else
+      {
+        ++it;
+      }
+    }
+    Game::getInstance().popState();
+    Game::getInstance().popState();
+  }
+
+}
Index: /code/branches/rocket2/src/libraries/network/Client.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/Client.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/Client.h	(revision 6952)
@@ -0,0 +1,93 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Interface: Client
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#ifndef _Client_H__
+#define _Client_H__
+
+#include "NetworkPrereqs.h"
+
+#include <string>
+
+#include "util/UtilPrereqs.h"
+#include "ClientConnection.h"
+#include "GamestateClient.h"
+#include "Host.h"
+
+namespace orxonox
+{
+  /**
+  Client *client;
+  * The network/Client class
+  * This class implements all necessary function for the network communication
+  * It is the root class of the network module
+  *
+  */
+  class _NetworkExport Client : public Host, public ClientConnection{
+  public:
+    Client();
+    Client(const std::string& address, int port);
+    ~Client();
+
+    bool establishConnection();
+    bool closeConnection();
+    bool queuePacket(ENetPacket *packet, int clientID);
+    bool processChat(const std::string& message, unsigned int playerID);
+    virtual bool chat(const std::string& message);
+    virtual bool broadcast(const std::string& message) { return false; }
+    virtual void printRTT();
+
+    void update(const Clock& time);
+  protected:
+    virtual void connectionClosed();
+  private:
+    Client(const Client& copy); // not used
+    virtual bool isServer_(){return false;}
+
+    GamestateClient gamestate;
+    bool isSynched_;
+
+    bool gameStateFailure_;
+    float timeSinceLastUpdate_;
+  };
+
+
+}
+
+#endif /* _Client_H__ */
Index: /code/branches/rocket2/src/libraries/network/ClientConnection.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/ClientConnection.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/ClientConnection.cc	(revision 6952)
@@ -0,0 +1,155 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ClientConnection.h"
+
+#include <cassert>
+#define WIN32_LEAN_AND_MEAN
+#include <enet/enet.h>
+#include "util/Debug.h"
+
+namespace orxonox
+{
+  const unsigned int NETWORK_CLIENT_WAIT_TIME = 1;
+  const unsigned int NETWORK_CLIENT_CONNECTION_TIMEOUT = 3000; //millisecs
+  const unsigned int NETWORK_CLIENT_MAX_CONNECTIONS = 1;
+  const unsigned int NETWORK_CLIENT_CHANNELS = 1;
+
+
+  ClientConnection::ClientConnection():
+    established_(false),
+    server_(NULL)
+  {
+    this->serverAddress_ = new ENetAddress();
+    //set standard address and port
+    enet_address_set_host(this->serverAddress_, "127.0.0.1");
+    serverAddress_->port = NETWORK_PORT;
+  }
+
+  ClientConnection::~ClientConnection(){
+    if(this->established_)
+      closeConnection();
+    delete this->serverAddress_; // surely was created
+  }
+
+  void ClientConnection::setServerAddress( const std::string& serverAddress ) {
+    enet_address_set_host (this->serverAddress_, serverAddress.c_str());
+  }
+
+  void ClientConnection::setPort( unsigned int port ) {
+    this->serverAddress_->port = port;
+  }
+
+  bool ClientConnection::establishConnection()
+  {
+    ENetEvent event;
+
+    this->host_ = enet_host_create(NULL, NETWORK_CLIENT_MAX_CONNECTIONS, 0, 0);
+    if ( this->host_ == NULL )
+    {
+      COUT(2) << "ClientConnection: host_ == NULL" << std::endl;
+      // error handling
+      return false;
+    }
+    this->server_ = enet_host_connect(this->host_, serverAddress_, NETWORK_CLIENT_CHANNELS);
+    if ( this->server_==NULL )
+    {
+      COUT(2) << "ClientConnection: server == NULL" << std::endl;
+      // error handling
+      return false;
+    }
+    // handshake
+    for( unsigned int i=0; i<NETWORK_CLIENT_CONNECTION_TIMEOUT/NETWORK_CLIENT_WAIT_TIME; i++ )
+    {
+      if( enet_host_service(this->host_, &event, NETWORK_CLIENT_WAIT_TIME)>=0 && event.type == ENET_EVENT_TYPE_CONNECT )
+      {
+        this->established_=true;
+        return true;
+      }
+    }
+    COUT(1) << "Could not connect to server" << endl;
+    return false;
+  }
+
+  bool ClientConnection::closeConnection() {
+    ENetEvent event;
+
+    if ( !this->established_ )
+      return true;
+    this->established_ = false;
+    enet_peer_disconnect(this->server_, 0);
+    for( unsigned int i=0; i<NETWORK_CLIENT_CONNECTION_TIMEOUT/NETWORK_CLIENT_WAIT_TIME; i++)
+    {
+      if ( enet_host_service(this->host_, &event, NETWORK_CLIENT_WAIT_TIME) >= 0 )
+      {
+        switch (event.type)
+        {
+          case ENET_EVENT_TYPE_NONE:
+          case ENET_EVENT_TYPE_CONNECT:
+            break;
+          case ENET_EVENT_TYPE_RECEIVE:
+            enet_packet_destroy(event.packet);
+            break;
+          case ENET_EVENT_TYPE_DISCONNECT:
+            COUT(4) << "received disconnect confirmation from server" << endl;
+            this->connectionClosed();
+            return true;
+        }
+      }
+    }
+    enet_peer_reset( this->server_ );
+    this->connectionClosed();
+    return false;
+  }
+
+
+  bool ClientConnection::addPacket(ENetPacket *packet) {
+    assert( this->server_ );
+    assert( packet );
+    return Connection::addPacket( packet, this->server_ );
+  }
+
+  void ClientConnection::addPeer(ENetEvent* event)
+  {
+    assert(0);
+  }
+  void ClientConnection::removePeer(ENetEvent* event)
+  {
+    this->established_=false;
+    COUT(1) << "Received disconnect Packet from Server!" << endl;
+        // server closed the connection
+    this->connectionClosed();
+  }
+
+  uint32_t ClientConnection::getRTT()
+  {
+    assert(server_);
+    return server_->roundTripTime;
+  }
+
+}
Index: /code/branches/rocket2/src/libraries/network/ClientConnection.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/ClientConnection.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/ClientConnection.h	(revision 6952)
@@ -0,0 +1,73 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ClientConnection_H__
+#define _ClientConnection_H__
+
+#include "NetworkPrereqs.h"
+#include "Connection.h"
+
+namespace orxonox
+{
+
+  class _NetworkExport ClientConnection: public Connection{
+  public:
+    ClientConnection();
+    virtual ~ClientConnection();
+
+    void setServerAddress( const std::string& serverAddress );
+    void setPort( unsigned int port );
+
+    ENetEvent *getEvent();
+    // check wheter the packet queue is empty
+    bool queueEmpty();
+    // create a new listener thread
+    virtual bool establishConnection();
+    virtual bool closeConnection();
+    // add a packet to queue for the server
+    bool addPacket(ENetPacket *packet);
+    inline bool isConnected(){ return this->established_; }
+  protected:
+    virtual void connectionClosed()=0;
+    uint32_t getRTT();
+  private:
+    virtual void addPeer(ENetEvent* event);
+    virtual void removePeer(ENetEvent* event);
+
+    bool disconnectConnection();
+    // enet stuff
+    ENetAddress *serverAddress_;
+    bool established_;
+    // clientlist
+    ENetPeer *server_;
+};
+
+
+}
+
+#endif /* _ClientConnection_H__ */
Index: /code/branches/rocket2/src/libraries/network/ClientConnectionListener.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/ClientConnectionListener.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/ClientConnectionListener.cc	(revision 6952)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ClientConnectionListener.h"
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "ClientInformation.h"
+
+namespace orxonox
+{
+    ClientConnectionListener::ClientConnectionListener()
+    {
+        RegisterRootObject(ClientConnectionListener);
+    }
+
+    void ClientConnectionListener::broadcastClientConnected(unsigned int clientID)
+    {
+        for (ObjectList<ClientConnectionListener>::iterator it = ObjectList<ClientConnectionListener>::begin(); it != ObjectList<ClientConnectionListener>::end(); ++it)
+            it->clientConnected(clientID);
+    }
+
+    void ClientConnectionListener::broadcastClientDisconnected(unsigned int clientID)
+    {
+        for (ObjectList<ClientConnectionListener>::iterator it = ObjectList<ClientConnectionListener>::begin(); it != ObjectList<ClientConnectionListener>::end(); ++it)
+            it->clientDisconnected(clientID);
+    }
+
+    void ClientConnectionListener::getConnectedClients()
+    {
+        ClientInformation* client = ClientInformation::getBegin();
+        while (client)
+        {
+            this->clientConnected(client->getID());
+            client = client->next();
+        }
+    }
+}
+
+
Index: /code/branches/rocket2/src/libraries/network/ClientConnectionListener.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/ClientConnectionListener.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/ClientConnectionListener.h	(revision 6952)
@@ -0,0 +1,55 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ClientConnectionListener_H__
+#define _ClientConnectionListener_H__
+
+#include "NetworkPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _NetworkExport ClientConnectionListener : virtual public OrxonoxClass
+    {
+        public:
+            ClientConnectionListener();
+            virtual ~ClientConnectionListener() {}
+
+            static void broadcastClientConnected(unsigned int clientID);
+            static void broadcastClientDisconnected(unsigned int clientID);
+
+            virtual void clientConnected(unsigned int clientID) = 0;
+            virtual void clientDisconnected(unsigned int clientID) = 0;
+
+        protected:
+            void getConnectedClients();
+    };
+}
+
+
+#endif /* _ClientConnectionListener_H__ */
Index: /code/branches/rocket2/src/libraries/network/ClientInformation.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/ClientInformation.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/ClientInformation.cc	(revision 6952)
@@ -0,0 +1,274 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      ...
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Implementation: ClientInformation
+//
+// Description:
+//
+//
+// Author:  <>, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "ClientInformation.h"
+#define WIN32_LEAN_AND_MEAN
+#include <enet/enet.h>
+#include "ClientConnectionListener.h"
+
+namespace orxonox
+{
+
+
+  ClientInformation *ClientInformation::head_=0;
+
+  ClientInformation::ClientInformation() {
+    if(!head_)
+      head_=this;
+    gamestateID_=GAMESTATEID_INITIAL;
+    preve=0;
+    nexte=0;
+    partialGamestateID_=GAMESTATEID_INITIAL-1;
+    synched_=false;
+  }
+
+  ClientInformation::~ClientInformation() {
+    if(prev()!=0)
+      prev()->setNext(this->next());
+    if(next()!=0)
+      next()->setPrev(this->prev());
+    if(this==head_)
+      head_=next();
+    ClientConnectionListener::broadcastClientDisconnected( this->getID() );
+  }
+
+  ClientInformation *ClientInformation::next() {
+    if(this!=0)
+      return this->nexte;
+    else
+      return 0;
+  }
+  ClientInformation *ClientInformation::prev() {
+    if(this!=0)
+      return this->preve;
+    else
+      return 0;
+  }
+
+  bool ClientInformation::setPrev(ClientInformation *prev) {
+    if(this==head_)
+      head_=prev;
+    this->preve = prev;
+    return true;
+  }
+
+  bool ClientInformation::setNext(ClientInformation *next) {
+    this->nexte = next;
+    return true;
+  }
+
+  ClientInformation *ClientInformation::insertAfter(ClientInformation *ins) {
+    this->next()->setPrev(ins);
+    ins->setNext(this->next());
+    ins->setPrev(this);
+    this->nexte = ins;
+    return ins;
+  }
+
+  ClientInformation *ClientInformation::insertBefore(ClientInformation *ins){
+    if(!this)
+      return NULL;
+    this->prev()->setNext(ins);
+    ins->setPrev(this->prev());
+    this->preve=ins;
+    ins->setNext(this);
+    return ins;
+  }
+
+  void ClientInformation::setID(int clientID){
+    if(!this)
+      return;
+    clientID_ = clientID;
+  }
+
+  bool ClientInformation::setPeer(ENetPeer *peer){
+    if(!this)
+      return false;
+    peer_ = peer;
+    return true;
+  }
+
+  bool ClientInformation::setGamestateID(int id){
+    if(!this)
+      return false;
+    gamestateID_=id;
+    return true;
+  }
+
+  bool ClientInformation::setPartialGamestateID(int id){
+    if(!this)
+      return false;
+    partialGamestateID_=id;
+    return true;
+  }
+
+  unsigned int ClientInformation::getID() {
+    if(!this)
+      return CLIENTID_UNKNOWN;
+    else
+      return clientID_;
+  }
+
+  ENetPeer *ClientInformation::getPeer() {
+    if(this)
+      return peer_;
+    else
+      return NULL;
+  }
+
+  int ClientInformation::getFailures(){
+    return failures_;
+  }
+  void ClientInformation::addFailure(){
+    failures_++;
+  }
+  void ClientInformation::resetFailures(){
+    failures_=0;
+  }
+
+  uint32_t ClientInformation::getRTT(){
+    return this->peer_->roundTripTime;
+  }
+
+  double ClientInformation::getPacketLoss(){
+    return static_cast<double>(this->peer_->packetLoss)/ENET_PEER_PACKET_LOSS_SCALE;
+  }
+
+  unsigned int ClientInformation::getGamestateID() {
+    if(this)
+      return gamestateID_;
+    else
+      return static_cast<unsigned int>(-1);
+  }
+
+  unsigned int ClientInformation::getPartialGamestateID() {
+    if(this)
+      return partialGamestateID_;
+    else
+      return static_cast<unsigned int>(-1);
+  }
+
+  ClientInformation *ClientInformation::insertBack(ClientInformation *ins) {
+    ClientInformation *temp = head_;
+    if(temp==ins){
+      return head_;
+    }
+    while(temp->next()!=0){
+      temp = temp->next();
+    }
+    temp->setNext(ins);
+    ins->setPrev(temp);
+    return ins;
+  }
+
+  bool ClientInformation::removeClient(unsigned int clientID) {
+    if(clientID==CLIENTID_UNKNOWN)
+      return false;
+    ClientInformation *temp = head_;
+    while(temp!=0 && temp->getID()!=clientID)
+      temp = temp->next();
+    if(temp==0)
+      return false;
+    delete temp;
+    return true;
+  }
+
+  bool ClientInformation::removeClient(ENetPeer *peer) {
+    if(!peer)
+      return false;
+    ClientInformation *temp = head_;
+    while(temp!=0){
+      if(temp->getPeer()->address.host==peer->address.host && temp->getPeer()->address.port==peer->address.port)
+        break;
+      temp = temp->next();
+    }
+    if(temp==0)
+      return false;
+    delete temp;
+    return true;
+  }
+
+  /**
+  * This function goes forward through the list and looks for an element with clientID
+  * This function should only be applied to the head of the list
+  * @param clientID id to look for
+  * @return pointer to the last element in the list or 0 if the search was unsuccessfull
+  */
+  ClientInformation *ClientInformation::findClient(unsigned int clientID, bool look_backwards) {
+    ClientInformation *temp = head_;
+    while(temp!=0 && temp->getID()!=clientID){
+      temp = temp->next();
+    }
+    // returns 0 if nothing has been found
+    return temp;
+  }
+
+  /**
+  * This function goes forward through the list and looks for an element with clientID
+  * This function should only be applied to the head of the list
+  * @param peer peer to look for
+  * @return pointer to the element in the list
+  */
+  ClientInformation *ClientInformation::findClient(ENetAddress *address, bool look_backwards) {
+    ClientInformation *temp = head_;
+    while(temp!=0){
+      if(temp->getPeer()->address.host==address->host && temp->getPeer()->address.port == address->port)
+        break;
+      temp = temp->next();
+    }
+    // returns 0 if nothing has been found
+    return temp;
+  }
+
+  bool ClientInformation::setSynched(bool s) {
+    if(!this)
+      return false;
+    synched_=s;
+    return true;
+  }
+
+  bool ClientInformation::getSynched() {
+    if(this)
+      return synched_;
+    else
+      return false;
+  }
+
+}
Index: /code/branches/rocket2/src/libraries/network/ClientInformation.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/ClientInformation.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/ClientInformation.h	(revision 6952)
@@ -0,0 +1,117 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      ...
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Interface: ClientInformation
+//
+// Description:
+//
+//
+// Author:  <>, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef _ClientInformation_H__
+#define _ClientInformation_H__
+
+#include "NetworkPrereqs.h"
+
+// WATCH OUT: THE CLIENTINFORMATION LIST IS NOT THREADSAFE ANYMORE
+
+namespace orxonox
+{
+
+  /**
+  * This class implements a list for client information
+  * @author Oliver Scheuss
+  */
+  class _NetworkExport ClientInformation{
+  public:
+    ClientInformation();
+    //   ClientInformation(ClientInformation *prev, ClientInformation *next);
+    //   ClientInformation(ClientInformation *prev);
+    ~ClientInformation();
+    ClientInformation *next();
+    ClientInformation *prev();
+    static ClientInformation *insertBack(ClientInformation *ins);
+
+    // set functions
+    void setID(int clientID);
+    bool setPeer(ENetPeer *peer);
+    bool setGamestateID(int id);
+    bool setPartialGamestateID(int id);
+    inline void setShipID(unsigned int id){ShipID_=id;}
+
+    // get functions
+    inline unsigned int getShipID(){return ShipID_;}
+    unsigned int getID();
+    unsigned int getGamestateID();
+    unsigned int getPartialGamestateID();
+    ENetPeer *getPeer();
+
+    int getFailures();
+    void addFailure();
+    void resetFailures();
+    uint32_t getRTT();
+    double getPacketLoss();
+
+    static bool removeClient(unsigned int clientID);
+    static bool removeClient(ENetPeer *peer);
+    static ClientInformation *findClient(unsigned int clientID, bool look_backwards=false);
+    static ClientInformation *findClient(ENetAddress *address, bool look_backwards=false);
+    static ClientInformation *getBegin(){return head_;}
+    static bool hasClients(){ return ClientInformation::head_!=0; }
+
+    bool setSynched(bool s);
+    bool getSynched();
+
+  private:
+    static ClientInformation *head_;
+
+    bool setNext(ClientInformation *next);
+    bool setPrev(ClientInformation *prev);
+    ClientInformation *insertAfter(ClientInformation *ins);
+    ClientInformation *insertBefore(ClientInformation *ins);
+
+    ClientInformation *preve;
+    ClientInformation *nexte;
+    //actual information:
+    ENetPeer *peer_;
+    unsigned int clientID_;
+    unsigned int gamestateID_;
+    unsigned int partialGamestateID_;
+    unsigned int ShipID_;   // this is the unique objectID
+    bool synched_;
+    unsigned short failures_;
+
+  };
+
+}
+
+#endif /* _ClientInformation_H__ */
Index: /code/branches/rocket2/src/libraries/network/Connection.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/Connection.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/Connection.cc	(revision 6952)
@@ -0,0 +1,104 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Connection.h"
+
+#include <cassert>
+#define WIN32_LEAN_AND_MEAN
+#include <enet/enet.h>
+#include "packet/Packet.h"
+
+namespace orxonox
+{
+  Connection *Connection::instance_=0;
+
+  Connection::Connection():
+    host_(0)
+  {
+    assert(instance_==0);
+    Connection::instance_=this;
+    enet_initialize();
+    atexit(enet_deinitialize);
+  }
+
+  Connection::~Connection(){
+    Connection::instance_=0;
+  }
+
+  int Connection::service(ENetEvent* event) {
+    return enet_host_service( this->host_, event, NETWORK_WAIT_TIMEOUT );
+  }
+
+  void Connection::disconnectPeer(ENetPeer *peer) {
+    enet_peer_disconnect(peer, 0);
+  }
+
+  bool Connection::addPacket(ENetPacket *packet, ENetPeer *peer) {
+    if(enet_peer_send(peer, NETWORK_DEFAULT_CHANNEL, packet)!=0)
+      return false;
+    else
+      return true;
+  }
+
+  bool Connection::sendPackets() {
+    if ( !Connection::instance_ || this->host_==NULL )
+      return false;
+    enet_host_flush(this->host_);
+    return true;
+  }
+
+  void Connection::processQueue() {
+    ENetEvent event;
+
+    assert(this->host_);
+
+    while( enet_host_service( this->host_, &event, NETWORK_WAIT_TIMEOUT ) > 0 )
+    {
+      switch(event.type){
+        // log handling ================
+        case ENET_EVENT_TYPE_CONNECT:
+          addPeer( &event );
+          break;
+        case ENET_EVENT_TYPE_DISCONNECT:
+          removePeer( &event );
+          break;
+        case ENET_EVENT_TYPE_RECEIVE:
+          processPacket( &event );
+          break;
+        case ENET_EVENT_TYPE_NONE:
+          break;
+      }
+    }
+  }
+
+  bool Connection::processPacket(ENetEvent* event) {
+    packet::Packet *p = packet::Packet::createPacket(event->packet, event->peer);
+    return p->process();
+  }
+
+}
Index: /code/branches/rocket2/src/libraries/network/Connection.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/Connection.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/Connection.h	(revision 6952)
@@ -0,0 +1,83 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Interface: Connection
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef _Connection_H__
+#define _Connection_H__
+
+#include "NetworkPrereqs.h"
+
+namespace orxonox
+{
+    const unsigned int NETWORK_PORT = 55556;
+    const unsigned int NETWORK_MAX_CONNECTIONS = 50;
+    const unsigned int NETWORK_WAIT_TIMEOUT = 0;
+    const unsigned int NETWORK_DEFAULT_CHANNEL = 0;
+    const unsigned int NETWORK_MAX_QUEUE_PROCESS_TIME = 5;
+
+  class _NetworkExport Connection{
+  public:
+    virtual ~Connection();
+
+    static bool addPacket(ENetPacket *packet, ENetPeer *peer);
+    bool sendPackets();
+    ENetHost* getHost(){ return this->host_; }
+
+  protected:
+    Connection();
+    static Connection* getInstance(){ return Connection::instance_; }
+
+    int service(ENetEvent* event);
+    virtual void disconnectPeer(ENetPeer *peer);
+
+    void processQueue();
+    virtual void addPeer(ENetEvent* event)=0;
+    virtual void removePeer(ENetEvent* event)=0;
+    virtual bool processPacket(ENetEvent* event);
+
+    ENetHost *host_;
+  private:
+    ENetAddress *bindAddress_;
+
+    static Connection *instance_;
+
+  };
+
+}
+
+#endif /* _Connection_H__ */
Index: /code/branches/rocket2/src/libraries/network/FunctionCallManager.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/FunctionCallManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/FunctionCallManager.cc	(revision 6952)
@@ -0,0 +1,165 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "FunctionCallManager.h"
+#include "packet/FunctionCalls.h"
+
+namespace orxonox {
+
+std::map<uint32_t, packet::FunctionCalls*> FunctionCallManager::clientMap_;
+
+// Static calls
+
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID)
+{
+  if(clientMap_.find(clientID)==clientMap_.end())
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls;
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID);
+  }
+  FunctionCallManager::clientMap_[clientID]->addCallStatic(functionID);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1)
+{
+  if(clientMap_.find(clientID)==clientMap_.end())
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls;
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID);
+  }
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2)
+{
+  if(clientMap_.find(clientID)==clientMap_.end())
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls;
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID);
+  }
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
+{
+  if(clientMap_.find(clientID)==clientMap_.end())
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls;
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID);
+  }
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2, &mt3);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
+{
+  if(clientMap_.find(clientID)==clientMap_.end())
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls;
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID);
+  }
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2, &mt3, &mt4);
+}
+void FunctionCallManager::addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
+{
+  if(clientMap_.find(clientID)==clientMap_.end())
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls;
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID);
+  }
+  FunctionCallManager:: clientMap_[clientID]->addCallStatic(functionID, &mt1, &mt2, &mt3, &mt4, &mt5);
+}
+
+
+// MemberCalls
+
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID)
+{
+  if(clientMap_.find(clientID)==clientMap_.end())
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls;
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID);
+  }
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1)
+{
+  if(clientMap_.find(clientID)==clientMap_.end())
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls;
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID);
+  }
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2)
+{
+  if(clientMap_.find(clientID)==clientMap_.end())
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls;
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID);
+  }
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
+{
+  if(clientMap_.find(clientID)==clientMap_.end())
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls;
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID);
+  }
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
+{
+  if(clientMap_.find(clientID)==clientMap_.end())
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls;
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID);
+  }
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3, &mt4);
+}
+void FunctionCallManager::addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
+{
+  if(clientMap_.find(clientID)==clientMap_.end())
+  {
+    FunctionCallManager::clientMap_[clientID] = new packet::FunctionCalls;
+    FunctionCallManager::clientMap_[clientID]->setClientID(clientID);
+  }
+  FunctionCallManager::clientMap_[clientID]->addCallMember(functionID, objectID, &mt1, &mt2, &mt3, &mt4, &mt5);
+}
+
+// Send calls
+
+void FunctionCallManager::sendCalls()
+{
+  std::map<uint32_t, packet::FunctionCalls*>::iterator it;
+  for (it = FunctionCallManager::clientMap_.begin(); it != FunctionCallManager::clientMap_.end(); it++ )
+  {
+    assert(!FunctionCallManager::clientMap_.empty());
+    it->second->send();
+  }
+  FunctionCallManager::clientMap_.clear();
+}
+
+
+} //namespace orxonox
Index: /code/branches/rocket2/src/libraries/network/FunctionCallManager.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/FunctionCallManager.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/FunctionCallManager.h	(revision 6952)
@@ -0,0 +1,69 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _FunctionCallManager_H__
+#define _FunctionCallManager_H__
+
+#include "NetworkPrereqs.h"
+
+#include <map>
+#include "util/UtilPrereqs.h"
+
+namespace orxonox {
+/**
+    @author
+*/
+
+class _NetworkExport FunctionCallManager
+{
+public:
+  static void addCallStatic(uint32_t functionID, uint32_t clientID);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4);
+  static void addCallStatic(uint32_t functionID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5);
+
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4);
+  static void addCallMember(uint32_t functionID, uint32_t objectID, uint32_t clientID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5);
+
+  static void sendCalls();
+
+  static std::map<uint32_t, packet::FunctionCalls*> clientMap_;
+protected:
+  FunctionCallManager();
+  ~FunctionCallManager();
+};
+
+} //namespace orxonox
+
+#endif /* _FunctionCallManager_H__ */
Index: /code/branches/rocket2/src/libraries/network/GamestateClient.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/GamestateClient.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/GamestateClient.cc	(revision 6952)
@@ -0,0 +1,186 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      Dumeni Manatschal
+ *
+ */
+
+#include "GamestateClient.h"
+
+#include "util/Debug.h"
+#include "core/ObjectList.h"
+#include "synchronisable/Synchronisable.h"
+#include "synchronisable/NetworkCallbackManager.h"
+#include "packet/Acknowledgement.h"
+#include "packet/Gamestate.h"
+
+
+namespace orxonox
+{
+  struct _NetworkExport GameStateItem{
+    packet::Gamestate *state;
+    unsigned int id;
+  };
+
+  GamestateClient::GamestateClient() {
+    COUT(5) << "this: " << this << std::endl;
+    last_diff_=0;
+    last_gamestate_=GAMESTATEID_INITIAL-1;
+    tempGamestate_=NULL;
+  }
+
+  GamestateClient::~GamestateClient() {
+      std::map<unsigned int, packet::Gamestate *>::iterator it;
+      for ( it = this->gamestateMap_.begin(); it != this->gamestateMap_.end(); ++it )
+          delete it->second;
+      if( this->tempGamestate_ )
+          delete this->tempGamestate_;
+  }
+
+  bool GamestateClient::ack(unsigned int gamestateID, unsigned int clientID){
+    return true;
+  }
+
+  bool GamestateClient::add(packet::Gamestate *gs, unsigned int clientID){
+    if(tempGamestate_!=NULL){
+      //delete the obsolete gamestate
+      if(tempGamestate_->getID()>gs->getID())
+        return false;
+      delete tempGamestate_;
+    }
+    tempGamestate_=gs;
+    return true;
+  }
+
+  bool GamestateClient::processGamestates(){
+    if(tempGamestate_==NULL)
+      return false;
+    bool isDiffed = tempGamestate_->isDiffed();
+    int id = GAMESTATEID_INITIAL;
+    packet::Gamestate *processed = processGamestate(tempGamestate_);
+    assert(processed);
+
+    //now call the queued callbacks
+    NetworkCallbackManager::callCallbacks();
+
+    if (!processed){
+      sendAck(0);
+      return false;
+    }
+    //successfully loaded data from gamestate. now save gamestate for diff and delete the old gs
+    tempGamestate_=NULL;
+    gamestateMap_[processed->getID()]=processed;
+    if(isDiffed)
+      last_diff_ = processed->getBaseID();
+    id = processed->getID();
+    sendAck(id);
+    return true;
+  }
+
+
+  /**
+  * This function removes a Synchronisable out of the universe
+  * @param it iterator of the list pointing to the object
+  * @return iterator pointing to the next object in the list
+  */
+  void GamestateClient::removeObject(ObjectList<Synchronisable>::iterator &it) {
+    ObjectList<Synchronisable>::iterator temp=it;
+    ++it;
+    temp->destroy(); // or delete?
+  }
+
+  packet::Gamestate *GamestateClient::getGamestate(){
+    packet::Gamestate *gs = new packet::Gamestate();
+    if(!gs->collectData(0,0x2)){
+      delete gs;
+      return 0;
+    }
+    return gs;
+  }
+
+  void GamestateClient::cleanup(){
+    std::map<unsigned int, packet::Gamestate*>::iterator temp, it = gamestateMap_.begin();
+    while(it!=gamestateMap_.end()){
+      if(it->first>=last_diff_)
+        break;
+      // otherwise delete that stuff
+      delete it->second;
+      temp=it++;
+      gamestateMap_.erase(temp);
+    }
+    tempGamestate_=NULL;
+  }
+
+  void GamestateClient::printGamestateMap(){
+    std::map<unsigned int, packet::Gamestate*>::iterator it;
+    COUT(4) << "gamestates: ";
+    for(it=gamestateMap_.begin(); it!=gamestateMap_.end(); it++){
+      COUT(4) << it->first << ':' << it->second << '|';
+    }
+    COUT(4) << std::endl;
+
+  }
+
+  bool GamestateClient::sendAck(unsigned int gamestateID){
+    packet::Acknowledgement *ack = new packet::Acknowledgement(gamestateID, 0);
+    if(!ack->send()){
+      COUT(3) << "could not ack gamestate: " << gamestateID << std::endl;
+      return false;
+    }
+    else{
+      COUT(5) << "acked a gamestate: " << gamestateID << std::endl;
+      return true;
+    }
+  }
+
+  packet::Gamestate *GamestateClient::processGamestate(packet::Gamestate *gs){
+    if(gs->isCompressed())
+    {
+      bool b = gs->decompressData();
+      assert(b);
+    }
+    if(gs->isDiffed()){
+      packet::Gamestate *base = gamestateMap_[gs->getBaseID()];
+      if(!base){
+        COUT(3) << "could not find base gamestate id: " << gs->getBaseID() << endl;
+        delete gs;
+        return 0;
+      }
+//       assert(base); //TODO: fix this
+      packet::Gamestate *undiffed = gs->undiff(base);
+      delete gs;
+      gs=undiffed;
+      COUT(5) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl;
+    }
+    if(gs->spreadData(0x2))
+      return gs;
+    else
+    {
+      COUT(3) << "could not spread gamestate" << endl;
+      return NULL;
+    }
+  }
+
+}
+
Index: /code/branches/rocket2/src/libraries/network/GamestateClient.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/GamestateClient.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/GamestateClient.h	(revision 6952)
@@ -0,0 +1,80 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      Dumeni Manatschal
+ *
+ */
+
+//
+// C++ Interface: GameStateClient
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef _GamestateClient_H__
+#define _GamestateClient_H__
+
+#include "NetworkPrereqs.h"
+
+#include <map>
+#include "core/CorePrereqs.h"
+#include "GamestateHandler.h"
+
+const unsigned int GAMESTATEID_INITIAL = static_cast<unsigned int>(-1);
+
+namespace orxonox
+{
+  class _NetworkExport GamestateClient: public GamestateHandler
+  {
+  public:
+    GamestateClient();
+    ~GamestateClient();
+
+    bool add(packet::Gamestate *gs, unsigned int clientID);
+    bool ack(unsigned int gamestateID, unsigned int clientID);
+
+    bool processGamestates();
+    packet::Gamestate *getGamestate();
+    void cleanup();
+  private:
+    packet::Gamestate *processGamestate(packet::Gamestate *gs);
+    void removeObject(ObjectListIterator<Synchronisable> &it);
+    void printGamestateMap();
+    bool sendAck(unsigned int gamestateID);
+
+    unsigned int           last_diff_;
+    unsigned int           last_gamestate_;
+    std::map<unsigned int, packet::Gamestate *> gamestateMap_;
+    packet::Gamestate *tempGamestate_; // we save the received gamestates here during processQueue
+
+  };
+
+}
+
+#endif /* _GamestateClient_H__ */
Index: /code/branches/rocket2/src/libraries/network/GamestateHandler.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/GamestateHandler.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/GamestateHandler.cc	(revision 6952)
@@ -0,0 +1,50 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "GamestateHandler.h"
+#include <cassert>
+
+namespace orxonox {
+
+GamestateHandler *GamestateHandler::instance_=0;
+
+GamestateHandler::GamestateHandler()
+{
+  assert(instance_==0);
+  instance_=this;
+}
+
+
+GamestateHandler::~GamestateHandler()
+{
+  instance_=0;
+}
+
+
+
+}//namespace orxonox
Index: /code/branches/rocket2/src/libraries/network/GamestateHandler.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/GamestateHandler.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/GamestateHandler.h	(revision 6952)
@@ -0,0 +1,58 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GamestateHandler_H__
+#define _GamestateHandler_H__
+
+#include "NetworkPrereqs.h"
+
+namespace orxonox {
+
+/**
+    @author Oliver Scheuss
+*/
+class _NetworkExport GamestateHandler{
+  private:
+    virtual bool add(packet::Gamestate *gs, unsigned int clientID)=0;
+    virtual bool ack(unsigned int gamestateID, unsigned int clientID)=0;
+
+    static GamestateHandler *instance_;
+
+
+  protected:
+    GamestateHandler();
+    virtual ~GamestateHandler();
+
+  public:
+    static bool addGamestate(packet::Gamestate *gs, unsigned int clientID){ return instance_->add(gs, clientID); }
+    static bool ackGamestate(unsigned int gamestateID, unsigned int clientID){ return instance_->ack(gamestateID, clientID); }
+};
+
+}
+
+#endif /* _GamestateHandler_H__ */
Index: /code/branches/rocket2/src/libraries/network/GamestateManager.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/GamestateManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/GamestateManager.cc	(revision 6952)
@@ -0,0 +1,276 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Implementation: GameStateManager
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "GamestateManager.h"
+
+#include <cassert>
+#include <queue>
+// #include <boost/thread/mutex.hpp>
+
+#include "util/Debug.h"
+#include "core/Executor.h"
+#include "core/ThreadPool.h"
+#include "ClientInformation.h"
+#include "packet/Acknowledgement.h"
+#include "packet/Gamestate.h"
+#include "synchronisable/NetworkCallbackManager.h"
+#include "TrafficControl.h"
+
+namespace orxonox
+{
+  GamestateManager::GamestateManager() :
+  reference(0), id_(0)
+  {
+    trafficControl_ = new TrafficControl();
+//     threadMutex_ = new boost::mutex();
+//     threadPool_ = new ThreadPool();
+  }
+
+  GamestateManager::~GamestateManager()
+  {
+    if( this->reference )
+        delete this->reference;std::map<unsigned int, packet::Gamestate*>::iterator it;
+    for( it = gamestateQueue.begin(); it != gamestateQueue.end(); ++it )
+      delete it->second;
+    std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator it1;
+    std::map<unsigned int, packet::Gamestate*>::iterator it2;
+    for( it1 = gamestateMap_.begin(); it1 != gamestateMap_.end(); ++it1 )
+    {
+      for( it2 = it1->second.begin(); it2 != it1->second.end(); ++it2 )
+        delete it2->second;
+    }
+    this->trafficControl_->destroy();
+//     delete this->threadMutex_;
+//     delete this->threadPool_;
+  }
+
+  bool GamestateManager::update(){
+//     cleanup();
+    return getSnapshot();
+  }
+
+  bool GamestateManager::add(packet::Gamestate *gs, unsigned int clientID){
+    assert(gs);
+    std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID);
+    if(it!=gamestateQueue.end()){
+      // delete obsolete gamestate
+      delete it->second;
+    }
+    gamestateQueue[clientID] = gs;
+    return true;
+  }
+
+  bool GamestateManager::processGamestates(){
+    if( this->gamestateQueue.empty() )
+        return true;
+    std::map<unsigned int, packet::Gamestate*>::iterator it;
+    // now push only the most recent gamestates we received (ignore obsolete ones)
+    for(it = gamestateQueue.begin(); it!=gamestateQueue.end(); it++){
+      bool b = processGamestate(it->second);
+      assert(b);
+      delete it->second;
+    }
+    // now clear the queue
+    gamestateQueue.clear();
+    //and call all queued callbacks
+    NetworkCallbackManager::callCallbacks();
+    return true;
+  }
+
+
+  bool GamestateManager::getSnapshot(){
+    if ( reference != 0 )
+      delete reference;
+    reference = new packet::Gamestate();
+    if(!reference->collectData(++id_, 0x1)){ //we have no data to send
+      delete reference;
+      reference=0;
+    }
+    return true;
+  }
+
+  void GamestateManager::sendGamestates()
+  {
+    ClientInformation *temp = ClientInformation::getBegin();
+    std::queue<packet::Gamestate*> clientGamestates;
+    while(temp != NULL){
+      if( !(temp->getSynched()) ){
+        COUT(5) << "Server: not sending gamestate" << std::endl;
+        temp=temp->next();
+        if(!temp)
+          break;
+        continue;
+      }
+      COUT(4) << "client id: " << temp->getID() << " RTT: " << temp->getRTT() << " loss: " << temp->getPacketLoss() << std::endl;
+      COUT(5) << "Server: doing gamestate gamestate preparation" << std::endl;
+      int cid = temp->getID(); //get client id
+
+      unsigned int gID = temp->getGamestateID();
+      if(!reference)
+        return;
+
+      packet::Gamestate *client=0;
+      if(gID != GAMESTATEID_INITIAL){
+        assert(gamestateMap_.find(cid)!=gamestateMap_.end());
+        std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateMap_[cid].find(gID);
+        if(it!=gamestateMap_[cid].end())
+        {
+          client = it->second;
+        }
+      }
+
+      clientGamestates.push(0);
+      finishGamestate( cid, &clientGamestates.back(), client, reference );
+      //FunctorMember<GamestateManager>* functor =
+//       ExecutorMember<GamestateManager>* executor = createExecutor( createFunctor(&GamestateManager::finishGamestate, this) );
+//       executor->setDefaultValues( cid, &clientGamestates.back(), client, reference );
+//       (*static_cast<Executor*>(executor))();
+//       this->threadPool_->passFunction( executor, true );
+//       (*functor)( cid, &(clientGamestates.back()), client, reference );
+
+      temp = temp->next();
+    }
+
+//     threadPool_->synchronise();
+
+    while( !clientGamestates.empty() )
+    {
+      if(clientGamestates.front())
+        clientGamestates.front()->send();
+      clientGamestates.pop();
+    }
+  }
+
+
+  void GamestateManager::finishGamestate( unsigned int clientID, packet::Gamestate** destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate ) {
+    //why are we searching the same client's gamestate id as we searched in
+    //Server::sendGameState?
+    // save the (undiffed) gamestate in the clients gamestate map
+    //chose wheather the next gamestate is the first or not
+
+    packet::Gamestate *gs = gamestate->doSelection(clientID, 20000);
+//     packet::Gamestate *gs = new packet::Gamestate(*gamestate);
+//     packet::Gamestate *gs = new packet::Gamestate();
+//     gs->collectData( id_, 0x1 );
+//     this->threadMutex_->lock();
+    gamestateMap_[clientID][gamestate->getID()]=gs;
+//     this->threadMutex_->unlock();
+
+    if(base)
+    {
+
+//       COUT(3) << "diffing" << std::endl;
+//       packet::Gamestate* gs1  = gs;
+      packet::Gamestate *diffed = gs->diff(base);
+      //packet::Gamestate *gs2 = diffed->undiff(gs);
+//       assert(*gs == *gs2);
+      gs = diffed;
+//       packet::Gamestate* gs2 = gs->undiff(client);
+//       gs = new packet::Gamestate(*gs);
+//       assert(*gs1==*gs2);
+    }
+    else{
+      gs = new packet::Gamestate(*gs);
+    }
+
+
+    bool b = gs->compressData();
+    assert(b);
+//     COUT(4) << "sending gamestate with id " << gs->getID();
+//     if(gamestate->isDiffed())
+//     COUT(4) << " and baseid " << gs->getBaseID() << endl;
+//     else
+//     COUT(4) << endl;
+    gs->setClientID(clientID);
+    *destgamestate = gs;
+  }
+
+
+  bool GamestateManager::ack(unsigned int gamestateID, unsigned int clientID) {
+    ClientInformation *temp = ClientInformation::findClient(clientID);
+    assert(temp);
+    unsigned int curid = temp->getGamestateID();
+
+    if(gamestateID == ACKID_NACK){
+      temp->setGamestateID(GAMESTATEID_INITIAL);
+      // now delete all saved gamestates for this client
+      std::map<unsigned int, packet::Gamestate*>::iterator it;
+      for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end(); ){
+        delete it->second;
+
+        gamestateMap_[clientID].erase(it++);
+      }
+      return true;
+    }
+
+    assert(curid==GAMESTATEID_INITIAL || curid<gamestateID);
+    COUT(5) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl;
+    std::map<unsigned int, packet::Gamestate*>::iterator it;
+    for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; ){
+      delete it->second;
+      gamestateMap_[clientID].erase(it++);
+    }
+    temp->setGamestateID(gamestateID);
+    TrafficControl::processAck(clientID, gamestateID);
+    return true;
+  }
+
+  void GamestateManager::removeClient(ClientInformation* client){
+    assert(client);
+    std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID());
+    // first delete all remained gamestates
+    std::map<unsigned int, packet::Gamestate*>::iterator it;
+    for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++)
+      delete it->second;
+    // now delete the clients gamestatemap
+    gamestateMap_.erase(clientMap);
+  }
+
+  bool GamestateManager::processGamestate(packet::Gamestate *gs){
+    if(gs->isCompressed())
+    {
+       bool b = gs->decompressData();
+       assert(b);
+    }
+    assert(!gs->isDiffed());
+    return gs->spreadData(0x1);
+  }
+
+}
Index: /code/branches/rocket2/src/libraries/network/GamestateManager.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/GamestateManager.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/GamestateManager.h	(revision 6952)
@@ -0,0 +1,98 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Interface: GamestateManager
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef _GamestateManager_H__
+#define _GamestateManager_H__
+
+#include "NetworkPrereqs.h"
+
+#include <map>
+#include "GamestateHandler.h"
+#include "core/CorePrereqs.h"
+
+namespace orxonox
+{
+
+  const int KEEP_GAMESTATES = 10;
+
+  /**
+  * This Class implements a manager for gamestates:
+  * - creating snapshots of gamestates
+  * - writing gamestates to universe
+  * - diffing gamestates
+  * EN/DECODATION:
+  * a: last Gamestate a client has received
+  * b: new Gamestate
+  * x: diffed and compressed gamestate
+  * x=(a^b)
+  * b=(a^x)
+  * diff(a,diff(a,x))=x (hope this is correct)
+  * @author Oliver Scheuss
+  */
+  class _NetworkExport GamestateManager: public GamestateHandler{
+  public:
+    GamestateManager();
+    ~GamestateManager();
+
+    bool add(packet::Gamestate *gs, unsigned int clientID);
+    bool processGamestates();
+    bool update();
+    void sendGamestates();
+//     packet::Gamestate *popGameState(unsigned int clientID);
+    void finishGamestate( unsigned int clientID, packet::Gamestate** destgamestate, packet::Gamestate* base, packet::Gamestate* gamestate );
+
+    bool getSnapshot();
+
+    bool ack(unsigned int gamestateID, unsigned int clientID);
+    void removeClient(ClientInformation *client);
+  private:
+    bool processGamestate(packet::Gamestate *gs);
+
+    std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> > gamestateMap_;
+    std::map<unsigned int, packet::Gamestate*> gamestateQueue;
+    packet::Gamestate *reference;
+    TrafficControl *trafficControl_;
+    unsigned int id_;
+//     boost::mutex* threadMutex_;
+    ThreadPool*   /*thread*/Pool_;
+  };
+
+}
+
+#endif /* _GameStateManager_H__ */
Index: /code/branches/rocket2/src/libraries/network/Host.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/Host.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/Host.cc	(revision 6952)
@@ -0,0 +1,118 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Host.h"
+
+#include <cassert>
+#include <string>
+
+#include "core/ConsoleCommand.h"
+#include "core/ObjectList.h"
+#include "ChatListener.h"
+
+namespace orxonox {
+
+SetConsoleCommandShortcut(Host, Chat);
+
+Host *Host::instance_=0;
+
+/**
+ * @brief Constructor: assures that only one reference will be created and sets the pointer
+ */
+Host::Host()
+{
+  clientID_=0;
+  assert(instance_==0);
+  instance_=this;
+  this->printRTTCC_ = createConsoleCommand( createFunctor(&Host::printRTT, this), "printRTT" );
+  CommandExecutor::addConsoleCommandShortcut( this->printRTTCC_ );
+}
+
+
+/**
+ * @brief Destructor: resets the instance pointer to 0
+ */
+Host::~Host()
+{
+  instance_=0;
+  if( this->printRTTCC_ )
+    delete this->printRTTCC_;
+}
+
+/**
+ * This function is used to add an enetpacket to be sent to another peer
+ * @param packet Packet to be added
+ * @param clientID ID of the client the packet should be sent to
+ * @return success?
+ */
+bool Host::addPacket(ENetPacket *packet, int clientID){
+  if(instance_)
+    return instance_->queuePacket(packet, clientID);
+  else
+    return false;
+}
+
+/**
+ * This function returns the ID of the player
+ * @return playerID
+ */
+unsigned int Host::getPlayerID(){
+  if(!instance_)
+    return 0;
+  return instance_->clientID_;
+}
+
+bool Host::Chat(const std::string& message){
+  if(!instance_)
+  {
+    for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)
+      it->incomingChat(message, 0);
+    return true;
+  }
+  return instance_->chat(message);
+}
+
+bool Host::Broadcast(const std::string& message){
+  if(!instance_)
+  {
+    for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)
+      it->incomingChat(message, CLIENTID_UNKNOWN);
+    return true;
+  }
+  else
+    return instance_->broadcast(message);
+}
+
+bool Host::incomingChat(const std::string& message, unsigned int playerID){
+  for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)
+    it->incomingChat(message, playerID);
+
+  return instance_->processChat(message, playerID);
+}
+
+}//namespace orxonox
Index: /code/branches/rocket2/src/libraries/network/Host.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/Host.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/Host.h	(revision 6952)
@@ -0,0 +1,89 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NETWORK_Host_H__
+#define _NETWORK_Host_H__
+
+#include "NetworkPrereqs.h"
+#include "core/CorePrereqs.h"
+
+namespace orxonox {
+
+  const unsigned int CLIENTID_SERVER = 0;
+  const unsigned int NETWORK_FREQUENCY = 30;
+  const float NETWORK_PERIOD = 1.0f/NETWORK_FREQUENCY;
+
+/**
+*       @brief Base class of Server and Client
+*       This is the Base class of the Server and Client classes
+*       - Makes server and client a singleton
+*       - defines static functions available on both server and client
+*       - is the interface to be used when communicating with the network
+*       @author Oliver Scheuss
+*/
+class _NetworkExport Host{
+  private:
+    //TODO add these functions or adequate
+    //virtual bool processChat(packet::Chat *message, unsigned int clientID)=0;
+    //virtual bool sendChat(packet::Chat *chat)=0;
+    virtual bool queuePacket(ENetPacket *packet, int clientID)=0;
+    virtual bool chat(const std::string& message)=0;
+    virtual bool broadcast(const std::string& message)=0;
+    virtual bool processChat(const std::string& message, unsigned int playerID)=0;
+    virtual bool isServer_()=0;
+
+
+
+  protected:
+    Host();
+    virtual ~Host();
+    static Host *instance_;
+    unsigned int clientID_;
+    unsigned int shipID_;
+
+  public:
+    static bool running(){return instance_!=0;}
+    static bool addPacket(ENetPacket *packet, int clientID=0);
+    //static bool chat(std::string& message);
+//     static bool receiveChat(packet::Chat *message, unsigned int clientID);
+    static unsigned int getPlayerID();
+    static unsigned int getShipID(){return instance_->shipID_;}
+    static void setClientID(unsigned int id){ instance_->clientID_ = id; }
+    static void setShipID(unsigned int id){ instance_->shipID_ = id; }
+    static bool isServer(){ return instance_->isServer_(); }
+    static bool Chat(const std::string& message);
+    static bool Broadcast(const std::string& message);
+    static bool incomingChat(const std::string& message, unsigned int playerID);
+    virtual void printRTT()=0;
+  private:
+    ConsoleCommand* printRTTCC_;
+};
+
+}
+
+#endif /* _NETWORK_Host_H__ */
Index: /code/branches/rocket2/src/libraries/network/NetworkFunction.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/NetworkFunction.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/NetworkFunction.cc	(revision 6952)
@@ -0,0 +1,112 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "NetworkFunction.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+  std::map<uint32_t, bool> NetworkFunctionBase::isStaticMap_;
+
+  std::map<NetworkFunctionPointer, NetworkMemberFunctionBase*> NetworkMemberFunctionBase::functorMap_;
+  std::map<uint32_t, NetworkMemberFunctionBase*> NetworkMemberFunctionBase::idMap_;
+
+  NetworkFunctionBase::NetworkFunctionBase(const std::string& name)
+  {
+    RegisterRootObject(NetworkFunctionBase);
+
+    static uint32_t networkID = 0;
+    this->networkID_ = networkID++;
+
+    this->name_ = name;
+    NetworkFunctionBase::getNameMap()[name] = this;
+  }
+  NetworkFunctionBase::~NetworkFunctionBase()
+  {
+  }
+
+
+  void NetworkFunctionBase::destroyAllNetworkFunctions()
+  {
+    std::map<std::string, NetworkFunctionBase*>& map = NetworkFunctionBase::getNameMap();
+    std::map<std::string, NetworkFunctionBase*>::iterator it;
+    for( it=map.begin(); it!=map.end(); ++it )
+      it->second->destroy();
+  }
+
+
+  /*static*/ std::map<std::string, NetworkFunctionBase*>& NetworkFunctionBase::getNameMap()
+  {
+    static std::map<std::string, NetworkFunctionBase*> nameMap_;
+    return nameMap_;
+  }
+
+
+  NetworkFunctionStatic::NetworkFunctionStatic(FunctorStatic* functor, const std::string& name, const NetworkFunctionPointer& p):
+    NetworkFunctionBase(name)
+  {
+    RegisterObject(NetworkFunctionStatic);
+
+    this->functor_ = functor;
+    NetworkFunctionStatic::getFunctorMap()[p] = this;
+    NetworkFunctionStatic::getIdMap()[ this->getNetworkID() ] = this;
+  }
+
+  NetworkFunctionStatic::~NetworkFunctionStatic()
+  {
+    delete this->functor_;
+  }
+
+  /*static*/ std::map<NetworkFunctionPointer, NetworkFunctionStatic*>& NetworkFunctionStatic::getFunctorMap()
+  {
+    static std::map<NetworkFunctionPointer, NetworkFunctionStatic*> functorMap_;
+    return functorMap_;
+  }
+
+  /*static*/ std::map<uint32_t, NetworkFunctionStatic*>& NetworkFunctionStatic::getIdMap()
+  {
+    static std::map<uint32_t, NetworkFunctionStatic*> idMap_;
+    return idMap_;
+  }
+
+
+  NetworkMemberFunctionBase::NetworkMemberFunctionBase(const std::string& name, const NetworkFunctionPointer& p):
+    NetworkFunctionBase(name)
+  {
+    RegisterObject(NetworkMemberFunctionBase);
+
+    this->functorMap_[p] = this;
+    this->idMap_[ this->getNetworkID() ] = this;
+  }
+
+  NetworkMemberFunctionBase::~NetworkMemberFunctionBase()
+  {
+  }
+
+
+}
Index: /code/branches/rocket2/src/libraries/network/NetworkFunction.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/NetworkFunction.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/NetworkFunction.h	(revision 6952)
@@ -0,0 +1,254 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NetworkFunction_H__
+#define _NetworkFunction_H__
+
+#include "NetworkPrereqs.h"
+
+#include <cassert>
+#include <cstring>
+#include <map>
+#include <string>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/static_assert.hpp>
+
+#include "core/Functor.h"
+#include "core/Identifier.h"
+#include "FunctionCallManager.h"
+#include "synchronisable/Synchronisable.h"
+
+namespace orxonox
+{
+
+#if defined(ORXONOX_COMPILER_GCC) && defined(ORXONOX_ARCH_32)
+static const unsigned int MAX_FUNCTION_POINTER_SIZE = 8;
+#else
+static const unsigned int MAX_FUNCTION_POINTER_SIZE = 16;
+#endif //ORXONOX_COMPILER_GCC
+static const unsigned int MAX_FUNCTION_POINTER_INTS = (MAX_FUNCTION_POINTER_SIZE-1)/4+1;
+
+struct _NetworkExport NetworkFunctionPointer {
+  uint32_t pointer[MAX_FUNCTION_POINTER_INTS];
+  bool operator<(const NetworkFunctionPointer& b) const
+  {
+#if defined(ORXONOX_COMPILER_GCC) && defined(ORXONOX_ARCH_32)
+    return pointer[0]<b.pointer[0] ? true : pointer[1]<b.pointer[1];
+#else //ORXONOX_COMPILER_GCC
+    return pointer[0]<b.pointer[0] ? true : ( pointer[1]<b.pointer[1] ? true : ( pointer[2]<b.pointer[2] ? true : pointer[3]<b.pointer[3] ) );
+#endif //ORXONOX_COMPILER_GCC
+  }
+};
+
+
+
+
+
+class _NetworkExport NetworkFunctionBase: virtual public OrxonoxClass {
+  public:
+    NetworkFunctionBase(const std::string& name);
+    ~NetworkFunctionBase();
+
+    virtual void        setNetworkID(uint32_t id)       { this->networkID_ = id; }
+    inline uint32_t     getNetworkID() const            { return this->networkID_; }
+    inline const std::string& getName() const           { return name_; }
+    static inline bool  isStatic( uint32_t networkID )  { return isStaticMap_[networkID]; }
+
+    static inline void setNetworkID(const std::string& name, uint32_t id)
+    {
+        std::map<std::string, NetworkFunctionBase*>& map = NetworkFunctionBase::getNameMap();
+        assert( map.find(name)!=map.end() );
+        map[name]->setNetworkID(id);
+    }
+
+    static void destroyAllNetworkFunctions();
+
+  protected:
+    static std::map<uint32_t, bool> isStaticMap_;
+
+  private:
+    static std::map<std::string, NetworkFunctionBase*>& getNameMap();
+    uint32_t networkID_;
+    std::string name_;
+
+};
+
+
+class _NetworkExport NetworkFunctionStatic: public NetworkFunctionBase {
+  public:
+    NetworkFunctionStatic(FunctorStatic* functor, const std::string& name, const NetworkFunctionPointer& p);
+    ~NetworkFunctionStatic();
+
+    inline void call(){ (*this->functor_)(); }
+    inline void call(const MultiType& mt1){ (*this->functor_)(mt1); }
+    inline void call(const MultiType& mt1, const MultiType& mt2){ (*this->functor_)(mt1, mt2); }
+    inline void call(const MultiType& mt1, const MultiType& mt2, const MultiType& mt3){ (*this->functor_)(mt1, mt2, mt3); }
+    inline void call(const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4){ (*this->functor_)(mt1, mt2, mt3, mt4); }
+    inline void call(const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5){ (*this->functor_)(mt1, mt2, mt3, mt4, mt5); }
+
+    virtual void setNetworkID( uint32_t id )
+        { NetworkFunctionBase::setNetworkID( id ); NetworkFunctionStatic::getIdMap()[id] = this; }
+    static inline NetworkFunctionStatic* getNetworkFunction( uint32_t id)
+        { assert( NetworkFunctionStatic::getIdMap().find(id)!=NetworkFunctionStatic::getIdMap().end() ); return NetworkFunctionStatic::getIdMap()[id]; }
+    static NetworkFunctionStatic* getFunction( uint32_t id )
+        { assert( NetworkFunctionStatic::getIdMap().find(id) != NetworkFunctionStatic::getIdMap().end() ); return NetworkFunctionStatic::getIdMap()[id]; }
+    static NetworkFunctionStatic* getFunction( const NetworkFunctionPointer& p )
+        { assert( NetworkFunctionStatic::getFunctorMap().find(p) != NetworkFunctionStatic::getFunctorMap().end() ); return NetworkFunctionStatic::getFunctorMap()[p]; }
+
+  private:
+    static std::map<NetworkFunctionPointer, NetworkFunctionStatic*>& getFunctorMap();
+    static std::map<uint32_t, NetworkFunctionStatic*>& getIdMap();
+    FunctorStatic* functor_;
+
+};
+
+
+class _NetworkExport NetworkMemberFunctionBase: public NetworkFunctionBase {
+  public:
+    NetworkMemberFunctionBase(const std::string& name, const NetworkFunctionPointer& p);
+    ~NetworkMemberFunctionBase();
+
+    virtual void setNetworkID( uint32_t id ){ NetworkFunctionBase::setNetworkID( id ); idMap_[id] = this; }
+    static inline NetworkMemberFunctionBase* getNetworkFunction( uint32_t id){ assert( idMap_.find(id)!=idMap_.end() ); return idMap_[id]; }
+    static NetworkMemberFunctionBase* getFunction( uint32_t id ){ assert( idMap_.find(id) != idMap_.end() ); return idMap_[id]; }
+    static NetworkMemberFunctionBase* getFunction( const NetworkFunctionPointer& p ){ assert( functorMap_.find(p) != functorMap_.end() ); return functorMap_[p]; }
+
+    //
+    virtual void call(uint32_t objectID)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)=0;
+    virtual void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)=0;
+
+  private:
+    static std::map<NetworkFunctionPointer, NetworkMemberFunctionBase*> functorMap_;
+    static std::map<uint32_t, NetworkMemberFunctionBase*> idMap_;
+};
+
+
+template <class T> class NetworkMemberFunction: public NetworkMemberFunctionBase {
+  public:
+    NetworkMemberFunction(FunctorMember<T>* functor, const std::string& name, const NetworkFunctionPointer& p);
+    ~NetworkMemberFunction();
+
+    inline void call(uint32_t objectID)
+    {
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)));
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1)
+    {
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1);
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2)
+    {
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2);
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3)
+    {
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3);
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4)
+    {
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3, mt4);
+    }
+    inline void call(uint32_t objectID, const MultiType& mt1, const MultiType& mt2, const MultiType& mt3, const MultiType& mt4, const MultiType& mt5)
+    {
+      if ( Synchronisable::getSynchronisable(objectID)!=0 )
+        (*this->functor_)(orxonox_cast<T*>(Synchronisable::getSynchronisable(objectID)), mt1, mt2, mt3, mt4, mt5);
+    }
+
+  private:
+    FunctorMember<T>* functor_;
+};
+
+template <class T> NetworkMemberFunction<T>::NetworkMemberFunction(FunctorMember<T>* functor, const std::string& name, const NetworkFunctionPointer& p):
+    NetworkMemberFunctionBase(name, p), functor_(functor)
+{
+}
+template <class T> NetworkMemberFunction<T>::~NetworkMemberFunction()
+{
+  delete this->functor_;
+}
+
+template<class T> inline void copyPtr( T ptr, NetworkFunctionPointer& destptr)
+{
+  if( sizeof(NetworkFunctionPointer)-sizeof(T) > 0)
+    memset((uint8_t*)&destptr + sizeof(T), 0, sizeof(NetworkFunctionPointer)-sizeof(T));
+  T p2 = ptr;
+  memcpy( &destptr, &p2, sizeof(T) );
+//   for(unsigned int i=0; i<(sizeof(T)-1/4)+1; i++)
+//     *((uint32_t*)destptr+i) = p2>>32*i;
+}
+
+template<class T> inline void* registerStaticNetworkFunctionFct( T ptr, const std::string& name )
+{
+  BOOST_STATIC_ASSERT( sizeof(T)<=sizeof(NetworkFunctionPointer) ); // if this fails your compiler uses bigger pointers for static functions than defined above
+  NetworkFunctionPointer destptr;
+  copyPtr( ptr, destptr );
+  new NetworkFunctionStatic( createFunctor(ptr), name, destptr );
+  return 0;
+}
+
+template<class T, class PT> inline void* registerMemberNetworkFunctionFct( PT ptr, const std::string& name )
+{
+  BOOST_STATIC_ASSERT( sizeof(PT)<=sizeof(NetworkFunctionPointer) ); // if this fails your compiler uses bigger pointers for a specific kind of member functions than defined above
+  NetworkFunctionPointer destptr;
+  copyPtr( ptr, destptr );
+  new NetworkMemberFunction<T>( createFunctor(ptr), name, destptr );
+  return 0;
+}
+
+#define registerStaticNetworkFunction( functionPointer ) \
+  static void* BOOST_PP_CAT( NETWORK_FUNCTION_, __LINE__ ) = registerStaticNetworkFunctionFct( functionPointer, #functionPointer );
+#define registerMemberNetworkFunction( class, function ) \
+  static void* BOOST_PP_CAT( NETWORK_FUNCTION_##class, __LINE__ ) = registerMemberNetworkFunctionFct<class>( &class::function, #class "_" #function);
+  // call it with functionPointer, clientID, args
+#define callStaticNetworkFunction( functionPointer, ...) \
+  { \
+    NetworkFunctionPointer p1; \
+    copyPtr( functionPointer, p1 ); \
+    FunctionCallManager::addCallStatic(NetworkFunctionStatic::getFunction(p1)->getNetworkID(), __VA_ARGS__); \
+  }
+  // call it with class, function, objectID, clientID, args
+#define callMemberNetworkFunction( class, function, objectID, ...) \
+  { \
+    NetworkFunctionPointer p1; \
+    copyPtr( &class::function, p1 ); \
+    FunctionCallManager::addCallMember(NetworkMemberFunctionBase::getFunction(p1)->getNetworkID(), objectID, __VA_ARGS__); \
+  }
+
+
+}
+
+#endif /* _NetworkFunction_H__ */
Index: /code/branches/rocket2/src/libraries/network/NetworkPrecompiledHeaders.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/NetworkPrecompiledHeaders.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/NetworkPrecompiledHeaders.h	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Compilation of the most often used header files in the network library
+@details
+    Updated: 13. September 2009
+    Total Files: 28
+*/
+
+#include "OrxonoxConfig.h"
+
+///////////////////////////////////////////
+/////          Stable Headers         /////
+///////////////////////////////////////////
+
+#include <cstring>  // 26
+#include <cassert>  // 24
+#include <string>   // 23
+#include <vector>   // 23
+#include <map>      // 23
+#include <fstream>  // 22
+#include <iostream> // 22
+#include <sstream>  // 22
+#include <set>      // 20
+
+#include "util/Debug.h"      // 20
+#include "util/TypeTraits.h" // 18
+
+#ifdef ORXONOX_COMPILER_MSVC
+
+#include <deque>    // 17
+#include <queue>    // 17
+#include <list>     // 16
+#include <cmath>    // 15
+
+#include <OgreMath.h>        // 15
+#include <OgreVector2.h>     // 15
+#include <OgreVector3.h>     // 15
+#include <OgreVector4.h>     // 15
+#include <OgreQuaternion.h>  // 15
+#include <OgreColourValue.h> // 15
+
+#include "util/mbool.h" // 11
+
+#define WIN32_LEAN_AND_MEAN
+#include <enet/enet.h> // 6, 3.1MB
+
+#endif /*ORXONOX_COMPILER_MSVC */
+
+
+// Just in case some header included windows.h
+#undef min
+#undef max
Index: /code/branches/rocket2/src/libraries/network/NetworkPrereqs.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/NetworkPrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/NetworkPrereqs.h	(revision 6952)
@@ -0,0 +1,159 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Shared library macros, enums, constants and forward declarations for the network library
+*/
+
+#ifndef _NetworkPrereqs_H__
+#define _NetworkPrereqs_H__
+
+#include "OrxonoxConfig.h"
+
+//-----------------------------------------------------------------------
+// Shared library settings
+//-----------------------------------------------------------------------
+
+#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined( NETWORK_STATIC_BUILD )
+#  ifdef NETWORK_SHARED_BUILD
+#    define _NetworkExport __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define _NetworkExport
+#    else
+#      define _NetworkExport __declspec(dllimport)
+#    endif
+#  endif
+#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _NetworkExport  __attribute__ ((visibility("default")))
+#else
+#  define _NetworkExport
+#endif
+
+//-----------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+  static const unsigned int GAMESTATEID_INITIAL = static_cast<unsigned int>(-1);
+  static const unsigned int CLIENTID_UNKNOWN    = static_cast<unsigned int>(-2);
+}
+
+//-----------------------------------------------------------------------
+// Enums
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+  namespace packet
+  {
+    namespace PacketFlag
+    {
+      enum Value
+      {
+        Reliable   = 1,
+        Unsequence = 2,
+        NoAllocate = 4
+      };
+    }
+  }
+}
+
+//-----------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------
+
+// from ENet
+struct _ENetPeer;
+typedef _ENetPeer ENetPeer;
+struct _ENetPacket;
+typedef _ENetPacket ENetPacket;
+struct _ENetEvent;
+typedef _ENetEvent ENetEvent;
+struct _ENetHost;
+typedef _ENetHost ENetHost;
+struct _ENetAddress;
+typedef _ENetAddress ENetAddress;
+
+namespace orxonox
+{
+  class ChatListener;
+  class Client;
+  class ClientConnection;
+  class ClientConnectionListener;
+  class ClientInformation;
+  class Connection;
+  class FunctionCallManager;
+  class GamestateClient;
+  class GamestateHandler;
+  class GamestateManager;
+  class Host;
+  class NetworkFunctionBase;
+  struct NetworkFunctionPointer;
+  class NetworkFunctionStatic;
+  template <class T>
+  class NetworkMemberFunction;
+  class NetworkMemberFunctionBase;
+  class Server;
+  class ServerConnection;
+  class TrafficControl;
+
+  // packet
+  namespace packet
+  {
+    class Acknowledgement;
+    class Chat;
+    class ClassID;
+    class DeleteObjects;
+    class FunctionCalls;
+    class FunctionIDs;
+    class Gamestate;
+    class Packet;
+    class Welcome;
+  }
+
+  // synchronisable
+  template <class T>
+  class NetworkCallback;
+  template <class T, class U>
+  class NetworkCallbackNotify;
+  class NetworkCallbackBase;
+  class NetworkCallbackManager;
+  class Synchronisable;
+  class SynchronisableHeader;
+  template <class T>
+  class SynchronisableVariable;
+  class SynchronisableVariableBase;
+  template <class T>
+  class SynchronisableVariableBidirectional;
+}
+
+#endif /* _NetworkPrereqs_H__ */
Index: /code/branches/rocket2/src/libraries/network/Server.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/Server.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/Server.cc	(revision 6952)
@@ -0,0 +1,390 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Implementation: Server
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include "Server.h"
+
+#define WIN32_LEAN_AND_MEAN
+#include <enet/enet.h>
+#include <cassert>
+#include <string>
+
+#include "util/Clock.h"
+#include "util/Debug.h"
+#include "core/ObjectList.h"
+#include "core/Executor.h"
+#include "packet/Chat.h"
+#include "packet/ClassID.h"
+#include "packet/DeleteObjects.h"
+#include "packet/FunctionIDs.h"
+#include "packet/Gamestate.h"
+#include "packet/Welcome.h"
+#include "ChatListener.h"
+#include "ClientInformation.h"
+#include "FunctionCallManager.h"
+#include "GamestateManager.h"
+
+namespace orxonox
+{
+  const unsigned int MAX_FAILURES = 20;
+
+  /**
+  * Constructor for default values (bindaddress is set to ENET_HOST_ANY
+  *
+  */
+  Server::Server() {
+    this->timeSinceLastUpdate_=0;
+  }
+
+  Server::Server(int port){
+    this->setPort( port );
+    this->timeSinceLastUpdate_=0;
+  }
+
+  /**
+  * Constructor
+  * @param port Port to listen on
+  * @param bindAddress Address to listen on
+  */
+  Server::Server(int port, const std::string& bindAddress) {
+    this->setPort( port );
+    this->setBindAddress( bindAddress );
+    this->timeSinceLastUpdate_=0;
+  }
+
+  /**
+  * @brief Destructor
+  */
+  Server::~Server(){
+  }
+
+  /**
+  * This function opens the server by creating the listener thread
+  */
+  void Server::open() {
+    COUT(4) << "opening server" << endl;
+    this->openListener();
+    return;
+  }
+
+  /**
+  * This function closes the server
+  */
+  void Server::close() {
+    COUT(4) << "closing server" << endl;
+    this->disconnectClients();
+    this->closeListener();
+    return;
+  }
+
+  bool Server::processChat(const std::string& message, unsigned int playerID){
+    ClientInformation *temp = ClientInformation::getBegin();
+    packet::Chat *chat;
+    while(temp){
+      chat = new packet::Chat(message, playerID);
+      chat->setClientID(temp->getID());
+      if(!chat->send())
+        COUT(3) << "could not send Chat message to client ID: " << temp->getID() << std::endl;
+      temp = temp->next();
+    }
+//    COUT(1) << "Player " << playerID << ": " << message << std::endl;
+    return true;
+  }
+
+
+  /**
+  * Run this function once every tick
+  * calls processQueue and updateGamestate
+  * @param time time since last tick
+  */
+  void Server::update(const Clock& time) {
+    // receive incoming packets
+    Connection::processQueue();
+
+    if ( ClientInformation::hasClients() )
+    {
+      // process incoming gamestates
+      GamestateManager::processGamestates();
+
+      // send function calls to clients
+      FunctionCallManager::sendCalls();
+
+      //this steers our network frequency
+      timeSinceLastUpdate_+=time.getDeltaTime();
+      if(timeSinceLastUpdate_>=NETWORK_PERIOD)
+      {
+        timeSinceLastUpdate_ -= static_cast<unsigned int>( timeSinceLastUpdate_ / NETWORK_PERIOD ) * NETWORK_PERIOD;
+        updateGamestate();
+      }
+      sendPackets(); // flush the enet queue
+    }
+  }
+
+  bool Server::queuePacket(ENetPacket *packet, int clientID){
+    return ServerConnection::addPacket(packet, clientID);
+  }
+
+  /**
+   * @brief: returns ping time to client in milliseconds
+   */
+  unsigned int Server::getRTT(unsigned int clientID){
+    assert(ClientInformation::findClient(clientID));
+    return ClientInformation::findClient(clientID)->getRTT();
+  }
+
+  void Server::printRTT()
+  {
+    for( ClientInformation* temp=ClientInformation::getBegin(); temp!=0; temp=temp->next() )
+      COUT(0) << "Round trip time to client with ID: " << temp->getID() << " is " << temp->getRTT() << " ms" << endl;
+  }
+
+  /**
+   * @brief: return packet loss ratio to client (scales from 0 to 1)
+   */
+  double Server::getPacketLoss(unsigned int clientID){
+    assert(ClientInformation::findClient(clientID));
+    return ClientInformation::findClient(clientID)->getPacketLoss();
+  }
+
+  /**
+  * takes a new snapshot of the gamestate and sends it to the clients
+  */
+  void Server::updateGamestate() {
+    if( ClientInformation::getBegin()==NULL )
+      //no client connected
+      return;
+    GamestateManager::update();
+    COUT(5) << "Server: one gamestate update complete, goig to sendGameState" << std::endl;
+    //std::cout << "updated gamestate, sending it" << std::endl;
+    //if(clients->getGamestateID()!=GAMESTATEID_INITIAL)
+    sendGameState();
+    sendObjectDeletes();
+    COUT(5) << "Server: one sendGameState turn complete, repeat in next tick" << std::endl;
+    //std::cout << "sent gamestate" << std::endl;
+  }
+
+  bool Server::processPacket( ENetPacket *packet, ENetPeer *peer ){
+    packet::Packet *p = packet::Packet::createPacket(packet, peer);
+    return p->process();
+  }
+
+  /**
+  * sends the gamestate
+  */
+  bool Server::sendGameState() {
+//     COUT(5) << "Server: starting function sendGameState" << std::endl;
+//     ClientInformation *temp = ClientInformation::getBegin();
+//     bool added=false;
+//     while(temp != NULL){
+//       if( !(temp->getSynched()) ){
+//         COUT(5) << "Server: not sending gamestate" << std::endl;
+//         temp=temp->next();
+//         if(!temp)
+//           break;
+//         continue;
+//       }
+//       COUT(4) << "client id: " << temp->getID() << " RTT: " << temp->getRTT() << " loss: " << temp->getPacketLoss() << std::endl;
+//       COUT(5) << "Server: doing gamestate gamestate preparation" << std::endl;
+//       int cid = temp->getID(); //get client id
+//       packet::Gamestate *gs = GamestateManager::popGameState(cid);
+//       if(gs==NULL){
+//         COUT(2) << "Server: could not generate gamestate (NULL from compress)" << std::endl;
+//         temp = temp->next();
+//         continue;
+//       }
+//       //std::cout << "adding gamestate" << std::endl;
+//       gs->setClientID(cid);
+//       if ( !gs->send() ){
+//         COUT(3) << "Server: packet with client id (cid): " << cid << " not sended: " << temp->getFailures() << std::endl;
+//         temp->addFailure();
+//       }else
+//         temp->resetFailures();
+//       added=true;
+//       temp=temp->next();
+//       // gs gets automatically deleted by enet callback
+//     }
+    GamestateManager::sendGamestates();
+    return true;
+  }
+
+  bool Server::sendObjectDeletes(){
+    ClientInformation *temp = ClientInformation::getBegin();
+    if( temp == NULL )
+      //no client connected
+      return true;
+    packet::DeleteObjects *del = new packet::DeleteObjects();
+    if(!del->fetchIDs())
+    {
+      delete del;
+      return true;  //everything ok (no deletes this tick)
+    }
+//     COUT(3) << "sending DeleteObjects" << std::endl;
+    while(temp != NULL){
+      if( !(temp->getSynched()) ){
+        COUT(5) << "Server: not sending gamestate" << std::endl;
+        temp=temp->next();
+        continue;
+      }
+      int cid = temp->getID(); //get client id
+      packet::DeleteObjects *cd = new packet::DeleteObjects(*del);
+      assert(cd);
+      cd->setClientID(cid);
+      if ( !cd->send() )
+        COUT(3) << "Server: packet with client id (cid): " << cid << " not sended: " << temp->getFailures() << std::endl;
+      temp=temp->next();
+      // gs gets automatically deleted by enet callback
+    }
+    delete del;
+    return true;
+  }
+
+
+  void Server::addPeer(ENetEvent *event){
+    static unsigned int newid=1;
+
+    COUT(2) << "Server: adding client" << std::endl;
+    ClientInformation *temp = ClientInformation::insertBack(new ClientInformation);
+    if(!temp){
+      COUT(2) << "Server: could not add client" << std::endl;
+    }
+    temp->setID(newid);
+    temp->setPeer(event->peer);
+
+    // inform all the listeners
+    ClientConnectionListener::broadcastClientConnected(newid);
+
+    ++newid;
+
+    COUT(3) << "Server: added client id: " << temp->getID() << std::endl;
+    createClient(temp->getID());
+}
+
+  void Server::removePeer(ENetEvent *event)
+  {
+    COUT(4) << "removing client from list" << std::endl;
+    ClientInformation *client = ClientInformation::findClient(&event->peer->address);
+    if(!client)
+      return;
+    else
+    {
+      //ServerConnection::disconnectClient( client );
+      //ClientConnectionListener::broadcastClientDisconnected( client->getID() ); //this is done in ClientInformation now
+      delete client;
+    }
+  }
+
+  bool Server::createClient(int clientID){
+    ClientInformation *temp = ClientInformation::findClient(clientID);
+    if(!temp){
+      COUT(2) << "Conn.Man. could not create client with id: " << clientID << std::endl;
+      return false;
+    }
+    COUT(5) << "Con.Man: creating client id: " << temp->getID() << std::endl;
+
+    // synchronise class ids
+    syncClassid(temp->getID());
+
+    // now synchronise functionIDs
+    packet::FunctionIDs *fIDs = new packet::FunctionIDs();
+    fIDs->setClientID(clientID);
+    bool b = fIDs->send();
+    assert(b);
+
+    temp->setSynched(true);
+    COUT(4) << "sending welcome" << std::endl;
+    packet::Welcome *w = new packet::Welcome(temp->getID(), temp->getShipID());
+    w->setClientID(temp->getID());
+    b = w->send();
+    assert(b);
+    packet::Gamestate *g = new packet::Gamestate();
+    g->setClientID(temp->getID());
+    b = g->collectData(0,0x1);
+    if(!b)
+      return false; //no data for the client
+    b = g->compressData();
+    assert(b);
+    b = g->send();
+    assert(b);
+    return true;
+  }
+
+  void Server::disconnectClient( ClientInformation *client ){
+    ServerConnection::disconnectClient( client );
+    GamestateManager::removeClient(client);
+    // inform all the listeners
+    // ClientConnectionListener::broadcastClientDisconnected(client->getID()); // this is done in ClientInformation now
+  }
+
+  bool Server::chat(const std::string& message){
+      return this->sendChat(message, Host::getPlayerID());
+  }
+
+  bool Server::broadcast(const std::string& message){
+      return this->sendChat(message, CLIENTID_UNKNOWN);
+  }
+
+  bool Server::sendChat(const std::string& message, unsigned int clientID){
+    ClientInformation *temp = ClientInformation::getBegin();
+    packet::Chat *chat;
+    while(temp){
+      chat = new packet::Chat(message, clientID);
+      chat->setClientID(temp->getID());
+      if(!chat->send())
+        COUT(3) << "could not send Chat message to client ID: " << temp->getID() << std::endl;
+      temp = temp->next();
+    }
+//    COUT(1) << "Player " << Host::getPlayerID() << ": " << message << std::endl;
+    for (ObjectList<ChatListener>::iterator it = ObjectList<ChatListener>::begin(); it != ObjectList<ChatListener>::end(); ++it)
+      it->incomingChat(message, clientID);
+
+    return true;
+  }
+
+  void Server::syncClassid(unsigned int clientID) {
+    int failures=0;
+    packet::ClassID *classid = new packet::ClassID();
+    classid->setClientID(clientID);
+    while(!classid->send() && failures < 10){
+      failures++;
+    }
+    assert(failures<10);
+    COUT(4) << "syncClassid:\tall synchClassID packets have been sent" << std::endl;
+  }
+
+}
Index: /code/branches/rocket2/src/libraries/network/Server.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/Server.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/Server.h	(revision 6952)
@@ -0,0 +1,90 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Server_H__
+#define _Server_H__
+
+#include "NetworkPrereqs.h"
+
+#include "util/UtilPrereqs.h"
+#include "core/CorePrereqs.h"
+#include "Host.h"
+#include "GamestateManager.h"
+#include "ServerConnection.h"
+
+namespace orxonox
+{
+
+  /**
+  * This class is the root class of the network module for a server.
+  * It implements all functions necessary for a Server
+  */
+  class _NetworkExport Server : public Host, public ServerConnection, public GamestateManager{
+  public:
+    Server();
+    Server(int port);
+    Server(int port, const std::string& bindAddress);
+    ~Server();
+
+    void open();
+    void close();
+    bool processChat(const std::string& message, unsigned int playerID);
+    bool queuePacket(ENetPacket *packet, int clientID);
+    void update(const Clock& time);
+    unsigned int getRTT(unsigned int clientID);
+    virtual void printRTT();
+    double getPacketLoss(unsigned int clientID);
+  protected:
+    void updateGamestate();
+  private:
+    virtual bool isServer_(){return true;}
+    unsigned int shipID(){return 0;}
+    unsigned int playerID(){return 0;}
+
+    void addPeer(ENetEvent *event);
+    void removePeer(ENetEvent *event);
+
+    bool createClient(int clientID);
+    void disconnectClient( ClientInformation *client);
+    bool processPacket( ENetPacket *packet, ENetPeer *peer );
+    bool sendGameState();
+    bool sendObjectDeletes();
+    virtual bool chat(const std::string& message);
+    virtual bool broadcast(const std::string& message);
+    bool sendChat(const std::string& message, unsigned int clientID);
+    void syncClassid(unsigned int clientID);
+
+    float timeSinceLastUpdate_;
+  };
+
+
+
+
+}
+
+#endif /* _Server_H__ */
Index: /code/branches/rocket2/src/libraries/network/ServerConnection.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/ServerConnection.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/ServerConnection.cc	(revision 6952)
@@ -0,0 +1,155 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ServerConnection.h"
+
+#include <cassert>
+#include <string>
+#define WIN32_LEAN_AND_MEAN
+#include <enet/enet.h>
+
+#include "util/Debug.h"
+#include "ClientInformation.h"
+
+namespace orxonox
+{
+
+  ServerConnection::ServerConnection():
+    bListening_(false)
+  {
+    this->bindAddress_ = new ENetAddress();
+    this->bindAddress_->host = ENET_HOST_ANY;
+    this->bindAddress_->port = NETWORK_PORT;
+  }
+
+  ServerConnection::~ServerConnection(){
+    if ( this->bListening_ )
+      closeListener();
+    delete this->bindAddress_;
+  }
+
+  void ServerConnection::setBindAddress( const std::string& bindAddress ) {
+    enet_address_set_host (this->bindAddress_, bindAddress.c_str());
+  }
+
+  void ServerConnection::setPort( unsigned int port ) {
+      this->bindAddress_->port = port;
+  }
+
+  bool ServerConnection::openListener() {
+    this->host_ = enet_host_create(this->bindAddress_, NETWORK_MAX_CONNECTIONS, 0, 0);
+    if ( this->host_ == NULL )
+      return false;
+    else
+      return true;
+  }
+
+  bool ServerConnection::closeListener() {
+    this->bListening_=false;
+    disconnectClients();
+    enet_host_destroy(this->host_);
+    return true;
+  }
+
+  bool ServerConnection::addPacket(ENetPacket *packet, unsigned int clientID) {
+    if ( clientID == CLIENTID_UNKNOWN )
+    {
+      return addPacketAll(packet);
+    }
+    else
+    {
+      ClientInformation *temp = ClientInformation::findClient(clientID);
+      if(!temp){
+        COUT(3) << "C.Man: addPacket findClient failed" << std::endl;
+        return false;
+      }
+      return Connection::addPacket(packet, temp->getPeer());
+    }
+  }
+
+  bool ServerConnection::addPacketAll(ENetPacket *packet) {
+    if ( !Connection::getInstance() )
+      return false;
+    enet_host_broadcast( Connection::getInstance()->getHost(), 0, packet);
+    return true;
+  }
+
+  void ServerConnection::disconnectClient(ClientInformation *client)
+  {
+    Connection::disconnectPeer( client->getPeer() );
+  }
+
+  void ServerConnection::disconnectClient(int clientID){
+    ClientInformation *client = ClientInformation::findClient(clientID);
+    if(client)
+      ServerConnection::disconnectClient(client);
+  }
+
+  void ServerConnection::disconnectClients() {
+    ENetEvent event;
+    ClientInformation *temp = ClientInformation::getBegin();
+    while(temp!=0){
+      ServerConnection::disconnectClient( temp );
+      temp = temp->next();
+    }
+    temp = ClientInformation::getBegin();
+    while( temp!=0 ){
+      if( service( &event ) )
+      {
+        switch (event.type)
+        {
+        case ENET_EVENT_TYPE_NONE: break;
+        case ENET_EVENT_TYPE_CONNECT: break;
+        case ENET_EVENT_TYPE_RECEIVE:
+          enet_packet_destroy(event.packet);
+          break;
+        case ENET_EVENT_TYPE_DISCONNECT:
+          removePeer( &event );
+          temp = ClientInformation::getBegin();
+          break;
+        }
+      }
+    }
+    return;
+  }
+
+
+  int ServerConnection::getClientID(ENetPeer* peer) {
+    return getClientID(&(peer->address));
+  }
+
+  int ServerConnection::getClientID(ENetAddress* address) {
+    return ClientInformation::findClient(address)->getID();
+  }
+
+  ENetPeer *ServerConnection::getClientPeer(int clientID) {
+    return ClientInformation::findClient(clientID)->getPeer();
+  }
+
+
+}
Index: /code/branches/rocket2/src/libraries/network/ServerConnection.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/ServerConnection.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/ServerConnection.h	(revision 6952)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+//
+// C++ Interface: ServerConnection
+//
+// Description:
+//
+//
+// Author:  Oliver Scheuss, (C) 2007
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef _ServerConnection_H__
+#define _ServerConnection_H__
+
+#include "NetworkPrereqs.h"
+#include "Connection.h"
+
+namespace orxonox
+{
+
+  class _NetworkExport ServerConnection : public Connection{
+  public:
+    ~ServerConnection();
+
+    void setBindAddress( const std::string& bindAddress );
+    void setPort( unsigned int port );
+
+    bool openListener();
+    bool closeListener();
+    static bool addPacket(ENetPacket *packet, unsigned int ID);
+    static bool addPacketAll(ENetPacket *packet);
+    virtual void disconnectClient(ClientInformation *client);
+    void disconnectClient(int clientID);
+  protected:
+    ServerConnection();
+    void disconnectClients();
+
+  private:
+    int getClientID(ENetPeer* peer);
+    int getClientID(ENetAddress* address);
+    ENetPeer* getClientPeer(int clientID);
+
+    ENetAddress* bindAddress_;
+
+    bool bListening_;
+
+  };
+
+}
+
+#endif /* _ServerConnection_H__ */
Index: /code/branches/rocket2/src/libraries/network/TODO
===================================================================
--- /code/branches/rocket2/src/libraries/network/TODO	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/TODO	(revision 6952)
@@ -0,0 +1,11 @@
+todo: 
+	test network functionality with paketloss/delay: http://www.linuxfoundation.org/en/Net:Netem#Packet_loss
+
+	minimize synchronisableHeader
+
+	!!! ensure that objects get synched, when newly created, even if not their tick
+
+	setvariable mode
+	objectmode
+	priorities (put into gamestatehandler)
+		manage delete object handling (only send deletes of acked objects)
Index: /code/branches/rocket2/src/libraries/network/TrafficControl.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/TrafficControl.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/TrafficControl.cc	(revision 6952)
@@ -0,0 +1,327 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "TrafficControl.h"
+
+#include <cassert>
+#include <boost/bind.hpp>
+
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "synchronisable/Synchronisable.h"
+
+namespace orxonox {
+
+  static const unsigned int SCHED_PRIORITY_OFFSET = static_cast<unsigned int>(-1);
+
+  objInfo::objInfo(uint32_t ID, uint32_t creatorID, int32_t curGsID, int32_t diffGsID, uint32_t size, unsigned int prioperm, unsigned int priosched)
+  {
+    objID = ID; objCreatorID = creatorID; objCurGS = curGsID; objDiffGS = diffGsID; objSize = size; objValuePerm = prioperm; objValueSched = priosched;
+  }
+
+  objInfo::objInfo()
+  {
+    objID = OBJECTID_UNKNOWN; objCreatorID = OBJECTID_UNKNOWN; objCurGS = GAMESTATEID_INITIAL; objDiffGS = objCurGS; objSize = 0; objValuePerm = 0; objValueSched = 0;
+  }
+
+
+
+  obj::obj()
+  {
+    objID = OBJECTID_UNKNOWN; objCreatorID = OBJECTID_UNKNOWN; objSize = 0; objDataOffset = 0;
+  }
+  obj::obj( uint32_t ID, uint32_t creatorID, uint32_t size, uint32_t offset )
+  {
+    objID = ID; objCreatorID = creatorID; objSize = size; objDataOffset = offset;
+  }
+
+/**
+*Initializing protected members
+*/
+    TrafficControl *TrafficControl::instance_=0;
+
+    /**
+    * @brief Constructor: assures that only one reference will be created and sets the pointer
+    */
+    TrafficControl::TrafficControl()
+    {
+    RegisterObject(TrafficControl);
+      assert(instance_==0);
+      instance_=this;
+    this->setConfigValues();
+    }
+
+    /**
+    * @brief Destructor: resets the instance pointer to 0
+    */
+    TrafficControl::~TrafficControl()
+    {
+      instance_=0;
+    }
+
+/**
+*Definition of public members
+*/
+
+  void TrafficControl::setConfigValues()
+  {
+    SetConfigValue ( bActive_, false );
+    SetConfigValue ( targetSize, 10000 );
+  }
+
+  /**
+  * sort-algorithm for sorting the objectlist after priorities
+  */
+  bool TrafficControl::prioritySort(uint32_t clientID, obj i, obj j)
+  {
+    assert(clientListPerm_.find(clientID) != clientListPerm_.end());  //make sure the client exists in our list
+    assert(clientListPerm_[clientID].find(i.objID) != clientListPerm_[clientID].end()); // make sure the object i is in the client list
+    assert(clientListPerm_[clientID].find(j.objID) != clientListPerm_[clientID].end()); // make sure the object j is in the client list
+
+    int prio1 = clientListPerm_[clientID][i.objID].objValuePerm + clientListPerm_[clientID][i.objID].objValueSched;
+    int prio2 = clientListPerm_[clientID][j.objID].objValuePerm + clientListPerm_[clientID][j.objID].objValueSched;
+    return prio1 < prio2;
+  }
+
+  /**
+  * sort-algorithm for sorting the objectList after position in original data stream
+  */
+  bool TrafficControl::dataSort(obj i, obj j)
+  {
+    int pos1 = i.objDataOffset;
+    int pos2 = j.objDataOffset;
+    return pos1 < pos2;
+  }
+
+
+
+    void TrafficControl::processObjectList(unsigned int clientID, unsigned int gamestateID, std::list<obj>& list)
+    {
+      currentClientID=clientID;
+      currentGamestateID=gamestateID;
+      evaluateList(clientID, list);
+      return;
+    }
+
+  TrafficControl *TrafficControl::getInstance()
+  {
+    assert(instance_);
+    return instance_;
+  }
+
+    void TrafficControl::ack(unsigned int clientID, unsigned int gamestateID)
+    {
+    if ( !this->bActive_ )
+      return;
+      std::list<obj>::iterator itvec;  // iterator to iterate through the acked objects
+
+    //assertions to make sure the maps already exist
+    assert(clientListTemp_.find(clientID) != clientListTemp_.end() );
+    assert(clientListPerm_.find(clientID) != clientListPerm_.end() );
+    assert( clientListTemp_[clientID].find(gamestateID) != clientListTemp_[clientID].end() );
+
+    // shortcut for maps
+    std::map<unsigned int, objInfo >& objectListPerm = clientListPerm_[clientID];
+    std::map<unsigned int, std::list<obj> >& objectListTemp = clientListTemp_[clientID];
+
+    for(itvec = objectListTemp[gamestateID].begin(); itvec != objectListTemp[gamestateID].end(); itvec++)
+      {
+      if(objectListPerm.find(itvec->objID) != objectListPerm.end()) // check whether the obj already exists in our lists
+      {
+        objectListPerm[itvec->objID].objCurGS = gamestateID;
+        objectListPerm[itvec->objID].objValueSched = 0; //set scheduling value back
+      }
+      else
+      {
+        assert(0);
+        objectListPerm[itvec->objID].objCurGS = gamestateID;
+        objectListPerm[itvec->objID].objID = itvec->objID;
+        objectListPerm[itvec->objID].objCreatorID = itvec->objCreatorID;
+        objectListPerm[itvec->objID].objSize = itvec->objSize;
+      }
+      }
+       // remove temporary list (with acked objects) from the map
+    objectListTemp.erase( objectListTemp.find(gamestateID) );
+    }
+
+/**
+*Definition of private members
+*/
+
+    /**
+    *updateClientListPerm
+    *returns void
+    */
+    void TrafficControl::insertinClientListPerm(unsigned int clientID, obj objinf)
+    {
+      std::map<unsigned int,std::map<unsigned int, objInfo> >::iterator itperm;//iterator clientListPerm over clientIDs
+    unsigned int gsid=GAMESTATEID_INITIAL, gsdiff=currentGamestateID, prioperm=Synchronisable::getSynchronisable(objinf.objID)->getPriority(), priomom=0;
+    clientListPerm_[clientID][objinf.objID] = objInfo(objinf.objID, objinf.objCreatorID,gsid,gsdiff, objinf.objSize,prioperm,priomom);
+    }
+
+  /**
+  * updateClientListTemp
+  * takes the shortened list which will be sent to the gsmanager and puts the *info into clientListTemp
+  */
+  void TrafficControl::updateClientListTemp(std::list<obj>& list)
+  {
+    clientListTemp_[currentClientID][currentGamestateID] = list;
+  }
+
+  /**
+  *cut
+  *takes the current list that has to be returned to the gsmanager and shortens it in criteria of bandwidth of clientID(XY)
+  */
+  void TrafficControl::cut(std::list<obj>& list, unsigned int targetsize)
+  {
+    unsigned int size=0;
+    std::list<obj>::iterator itvec, ittemp;
+    assert(!list.empty());
+    for(itvec = list.begin(); itvec != list.end();)
+    {
+      assert( itvec->objSize < 1000);
+      if ( ( size + itvec->objSize ) < targetsize )
+      {
+        size += itvec->objSize;//objSize is given in bytes
+        ++itvec;
+      }
+      else
+      {
+        clientListPerm_[currentClientID][itvec->objID].objValueSched += SCHED_PRIORITY_OFFSET; // NOTE: SCHED_PRIORITY_OFFSET is negative
+        list.erase(itvec, list.end());
+        break;
+      }
+//       printList(list, currentClientID);
+    }
+    assert(!list.empty());
+  }
+
+
+    /**
+    *evaluateList evaluates whether new obj are there, whether there are things to be updatet and manipulates all this.
+    */
+    void TrafficControl::evaluateList(unsigned int clientID, std::list<obj>& list)
+    {
+
+    if( bActive_ )
+    {
+      //now the sorting
+
+      //compare listToProcess vs clientListPerm
+      //if listToProcess contains new Objects, add them to clientListPerm
+      std::list<obj>::iterator itvec;
+
+      std::map<unsigned int, objInfo >& objectListPerm = clientListPerm_[clientID];
+
+      for( itvec=list.begin(); itvec != list.end(); itvec++)
+      {
+        if ( objectListPerm.find( itvec->objID) != objectListPerm.end() )
+        {
+        // we already have the object in our map
+        //obj bleibt in liste und permanente prio wird berechnet
+          objectListPerm[itvec->objID].objDiffGS = currentGamestateID - objectListPerm[itvec->objID].objCurGS;
+          continue;//check next objId
+        }
+        else
+        {
+        // insert the object into clientListPerm
+          insertinClientListPerm(clientID,*itvec);
+          continue;//check next objId
+        }
+      }
+    //end compare listToProcess vs clientListPerm
+
+      //sort copied list according to priorities
+      // use boost bind here because we need to pass a memberfunction to stl sort
+//       sort( list.begin(), list.end(), boost::bind(&TrafficControl::prioritySort, this, clientID, _1, _2) );
+      list.sort( boost::bind(&TrafficControl::prioritySort, this, clientID, _1, _2) );
+
+//       list.sort(boost::bind(&TrafficControl::prioritySort, this, clientID, _1, _2) );
+
+      //now we check, that the creator of an object always exists on a client
+      std::list<obj>::iterator itcreator;
+      for(itvec = list.begin(); itvec != list.end(); itvec++)
+      {
+        fixCreatorDependencies(itvec, list, clientID);
+      }
+      //end of sorting
+      //now the cutting, work the same obj out in processobjectlist and copiedlist, compression rate muss noch festgelegt werden.
+//       printList(list, clientID);
+      cut(list, targetSize);
+      //now sort again after objDataOffset
+//       sort(list.begin(), list.end(), boost::bind(&TrafficControl::dataSort, this, _1, _2) );
+      list.sort( boost::bind(&TrafficControl::dataSort, this, _1, _2) );
+
+      //diese Funktion updateClientList muss noch gemacht werden
+      updateClientListTemp(list);
+      //end of sorting
+    }
+  }
+
+  void TrafficControl::printList(std::list<obj>& list, unsigned int clientID)
+  {
+    std::list<obj>::iterator it;
+    COUT(0) << "=========== Objectlist ===========" << endl;
+    for( it=list.begin(); it!=list.end(); it++)
+      COUT(0) << "ObjectID: " << it->objID << " creatorID: " << it->objCreatorID << " Priority: " << clientListPerm_[clientID][it->objID].objValuePerm + clientListPerm_[clientID][it->objID].objValueSched << " size: " << it->objSize << endl;
+  }
+
+  void TrafficControl::fixCreatorDependencies(std::list<obj>::iterator it1, std::list<obj>& list, unsigned int clientID)
+  {
+    if ( it1->objCreatorID == OBJECTID_UNKNOWN )
+      return;
+    if( clientListPerm_[clientID][it1->objCreatorID].objCurGS != GAMESTATEID_INITIAL )
+      return;
+    std::list<obj>::iterator it2, it3=it1;
+    for( it2 = ++it3; it2 != list.end(); it2++ )
+    {
+      if( it2->objID == it1->objCreatorID )
+      {
+        it3 = list.insert(it1, *it2); //insert creator before it1
+        list.erase(it2);
+//         printList(list, clientID);
+        fixCreatorDependencies( it3, list, clientID );
+        break;
+      }
+    }
+  }
+
+  void TrafficControl::clientDisconnected(unsigned int clientID)
+  {
+    if( clientListPerm_.find(clientID) == clientListPerm_.end() )
+    {
+      assert(!this->bActive_);
+      return;
+    }
+    clientListTemp_.erase(clientListTemp_.find(clientID));
+    if( clientListTemp_.find(clientID) != clientListTemp_.end() )
+      clientListPerm_.erase(clientListPerm_.find(clientID));
+  }
+
+
+}//namespace network
Index: /code/branches/rocket2/src/libraries/network/TrafficControl.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/TrafficControl.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/TrafficControl.h	(revision 6952)
@@ -0,0 +1,142 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>
+ *   Co-authors:
+ *      ...
+ *
+
+ */
+#ifndef _TrafficControl_H__
+#define _TrafficControl_H__
+
+#include "NetworkPrereqs.h"
+
+#include <list>
+#include <map>
+#include "ClientConnectionListener.h"
+
+namespace orxonox {
+
+
+  /**
+   *a list of objects of this type will be given by the Server's Gamestate Manager
+   */
+  class objInfo
+  {
+    public:
+      uint32_t objID;
+      uint32_t objCreatorID;
+      uint32_t objCurGS;//current GameState ID
+      uint32_t objDiffGS;//difference between current and latest GameState
+      uint32_t objSize;
+      int objValuePerm;
+      int objValueSched;
+      objInfo(uint32_t ID, uint32_t creatorID, int32_t curGsID, int32_t diffGsID, uint32_t size, unsigned int prioperm, unsigned int priosched);
+      objInfo();
+  };
+
+/**
+   *a list of objects of this type will be given by the Server's Gamestate Manager
+ */
+  class obj
+  {
+    public:
+      uint32_t objID;
+      uint32_t objCreatorID;
+      uint32_t objSize;
+      uint32_t objDataOffset;
+      obj();
+      obj( uint32_t ID, uint32_t creatorID, uint32_t size, uint32_t offset );
+  };
+
+
+
+
+/**
+*
+*/
+class TrafficControl : public ClientConnectionListener {
+  private:
+
+    /**
+    *permanent client list: contains client ids, object ids and objectInfos (in this order)
+    */
+    std::map<unsigned int, std::map<unsigned int, objInfo > > clientListPerm_;
+    //has to be created with constructor and then needs to be updated by evaluateList().
+
+    /**
+    *temporary client list: contains client ids, gamestate ids and object ids (in this order)
+    */
+    std::map<unsigned int, std::map<unsigned int, std::list<obj> > > clientListTemp_;
+
+    /**updateReferenceList
+    *currentGamestateID and currentClientID will be defined as soon as TrafficControl is being called by Server
+    */
+    unsigned int currentGamestateID;
+    unsigned int currentClientID;
+    unsigned int targetSize;
+    bool         bActive_;
+
+    void insertinClientListPerm(unsigned int clientID, obj objinf);
+
+    void cut(std::list<obj>& list, unsigned int targetsize);
+    void updateClientListTemp(std::list<obj>& list);//done
+    /**
+    *evaluates Data given (list) and produces result(->Data to be updated)
+    */
+    void evaluateList(unsigned int clientID, std::list<obj>& list);//done
+    void ack(unsigned int clientID, unsigned int gamestateID);  // this function gets called when the server receives an ack from the client
+
+    //ClientConnectionListener functions
+    virtual void clientConnected(unsigned int clientID){};
+    virtual void clientDisconnected(unsigned int clientID);
+
+
+  protected:
+    static TrafficControl *instance_;
+
+  public:
+    TrafficControl();
+    virtual ~TrafficControl();
+    /**
+    *is being used by GSManager from Server:
+    *list contains: ObjIds, CreatorIds, Size (in this order) from Client XY
+    *Elements of list are accessed by *list[i]
+    *Elements of struct i are therefore: *list[i].objID
+    */
+    void setConfigValues();
+    static TrafficControl *getInstance();
+    void processObjectList(unsigned int clientID, unsigned int gamestateID, std::list<obj>& list); //gets a pointer to the list (containing objectIDs) and sorts it
+    static void processAck(unsigned int clientID, unsigned int gamestateID)
+    { return instance_->ack(clientID, gamestateID); }
+    void deleteObject(unsigned int objectID);               // this function gets called when an object has been deleted (in order to clean up lists and maps)
+
+    bool prioritySort(uint32_t clientID, obj i, obj j);
+    bool dataSort(obj i, obj j);
+    void printList(std::list<obj>& list, unsigned int clientID);
+    void fixCreatorDependencies(std::list<obj>::iterator it, std::list<obj>& list, unsigned int clientID);
+};
+
+}
+
+#endif /* _TrafficControl_H__ */
Index: /code/branches/rocket2/src/libraries/network/packet/Acknowledgement.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/Acknowledgement.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/Acknowledgement.cc	(revision 6952)
@@ -0,0 +1,76 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Acknowledgement.h"
+
+#include "util/Debug.h"
+#include "network/GamestateHandler.h"
+
+namespace orxonox {
+namespace packet {
+
+#define PACKET_FLAGS_ACK    0
+#define _PACKETID           0
+#define _ACKID              _PACKETID + sizeof(packet::Type::Value)
+
+Acknowledgement::Acknowledgement( unsigned int id, unsigned int clientID )
+ : Packet()
+{
+  flags_ = flags_ | PACKET_FLAGS_ACK;
+  data_=new uint8_t[ getSize() ];
+  *(Type::Value *)(data_ + _PACKETID ) = Type::Acknowledgement;
+  *(uint32_t *)(data_ + _ACKID ) = id;
+  clientID_=clientID;
+}
+
+Acknowledgement::Acknowledgement( uint8_t *data, unsigned int clientID )
+  : Packet(data, clientID)
+{
+}
+
+Acknowledgement::~Acknowledgement()
+{
+}
+
+unsigned int Acknowledgement::getSize() const{
+  return _ACKID + sizeof(uint32_t);
+}
+
+bool Acknowledgement::process(){
+  COUT(5) << "processing ACK with ID: " << getAckID() << endl;
+  bool b = GamestateHandler::ackGamestate(getAckID(), clientID_);
+  delete this;
+  return b;
+}
+
+unsigned int Acknowledgement::getAckID(){
+  return *(uint32_t *)(data_ + _ACKID);
+}
+
+} //namespace packet
+} //namespace orxonox
Index: /code/branches/rocket2/src/libraries/network/packet/Acknowledgement.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/Acknowledgement.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/Acknowledgement.h	(revision 6952)
@@ -0,0 +1,58 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Acknowledgement_H__
+#define _Acknowledgement_H__
+
+#include "network/NetworkPrereqs.h"
+#include "Packet.h"
+
+namespace orxonox {
+const unsigned int ACKID_NACK = 0;
+namespace packet {
+/**
+    @author
+*/
+class _NetworkExport Acknowledgement : public Packet
+{
+public:
+  Acknowledgement( unsigned int id, unsigned int clientID );
+  Acknowledgement( uint8_t* data, unsigned int clientID );
+  ~Acknowledgement();
+
+  inline unsigned int getSize() const;
+  bool process();
+
+  unsigned int getAckID();
+private:
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif /* _Acknowledgement_H__ */
Index: /code/branches/rocket2/src/libraries/network/packet/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,26 @@
+ADD_SOURCE_FILES(NETWORK_SRC_FILES
+COMPILATION_BEGIN PacketCompilation.cc
+  Acknowledgement.cc
+  Chat.cc
+  ClassID.cc
+  DeleteObjects.cc
+  FunctionIDs.cc
+  FunctionCalls.cc
+  Gamestate.cc
+  Packet.cc
+  Welcome.cc
+COMPILATION_END
+)
+
+ADD_SOURCE_FILES(NETWORK_HDR_FILES
+  Acknowledgement.h
+  Chat.cc
+  Chat.h
+  ClassID.h
+  DeleteObjects.h
+  FunctionCalls.h
+  FunctionIDs.h
+  Gamestate.h
+  Packet.h
+  Welcome.h
+)
Index: /code/branches/rocket2/src/libraries/network/packet/Chat.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/Chat.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/Chat.cc	(revision 6952)
@@ -0,0 +1,93 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Chat.h"
+
+#include <cstring>
+#include <string>
+#include "network/Host.h"
+
+namespace orxonox {
+namespace packet {
+
+#define   PACKET_FLAGS_CHAT PacketFlag::Reliable
+
+/* Some lengths */
+#define   _PACKETID         0
+const int _PLAYERID     =   _PACKETID + sizeof(Type::Value);
+#define   _MESSAGELENGTH    _PLAYERID + sizeof(uint32_t)
+#define   _MESSAGE          _MESSAGELENGTH + sizeof(uint32_t)
+
+Chat::Chat( const std::string& message, unsigned int playerID )
+ : Packet()
+{
+  /* Add chat flag to packet flags */
+  flags_ = flags_ | PACKET_FLAGS_CHAT;
+
+  /* set message length to length of input string + 1 */
+  messageLength_ = message.length()+1;
+
+  /* allocate memory for the data */
+  data_=new unsigned char[ getSize() ];
+
+  *(Type::Value *)(data_ + _PACKETID ) = Type::Chat;
+  *(unsigned int *)(data_ + _PLAYERID ) = playerID;
+  *(unsigned int *)(data_ + _MESSAGELENGTH ) = messageLength_;
+
+  /* cast the hell out of the message string, and copy it into the 
+   * data buffer. 
+   */
+  memcpy( data_+_MESSAGE, static_cast<void*>(const_cast<char*>(message.c_str())), messageLength_ );
+}
+
+Chat::Chat( uint8_t* data, unsigned int clientID )
+  : Packet(data, clientID)
+{
+  messageLength_ = *(uint32_t *)(data + _MESSAGELENGTH );
+}
+
+Chat::~Chat()
+{
+}
+
+unsigned int Chat::getSize() const{
+  return _MESSAGE + messageLength_;
+}
+
+bool Chat::process(){
+  bool b = Host::incomingChat(std::string((const char*)data_+_MESSAGE), *(uint32_t *)(data_+_PLAYERID));
+  delete this;
+  return b;
+}
+
+unsigned char *Chat::getMessage(){
+  return data_ + _MESSAGE;
+}
+
+} //namespace packet
+} //namespace orxonox
Index: /code/branches/rocket2/src/libraries/network/packet/Chat.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/Chat.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/Chat.h	(revision 6952)
@@ -0,0 +1,74 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NETWORK_Chat_H__
+#define _NETWORK_Chat_H__
+
+#include "network/NetworkPrereqs.h"
+#include "Packet.h"
+
+namespace orxonox {
+namespace packet {
+/**
+    @author
+*/
+class _NetworkExport Chat : public Packet
+{
+public:
+  /* constructors */
+  Chat( const std::string& message, unsigned int playerID );
+  Chat( uint8_t* data, unsigned int clientID );
+
+  /* destructor */
+  ~Chat();
+
+  /* get size of packet */
+  inline unsigned int getSize() const;
+
+  /* process chat message packet and remove it afterwards */
+  bool process();
+
+  /* Get the length of the message (not the full size of the packet) */
+  unsigned int getMessageLength(){ return messageLength_; };
+
+  /* return message content */
+  unsigned char *getMessage();
+
+private:
+
+  /* Message length */
+  uint32_t messageLength_;
+
+  /* Client ID (an integral value for identification) */
+  unsigned int clientID_;
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif /* _NETWORK_Chat_H__ */
Index: /code/branches/rocket2/src/libraries/network/packet/ClassID.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/ClassID.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/ClassID.cc	(revision 6952)
@@ -0,0 +1,155 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ClassID.h"
+
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+#include <map>
+#include <queue>
+#include <string>
+
+#include "core/CoreIncludes.h"
+
+namespace orxonox {
+namespace packet {
+
+
+#define PACKET_FLAGS_CLASSID  PacketFlag::Reliable
+#define _PACKETID             0
+
+
+ClassID::ClassID( ) : Packet(){
+  Identifier *id;
+  unsigned int nrOfClasses=0;
+  unsigned int packetSize=2*sizeof(uint32_t); //space for the packetID and for the nrofclasses
+  uint32_t network_id;
+  flags_ = flags_ | PACKET_FLAGS_CLASSID;
+  std::queue<std::pair<uint32_t, std::string> > tempQueue;
+
+  //calculate total needed size (for all strings and integers)
+  std::map<std::string, Identifier*>::const_iterator it = Identifier::getStringIdentifierMapBegin();
+  for(;it != Identifier::getStringIdentifierMapEnd();++it){
+    id = it->second;
+    if(id == NULL || !id->hasFactory())
+      continue;
+    const std::string& classname = id->getName();
+    network_id = id->getNetworkID();
+    // now push the network id and the classname to the stack
+    tempQueue.push( std::pair<unsigned int, std::string>(network_id, classname) );
+    ++nrOfClasses;
+    packetSize += (classname.size()+1)+sizeof(uint32_t)+sizeof(uint32_t);
+  }
+
+  this->data_=new uint8_t[ packetSize ];
+  //set the appropriate packet id
+  assert(this->data_);
+  *(Type::Value *)(this->data_ + _PACKETID ) = Type::ClassID;
+
+  uint8_t *temp=data_+sizeof(uint32_t);
+  // save the number of all classes
+  *(uint32_t*)temp = nrOfClasses;
+  temp += sizeof(uint32_t);
+
+  // now save all classids and classnames
+  std::pair<uint32_t, std::string> tempPair;
+  while( !tempQueue.empty() ){
+    tempPair = tempQueue.front();
+    tempQueue.pop();
+    *(uint32_t*)temp = tempPair.first;
+    *(uint32_t*)(temp+sizeof(uint32_t)) = tempPair.second.size()+1;
+    memcpy(temp+2*sizeof(uint32_t), tempPair.second.c_str(), tempPair.second.size()+1);
+    temp+=2*sizeof(uint32_t)+tempPair.second.size()+1;
+  }
+
+  COUT(5) << "classid packetSize is " << packetSize << endl;
+
+}
+
+ClassID::ClassID( uint8_t* data, unsigned int clientID )
+  : Packet(data, clientID)
+{
+}
+
+ClassID::~ClassID()
+{
+}
+
+uint32_t ClassID::getSize() const{
+  uint8_t *temp = data_+sizeof(uint32_t); // packet identification
+  uint32_t totalsize = sizeof(uint32_t); // packet identification
+  uint32_t nrOfClasses = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+  totalsize += sizeof(uint32_t); // storage size for nr of all classes
+
+  for(unsigned int i=0; i<nrOfClasses; i++){
+    totalsize += 2*sizeof(uint32_t) + *(uint32_t*)(temp + sizeof(uint32_t));
+  }
+  return totalsize;
+}
+
+
+bool ClassID::process(){
+  int nrOfClasses;
+  uint8_t *temp = data_+sizeof(uint32_t); //skip the packetid
+  uint32_t networkID;
+  uint32_t stringsize;
+  unsigned char *classname;
+
+
+  //clear the map of network ids
+  Identifier::clearNetworkIDs();
+
+  COUT(4) << "=== processing classids: " << endl;
+  std::pair<uint32_t, std::string> tempPair;
+  Identifier *id;
+  // read the total number of classes
+  nrOfClasses = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+
+  for( int i=0; i<nrOfClasses; i++){
+    networkID = *(uint32_t*)temp;
+    stringsize = *(uint32_t*)(temp+sizeof(uint32_t));
+    classname = temp+2*sizeof(uint32_t);
+    id=ClassByString( std::string((const char*)classname) );
+    COUT(3) << "processing classid: " << networkID << " name: " << classname << " id: " << id << std::endl;
+    if(id==NULL){
+      COUT(0) << "Recieved a bad classname" << endl;
+      abort();
+    }
+    id->setNetworkID( networkID );
+    temp += 2*sizeof(uint32_t) + stringsize;
+  }
+  delete this;
+  return true;
+}
+
+
+} //namespace packet
+}//namespace orxonox
Index: /code/branches/rocket2/src/libraries/network/packet/ClassID.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/ClassID.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/ClassID.h	(revision 6952)
@@ -0,0 +1,58 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NETWORK_ClassID_H__
+#define _NETWORK_ClassID_H__
+
+#include "network/NetworkPrereqs.h"
+#include "Packet.h"
+
+namespace orxonox {
+namespace packet {
+
+
+/**
+    @author
+*/
+class _NetworkExport ClassID : public Packet
+{
+public:
+  ClassID( );
+  ClassID( uint8_t* data, unsigned int clientID );
+  ~ClassID();
+
+  uint32_t getSize() const;
+  bool process();
+
+private:
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif /* _NETWORK_ClassID_H__ */
Index: /code/branches/rocket2/src/libraries/network/packet/DeleteObjects.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/DeleteObjects.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/DeleteObjects.cc	(revision 6952)
@@ -0,0 +1,97 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#include "DeleteObjects.h"
+
+#include <cassert>
+#include "util/Debug.h"
+#include "network/synchronisable/Synchronisable.h"
+
+namespace orxonox {
+namespace packet {
+
+#define PACKET_FLAG_DELETE  PacketFlag::Reliable
+#define _PACKETID           0
+#define _QUANTITY           _PACKETID + sizeof(Type::Value)
+#define _OBJECTIDS          _QUANTITY + sizeof(uint32_t)
+
+DeleteObjects::DeleteObjects()
+ : Packet()
+{
+  flags_ = flags_ | PACKET_FLAG_DELETE;
+}
+
+DeleteObjects::DeleteObjects( uint8_t *data, unsigned int clientID )
+  : Packet(data, clientID)
+{
+}
+
+DeleteObjects::~DeleteObjects()
+{
+}
+
+bool DeleteObjects::fetchIDs(){
+  unsigned int number = Synchronisable::getNumberOfDeletedObject();
+  if(number==0)
+    return false;
+  COUT(4) << "sending DeleteObjects: ";
+  unsigned int size = sizeof(Type::Value) + sizeof(uint32_t)*(number+1);
+  data_ = new uint8_t[size];
+  uint8_t *tdata = data_;
+  *reinterpret_cast<Type::Value*>(tdata) = Type::DeleteObjects;
+  tdata += sizeof(Type::Value);
+  *(uint32_t *)tdata = number;
+  tdata += sizeof(uint32_t);
+  for(unsigned int i=0; i<number; i++){
+    unsigned int temp = Synchronisable::popDeletedObject();
+    *reinterpret_cast<uint32_t*>(tdata) = temp;
+    COUT(4) << temp << ' ';
+    tdata += sizeof(uint32_t);
+  }
+  COUT(4) << std::endl;
+  return true;
+}
+
+unsigned int DeleteObjects::getSize() const{
+  assert(data_);
+  return _OBJECTIDS + *(uint32_t*)(data_+_QUANTITY)*sizeof(uint32_t);
+}
+
+bool DeleteObjects::process(){
+  for(unsigned int i=0; i<*(unsigned int *)(data_+_QUANTITY); i++){
+    COUT(4) << "deleting object with id: " << *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) << std::endl;
+    Synchronisable::deleteObject( *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) );
+  }
+  delete this;
+  return true;
+}
+
+
+} //namespace packet
+} //namespace orxonox
Index: /code/branches/rocket2/src/libraries/network/packet/DeleteObjects.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/DeleteObjects.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/DeleteObjects.h	(revision 6952)
@@ -0,0 +1,57 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+#ifndef _DeleteObjects_H__
+#define _DeleteObjects_H__
+
+#include "network/NetworkPrereqs.h"
+#include "Packet.h"
+
+namespace orxonox {
+namespace packet {
+/**
+    @author
+*/
+class _NetworkExport DeleteObjects : public Packet
+{
+public:
+  DeleteObjects( );
+  DeleteObjects( uint8_t* data, unsigned int clientID );
+  ~DeleteObjects();
+
+  bool fetchIDs();
+
+  inline unsigned int getSize() const;
+  bool process();
+
+private:
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif /* _DeleteObjects_H__ */
Index: /code/branches/rocket2/src/libraries/network/packet/FunctionCalls.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/FunctionCalls.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/FunctionCalls.cc	(revision 6952)
@@ -0,0 +1,321 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "FunctionCalls.h"
+
+#include <cassert>
+#include <cstring>
+#include "util/MultiType.h"
+#include "network/NetworkFunction.h"
+
+namespace orxonox {
+namespace packet {
+
+#define   PACKET_FLAGS_FUNCTIONCALLS PacketFlag::Reliable
+#define   _PACKETID         0
+const unsigned int FUNCTIONCALLS_MEM_ALLOCATION = 1000;
+
+FunctionCalls::FunctionCalls()
+ : Packet()
+{
+  flags_ = flags_ | PACKET_FLAGS_FUNCTIONCALLS;
+  currentSize_ = 2*sizeof(uint32_t); // for packetid and nrOfCalls
+  nrOfCalls_ = 0;
+  currentMemBlocks_ = 1;
+  data_=new uint8_t[ FUNCTIONCALLS_MEM_ALLOCATION ];
+  *(Type::Value *)(data_ + _PACKETID ) = Type::FunctionCalls;
+  *(uint32_t*)(data_+sizeof(uint32_t)) = 0; // set nrOfCalls to 0
+}
+
+FunctionCalls::FunctionCalls( uint8_t* data, unsigned int clientID )
+  : Packet(data, clientID)
+{
+}
+
+FunctionCalls::~FunctionCalls()
+{
+}
+
+
+bool FunctionCalls::process(){
+  assert(isDataENetAllocated());
+  uint8_t* temp = data_+sizeof(uint32_t); //skip packetid
+  this->nrOfCalls_ = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+  for( unsigned int i = 0; i<this->nrOfCalls_; i++ )
+  {
+    uint32_t functionID = *(uint32_t*)temp;
+    bool isStatic = *(uint8_t*)(temp+sizeof(uint32_t));
+    if( isStatic )
+    {
+      MultiType mt1, mt2, mt3, mt4, mt5;
+      NetworkFunctionStatic *fct = NetworkFunctionStatic::getFunction( functionID );
+      uint32_t nrOfArguments = *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t));
+      temp+=2*sizeof(uint32_t)+sizeof(uint8_t);
+      switch(nrOfArguments)
+      {
+        case 0:
+          fct->call();
+          break;
+        case 1:
+          mt1.importData(temp);
+          fct->call(mt1);
+          break;
+        case 2:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          fct->call(mt1, mt2);
+          break;
+        case 3:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          fct->call(mt1, mt2, mt3);
+          break;
+        case 4:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          mt4.importData(temp);
+          fct->call(mt1, mt2, mt3, mt4);
+          break;
+        case 5:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          mt4.importData(temp);
+          mt5.importData(temp);
+          fct->call(mt1, mt2, mt3, mt4, mt5);
+          break;
+        default:
+          assert(0);
+      }
+    }
+    else // not a static function, so also handle the objectID
+    {
+      MultiType mt1, mt2, mt3, mt4, mt5;
+      NetworkMemberFunctionBase *fct = NetworkMemberFunctionBase::getFunction( functionID );
+      uint32_t nrOfArguments = *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t));
+      uint32_t objectID = *(uint32_t*)(temp+2*sizeof(uint32_t)+sizeof(uint8_t));
+      temp+=3*sizeof(uint32_t)+sizeof(uint8_t);
+      switch(nrOfArguments)
+      {
+        case 0:
+          fct->call(objectID);
+          break;
+        case 1:
+          mt1.importData(temp);
+          fct->call(objectID, mt1);
+          break;
+        case 2:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          fct->call(objectID, mt1, mt2);
+          break;
+        case 3:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          fct->call(objectID, mt1, mt2, mt3);
+          break;
+        case 4:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          mt4.importData(temp);
+          fct->call(objectID, mt1, mt2, mt3, mt4);
+          break;
+        case 5:
+          mt1.importData(temp);
+          mt2.importData(temp);
+          mt3.importData(temp);
+          mt4.importData(temp);
+          mt5.importData(temp);
+          fct->call(objectID, mt1, mt2, mt3, mt4, mt5);
+          break;
+        default:
+          assert(0);
+          break;
+      }
+    }
+  }
+  delete this;
+  return true;
+}
+
+void FunctionCalls::addCallStatic( uint32_t networkID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5){
+  assert(!isDataENetAllocated());
+
+  // first determine the size that has to be reserved for this call
+  uint32_t callsize = 2*sizeof(uint32_t)+sizeof(uint8_t); //size for network-function-id and nrOfArguments and for bool isStatic
+  uint32_t nrOfArguments = 0;
+  if(mt1)
+  {
+    nrOfArguments++;
+    callsize += mt1->getNetworkSize();
+    if(mt2)
+    {
+      nrOfArguments++;
+      callsize += mt2->getNetworkSize();
+      if(mt3)
+      {
+        nrOfArguments++;
+        callsize += mt3->getNetworkSize();
+        if(mt4)
+        {
+          nrOfArguments++;
+          callsize += mt4->getNetworkSize();
+          if(mt5)
+          {
+            nrOfArguments++;
+            callsize += mt5->getNetworkSize();
+          }
+        }
+      }
+    }
+  }
+
+  // now allocated mem if neccessary
+  if( currentSize_ + callsize > currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION )
+  {
+    currentMemBlocks_ = (currentSize_ + callsize)%FUNCTIONCALLS_MEM_ALLOCATION+1;
+    uint8_t *temp = new uint8_t[currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION];
+    memcpy( temp, data_, currentSize_ );
+    delete[] data_;
+    data_ = temp;
+  }
+
+  // now serialise the mt values and copy the function id and isStatic
+  uint8_t* temp = data_+currentSize_;
+  *(uint32_t*)(data_+sizeof(uint32_t)) = *(uint32_t*)(data_+sizeof(uint32_t))+1; // increase number of calls
+  *(uint32_t*)temp = networkID;
+  *(uint8_t*)(temp+sizeof(uint32_t)) = true;
+  *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t)) = nrOfArguments;
+  temp += 2*sizeof(uint32_t)+sizeof(uint8_t);
+  if(mt1)
+  {
+    mt1->exportData( temp ); //temp gets automatically increased
+    if(mt2)
+    {
+      mt2->exportData( temp ); //temp gets automatically increased
+      if(mt3)
+      {
+        mt3->exportData( temp ); //temp gets automatically increased
+        if(mt4)
+        {
+          mt4->exportData( temp ); //temp gets automatically increased
+          if(mt5)
+          {
+            mt5->exportData( temp ); //temp gets automatically increased
+          }
+        }
+      }
+    }
+  }
+  //currentSize_ += callsize;
+  currentSize_ = temp-data_;
+
+}
+
+void FunctionCalls::addCallMember( uint32_t networkID, uint32_t objectID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5){
+  assert(!isDataENetAllocated());
+
+  // first determine the size that has to be reserved for this call
+  uint32_t callsize = 3*sizeof(uint32_t)+sizeof(uint8_t); //size for network-function-id and nrOfArguments and the objectID
+  uint32_t nrOfArguments = 0;
+  if(mt1)
+  {
+    nrOfArguments++;
+    callsize += mt1->getNetworkSize();
+    if(mt2)
+    {
+      nrOfArguments++;
+      callsize += mt2->getNetworkSize();
+      if(mt3)
+      {
+        nrOfArguments++;
+        callsize += mt3->getNetworkSize();
+        if(mt4)
+        {
+          nrOfArguments++;
+          callsize += mt4->getNetworkSize();
+          if(mt5)
+          {
+            nrOfArguments++;
+            callsize += mt5->getNetworkSize();
+          }
+        }
+      }
+    }
+  }
+
+  // now allocated mem if neccessary
+  if( currentSize_ + callsize > currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION )
+  {
+    currentMemBlocks_ = (currentSize_ + callsize)%FUNCTIONCALLS_MEM_ALLOCATION+1;
+    uint8_t *temp = new uint8_t[currentMemBlocks_*FUNCTIONCALLS_MEM_ALLOCATION];
+    memcpy( temp, data_, currentSize_ );
+    delete[] data_;
+    data_ = temp;
+  }
+
+  // now serialise the mt values and copy the function id
+  uint8_t* temp = data_+currentSize_;
+  *(uint32_t*)(data_+sizeof(uint32_t)) = *(uint32_t*)(data_+sizeof(uint32_t))+1; // increase number of calls
+  *(uint32_t*)temp = networkID;
+  *(uint8_t*)(temp+sizeof(uint32_t)) = false;
+  *(uint32_t*)(temp+sizeof(uint32_t)+sizeof(uint8_t)) = nrOfArguments;
+  *(uint32_t*)(temp+2*sizeof(uint32_t)+sizeof(uint8_t)) = objectID;
+  temp += 3*sizeof(uint32_t)+sizeof(uint8_t);
+  if(mt1)
+  {
+    mt1->exportData( temp ); //temp gets automatically increased
+    if(mt2)
+    {
+      mt2->exportData( temp ); //temp gets automatically increased
+      if(mt3)
+      {
+        mt3->exportData( temp ); //temp gets automatically increased
+        if(mt4)
+        {
+          mt4->exportData( temp ); //temp gets automatically increased
+          if(mt5)
+          {
+            mt5->exportData( temp ); //temp gets automatically increased
+          }
+        }
+      }
+    }
+  }
+  currentSize_ += callsize;
+
+}
+
+
+} //namespace packet
+} //namespace orxonox
Index: /code/branches/rocket2/src/libraries/network/packet/FunctionCalls.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/FunctionCalls.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/FunctionCalls.h	(revision 6952)
@@ -0,0 +1,69 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _FunctionCalls_H__
+#define _FunctionCalls_H__
+
+#include "network/NetworkPrereqs.h"
+
+#include <cassert>
+#include "util/UtilPrereqs.h"
+#include "Packet.h"
+
+namespace orxonox {
+
+namespace packet {
+/**
+    @author
+*/
+
+
+class _NetworkExport FunctionCalls : public Packet
+{
+public:
+  FunctionCalls();
+  FunctionCalls( uint8_t* data, unsigned int clientID );
+  ~FunctionCalls();
+
+  inline unsigned int getSize() const
+    { assert(!this->isDataENetAllocated()); return currentSize_; }
+  bool process();
+
+  void addCallStatic( uint32_t networkID, const MultiType* mt1=0, const MultiType* mt2=0, const MultiType* mt3=0, const MultiType* mt4=0, const MultiType* mt5=0);
+  void addCallMember( uint32_t networkID, uint32_t objectID, const MultiType* mt1=0, const MultiType* mt2=0, const MultiType* mt3=0, const MultiType* mt4=0, const MultiType* mt5=0);
+private:
+  uint32_t nrOfCalls_;
+  unsigned int clientID_;
+  uint32_t currentSize_;
+  uint32_t currentMemBlocks_; // this saves the number of memory blocks (of size FUNCTIONCALLS_MEM_ALLOCATION) allocated
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif /* _FunctionCalls_H__ */
Index: /code/branches/rocket2/src/libraries/network/packet/FunctionIDs.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/FunctionIDs.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/FunctionIDs.cc	(revision 6952)
@@ -0,0 +1,143 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "FunctionIDs.h"
+
+#include <cassert>
+#include <cstring>
+#include <queue>
+#include <string>
+
+#include "util/Debug.h"
+#include "core/ObjectList.h"
+#include "network/NetworkFunction.h"
+
+namespace orxonox {
+namespace packet {
+
+
+#define PACKET_FLAGS_FUNCTIONIDS  PacketFlag::Reliable
+#define _PACKETID                 0
+
+
+FunctionIDs::FunctionIDs( ) : Packet(){
+  unsigned int nrOfFunctions=0;
+  unsigned int packetSize=2*sizeof(uint32_t); //space for the packetID and for the nroffunctions
+  uint32_t networkID;
+  flags_ = flags_ | PACKET_FLAGS_FUNCTIONIDS;
+  std::queue<std::pair<uint32_t, std::string> > tempQueue;
+
+  //calculate total needed size (for all strings and integers)
+  ObjectList<NetworkFunctionBase>::iterator it;
+  for(it = ObjectList<NetworkFunctionBase>::begin(); it; ++it){
+    const std::string& functionname = it->getName();
+    networkID = it->getNetworkID();
+    // now push the network id and the classname to the stack
+    tempQueue.push( std::pair<unsigned int, std::string>(networkID, functionname) );
+    ++nrOfFunctions;
+    packetSize += (functionname.size()+1)+sizeof(uint32_t)+sizeof(uint32_t); // reserver size for the functionname string, the functionname length and the networkID
+  }
+
+  this->data_=new uint8_t[ packetSize ];
+  //set the appropriate packet id
+  assert(this->data_);
+  *(Type::Value *)(this->data_ + _PACKETID ) = Type::FunctionIDs;
+
+  uint8_t *temp=data_+sizeof(uint32_t);
+  // save the number of all classes
+  *(uint32_t*)temp = nrOfFunctions;
+  temp += sizeof(uint32_t);
+
+  // now save all classids and classnames
+  std::pair<uint32_t, std::string> tempPair;
+  while( !tempQueue.empty() ){
+    tempPair = tempQueue.front();
+    tempQueue.pop();
+    *(uint32_t*)temp = tempPair.first;
+    *(uint32_t*)(temp+sizeof(uint32_t)) = tempPair.second.size()+1;
+    memcpy(temp+2*sizeof(uint32_t), tempPair.second.c_str(), tempPair.second.size()+1);
+    temp+=2*sizeof(uint32_t)+tempPair.second.size()+1;
+  }
+
+  COUT(5) << "FunctionIDs packetSize is " << packetSize << endl;
+
+}
+
+FunctionIDs::FunctionIDs( uint8_t* data, unsigned int clientID )
+  : Packet(data, clientID)
+{
+}
+
+FunctionIDs::~FunctionIDs()
+{
+}
+
+uint32_t FunctionIDs::getSize() const{
+  assert(this->data_);
+  uint8_t *temp = data_+sizeof(uint32_t); // packet identification
+  uint32_t totalsize = sizeof(uint32_t); // data size
+  uint32_t nrOfFunctions = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+  totalsize += sizeof(uint32_t); // storage size for nr of all classes
+
+  for(unsigned int i=0; i<nrOfFunctions; i++){
+    totalsize += 2*sizeof(uint32_t) + *(uint32_t*)(temp + sizeof(uint32_t)); // for each network function add size for id, sizeof(string) and length of string itself to totalsize
+    temp += 2*sizeof(uint32_t) + *(uint32_t*)(temp + sizeof(uint32_t));
+  }
+  return totalsize;
+}
+
+
+bool FunctionIDs::process(){
+  int nrOfFunctions;
+  uint8_t *temp = data_+sizeof(uint32_t); //skip the packetid
+  uint32_t networkID;
+  uint32_t stringsize;
+  unsigned char *functionname;
+
+  COUT(4) << "=== processing functionids: " << endl;
+  std::pair<uint32_t, std::string> tempPair;
+  // read the total number of classes
+  nrOfFunctions = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+
+  for( int i=0; i<nrOfFunctions; i++){
+    networkID = *(uint32_t*)temp;
+    stringsize = *(uint32_t*)(temp+sizeof(uint32_t));
+    functionname = temp+2*sizeof(uint32_t);
+    COUT(3) << "processing functionid: " << networkID << " name: " << functionname << std::endl;
+    NetworkFunctionBase::setNetworkID((const char*)functionname, networkID);
+    temp += 2*sizeof(uint32_t) + stringsize;
+  }
+  delete this;
+  return true;
+}
+
+
+} //namespace packet
+}//namespace orxonox
Index: /code/branches/rocket2/src/libraries/network/packet/FunctionIDs.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/FunctionIDs.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/FunctionIDs.h	(revision 6952)
@@ -0,0 +1,58 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _FunctionIDs_H__
+#define _FunctionIDs_H__
+
+#include "network/NetworkPrereqs.h"
+#include "Packet.h"
+
+namespace orxonox {
+namespace packet {
+
+
+/**
+    @author
+*/
+class _NetworkExport FunctionIDs : public Packet
+{
+public:
+  FunctionIDs( );
+  FunctionIDs( uint8_t* data, unsigned int clientID );
+  ~FunctionIDs();
+
+  uint32_t getSize() const;
+  bool process();
+
+private:
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif /* _FunctionIDs_H__ */
Index: /code/branches/rocket2/src/libraries/network/packet/Gamestate.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/Gamestate.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/Gamestate.cc	(revision 6952)
@@ -0,0 +1,623 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Gamestate.h"
+
+#include <zlib.h>
+
+#include "util/Debug.h"
+#include "core/GameMode.h"
+#include "core/ObjectList.h"
+#include "network/synchronisable/Synchronisable.h"
+#include "network/GamestateHandler.h"
+
+namespace orxonox {
+
+namespace packet {
+
+#define GAMESTATE_START(data) (data + GamestateHeader::getSize())
+
+#define PACKET_FLAG_GAMESTATE  PacketFlag::Reliable
+
+
+Gamestate::Gamestate()
+{
+  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
+  header_ = 0;
+}
+
+Gamestate::Gamestate(uint8_t *data, unsigned int clientID):
+    Packet(data, clientID)
+{
+  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
+  header_ = new GamestateHeader(data_);
+}
+
+Gamestate::Gamestate(uint8_t *data)
+{
+  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
+  data_=data;
+  header_ = new GamestateHeader(data_);
+}
+
+Gamestate::Gamestate(const Gamestate& g) :
+    Packet( *(Packet*)&g )
+{
+  flags_ = flags_ | PACKET_FLAG_GAMESTATE;
+  header_ = new GamestateHeader(data_);
+}
+
+
+Gamestate::~Gamestate()
+{
+  if( header_ )
+    delete header_;
+}
+
+bool Gamestate::collectData(int id, uint8_t mode)
+{
+  assert(this->header_==0); // make sure the header didn't exist before
+  uint32_t tempsize=0, currentsize=0;
+  assert(data_==0);
+  uint32_t size = calcGamestateSize(id, mode);
+
+  COUT(4) << "G.ST.Man: producing gamestate with id: " << id << std::endl;
+  if(size==0)
+    return false;
+  data_ = new uint8_t[size + GamestateHeader::getSize()];
+  if(!data_){
+    COUT(2) << "GameStateManager: could not allocate memory" << std::endl;
+    return false;
+  }
+
+  // create the header object
+  assert( header_ == 0 );
+  header_ = new GamestateHeader(data_);
+
+  //start collect data synchronisable by synchronisable
+  uint8_t *mem=data_;
+  mem += GamestateHeader::getSize();
+  ObjectList<Synchronisable>::iterator it;
+  for(it = ObjectList<Synchronisable>::begin(); it; ++it){
+
+//     tempsize=it->getSize(id, mode);
+
+    tempsize = it->getData(mem, id, mode);
+    if ( tempsize != 0 )
+      dataVector_.push_back( obj(it->getObjectID(), it->getCreatorID(), tempsize, mem-data_) );
+
+#ifndef NDEBUG
+    if(currentsize+tempsize > size){
+      assert(0); // if we don't use multithreading this part shouldn't be neccessary
+      // start allocate additional memory
+      COUT(3) << "G.St.Man: need additional memory" << std::endl;
+      ObjectList<Synchronisable>::iterator temp = it;
+      uint32_t addsize=tempsize;
+      while(++temp)
+        addsize+=temp->getSize(id, mode);
+      data_ = (uint8_t *)realloc(data_, GamestateHeader::getSize() + currentsize + addsize);
+      if(!data_)
+        return false;
+      size = currentsize+addsize;
+    }// stop allocate additional memory
+#endif
+//     if(!it->getData(mem, id, mode))
+//       return false; // mem pointer gets automatically increased because of call by reference
+    // increase size counter by size of current synchronisable
+    currentsize+=tempsize;
+  }
+
+
+  //start write gamestate header
+  header_->setDataSize( currentsize );
+  header_->setID( id );
+  header_->setBaseID( GAMESTATEID_INITIAL );
+  header_->setDiffed( false );
+  header_->setComplete( true );
+  header_->setCompressed( false );
+  //stop write gamestate header
+
+  COUT(5) << "G.ST.Man: Gamestate size: " << currentsize << std::endl;
+  COUT(5) << "G.ST.Man: 'estimated' (and corrected) Gamestate size: " << size << std::endl;
+  return true;
+}
+
+bool Gamestate::spreadData(uint8_t mode)
+{
+  COUT(4) << "processing gamestate with id " << header_->getID() << endl;
+  assert(data_);
+  assert(!header_->isCompressed());
+  assert(!header_->isDiffed());
+  uint8_t *mem=data_+GamestateHeader::getSize();
+  Synchronisable *s;
+
+  // update the data of the objects we received
+  while(mem < data_+GamestateHeader::getSize()+header_->getDataSize()){
+    SynchronisableHeader objectheader(mem);
+
+    s = Synchronisable::getSynchronisable( objectheader.getObjectID() );
+    if(!s)
+    {
+      if (!GameMode::isMaster())
+      {
+        Synchronisable::fabricate(mem, mode);
+      }
+      else
+      {
+        mem += objectheader.getDataSize();
+      }
+    }
+    else
+    {
+      bool b = s->updateData(mem, mode);
+      assert(b);
+    }
+  }
+   // In debug mode, check first, whether there are no duplicate objectIDs
+#ifndef NDEBUG
+  if(this->getID()%1000==0){
+    std::list<uint32_t> v1;
+    ObjectList<Synchronisable>::iterator it;
+    for (it = ObjectList<Synchronisable>::begin(); it != ObjectList<Synchronisable>::end(); ++it) {
+      if (it->getObjectID() == OBJECTID_UNKNOWN) {
+        if (it->objectMode_ != 0x0) {
+          COUT(0) << "Found object with OBJECTID_UNKNOWN on the client with objectMode != 0x0!" << std::endl;
+          COUT(0) << "Possible reason for this error: Client created a synchronized object without the Server's approval." << std::endl;
+          COUT(0) << "Objects class: " << it->getIdentifier()->getName() << std::endl;
+          assert(false);
+        }
+      }
+      else {
+        std::list<uint32_t>::iterator it2;
+        for (it2 = v1.begin(); it2 != v1.end(); ++it2) {
+          if (it->getObjectID() == *it2) {
+            COUT(0) << "Found duplicate objectIDs on the client!" << std::endl
+                    << "Are you sure you don't create a Sychnronisable objcect with 'new' \
+                        that doesn't have objectMode = 0x0?" << std::endl;
+            assert(false);
+          }
+        }
+        v1.push_back(it->getObjectID());
+      }
+    }
+  }
+#endif
+  return true;
+}
+
+uint32_t Gamestate::getSize() const
+{
+  assert(data_);
+  if(header_->isCompressed())
+    return header_->getCompSize()+GamestateHeader::getSize();
+  else
+  {
+    return header_->getDataSize()+GamestateHeader::getSize();
+  }
+}
+
+bool Gamestate::operator==(packet::Gamestate gs){
+  uint8_t *d1 = data_+GamestateHeader::getSize();
+  uint8_t *d2 = gs.data_+GamestateHeader::getSize();
+  GamestateHeader* h1 = new GamestateHeader(data_);
+  GamestateHeader* h2 = new GamestateHeader(gs.data_);
+  assert(h1->getDataSize() == h2->getDataSize());
+  assert(!isCompressed());
+  assert(!gs.isCompressed());
+  return memcmp(d1, d2, h1->getDataSize())==0;
+}
+
+bool Gamestate::process()
+{
+  return GamestateHandler::addGamestate(this, getClientID());
+}
+
+
+
+bool Gamestate::compressData()
+{
+  assert(data_);
+  assert(!header_->isCompressed());
+  uLongf buffer = (uLongf)(((header_->getDataSize() + 12)*1.01)+1);
+  if(buffer==0)
+    return false;
+
+  uint8_t *ndata = new uint8_t[buffer+GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+  uint8_t *source = data_ + GamestateHeader::getSize();
+  int retval;
+  retval = compress( dest, &buffer, source, (uLong)(header_->getDataSize()) );
+  switch ( retval ) {
+    case Z_OK: COUT(5) << "G.St.Man: compress: successfully compressed" << std::endl; break;
+    case Z_MEM_ERROR: COUT(1) << "G.St.Man: compress: not enough memory available in gamestate.compress" << std::endl; return false;
+    case Z_BUF_ERROR: COUT(2) << "G.St.Man: compress: not enough memory available in the buffer in gamestate.compress" << std::endl; return false;
+    case Z_DATA_ERROR: COUT(2) << "G.St.Man: compress: data corrupted in gamestate.compress" << std::endl; return false;
+  }
+
+  //copy and modify header
+  GamestateHeader *temp = header_;
+  header_ = new GamestateHeader(ndata, temp);
+  delete temp;
+  //delete old data
+  delete[] data_;
+  //save new data
+  data_ = ndata;
+  header_->setCompSize( buffer );
+  header_->setCompressed( true );
+  COUT(5) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl;
+  return true;
+}
+bool Gamestate::decompressData()
+{
+  assert(data_);
+  assert(header_->isCompressed());
+  COUT(4) << "GameStateClient: uncompressing gamestate. id: " << header_->getID() << ", baseid: " << header_->getBaseID() << ", datasize: " << header_->getDataSize() << ", compsize: " << header_->getCompSize() << std::endl;
+  uint32_t datasize = header_->getDataSize();
+  uint32_t compsize = header_->getCompSize();
+  uint32_t bufsize;
+  bufsize = datasize;
+  assert(bufsize!=0);
+  uint8_t *ndata = new uint8_t[bufsize + GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+  uint8_t *source = data_ + GamestateHeader::getSize();
+  int retval;
+  uLongf length=bufsize;
+  retval = uncompress( dest, &length, source, (uLong)compsize );
+  switch ( retval ) {
+    case Z_OK: COUT(5) << "successfully decompressed" << std::endl; break;
+    case Z_MEM_ERROR: COUT(1) << "not enough memory available" << std::endl; return false;
+    case Z_BUF_ERROR: COUT(2) << "not enough memory available in the buffer" << std::endl; return false;
+    case Z_DATA_ERROR: COUT(2) << "data corrupted (zlib)" << std::endl; return false;
+  }
+
+  //copy over the header
+  GamestateHeader *temp = header_;
+  header_ = new GamestateHeader( data_, header_ );
+  delete temp;
+
+  if (this->bDataENetAllocated_){
+    // Memory was allocated by ENet. --> We let it be since enet_packet_destroy will
+    // deallocated it anyway. So data and packet stay together.
+    this->bDataENetAllocated_ = false;
+  }
+  else{
+    // We allocated the memory in the first place (unlikely). So we destroy the old data
+    // and overwrite it with the new decompressed data.
+    delete[] this->data_;
+  }
+
+  //set new pointers
+  data_ = ndata;
+  header_->setCompressed( false );
+  assert(header_->getDataSize()==datasize);
+  assert(header_->getCompSize()==compsize);
+  return true;
+}
+
+/*Gamestate *Gamestate::diff(Gamestate *base)
+{
+  assert(data_);
+  assert(!header_->isCompressed());
+  assert(!header_->isDiffed());
+  GamestateHeader diffHeader(base->data_);
+  uint8_t *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_);
+  uint32_t of=0; // pointers offset
+  uint32_t dest_length=0;
+  dest_length=header_->getDataSize();
+  if(dest_length==0)
+    return NULL;
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+  while(of < diffHeader.getDataSize() && of < header_->getDataSize()){
+    *(dest+of)=*(basep+of)^*(gs+of); // do the xor
+    ++of;
+  }
+  if(diffHeader.getDataSize()!=header_->getDataSize()){
+    uint8_t n=0;
+    if(diffHeader.getDataSize() < header_->getDataSize()){
+      while(of<dest_length){
+        *(dest+of)=n^*(gs+of);
+        of++;
+      }
+    }
+  }
+
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  *(g->header_) = *header_;
+  g->header_->setDiffed( true );
+  g->header_->setBaseID( base->getID() );
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
+  return g;
+}*/
+
+Gamestate *Gamestate::diff(Gamestate *base)
+{
+  assert(this && base); assert(data_ && base->data_);
+  assert(!header_->isCompressed() && !base->header_->isCompressed());
+  assert(!header_->isDiffed());
+
+  uint8_t *basep = GAMESTATE_START(base->data_);
+  uint8_t *gs = GAMESTATE_START(this->data_);
+  uint32_t dest_length = header_->getDataSize();
+
+  if(dest_length==0)
+    return NULL;
+
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = GAMESTATE_START(ndata);
+
+  rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
+#ifndef NDEBUG
+  uint8_t *dest2 = new uint8_t[dest_length];
+  rawDiff( dest2, dest, basep, header_->getDataSize(), base->header_->getDataSize() );
+  assert( memcmp( dest2, gs, dest_length) == 0 );
+  delete dest2;
+#endif
+
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  assert(g->header_);
+  *(g->header_) = *header_;
+  g->header_->setDiffed( true );
+  g->header_->setBaseID( base->getID() );
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
+  assert(g->isDiffed());
+  assert(!g->isCompressed());
+  return g;
+}
+
+Gamestate *Gamestate::undiff(Gamestate *base)
+{
+  assert(this && base); assert(data_ && base->data_);
+  assert(!header_->isCompressed() && !base->header_->isCompressed());
+  assert(header_->isDiffed());
+
+  uint8_t *basep = GAMESTATE_START(base->data_);
+  uint8_t *gs = GAMESTATE_START(this->data_);
+  uint32_t dest_length = header_->getDataSize();
+
+  if(dest_length==0)
+    return NULL;
+
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+
+  rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
+
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  assert(g->header_);
+  *(g->header_) = *header_;
+  g->header_->setDiffed( false );
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
+  assert(!g->isDiffed());
+  assert(!g->isCompressed());
+  return g;
+}
+
+
+// Gamestate *Gamestate::diff(Gamestate *base)
+// {
+//   assert(data_);
+//   assert(!header_->isCompressed());
+//   assert(!header_->isDiffed());
+//   GamestateHeader diffHeader(base->data_);
+//   uint8_t *basep = GAMESTATE_START(base->data_), *gs = GAMESTATE_START(this->data_);
+//   uint32_t of=0; // pointers offset
+//   uint32_t dest_length=0;
+//   dest_length=header_->getDataSize();
+//   if(dest_length==0)
+//     return NULL;
+//   uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+//   uint8_t *dest = ndata + GamestateHeader::getSize();
+//
+//
+//   // LOOP-UNROLLED DIFFING
+//   uint32_t *dest32 = (uint32_t*)dest, *base32 = (uint32_t*)basep, *gs32 = (uint32_t*)gs;
+//   // diff in 4-byte steps
+//   while( of < (uint32_t)(header_->getDataSize())/4 ){
+//     if( of < (uint32_t)(diffHeader.getDataSize())/4 )
+//     {
+//       *(dest32+of)=*(base32+of) ^ *(gs32+of); // do the xor
+//       ++of;
+//     }
+//     else
+//     {
+//       *(dest32+of)=*(gs32+of); // same as 0 ^ *(gs32+of)
+//       ++of;
+//     }
+//   }
+//   for( unsigned int of2 = 0; of2 < header_->getDataSize()%4; ++of2 )
+//   {
+//     if( of*4+of2 < diffHeader.getDataSize() )
+//     {
+//       *(dest+4*of+of2)=*(basep+4*of+of2) ^ *(gs+4*of+of2); // do the xor
+//     }
+//     else
+//     {
+//       *(dest+4*of+of2)=*(gs+4*of+of2); // same as 0 ^ *(gs32+of)
+//     }
+//   }
+//
+//   Gamestate *g = new Gamestate(ndata, getClientID());
+//   *(g->header_) = *header_;
+//   g->header_->setDiffed( true );
+//   g->header_->setBaseID( base->getID() );
+//   g->flags_=flags_;
+//   g->packetDirection_ = packetDirection_;
+//   return g;
+// }
+
+
+void Gamestate::rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength)
+{
+  uint64_t* gd = (uint64_t*)data;
+  uint64_t* bd = (uint64_t*)basedata;
+  uint64_t* nd = (uint64_t*)newdata;
+
+  unsigned int i;
+  for( i=0; i<datalength/8; i++ )
+  {
+    if( i<baselength/8 )
+      *(nd+i) = *(gd+i) ^ *(bd+i);  // xor the data
+    else
+      *(nd+i) = *(gd+i); // just copy over the data
+  }
+  unsigned int j;
+  // now process the rest (when datalength isn't a multiple of 4)
+  for( j = 8*(datalength/8); j<datalength; j++ )
+  {
+    if( j<baselength )
+      *(newdata+j) = *(data+j) ^ *(basedata+j); // xor
+    else
+      *(newdata+j) = *(data+j); // just copy
+  }
+  assert(j==datalength);
+}
+
+Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){
+  assert(data_);
+  std::list<obj>::iterator it;
+
+  // allocate memory for new data
+  uint8_t *gdata = new uint8_t[header_->getDataSize()+GamestateHeader::getSize()];
+  // create a gamestate out of it
+  Gamestate *gs = new Gamestate(gdata);
+  uint8_t *newdata = gdata + GamestateHeader::getSize();
+  uint8_t *origdata = GAMESTATE_START(data_);
+
+  //copy the GamestateHeader
+  assert(gs->header_);
+  *(gs->header_) = *header_;
+
+  uint32_t objectOffset;
+  unsigned int objectsize, destsize=0;
+  // TODO: Why is this variable not used?
+  //Synchronisable *object;
+
+  //call TrafficControl
+  TrafficControl::getInstance()->processObjectList( clientID, header_->getID(), dataVector_ );
+
+  //copy in the zeros
+//   std::list<obj>::iterator itt;
+//   COUT(0) << "myvector contains:";
+//   for ( itt=dataVector_.begin() ; itt!=dataVector_.end(); itt++ )
+//     COUT(0) << ' ' << (*itt).objID;
+//   COUT(0) << endl;
+  for(it=dataVector_.begin(); it!=dataVector_.end();){
+    SynchronisableHeader oldobjectheader(origdata);
+    SynchronisableHeader newobjectheader(newdata);
+    if ( it->objSize == 0 )
+    {
+      ++it;
+      continue;
+    }
+    objectsize = oldobjectheader.getDataSize();
+    objectOffset=SynchronisableHeader::getSize(); //skip the size and the availableData variables in the objectheader
+    if ( it->objID == oldobjectheader.getObjectID() ){
+      memcpy(newdata, origdata, objectsize);
+      assert(newobjectheader.isDataAvailable()==true);
+      ++it;
+    }else{
+      newobjectheader = oldobjectheader;
+      newobjectheader.setDataAvailable(false);
+      memset(newdata+objectOffset, 0, objectsize-objectOffset);
+    }
+    newdata += objectsize;
+    origdata += objectsize;
+    destsize += objectsize;
+  }
+#ifndef NDEBUG
+  uint32_t origsize = destsize;
+  while ( origsize < header_->getDataSize() )
+  {
+    SynchronisableHeader oldobjectheader(origdata);
+    objectsize = oldobjectheader.getDataSize();
+    origdata += objectsize;
+    origsize += objectsize;
+  }
+  assert(origsize==header_->getDataSize());
+  assert(destsize!=0);
+#endif
+  gs->header_->setDataSize( destsize );
+  return gs;
+}
+
+
+/*Gamestate *Gamestate::undiff(Gamestate *base)
+{
+  assert(this && base);assert(data_);
+  assert(header_->isDiffed());
+  assert(!header_->isCompressed() && !base->header_->isCompressed());
+  uint8_t *basep = GAMESTATE_START(base->data_);
+  uint8_t *gs = GAMESTATE_START(this->data_);
+  uint32_t of=0; // pointers offset
+  uint32_t dest_length=0;
+  dest_length=header_->getDataSize();
+  if(dest_length==0)
+    return NULL;
+  uint8_t *ndata = new uint8_t[dest_length*sizeof(uint8_t)+GamestateHeader::getSize()];
+  uint8_t *dest = ndata + GamestateHeader::getSize();
+  while(of < base->header_->getDataSize() && of < header_->getDataSize()){
+    *(dest+of)=*(basep+of)^*(gs+of); // do the xor
+    ++of;
+  }
+  if(base->header_->getDataSize()!=header_->getDataSize()){
+    uint8_t n=0;
+    if(base->header_->getDataSize() < header_->getDataSize()){
+      while(of < dest_length){
+        *(dest+of)=n^*(gs+of);
+        of++;
+      }
+    }
+  }
+  Gamestate *g = new Gamestate(ndata, getClientID());
+  assert(g->header_);
+  *(g->header_) = *header_;
+  g->header_->setDiffed( false );
+  g->flags_=flags_;
+  g->packetDirection_ = packetDirection_;
+  assert(!g->isDiffed());
+  assert(!g->isCompressed());
+  return g;
+}*/
+
+uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode)
+{
+  uint32_t size=0;
+    // get the start of the Synchronisable list
+  ObjectList<Synchronisable>::iterator it;
+    // get total size of gamestate
+  for(it = ObjectList<Synchronisable>::begin(); it; ++it)
+    size+=it->getSize(id, mode); // size of the actual data of the synchronisable
+  return size;
+}
+
+} //namespace packet
+} //namespace orxonox
Index: /code/branches/rocket2/src/libraries/network/packet/Gamestate.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/Gamestate.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/Gamestate.h	(revision 6952)
@@ -0,0 +1,138 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#ifndef _Gamestate_H__
+#define _Gamestate_H__
+
+#include "network/NetworkPrereqs.h"
+
+#include <cassert>
+#include <cstring>
+#include <list>
+
+#include "util/CRC32.h"
+#include "network/TrafficControl.h"
+#include "Packet.h"
+
+namespace orxonox {
+
+namespace packet {
+
+class _NetworkExport GamestateHeader{
+  public:
+    GamestateHeader(uint8_t *data){ assert(data); data_ = data; *(uint32_t*)data_ = Type::Gamestate; }
+    GamestateHeader(uint8_t *data, GamestateHeader* h)
+    { assert(data); data_=data; memcpy(data_, h->data_, getSize()); }
+    static inline uint32_t getSize()
+    { return 21; }
+
+    inline int32_t getID() const
+    { assert(data_); return *(int32_t*)(data_+4); }
+    inline void setID(int32_t id)
+    { assert(data_); *(int32_t*)(data_+4) = id; }
+
+    inline int32_t getBaseID() const
+    { assert(data_); return *(int32_t*)(data_+8); }
+    inline void setBaseID(int32_t id)
+    { assert(data_); *(int32_t*)(data_+8) = id; }
+
+    inline uint32_t getDataSize() const
+    { assert(data_); return *(uint32_t*)(data_+12); }
+    inline void setDataSize(uint32_t size)
+    { assert(data_); *(uint32_t*)(data_+12) = size; }
+
+    inline uint32_t getCompSize() const
+    { assert(data_); return *(uint32_t*)(data_+16); }
+    inline void setCompSize(uint32_t size)
+    { assert(data_); *(uint32_t*)(data_+16) = size; }
+
+    inline bool isDiffed() const
+    { assert(data_); return *(int8_t*)(data_+20) & 0x1; }
+    inline void setDiffed(bool b)
+    { assert(data_); *(int8_t*)(data_+20) = (b<<0) | (*(int8_t*)(data_+20) & 0x6 ); }
+
+    inline bool isComplete() const
+    { assert(data_); return *(int8_t*)(data_+20) & 0x2; }
+    inline void setComplete(bool b)
+    { assert(data_); *(int8_t*)(data_+20) = (b<<1) | (*(int8_t*)(data_+20) & 0x5 ); }
+
+    inline bool isCompressed() const
+    { assert(data_); return *(int8_t*)(data_+20) & 0x4; }
+    inline void setCompressed(bool b)
+    { assert(data_); *(int8_t*)(data_+20) = (b<<2) | (*(int8_t*)(data_+20) & 0x3 ); }
+
+    inline void operator=(GamestateHeader& h)
+    { assert(data_); assert(h.data_); memcpy( data_, h.data_, getSize()); }
+  private:
+    uint8_t *data_;
+
+};
+
+/**
+    @author Oliver Scheuss
+*/
+class _NetworkExport Gamestate: public Packet{
+  public:
+    Gamestate();
+    Gamestate(uint8_t *data, unsigned int clientID);
+    Gamestate(uint8_t *data);
+    Gamestate(const Gamestate& g);
+
+    ~Gamestate();
+
+    bool collectData(int id, uint8_t mode=0x0);
+    bool spreadData( uint8_t mode=0x0);
+    inline int32_t getID() const { return header_->getID(); }
+    inline bool isDiffed() const { return header_->isDiffed(); }
+    inline bool isCompressed() const { return header_->isCompressed(); }
+    inline int32_t getBaseID() const { return header_->getBaseID(); }
+    Gamestate *diff(Gamestate *base);
+    Gamestate *undiff(Gamestate *base);
+    Gamestate* doSelection(unsigned int clientID, unsigned int targetSize);
+    bool compressData();
+    bool decompressData();
+    bool operator ==(packet::Gamestate gs);
+
+    // Packet functions
+  private:
+    void rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength);
+    virtual uint32_t getSize() const;
+    virtual inline bool process();
+
+  private:
+    uint32_t calcGamestateSize(int32_t id, uint8_t mode=0x0);
+    std::list<obj> dataVector_;
+    GamestateHeader* header_;
+};
+
+}
+
+}
+
+#endif /* _Gamestate_H__ */
Index: /code/branches/rocket2/src/libraries/network/packet/Packet.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/Packet.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/Packet.cc	(revision 6952)
@@ -0,0 +1,245 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#include "Packet.h"
+
+#include <cassert>
+#include <cstring>
+#define WIN32_LEAN_AND_MEAN
+#include <enet/enet.h>
+#include <boost/static_assert.hpp>
+
+#include "util/Debug.h"
+#include "Acknowledgement.h"
+#include "Chat.h"
+#include "ClassID.h"
+#include "DeleteObjects.h"
+#include "FunctionCalls.h"
+#include "FunctionIDs.h"
+#include "Gamestate.h"
+#include "Welcome.h"
+#include "network/Host.h"
+#include "network/ClientInformation.h"
+
+namespace orxonox{
+
+namespace packet{
+
+// Make sure we assume the right values
+BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::Reliable)   == static_cast<int>(ENET_PACKET_FLAG_RELIABLE));
+BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::Unsequence) == static_cast<int>(ENET_PACKET_FLAG_UNSEQUENCED));
+BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::NoAllocate) == static_cast<int>(ENET_PACKET_FLAG_NO_ALLOCATE));
+
+#define PACKET_FLAG_DEFAULT PacketFlag::NoAllocate
+#define _PACKETID           0
+
+std::map<size_t, Packet *> Packet::packetMap_;
+
+Packet::Packet(){
+  flags_ = PACKET_FLAG_DEFAULT;
+  packetDirection_ = Direction::Outgoing;
+  clientID_=0;
+  data_=0;
+  enetPacket_=0;
+  bDataENetAllocated_ = false;
+}
+
+void blub(ENetPacket *packet){
+  COUT(4) << "blubb" << std::endl;
+}
+
+Packet::Packet(uint8_t *data, unsigned int clientID){
+  flags_ = PACKET_FLAG_DEFAULT;
+  packetDirection_ = Direction::Incoming;
+  clientID_=clientID;
+  data_=data;
+  enetPacket_=0;
+  bDataENetAllocated_ = false;
+}
+
+
+Packet::Packet(const Packet &p){
+  enetPacket_=p.enetPacket_;
+  flags_=p.flags_;
+  packetDirection_ = p.packetDirection_;
+  clientID_ = p.clientID_;
+  if(p.data_){
+    data_ = new uint8_t[p.getSize()];
+    memcpy(data_, p.data_, p.getSize());
+  }else
+    data_=0;
+  bDataENetAllocated_ = p.bDataENetAllocated_;
+}
+
+/**
+@brief
+    Destroys a packet completely.
+
+    That also means destroying the ENetPacket if one exists. There
+*/
+Packet::~Packet(){
+  // Deallocate data_ memory if necessary.
+  if (this->bDataENetAllocated_){
+    // In this case ENet allocated data_ and will destroy it.
+  }
+  else if (this->data_) {
+    // This destructor was probably called as a consequence of ENet executing our callback.
+    // It simply serves us to be able to deallocate the packet content (data_) ourselves since
+    // we have created it in the first place.
+    delete[] this->data_;
+  }
+
+  // Destroy the ENetPacket if necessary.
+  // Note: For the case ENet used the callback to destroy the packet, we have already set
+  // enetPacket_ to NULL to avoid destroying it again.
+  if (this->enetPacket_){
+    // enetPacket_->data gets destroyed too by ENet if it was allocated by it.
+    enet_packet_destroy(enetPacket_);
+  }
+}
+
+bool Packet::send(){
+  if(packetDirection_ != Direction::Outgoing && packetDirection_ != Direction::Bidirectional ){
+    assert(0);
+    return false;
+  }
+  if(!enetPacket_){
+    if(!data_){
+      assert(0);
+      return false;
+    }
+    // We deliver ENet the data address so that it doesn't memcpy everything again.
+    // --> We have to delete data_ ourselves!
+    enetPacket_ = enet_packet_create(getData(), getSize(), getFlags());
+    enetPacket_->freeCallback = &Packet::deletePacket;
+    // Add the packet to a global list so we can access it again once enet calls our
+    // deletePacket method. We can of course only give a one argument function to the ENet C library.
+    {
+      // Assures we don't create a packet and destroy it right after in another thread
+      // without having a reference in the packetMap_
+      packetMap_[reinterpret_cast<size_t>(enetPacket_)] = this;
+    }
+  }
+#ifndef NDEBUG
+  switch( *(Type::Value *)(data_ + _PACKETID) )
+  {
+    case Type::Acknowledgement:
+    case Type::Chat:
+    case Type::ClassID:
+    case Type::Gamestate:
+    case Type::Welcome:
+    case Type::DeleteObjects:
+    case Type::FunctionIDs:
+    case Type::FunctionCalls:
+      break;
+    default:
+      assert(0); //there was some error, if this is the case
+      break;
+  }
+#endif
+//  ENetPacket *temp = enetPacket_;
+//  enetPacket_ = 0; // otherwise we have a double free because enet already handles the deallocation of the packet
+  if(!Host::addPacket( enetPacket_, clientID_))
+    enet_packet_destroy(this->enetPacket_); // if we could not add the packet to the enet queue delete it manually
+  return true;
+}
+
+Packet *Packet::createPacket(ENetPacket *packet, ENetPeer *peer){
+  uint8_t *data = packet->data;
+  assert(ClientInformation::findClient(&peer->address)->getID() != static_cast<unsigned int>(-2) || !Host::isServer());
+  unsigned int clientID = ClientInformation::findClient(&peer->address)->getID();
+  Packet *p = 0;
+  COUT(6) << "packet type: " << *(Type::Value *)&data[_PACKETID] << std::endl;
+  switch( *(Type::Value *)(data + _PACKETID) )
+  {
+    case Type::Acknowledgement:
+      COUT(5) << "ack" << std::endl;
+      p = new Acknowledgement( data, clientID );
+      break;
+    case Type::Chat:
+      COUT(5) << "chat" << std::endl;
+      p = new Chat( data, clientID );
+      break;
+    case Type::ClassID:
+      COUT(5) << "classid" << std::endl;
+      p = new ClassID( data, clientID );
+      break;
+    case Type::Gamestate:
+      COUT(5) << "gamestate" << std::endl;
+      // TODO: remove brackets
+      p = new Gamestate( data, clientID );
+      break;
+    case Type::Welcome:
+      COUT(5) << "welcome" << std::endl;
+      p = new Welcome( data, clientID );
+      break;
+    case Type::DeleteObjects:
+      COUT(5) << "deleteobjects" << std::endl;
+      p = new DeleteObjects( data, clientID );
+      break;
+    case Type::FunctionCalls:
+      COUT(5) << "functionCalls" << std::endl;
+      p = new FunctionCalls( data, clientID );
+      break;
+    case Type::FunctionIDs:
+      COUT(5) << "functionIDs" << std::endl;
+      p = new FunctionIDs( data, clientID );
+      break;
+    default:
+      assert(0); //TODO: repair this
+      break;
+  }
+
+  // Data was created by ENet
+  p->bDataENetAllocated_ = true;
+  p->enetPacket_ = packet;
+
+  return p;
+}
+
+/**
+@brief
+    ENet calls this method whenever it wants to destroy a packet that contains
+    data we allocated ourselves.
+*/
+void Packet::deletePacket(ENetPacket *enetPacket){
+  // Get our Packet from a global map with all Packets created in the send() method of Packet.
+  std::map<size_t, Packet*>::iterator it = packetMap_.find(reinterpret_cast<size_t>(enetPacket));
+  assert(it != packetMap_.end());
+  // Make sure we don't delete it again in the destructor
+  it->second->enetPacket_ = 0;
+  delete it->second;
+  packetMap_.erase(it);
+  COUT(6) << "PacketMap size: " << packetMap_.size() << std::endl;
+}
+
+} // namespace packet
+
+} // namespace orxonox
+
Index: /code/branches/rocket2/src/libraries/network/packet/Packet.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/Packet.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/Packet.h	(revision 6952)
@@ -0,0 +1,105 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+#ifndef _NETWORK_Packet_H__
+#define _NETWORK_Packet_H__
+
+#include "network/NetworkPrereqs.h"
+#include <map>
+
+namespace orxonox {
+
+namespace packet{
+
+namespace Direction{
+  enum Value{
+    Incoming,
+    Outgoing,
+    Bidirectional
+  };
+}
+namespace Type{
+  enum Value{
+    Acknowledgement,
+    Chat,
+    ClassID,
+    DeleteObjects,
+    FunctionIDs,
+    FunctionCalls,
+    Gamestate,
+    Welcome
+  };
+}
+
+/**
+    @author Oliver Scheuss <scheusso [at] ee.ethz.ch>
+*/
+class _NetworkExport Packet{
+  public:
+    Packet(const Packet &p);
+    virtual ~Packet();
+    static Packet *createPacket(ENetPacket *packet, ENetPeer *peer);
+    static void deletePacket(ENetPacket *packet);
+
+    virtual unsigned char *getData(){ return data_; };
+    virtual unsigned int getSize() const =0;
+    virtual bool process()=0;
+    inline uint32_t getFlags()
+      { return flags_; }
+    inline int getClientID()
+      { return clientID_; }
+    inline void setClientID( int id )
+      { clientID_ = id; }
+
+    bool send();
+  protected:
+    Packet();
+    Packet(uint8_t *data, unsigned int clientID);
+//    Packet(ENetPacket *packet, ENetPeer *peer);
+    inline bool isDataENetAllocated() const
+      { return bDataENetAllocated_; }
+
+    uint32_t flags_;
+    unsigned int clientID_;
+    Direction::Value packetDirection_;
+    /** Pointer to the data. Be careful when deleting it because it might
+        point to a location that was allocated by ENet.
+        See bDataENetAllocated_ */
+    uint8_t *data_;
+    /** Tells whether data_ was allocated by ENet or ourselves.
+        data_ might no correlate with enetPacket_->data. */
+    bool bDataENetAllocated_;
+  private:
+    static std::map<size_t, Packet *> packetMap_;
+    ENetPacket *enetPacket_;
+};
+
+} //namespace packet
+
+} //namespace orxonox
+
+#endif /* _NETWORK_Packet_H__ */
Index: /code/branches/rocket2/src/libraries/network/packet/Welcome.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/Welcome.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/Welcome.cc	(revision 6952)
@@ -0,0 +1,88 @@
+
+
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Welcome.h"
+
+#include <cassert>
+#include "util/Debug.h"
+#include "network/Host.h"
+#include "network/synchronisable/Synchronisable.h"
+
+namespace orxonox {
+namespace packet {
+
+#define PACKET_FLAGS_CLASSID  PacketFlag::Reliable
+#define _PACKETID             0
+#define _CLIENTID             _PACKETID + sizeof(Type::Value)
+#define _ENDIANTEST           _CLIENTID + sizeof(uint32_t)
+
+  Welcome::Welcome( uint32_t clientID, uint32_t shipID )
+ : Packet()
+{
+  flags_ = flags_ | PACKET_FLAGS_CLASSID;
+  assert(getSize());
+  data_=new uint8_t[ getSize() ];
+  assert(data_);
+  *(packet::Type::Value *)(data_ + _PACKETID ) = packet::Type::Welcome;
+  *(uint32_t *)(data_ + _CLIENTID ) = static_cast<uint32_t>(clientID);
+  *(uint32_t *)(data_ + _ENDIANTEST ) = 0xFEDC4321;
+}
+
+Welcome::Welcome( uint8_t* data, uint32_t clientID )
+  : Packet(data, clientID)
+{
+}
+
+Welcome::~Welcome()
+{
+}
+
+uint8_t *Welcome::getData(){
+  return data_;
+}
+
+unsigned int Welcome::getSize() const{
+  return sizeof(packet::Type::Value) + 2*sizeof(uint32_t);
+}
+
+bool Welcome::process(){
+  uint32_t clientID;
+  clientID = *(uint32_t *)(data_ + _CLIENTID );
+  assert(*(uint32_t *)(data_ + _ENDIANTEST ) == 0xFEDC4321);
+  Host::setClientID(clientID);
+  COUT(3) << "Welcome set clientId: " << clientID << endl;
+  Synchronisable::setClient(true);
+  delete this;
+  return true;
+}
+
+
+} //namespace packet
+}//namespace orxonox
Index: /code/branches/rocket2/src/libraries/network/packet/Welcome.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/packet/Welcome.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/packet/Welcome.h	(revision 6952)
@@ -0,0 +1,57 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss <scheusso [at] ee.ethz.ch>, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+#ifndef _NETWORK_Welcome_H__
+#define _NETWORK_Welcome_H__
+
+#include "network/NetworkPrereqs.h"
+#include "Packet.h"
+
+namespace orxonox {
+namespace packet {
+
+/**
+    @author
+*/
+class _NetworkExport Welcome : public Packet
+{
+public:
+  Welcome( uint32_t clientID, uint32_t shipID );
+  Welcome( uint8_t* data, uint32_t clientID );
+  virtual ~Welcome();
+
+  uint8_t *getData();
+  inline unsigned int getSize() const;
+  bool process();
+
+private:
+};
+
+} //namespace packet
+} //namespace orxonox
+
+#endif /* _NETWORK_Welcome_H__ */
Index: /code/branches/rocket2/src/libraries/network/synchronisable/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/libraries/network/synchronisable/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/synchronisable/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,12 @@
+ADD_SOURCE_FILES(NETWORK_SRC_FILES
+  NetworkCallbackManager.cc
+  Synchronisable.cc
+  SynchronisableVariable.cc
+)
+
+ADD_SOURCE_FILES(NETWORK_HDR_FILES
+  NetworkCallback.h
+  NetworkCallbackManager.h
+  Synchronisable.h
+  SynchronisableVariable.h
+)
Index: /code/branches/rocket2/src/libraries/network/synchronisable/NetworkCallback.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/synchronisable/NetworkCallback.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/synchronisable/NetworkCallback.h	(revision 6952)
@@ -0,0 +1,82 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#ifndef _NetworkCallback_H__
+#define _NetworkCallback_H__
+
+#include "network/NetworkPrereqs.h"
+#include "NetworkCallbackManager.h"
+// #include "util/MultiType.h"
+
+namespace orxonox{
+
+  struct EmptyType{};
+
+  class _NetworkExport NetworkCallbackBase
+  {
+    public:
+      virtual void call() = 0;
+      NetworkCallbackBase(){ NetworkCallbackManager::registerCallback( this ); }
+      virtual ~NetworkCallbackBase() {}
+  };
+
+  template <class T>
+  class NetworkCallback: public NetworkCallbackBase
+  {
+    public:
+      NetworkCallback(T* object, void (T::*function) (void)) : object_(object), function_(function) {}
+      virtual ~NetworkCallback() {}
+      virtual void call()
+        { (this->object_->*function_)(); }
+
+    private:
+      T* object_;
+      void (T::*function_) (void);
+  };
+
+  template <class T, class U>
+  class NetworkCallbackNotify: public NetworkCallbackBase
+  {
+    public:
+      NetworkCallbackNotify(T* object, void (T::*function) (const U&)) : object_(object), function_(function) {}
+      NetworkCallbackNotify() {}
+      virtual ~NetworkCallbackNotify() {}
+      virtual void call()
+        { (this->object_->*function_)( this->oldValue_ ); }
+      void setOldValue(const U& value){ this->oldValue_ = value; }
+    private:
+      T* object_;
+      U oldValue_;
+      void (T::*function_) (const U&);
+  };
+
+}
+
+
+#endif /* _NetworkCallback_H__ */
Index: /code/branches/rocket2/src/libraries/network/synchronisable/NetworkCallbackManager.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/synchronisable/NetworkCallbackManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/synchronisable/NetworkCallbackManager.cc	(revision 6952)
@@ -0,0 +1,67 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "NetworkCallbackManager.h"
+#include "NetworkCallback.h"
+
+namespace orxonox{
+
+  std::set<NetworkCallbackBase*> NetworkCallbackManager::callbackSet_;
+  std::queue<NetworkCallbackBase*> NetworkCallbackManager::triggeredCallbacks_;
+
+  void NetworkCallbackManager::registerCallback(NetworkCallbackBase *cb)
+  {
+    callbackSet_.insert(cb);
+  }
+  void NetworkCallbackManager::deleteCallback(NetworkCallbackBase *cb)
+  {
+    std::set<NetworkCallbackBase*>::iterator it = callbackSet_.find(cb);
+    if (it != callbackSet_.end())
+    {
+      callbackSet_.erase(it);
+      delete cb;
+    }
+  }
+
+  void NetworkCallbackManager::triggerCallback(NetworkCallbackBase *cb)
+  {
+    if (triggeredCallbacks_.empty() || triggeredCallbacks_.front() != cb)
+      triggeredCallbacks_.push(cb);
+  }
+
+  void NetworkCallbackManager::callCallbacks()
+  {
+    while( triggeredCallbacks_.empty()==false )
+    {
+      //make sure callback hasn't been deleted before
+      if ( callbackSet_.find(triggeredCallbacks_.front()) != callbackSet_.end() )
+        triggeredCallbacks_.front()->call();
+      triggeredCallbacks_.pop();
+    }
+  }
+}
Index: /code/branches/rocket2/src/libraries/network/synchronisable/NetworkCallbackManager.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/synchronisable/NetworkCallbackManager.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/synchronisable/NetworkCallbackManager.h	(revision 6952)
@@ -0,0 +1,55 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss, (C) 2008
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#ifndef _NetworkCallbackManager_H__
+#define _NetworkCallbackManager_H__
+
+#include "network/NetworkPrereqs.h"
+
+#include <set>
+#include <queue>
+
+namespace orxonox{
+
+  class _NetworkExport NetworkCallbackManager{
+    public:
+      static void registerCallback(NetworkCallbackBase *cb);
+      static void deleteCallback(NetworkCallbackBase *cb);
+      static void triggerCallback(NetworkCallbackBase *cb);
+      static void callCallbacks();
+    private:
+      static std::set<NetworkCallbackBase*> callbackSet_;
+      static std::queue<NetworkCallbackBase*> triggeredCallbacks_;
+  };
+
+
+}
+
+
+#endif /* _NetworkCallbackManager_H__ */
Index: /code/branches/rocket2/src/libraries/network/synchronisable/Serialise.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/synchronisable/Serialise.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/synchronisable/Serialise.h	(revision 6952)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Functions to serialise pointers to objects that inherit from Synchronisable
+*/
+
+#ifndef _NetworkSerialise_H__
+#define _NetworkSerialise_H__
+
+#include "util/Serialise.h"
+#include "util/TypeTraits.h"
+#include "core/CorePrereqs.h"
+
+namespace orxonox{
+    
+    // These functions implement loading / saving / etc. for pointer types
+    
+    /** @brief returns the size of the objectID needed to synchronise the pointer */
+    template <class T> inline uint32_t returnSize( T*& variable )
+    {
+      return sizeof(uint32_t);
+    }
+    
+    /** @brief reads the objectID of a pointer out of the bytestream and increases the mem pointer */
+    template <class T> inline void loadAndIncrease( T*& variable, uint8_t*& mem )
+    {
+        *const_cast<typename Loki::TypeTraits<T*>::UnqualifiedType*>(&variable) = dynamic_cast<T*>(variable->getSynchronisable( *(uint32_t*)(mem) ));
+        mem += returnSize( variable );
+    }
+    
+    /** @brief saves the objectID of a pointer into the bytestream and increases the mem pointer */
+    template <class T> inline void saveAndIncrease( T*& variable, uint8_t*& mem )
+    {
+        if ( variable )
+            *(uint32_t*)(mem) = static_cast<uint32_t>(variable->getObjectID());
+        else
+            *(uint32_t*)(mem) = OBJECTID_UNKNOWN;
+        mem += returnSize( variable );
+    }
+    
+    /** @brief checks whether the objectID of the variable is the same as in the bytestream */
+    template <class T> inline  bool checkEquality( T*& variable, uint8_t* mem )
+    {
+        if ( variable )
+            return *(uint32_t*)(mem) == variable->getObjectID();
+        else
+            return *(uint32_t*)(mem) == OBJECTID_UNKNOWN;
+    }
+}
+
+
+#endif
Index: /code/branches/rocket2/src/libraries/network/synchronisable/Synchronisable.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/synchronisable/Synchronisable.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/synchronisable/Synchronisable.cc	(revision 6952)
@@ -0,0 +1,404 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Dumeni Manatschal, (C) 2007
+ *      Oliver Scheuss, (C) 2007
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#include "Synchronisable.h"
+
+#include <cstdlib>
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/BaseObject.h"
+#include "network/Host.h"
+
+namespace orxonox
+{
+
+  std::map<uint32_t, Synchronisable *> Synchronisable::objectMap_;
+  std::queue<uint32_t> Synchronisable::deletedObjects_;
+
+  uint8_t Synchronisable::state_=0x1; // detemines wheter we are server (default) or client
+
+  /**
+  * Constructor:
+  * Initializes all Variables and sets the right objectID_
+  */
+  Synchronisable::Synchronisable(BaseObject* creator ){
+    RegisterRootObject(Synchronisable);
+    static uint32_t idCounter=0;
+    objectMode_=0x1; // by default do not send data to server
+    if ( GameMode::isMaster() || ( Host::running() && Host::isServer() ) )
+    {
+      this->setObjectID( idCounter++ );
+    }
+    else
+    {
+      objectID_=OBJECTID_UNKNOWN;
+    }
+    classID_ = static_cast<uint32_t>(-1);
+
+    // set dataSize to 0
+    this->dataSize_ = 0;
+    // set standard priority
+    this->setPriority( Priority::Normal );
+
+    // get creator id
+    if( creator )
+      this->creatorID_ = creator->getSceneID();
+    else
+      this->creatorID_ = OBJECTID_UNKNOWN;
+
+    /*searchcreatorID:
+    if (creator)
+    {
+        Synchronisable* synchronisable_creator = orxonox_cast<Synchronisable*>(creator);
+        if (synchronisable_creator && synchronisable_creator->objectMode_)
+        {
+            this->creatorID = synchronisable_creator->getScene()->getObjectID();
+        }
+        else if (creator != creator->getCreator())
+        {
+            creator = creator->getCreator();
+            goto searchcreatorID;
+        }
+    }*/
+  }
+
+  /**
+   * Destructor:
+   * Delete all callback objects and remove objectID_ from the objectMap_
+   */
+  Synchronisable::~Synchronisable(){
+    // delete callback function objects
+    if(!Identifier::isCreatingHierarchy()){
+      // remove object from the static objectMap
+      if (this->objectMode_ != 0x0 && (Host::running() && Host::isServer()))
+        deletedObjects_.push(objectID_);
+    }
+    // delete all Synchronisable Variables from syncList ( which are also in stringList )
+    for(std::vector<SynchronisableVariableBase*>::iterator it = syncList.begin(); it!=syncList.end(); it++)
+      delete (*it);
+    syncList.clear();
+    stringList.clear();
+    std::map<uint32_t, Synchronisable*>::iterator it;
+    it = objectMap_.find(objectID_);
+    if (it != objectMap_.end())
+      objectMap_.erase(it);
+
+  }
+
+
+  /**
+   * This function sets the internal mode for synchronisation
+   * @param b true if this object is located on a client or on a server
+   */
+  void Synchronisable::setClient(bool b){
+    if(b) // client
+      state_=0x2;
+    else  // server
+      state_=0x1;
+  }
+
+  /**
+   * This function fabricated a new synchrnisable (and children of it), sets calls updateData and create
+   * After calling this function the mem pointer will be increased by the size of the needed data
+   * @param mem pointer to where the appropriate data is located
+   * @param mode defines the mode, how the data should be loaded
+   * @return pointer to the newly created synchronisable
+   */
+  Synchronisable *Synchronisable::fabricate(uint8_t*& mem, uint8_t mode)
+  {
+    SynchronisableHeader header(mem);
+
+    if(!header.isDataAvailable())
+    {
+      mem += header.getDataSize();
+      return 0;
+    }
+
+    COUT(4) << "fabricating object with id: " << header.getObjectID() << std::endl;
+
+    Identifier* id = ClassByID(header.getClassID());
+    if (!id)
+    {
+        for(int i = 0; i<160; i++)
+            COUT(0) << "classid: " << i << " identifier: " << ClassByID(i) << endl;
+        COUT(0) << "Assertion failed: id" << std::endl;
+        COUT(0) << "Possible reason for this error: Client received a synchronizable object whose class has no factory." << std::endl;
+        abort();
+    }
+    assert(id);
+    BaseObject* creator = 0;
+    if (header.getCreatorID() != OBJECTID_UNKNOWN)
+    {
+      Synchronisable* synchronisable_creator = Synchronisable::getSynchronisable(header.getCreatorID());
+      if (!synchronisable_creator)
+      {
+        mem += header.getDataSize(); //.TODO: this suckz.... remove size from header
+        assert(0); // TODO: uncomment this if we have a clean objecthierarchy (with destruction of children of objects) ^^
+        return 0;
+      }
+      else
+        creator = orxonox_cast<BaseObject*>(synchronisable_creator);
+    }
+    assert(getSynchronisable(header.getObjectID())==0);   //make sure no object with this id exists
+    BaseObject *bo = id->fabricate(creator);
+    assert(bo);
+    Synchronisable *no = orxonox_cast<Synchronisable*>(bo);
+    assert(no);
+    assert( Synchronisable::objectMap_.find(header.getObjectID()) == Synchronisable::objectMap_.end() );
+    no->setObjectID(header.getObjectID());
+    //no->creatorID=header.getCreatorID(); //TODO: remove this
+    no->setClassID(header.getClassID());
+    assert(no->creatorID_ == header.getCreatorID());
+    //assert(no->classID_ == header.getClassID());
+    COUT(4) << "fabricate objectID_: " << no->objectID_ << " classID_: " << no->classID_ << std::endl;
+          // update data and create object/entity...
+    bool b = no->updateData(mem, mode, true);
+    assert(b);
+    if (b)
+    {
+//        b = no->create();
+        assert(b);
+    }
+    return no;
+  }
+
+
+  /**
+   * Finds and deletes the Synchronisable with the appropriate objectID_
+   * @param objectID_ objectID_ of the Synchronisable
+   * @return true/false
+   */
+  bool Synchronisable::deleteObject(uint32_t objectID_){
+    if(!getSynchronisable(objectID_))
+      return false;
+    assert(getSynchronisable(objectID_)->objectID_==objectID_);
+    Synchronisable *s = getSynchronisable(objectID_);
+    if(s)
+      s->destroy(); // or delete?
+    else
+      return false;
+    return true;
+  }
+
+  /**
+   * This function looks up the objectID_ in the objectMap_ and returns a pointer to the right Synchronisable
+   * @param objectID_ objectID_ of the Synchronisable
+   * @return pointer to the Synchronisable with the objectID_
+   */
+  Synchronisable* Synchronisable::getSynchronisable(uint32_t objectID_){
+    std::map<uint32_t, Synchronisable*>::iterator it1;
+    it1 = objectMap_.find(objectID_);
+    if (it1 != objectMap_.end())
+      return it1->second;
+
+//     ObjectList<Synchronisable>::iterator it;
+//     for(it = ObjectList<Synchronisable>::begin(); it; ++it){
+//       if( it->getObjectID()==objectID_ ){
+//         objectMap_[objectID_] = *it;
+//         return *it;
+//       }
+//     }
+    // if the objects not in the map it should'nt exist at all anymore
+    return NULL;
+  }
+
+
+  /**
+   * This function takes all SynchronisableVariables out of the Synchronisable and saves them together with the size, objectID_ and classID_ to the given memory
+   * takes a pointer to already allocated memory (must have at least getSize bytes length)
+   * structure of the bitstream:
+   * |totalsize,objectID_,classID_,var1,var2,string1_length,string1,var3,...|
+   * length of varx: size saved int syncvarlist
+   * @param mem pointer to allocated memory with enough size
+   * @param id gamestateid of the gamestate to be saved (important for priorities)
+   * @param mode defines the direction in which the data will be send/received
+   *             0x1: server->client
+   *             0x2: client->server (not recommended)
+   *             0x3: bidirectional
+   * @return true: if !doSync or if everything was successfully saved
+   */
+  uint32_t Synchronisable::getData(uint8_t*& mem, int32_t id, uint8_t mode){
+    if(mode==0x0)
+      mode=state_;
+    //if this tick is we dont synchronise, then abort now
+    if(!doSync(id, mode))
+      return 0;
+    uint32_t tempsize = 0;
+#ifndef NDEBUG
+    if (this->classID_==0)
+      COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl;
+#endif
+
+    if (this->classID_ == static_cast<uint32_t>(-1))
+        this->classID_ = this->getIdentifier()->getNetworkID();
+
+    assert(ClassByID(this->classID_));
+    assert(this->classID_==this->getIdentifier()->getNetworkID());
+    assert(this->objectID_!=OBJECTID_UNKNOWN);
+    std::vector<SynchronisableVariableBase*>::iterator i;
+
+    // start copy header
+    SynchronisableHeader header(mem);
+    mem += SynchronisableHeader::getSize();
+    // end copy header
+
+
+    COUT(5) << "Synchronisable getting data from objectID_: " << objectID_ << " classID_: " << classID_ << std::endl;
+    // copy to location
+    for(i=syncList.begin(); i!=syncList.end(); ++i){
+      tempsize += (*i)->getData( mem, mode );
+      //tempsize += (*i)->getSize( mode );
+    }
+
+    tempsize += SynchronisableHeader::getSize();
+    header.setObjectID( this->objectID_ );
+    header.setCreatorID( this->creatorID_ );
+    header.setClassID( this->classID_ );
+    header.setDataAvailable( true );
+    header.setDataSize( tempsize );
+
+#ifndef NDEBUG
+    uint32_t size;
+    size=getSize(id, mode);
+    assert(tempsize==size);
+#endif
+    return tempsize;
+  }
+
+
+  /**
+   * This function takes a bytestream and loads the data into the registered variables
+   * @param mem pointer to the bytestream
+   * @param mode same as in getData
+   * @return true/false
+   */
+  bool Synchronisable::updateData(uint8_t*& mem, uint8_t mode, bool forceCallback){
+    if(mode==0x0)
+      mode=state_;
+    std::vector<SynchronisableVariableBase *>::iterator i;
+    if(syncList.empty()){
+      assert(0);
+      COUT(4) << "Synchronisable::updateData syncList is empty" << std::endl;
+      return false;
+    }
+
+    uint8_t* data=mem;
+    // start extract header
+    SynchronisableHeader syncHeader(mem);
+    assert(syncHeader.getObjectID()==this->objectID_);
+    assert(syncHeader.getCreatorID()==this->creatorID_);
+    assert(syncHeader.getClassID()==this->classID_);
+    if(syncHeader.isDataAvailable()==false){
+      mem += syncHeader.getDataSize();
+      return true;
+    }
+
+    mem += SynchronisableHeader::getSize();
+    // stop extract header
+
+    //COUT(5) << "Synchronisable: objectID_ " << syncHeader.getObjectID() << ", classID_ " << syncHeader.getClassID() << " size: " << syncHeader.getDataSize() << " synchronising data" << std::endl;
+    for(i=syncList.begin(); i!=syncList.end(); i++)
+    {
+      assert( mem <= data+syncHeader.getDataSize() ); // always make sure we don't exceed the datasize in our stream
+      (*i)->putData( mem, mode, forceCallback );
+    }
+    assert(mem == data+syncHeader.getDataSize());
+    return true;
+  }
+
+  /**
+  * This function returns the total amount of bytes needed by getData to save the whole content of the variables
+  * @param id id of the gamestate
+  * @param mode same as getData
+  * @return amount of bytes
+  */
+  uint32_t Synchronisable::getSize(int32_t id, uint8_t mode){
+    int tsize=SynchronisableHeader::getSize();
+    if (mode==0x0)
+      mode=state_;
+    if (!doSync(id, mode))
+      return 0;
+    assert( mode==state_ );
+    tsize += this->dataSize_;
+    std::vector<SynchronisableVariableBase*>::iterator i;
+    for(i=stringList.begin(); i!=stringList.end(); ++i){
+      tsize += (*i)->getSize( mode );
+    }
+    return tsize;
+  }
+
+  /**
+   * This function determines, wheter the object should be saved to the bytestream (according to its syncmode/direction)
+   * @param id gamestate id
+   * @return true/false
+   */
+  bool Synchronisable::doSync(int32_t id, uint8_t mode){
+    if(mode==0x0)
+      mode=state_;
+    return ( (this->objectMode_ & mode)!=0 && (!syncList.empty() ) );
+  }
+
+  /**
+   * This function looks at the header located in the bytestream and checks wheter objectID_ and classID_ match with the Synchronisables ones
+   * @param mem pointer to the bytestream
+   */
+  bool Synchronisable::isMyData(uint8_t* mem)
+  {
+    SynchronisableHeader header(mem);
+    assert(header.getObjectID()==this->objectID_);
+    return header.isDataAvailable();
+  }
+
+  /**
+   * This function sets the synchronisation mode of the object
+   * If set to 0x0 variables will not be synchronised at all
+   * If set to 0x1 variables will only be synchronised to the client
+   * If set to 0x2 variables will only be synchronised to the server
+   * If set to 0x3 variables will be synchronised bidirectionally (only if set so in registerVar)
+   * @param mode same as in registerVar
+   */
+  void Synchronisable::setSyncMode(uint8_t mode){
+    assert(mode==0x0 || mode==0x1 || mode==0x2 || mode==0x3);
+    this->objectMode_=mode;
+  }
+
+  template <> void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
+  {
+    SynchronisableVariableBase* sv;
+    if (bidirectional)
+      sv = new SynchronisableVariableBidirectional<std::string>(variable, mode, cb);
+    else
+      sv = new SynchronisableVariable<std::string>(variable, mode, cb);
+    syncList.push_back(sv);
+    stringList.push_back(sv);
+  }
+
+
+}
Index: /code/branches/rocket2/src/libraries/network/synchronisable/Synchronisable.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/synchronisable/Synchronisable.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/synchronisable/Synchronisable.h	(revision 6952)
@@ -0,0 +1,189 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss, (C) 2007
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Synchronisable_H__
+#define _Synchronisable_H__
+
+#include "network/NetworkPrereqs.h"
+
+#include <cassert>
+#include <cstring>
+#include <vector>
+#include <map>
+#include <queue>
+
+#include "util/mbool.h"
+#include "core/OrxonoxClass.h"
+#include "SynchronisableVariable.h"
+#include "NetworkCallback.h"
+
+
+namespace orxonox
+{
+
+  namespace ObjectDirection{
+    enum Value{
+      ToClient=0x1,
+      ToServer=0x2,
+      Bidirectional=0x3
+    };
+  }
+
+  namespace Priority{
+    enum Value{
+      VeryHigh    = -100,
+      High        = -15,
+      Normal      = 0,
+      Low         = 15,
+      VeryLow     = 100
+    };
+  }
+
+  /**
+   * @brief: stores information about a Synchronisable
+   *
+   * This class stores the information about a Synchronisable (objectID_, classID_, creatorID_, dataSize)
+   * in an emulated bitset.
+   * Bit 1 to 31 store the size of the Data the synchronisable consumes in the stream
+   * Bit 32 is a bool and defines whether the data is actually stored or is just filled up with 0
+   * Byte 5 to 8: objectID_
+   * Byte 9 to 12: classID_
+   * Byte 13 to 16: creatorID_
+   */
+  class _NetworkExport SynchronisableHeader{
+    private:
+      uint8_t *data_;
+    public:
+      SynchronisableHeader(uint8_t* data)
+        { data_ = data; }
+      inline static uint32_t getSize()
+        { return 16; }
+      inline uint32_t getDataSize() const
+        { return (*(uint32_t*)data_) & 0x7FFFFFFF; } //only use the first 31 bits
+      inline void setDataSize(uint32_t size)
+        { *(uint32_t*)(data_) = (size & 0x7FFFFFFF) | (*(uint32_t*)(data_) & 0x80000000 ); }
+      inline bool isDataAvailable() const
+        { return ( (*(uint32_t*)data_) & 0x80000000 ) == 0x80000000; }
+      inline void setDataAvailable( bool b)
+        { *(uint32_t*)(data_) = (b << 31) | (*(uint32_t*)(data_) & 0x7FFFFFFF ); }
+      inline uint32_t getObjectID() const
+        { return *(uint32_t*)(data_+4); }
+      inline void setObjectID(uint32_t objectID_)
+        { *(uint32_t*)(data_+4) = objectID_; }
+      inline uint32_t getClassID() const
+        { return *(uint32_t*)(data_+8); }
+      inline void setClassID(uint32_t classID_)
+        { *(uint32_t*)(data_+8) = classID_; }
+      inline uint32_t getCreatorID() const
+        { return *(uint32_t*)(data_+12); }
+      inline void setCreatorID(uint32_t creatorID_)
+        { *(uint32_t*)(data_+12) = creatorID_; }
+      inline void operator=(SynchronisableHeader& h)
+        { memcpy(data_, h.data_, getSize()); }
+  };
+
+
+  /**
+  * This class is the base class of all the Objects in the universe that need to be synchronised over the network
+  * Every class, that inherits from this class has to link the DATA THAT NEEDS TO BE SYNCHRONISED into the linked list.
+  * @author Oliver Scheuss
+  */
+  class _NetworkExport Synchronisable : virtual public OrxonoxClass{
+  public:
+    friend class packet::Gamestate;
+    virtual ~Synchronisable();
+
+    static void setClient(bool b);
+
+    static Synchronisable *fabricate(uint8_t*& mem, uint8_t mode=0x0);
+    static bool deleteObject(uint32_t objectID_);
+    static Synchronisable *getSynchronisable(uint32_t objectID_);
+    static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
+    static uint32_t popDeletedObject(){ uint32_t i = deletedObjects_.front(); deletedObjects_.pop(); return i; }
+
+    inline uint32_t getObjectID() const {return this->objectID_;}
+    inline unsigned int getCreatorID() const {return this->creatorID_;}
+    inline uint32_t getClassID() const {return this->classID_;}
+    inline unsigned int getPriority() const { return this->objectFrequency_;}
+    inline uint8_t getSyncMode() const { return this->objectMode_; }
+
+    void setSyncMode(uint8_t mode);
+
+  protected:
+    Synchronisable(BaseObject* creator);
+    template <class T> void registerVariable(T& variable, uint8_t mode=0x1, NetworkCallbackBase *cb=0, bool bidirectional=false);
+
+    void setPriority(unsigned int freq){ objectFrequency_ = freq; }
+
+
+  private:
+    uint32_t getData(uint8_t*& men, int32_t id, uint8_t mode=0x0);
+    uint32_t getSize(int32_t id, uint8_t mode=0x0);
+    bool updateData(uint8_t*& mem, uint8_t mode=0x0, bool forceCallback=false);
+    bool isMyData(uint8_t* mem);
+    bool doSync(int32_t id, uint8_t mode=0x0);
+
+    inline void setObjectID(uint32_t id){ this->objectID_ = id; objectMap_[this->objectID_] = this; }
+    inline void setClassID(uint32_t id){ this->classID_ = id; }
+
+    uint32_t objectID_;
+    uint32_t creatorID_;
+    uint32_t classID_;
+
+    std::vector<SynchronisableVariableBase*> syncList;
+    std::vector<SynchronisableVariableBase*> stringList;
+    uint32_t dataSize_; //size of all variables except strings
+    static uint8_t state_; // detemines wheter we are server (default) or client
+    bool backsync_; // if true the variables with mode > 1 will be synchronised to server (client -> server)
+    unsigned int objectFrequency_;
+    int objectMode_;
+    static std::map<uint32_t, Synchronisable *> objectMap_;
+    static std::queue<uint32_t> deletedObjects_;
+  };
+
+  template <class T> void Synchronisable::registerVariable(T& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional)
+  {
+    if (bidirectional)
+    {
+      syncList.push_back(new SynchronisableVariableBidirectional<T>(variable, mode, cb));
+      this->dataSize_ += syncList.back()->getSize(state_);
+    }
+    else
+    {
+      syncList.push_back(new SynchronisableVariable<T>(variable, mode, cb));
+      if ( this->state_ == mode )
+        this->dataSize_ += syncList.back()->getSize(state_);
+    }
+  }
+
+  template <> _NetworkExport void Synchronisable::registerVariable( std::string& variable, uint8_t mode, NetworkCallbackBase *cb, bool bidirectional);
+
+
+}
+
+#endif /* _Synchronisable_H__ */
Index: /code/branches/rocket2/src/libraries/network/synchronisable/SynchronisableVariable.cc
===================================================================
--- /code/branches/rocket2/src/libraries/network/synchronisable/SynchronisableVariable.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/synchronisable/SynchronisableVariable.cc	(revision 6952)
@@ -0,0 +1,36 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "SynchronisableVariable.h"
+
+namespace orxonox{
+
+uint8_t SynchronisableVariableBase::state_ = 0;
+
+
+} //namespace
Index: /code/branches/rocket2/src/libraries/network/synchronisable/SynchronisableVariable.h
===================================================================
--- /code/branches/rocket2/src/libraries/network/synchronisable/SynchronisableVariable.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/network/synchronisable/SynchronisableVariable.h	(revision 6952)
@@ -0,0 +1,260 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#ifndef _SynchronisableVariable_H__
+#define _SynchronisableVariable_H__
+
+#include "network/NetworkPrereqs.h"
+
+#include <cassert>
+#include <cstring>
+#include "Serialise.h"
+#include "util/TypeTraits.h"
+#include "core/GameMode.h"
+#include "network/synchronisable/NetworkCallbackManager.h"
+
+namespace orxonox{
+
+  namespace VariableDirection{
+    enum Value{
+      ToClient=0x1,
+      ToServer=0x2
+    };
+  }
+  namespace Bidirectionality{
+    enum Value{
+      ServerMaster=0x1,
+      ClientMaster=0x2
+    };
+  }
+
+  class _NetworkExport SynchronisableVariableBase
+  {
+    public:
+      virtual uint32_t getData(uint8_t*& mem, uint8_t mode)=0;
+      virtual void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false)=0;
+      virtual uint32_t getSize(uint8_t mode)=0;
+      virtual void* getReference()=0;
+      virtual uint8_t getMode()=0;
+      virtual ~SynchronisableVariableBase() {}
+    protected:
+      static uint8_t state_;
+  };
+
+  template <class T>
+  class SynchronisableVariable: public SynchronisableVariableBase
+  {
+    public:
+      SynchronisableVariable(T& variable, uint8_t syncDirection=VariableDirection::ToClient, NetworkCallbackBase *cb=0);
+      virtual ~SynchronisableVariable();
+
+      virtual inline uint8_t getMode(){ return mode_; }
+      virtual inline uint32_t getData(uint8_t*& mem, uint8_t mode);
+      virtual inline void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false);
+      virtual inline uint32_t getSize(uint8_t mode);
+      virtual inline void* getReference(){ return static_cast<void*>(const_cast<typename Loki::TypeTraits<T>::UnqualifiedType*>(&this->variable_)); }
+    protected:
+      T&                       variable_;
+      uint8_t                  mode_;
+      NetworkCallbackBase      *callback_;
+  };
+
+  template <class T>
+  class SynchronisableVariableBidirectional: public SynchronisableVariable<T>
+  {
+    public:
+      SynchronisableVariableBidirectional(T& variable, uint8_t master=Bidirectionality::ServerMaster, NetworkCallbackBase *cb=0);
+      virtual ~SynchronisableVariableBidirectional();
+
+      virtual inline uint8_t getMode(){ return 0x3; } //this basically is a hack ^^
+      virtual inline uint32_t getData(uint8_t*& mem, uint8_t mode);
+      virtual void putData(uint8_t*& mem, uint8_t mode, bool forceCallback = false);
+      virtual inline uint32_t getSize(uint8_t mode);
+    private:
+      T varBuffer_;
+      uint8_t varReference_;
+  };
+
+  // ================= Unidirectional Part ===============
+
+  template <class T> SynchronisableVariable<T>::SynchronisableVariable(T& variable, uint8_t syncDirection, NetworkCallbackBase *cb):
+      variable_( variable ), mode_( syncDirection ), callback_( cb )
+  {
+    if ( state_ == 0x0 )
+    {
+      state_ = GameMode::isMaster() ? 0x1 : 0x2;  // set the appropriate mode here
+    }
+  }
+
+  template <class T> SynchronisableVariable<T>::~SynchronisableVariable()
+  {
+    if (this->callback_)
+    {
+      NetworkCallbackManager::deleteCallback(this->callback_); //safe call for deletion
+      // this is neccessary because for example for a Vector3 all 3 components of the vector use the same callback
+    }
+  }
+
+  template <class T> inline uint32_t SynchronisableVariable<T>::getData(uint8_t*& mem, uint8_t mode)
+  {
+    if ( mode == this->mode_ )
+    {
+      saveAndIncrease( this->variable_, mem );
+      return returnSize( this->variable_ );
+    }
+    else
+      return 0;
+  }
+
+  template <class T> void SynchronisableVariable<T>::putData(uint8_t*& mem, uint8_t mode, bool forceCallback)
+  {
+    assert ( mode == 0x1 || mode == 0x2 );
+    bool callback = false;
+    if ( mode == this->mode_ ) //don't do anything
+      return;
+  // check whether we need to consider a callback
+    if ( this->callback_ )
+    {
+      callback = forceCallback || !checkEquality( this->variable_, mem );
+    }
+  // now do a callback if neccessary
+    if ( callback )
+    {
+      NetworkCallbackManager::triggerCallback( this->callback_ );
+    }
+  // write the data
+    loadAndIncrease( this->variable_, mem );
+  }
+
+  template <class T> inline uint32_t SynchronisableVariable<T>::getSize(uint8_t mode)
+  {
+    if ( mode == this->mode_ )
+      return returnSize( this->variable_ );
+    else
+      return 0;
+  }
+
+
+
+
+// ================= Bidirectional Part ================
+
+    template <class T> SynchronisableVariableBidirectional<T>::SynchronisableVariableBidirectional(T& variable, uint8_t master, NetworkCallbackBase *cb):
+    SynchronisableVariable<T>( variable, master, cb ), varBuffer_( variable ), varReference_( 0 )
+    {
+    }
+
+    template <class T> SynchronisableVariableBidirectional<T>::~SynchronisableVariableBidirectional()
+    {
+    }
+
+    template <class T> uint32_t SynchronisableVariableBidirectional<T>::getData(uint8_t*& mem, uint8_t mode)
+    {
+      if ( this->mode_ == mode )
+      {   // we are master for this variable and have to check whether to change the varReference
+        if( this->varBuffer_ != this->variable_ )
+        {
+          this->varReference_++;
+          memcpy(static_cast<void*>(const_cast<typename Loki::TypeTraits<T>::UnqualifiedType*>(&this->varBuffer_)), &this->variable_, sizeof(this->variable_));
+        }
+      }
+  // write the reference number to the stream
+      *static_cast<uint8_t*>(mem) = varReference_;
+      mem += sizeof(this->varReference_);
+  // now write the content
+      saveAndIncrease( this->variable_, mem );
+      return SynchronisableVariableBidirectional::getSize(mode);
+    }
+
+    template <class T> void SynchronisableVariableBidirectional<T>::putData(uint8_t*& mem, uint8_t mode, bool forceCallback)
+    {
+      bool callback = false;
+      if ( this->mode_ == mode )
+      {   //        MASTER
+        // check that the client (source of the data) has a recent version of this variable
+        if ( *static_cast<uint8_t*>(mem) != this->varReference_ )
+        { // wrong reference number, so discard the data
+//           COUT(0) << "discharding data" << endl;
+          mem += getSize( mode ); // SynchronisableVariableBidirectional::getSize returns size of variable + reference
+          return;
+        }
+        else{
+          // apply data
+          if ( checkEquality( this->variable_, mem+sizeof(varReference_) )==true )
+          {
+            mem += getSize( mode );
+            return;
+          }
+          else
+          {
+            mem += sizeof(varReference_);
+            memcpy(static_cast<void*>(const_cast<typename Loki::TypeTraits<T>::UnqualifiedType*>(&this->varBuffer_)), &this->variable_, sizeof(T));
+            if ( this->callback_ )
+              callback = true;
+          }
+        }
+      }
+      else
+      {   // we are slave for this variable
+        if (*static_cast<uint8_t*>(mem) == this->varReference_ && !forceCallback)
+        {
+          mem += getSize( mode ); //just skip the variable because nothing changed
+          return;
+        }
+        else
+        {
+          this->varReference_ = *static_cast<uint8_t*>(mem);
+          mem += sizeof(varReference_);
+          if ( checkEquality( this->variable_, mem ) == false )
+          {
+            // value changed so remark for callback
+            if ( this->callback_ )
+              callback = true;
+          }
+        }
+      }
+  // now do a callback if neccessary
+      if ( callback )
+      {
+        NetworkCallbackManager::triggerCallback( this->callback_ );
+      }
+  // now write the data
+      loadAndIncrease(this->variable_, mem);
+    }
+
+    template <class T> inline uint32_t SynchronisableVariableBidirectional<T>::getSize(uint8_t mode)
+    {
+      return returnSize( this->variable_ ) + sizeof(varReference_);
+    }
+
+
+}
+
+
+#endif /* _SynchronisableVariable_H__ */
Index: /code/branches/rocket2/src/libraries/tools/BillboardSet.cc
===================================================================
--- /code/branches/rocket2/src/libraries/tools/BillboardSet.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/BillboardSet.cc	(revision 6952)
@@ -0,0 +1,173 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "BillboardSet.h"
+
+#include <cassert>
+#include <string>
+#include <sstream>
+#include <OgreSceneManager.h>
+#include <OgreBillboardSet.h>
+#include <OgreBillboard.h>
+
+#include "util/Convert.h"
+#include "util/Math.h"
+#include "core/GameMode.h"
+
+namespace orxonox
+{
+    unsigned int BillboardSet::billboardSetCounter_s = 0;
+
+    BillboardSet::BillboardSet()
+    {
+        this->billboardSet_ = 0;
+    }
+
+    BillboardSet::~BillboardSet()
+    {
+        this->destroyBillboardSet();
+    }
+
+    void BillboardSet::setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, int count)
+    {
+        this->setBillboardSet(scenemanager, file, Vector3::ZERO, count);
+    }
+
+    void BillboardSet::setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const ColourValue& colour, int count)
+    {
+        this->setBillboardSet(scenemanager, file, colour, Vector3::ZERO, count);
+    }
+
+    void BillboardSet::setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const Vector3& position, int count)
+    {
+        assert(scenemanager);
+        this->destroyBillboardSet();
+
+        try
+        {
+            if (GameMode::showsGraphics())
+            {
+                this->billboardSet_ = scenemanager->createBillboardSet("Billboard" + multi_cast<std::string>(BillboardSet::billboardSetCounter_s++), count);
+                this->billboardSet_->createBillboard(position);
+                this->billboardSet_->setMaterialName(file);
+            }
+        }
+        catch (...)
+        {
+            COUT(1) << "Error: Couln't load billboard \"" << file << '"' << std::endl;
+            this->billboardSet_ = 0;
+        }
+
+        this->scenemanager_ = scenemanager;
+    }
+
+    void BillboardSet::setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const ColourValue& colour, const Vector3& position, int count)
+    {
+        assert(scenemanager);
+        this->destroyBillboardSet();
+
+        try
+        {
+            if (GameMode::showsGraphics())
+            {
+                this->billboardSet_ = scenemanager->createBillboardSet("Billboard" + multi_cast<std::string>(BillboardSet::billboardSetCounter_s++), count);
+                this->billboardSet_->createBillboard(position, colour);
+                this->billboardSet_->setMaterialName(file);
+            }
+        }
+        catch (...)
+        {
+            COUT(1) << "Error: Couln't load billboard \"" << file << '"' << std::endl;
+            this->billboardSet_ = 0;
+        }
+
+        this->scenemanager_ = scenemanager;
+    }
+
+    void BillboardSet::destroyBillboardSet()
+    {
+        if (this->billboardSet_ && this->scenemanager_)
+            this->scenemanager_->destroyBillboardSet(this->billboardSet_);
+        this->billboardSet_ = 0;
+    }
+
+    const std::string& BillboardSet::getName() const
+    {
+        if (this->billboardSet_)
+            return this->billboardSet_->getName();
+        else
+            return BLANKSTRING;
+    }
+
+    void BillboardSet::setVisible(bool visible)
+    {
+        if (this->billboardSet_)
+            this->billboardSet_->setVisible(visible);
+    }
+
+    bool BillboardSet::getVisible() const
+    {
+        if (this->billboardSet_)
+            return this->billboardSet_->getVisible();
+        else
+            return false;
+    }
+
+    void BillboardSet::setColour(const ColourValue& colour)
+    {
+        if (this->billboardSet_)
+        {
+            for (int i = 0; i < this->billboardSet_->getNumBillboards(); ++i)
+                this->billboardSet_->getBillboard(i)->setColour(colour);
+        }
+    }
+
+    const ColourValue& BillboardSet::getColour() const
+    {
+        if (this->billboardSet_ && this->billboardSet_->getNumBillboards() > 0)
+        {
+            return this->billboardSet_->getBillboard(0)->getColour();
+        }
+        else
+            return ColourValue::White;
+    }
+
+    void BillboardSet::setMaterial(const std::string& material)
+    {
+        if (this->billboardSet_)
+            this->billboardSet_->setMaterialName(material);
+    }
+
+    const std::string& BillboardSet::getMaterial() const
+    {
+        if (this->billboardSet_)
+            return this->billboardSet_->getMaterialName();
+        else
+            return BLANKSTRING;
+    }
+}
Index: /code/branches/rocket2/src/libraries/tools/BillboardSet.h
===================================================================
--- /code/branches/rocket2/src/libraries/tools/BillboardSet.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/BillboardSet.h	(revision 6952)
@@ -0,0 +1,74 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _BillboardSet_H__
+#define _BillboardSet_H__
+
+#include "tools/ToolsPrereqs.h"
+#include "util/OgreForwardRefs.h"
+
+namespace orxonox
+{
+    class _ToolsExport BillboardSet
+    {
+        public:
+            BillboardSet();
+            ~BillboardSet();
+
+            void setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, int count = 1);
+            void setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const ColourValue& colour, int count = 1);
+            void setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const Vector3& position, int count = 1);
+            void setBillboardSet(Ogre::SceneManager* scenemanager, const std::string& file, const ColourValue& colour, const Vector3& position, int count = 1);
+
+            inline Ogre::BillboardSet* getBillboardSet()
+                { return this->billboardSet_; }
+            inline Ogre::SceneManager* getSceneManager() const
+                { return this->scenemanager_; }
+
+            const std::string& getName() const;
+
+            void setVisible(bool visible);
+            bool getVisible() const;
+
+            void setColour(const ColourValue& colour);
+            const ColourValue& getColour() const;
+
+            void setMaterial(const std::string& material);
+            const std::string& getMaterial() const;
+
+        private:
+            void destroyBillboardSet();
+
+            Ogre::BillboardSet* billboardSet_;
+            Ogre::SceneManager* scenemanager_;
+
+            static unsigned int billboardSetCounter_s;
+    };
+}
+
+#endif /* _BillboardSet_H__ */
Index: /code/branches/rocket2/src/libraries/tools/BulletConversions.h
===================================================================
--- /code/branches/rocket2/src/libraries/tools/BulletConversions.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/BulletConversions.h	(revision 6952)
@@ -0,0 +1,96 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _BulletConversions_H__
+#define _BulletConversions_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include "util/Convert.h"
+#include "util/Math.h"
+#include <LinearMath/btQuaternion.h>
+#include <LinearMath/btVector3.h>
+
+namespace orxonox
+{
+    // Vector3 to btVector3
+    template <>
+    struct ConverterExplicit<orxonox::Vector3, btVector3>
+    {
+        FORCEINLINE static bool convert(btVector3* output, const orxonox::Vector3& input)
+        {
+            output->setX(input.x);
+            output->setY(input.y);
+            output->setZ(input.z);
+            return true;
+        }
+    };
+
+    // btVector3 to Vector3
+    template <>
+    struct ConverterExplicit<btVector3, orxonox::Vector3>
+    {
+        FORCEINLINE static bool convert(orxonox::Vector3* output, const btVector3& input)
+        {
+            output->x = input.x();
+            output->y = input.y();
+            output->z = input.z();
+            return true;
+        }
+    };
+
+    // Quaternion to btQuaternion
+    template <>
+    struct ConverterExplicit<orxonox::Quaternion, btQuaternion>
+    {
+        FORCEINLINE static bool convert(btQuaternion* output, const orxonox::Quaternion& input)
+        {
+            output->setW(input.w);
+            output->setX(input.x);
+            output->setY(input.y);
+            output->setZ(input.z);
+            return true;
+        }
+    };
+
+    // btQuaternion to Vector3
+    template <>
+    struct ConverterExplicit<btQuaternion, orxonox::Quaternion>
+    {
+        FORCEINLINE static bool convert(orxonox::Quaternion* output, const btQuaternion& input)
+        {
+            output->w = input.w();
+            output->x = input.x();
+            output->y = input.y();
+            output->z = input.z();
+            return true;
+        }
+    };
+}
+
+#endif /* _BulletConversions_H__ */
Index: /code/branches/rocket2/src/libraries/tools/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/libraries/tools/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,27 @@
+SET_SOURCE_FILES(TOOLS_SRC_FILES
+COMPILATION_BEGIN ResourceCompilation.cc
+  ResourceCollection.cc
+  ResourceLocation.cc
+COMPILATION_END
+  TextureGenerator.cc
+  Timer.cc
+COMPILATION_BEGIN OgreCompilation.cc
+  BillboardSet.cc
+  DynamicLines.cc
+  DynamicRenderable.cc
+  Mesh.cc
+  ParticleInterface.cc
+  Shader.cc
+COMPILATION_END
+)
+ADD_SUBDIRECTORY(interfaces)
+
+ORXONOX_ADD_LIBRARY(tools
+  FIND_HEADER_FILES
+  DEFINE_SYMBOL
+    "TOOLS_SHARED_BUILD"
+  LINK_LIBRARIES
+    core
+    network
+  SOURCE_FILES ${TOOLS_SRC_FILES}
+)
Index: /code/branches/rocket2/src/libraries/tools/DynamicLines.cc
===================================================================
--- /code/branches/rocket2/src/libraries/tools/DynamicLines.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/DynamicLines.cc	(revision 6952)
@@ -0,0 +1,178 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Baxissimo, Emmeran, DWORD, EtherDrive (OGRE Wiki)
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "DynamicLines.h"
+
+#include <cassert>
+#include <cmath>
+
+namespace Ogre
+{
+    enum
+    {
+        POSITION_BINDING,
+        TEXCOORD_BINDING
+    };
+
+    DynamicLines::DynamicLines(OperationType opType)
+    {
+        initialize(opType,false);
+        setMaterial("BaseWhiteNoLighting");
+        mDirty = true;
+    }
+
+    DynamicLines::~DynamicLines()
+    {
+    }
+
+    void DynamicLines::setOperationType(OperationType opType)
+    {
+        mRenderOp.operationType = opType;
+    }
+
+    RenderOperation::OperationType DynamicLines::getOperationType() const
+    {
+        return mRenderOp.operationType;
+    }
+
+    void DynamicLines::addPoint(const Vector3 &p)
+    {
+        mPoints.push_back(p);
+        mDirty = true;
+    }
+
+    void DynamicLines::addPoint(Real x, Real y, Real z)
+    {
+        mPoints.push_back(Vector3(x,y,z));
+        mDirty = true;
+    }
+
+    const Vector3& DynamicLines::getPoint(unsigned short index) const
+    {
+        assert(index < mPoints.size() && "Point index is out of bounds!!");
+        return mPoints[index];
+    }
+
+    unsigned short DynamicLines::getNumPoints(void) const
+    {
+        return (unsigned short)mPoints.size();
+    }
+
+    void DynamicLines::setPoint(unsigned short index, const Vector3 &value)
+    {
+        assert(index < mPoints.size() && "Point index is out of bounds!!");
+
+        mPoints[index] = value;
+        mDirty = true;
+    }
+
+    void DynamicLines::clear()
+    {
+        mPoints.clear();
+        mDirty = true;
+    }
+
+    void DynamicLines::update()
+    {
+        if (mDirty)
+            fillHardwareBuffers();
+    }
+
+    void DynamicLines::createVertexDeclaration()
+    {
+        VertexDeclaration *decl = mRenderOp.vertexData->vertexDeclaration;
+        decl->addElement(POSITION_BINDING, 0, VET_FLOAT3, VES_POSITION);
+    }
+
+    void DynamicLines::fillHardwareBuffers()
+    {
+        int size = mPoints.size();
+
+        prepareHardwareBuffers(size,0);
+
+        if (!size)
+        {
+            mBox.setExtents(Vector3::ZERO,Vector3::ZERO);
+            mDirty=false;
+            return;
+        }
+
+        Vector3 vaabMin = mPoints[0];
+        Vector3 vaabMax = mPoints[0];
+
+        HardwareVertexBufferSharedPtr vbuf =
+            mRenderOp.vertexData->vertexBufferBinding->getBuffer(0);
+
+        Real *prPos = static_cast<Real*>(vbuf->lock(HardwareBuffer::HBL_DISCARD));
+        for (int i = 0; i < size; i++)
+        {
+            *prPos++ = mPoints[i].x;
+            *prPos++ = mPoints[i].y;
+            *prPos++ = mPoints[i].z;
+
+            if (mPoints[i].x < vaabMin.x)
+                vaabMin.x = mPoints[i].x;
+            if (mPoints[i].y < vaabMin.y)
+                vaabMin.y = mPoints[i].y;
+            if (mPoints[i].z < vaabMin.z)
+                vaabMin.z = mPoints[i].z;
+
+            if (mPoints[i].x > vaabMax.x)
+                vaabMax.x = mPoints[i].x;
+            if (mPoints[i].y > vaabMax.y)
+                vaabMax.y = mPoints[i].y;
+            if (mPoints[i].z > vaabMax.z)
+                vaabMax.z = mPoints[i].z;
+        }
+        vbuf->unlock();
+
+        mBox.setExtents(vaabMin, vaabMax);
+
+        mDirty = false;
+    }
+
+    /*
+    void DynamicLines::getWorldTransforms(Matrix4 *xform) const
+    {
+        // return identity matrix to prevent parent transforms
+        *xform = Matrix4::IDENTITY;
+    }
+    */
+
+    /*
+    const Quaternion &DynamicLines::getWorldOrientation(void) const
+    {
+        return Quaternion::IDENTITY;
+    }
+
+    const Vector3 &DynamicLines::getWorldPosition(void) const
+    {
+        return Vector3::ZERO;
+    }
+    */
+}
Index: /code/branches/rocket2/src/libraries/tools/DynamicLines.h
===================================================================
--- /code/branches/rocket2/src/libraries/tools/DynamicLines.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/DynamicLines.h	(revision 6952)
@@ -0,0 +1,96 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Baxissimo, Emmeran, DWORD, EtherDrive (OGRE Wiki)
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _DynamicLines_H__
+#define _DynamicLines_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include <vector>
+#include "DynamicRenderable.h"
+
+namespace Ogre
+{
+    class _ToolsExport DynamicLines : public DynamicRenderable
+    {
+        typedef RenderOperation::OperationType OperationType;
+
+    public:
+        /// Constructor - see setOperationType() for description of argument.
+        DynamicLines(OperationType opType = RenderOperation::OT_LINE_STRIP);
+        virtual ~DynamicLines();
+
+        /// Add a point to the point list
+        void addPoint(const Vector3 &p);
+        /// Add a point to the point list
+        void addPoint(Real x, Real y, Real z);
+
+        /// Change the location of an existing point in the point list
+        void setPoint(unsigned short index, const Vector3 &value);
+
+        /// Return the location of an existing point in the point list
+        const Vector3& getPoint(unsigned short index) const;
+
+        /// Return the total number of points in the point list
+        unsigned short getNumPoints(void) const;
+
+        /// Remove all points from the point list
+        void clear();
+
+        /// Call this to update the hardware buffer after making changes.
+        void update();
+
+        /**
+        @brief
+            Set the type of operation to draw with.
+        @param opType
+            Can be one of
+                - RenderOperation::OT_LINE_STRIP
+                - RenderOperation::OT_LINE_LIST
+                - RenderOperation::OT_POINT_LIST
+                - RenderOperation::OT_TRIANGLE_LIST
+                - RenderOperation::OT_TRIANGLE_STRIP
+                - RenderOperation::OT_TRIANGLE_FAN
+            The default is OT_LINE_STRIP.
+        */
+        void setOperationType(OperationType opType);
+        OperationType getOperationType() const;
+
+    protected:
+        /// Implementation DynamicRenderable, creates a simple vertex-only decl
+        virtual void createVertexDeclaration();
+        /// Implementation DynamicRenderable, pushes point list out to hardware memory
+        virtual void fillHardwareBuffers();
+
+    private:
+        std::vector<Vector3> mPoints;
+        bool mDirty;
+    };
+}
+
+#endif /* _DynamicLines_H__ */
Index: /code/branches/rocket2/src/libraries/tools/DynamicRenderable.cc
===================================================================
--- /code/branches/rocket2/src/libraries/tools/DynamicRenderable.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/DynamicRenderable.cc	(revision 6952)
@@ -0,0 +1,160 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Sinbad, Baxissimo, DWORD, TheBren (OGRE Wiki)
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "DynamicRenderable.h"
+
+#include <OgreCamera.h>
+#include <OgreHardwareBufferManager.h>
+
+namespace Ogre
+{
+    DynamicRenderable::DynamicRenderable()
+    {
+    }
+
+    DynamicRenderable::~DynamicRenderable()
+    {
+        delete mRenderOp.vertexData;
+        delete mRenderOp.indexData;
+    }
+
+    void DynamicRenderable::initialize(RenderOperation::OperationType operationType,
+           bool useIndices)
+    {
+        // Initialize render operation
+        mRenderOp.operationType = operationType;
+        mRenderOp.useIndexes = useIndices;
+        mRenderOp.vertexData = new VertexData;
+        if (mRenderOp.useIndexes)
+            mRenderOp.indexData = new IndexData;
+
+        // Reset buffer capacities
+        mVertexBufferCapacity = 0;
+        mIndexBufferCapacity = 0;
+
+        // Create vertex declaration
+        createVertexDeclaration();
+    }
+
+    void DynamicRenderable::prepareHardwareBuffers(size_t vertexCount, size_t indexCount)
+    {
+        // Prepare vertex buffer
+        size_t newVertCapacity = mVertexBufferCapacity;
+        if ((vertexCount > mVertexBufferCapacity) || (!mVertexBufferCapacity))
+        {
+            // vertexCount exceeds current capacity!
+            // It is necessary to reallocate the buffer.
+
+            // Check if this is the first call
+            if (!newVertCapacity)
+                newVertCapacity = 1;
+
+            // Make capacity the next power of two
+            while (newVertCapacity < vertexCount)
+                newVertCapacity <<= 1;
+        }
+        else if (vertexCount < mVertexBufferCapacity>>1)
+        {
+            // Make capacity the previous power of two
+            while (vertexCount < newVertCapacity>>1)
+                newVertCapacity >>= 1;
+        }
+        if (newVertCapacity != mVertexBufferCapacity)
+        {
+            mVertexBufferCapacity = newVertCapacity;
+            // Create new vertex buffer
+            HardwareVertexBufferSharedPtr vbuf =
+                HardwareBufferManager::getSingleton().createVertexBuffer(
+                mRenderOp.vertexData->vertexDeclaration->getVertexSize(0),
+                mVertexBufferCapacity,
+                HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?
+
+            // Bind buffer
+            mRenderOp.vertexData->vertexBufferBinding->setBinding(0, vbuf);
+        }
+        // Update vertex count in the render operation
+        mRenderOp.vertexData->vertexCount = vertexCount;
+
+        if (mRenderOp.useIndexes)
+        {
+            OgreAssert(indexCount <= std::numeric_limits<unsigned short>::max(), "indexCount exceeds 16 bit");
+
+            size_t newIndexCapacity = mIndexBufferCapacity;
+            // Prepare index buffer
+            if ((indexCount > newIndexCapacity) || (!newIndexCapacity))
+            {
+                // indexCount exceeds current capacity!
+                // It is necessary to reallocate the buffer.
+
+                // Check if this is the first call
+                if (!newIndexCapacity)
+                    newIndexCapacity = 1;
+
+                // Make capacity the next power of two
+                while (newIndexCapacity < indexCount)
+                    newIndexCapacity <<= 1;
+            }
+            else if (indexCount < newIndexCapacity>>1)
+            {
+                // Make capacity the previous power of two
+                while (indexCount < newIndexCapacity>>1)
+                    newIndexCapacity >>= 1;
+            }
+
+            if (newIndexCapacity != mIndexBufferCapacity)
+            {
+                mIndexBufferCapacity = newIndexCapacity;
+                // Create new index buffer
+                mRenderOp.indexData->indexBuffer =
+                    HardwareBufferManager::getSingleton().createIndexBuffer(
+                    HardwareIndexBuffer::IT_16BIT,
+                    mIndexBufferCapacity,
+                    HardwareBuffer::HBU_DYNAMIC_WRITE_ONLY); // TODO: Custom HBU_?
+            }
+
+            // Update index count in the render operation
+            mRenderOp.indexData->indexCount = indexCount;
+        }
+    }
+
+    Real DynamicRenderable::getBoundingRadius(void) const
+    {
+        return Math::Sqrt(std::max(mBox.getMaximum().squaredLength(), mBox.getMinimum().squaredLength()));
+    }
+
+    Real DynamicRenderable::getSquaredViewDepth(const Camera* cam) const
+    {
+        Vector3 vMin, vMax, vMid, vDist;
+        vMin = mBox.getMinimum();
+        vMax = mBox.getMaximum();
+        vMid = ((vMax - vMin) * 0.5) + vMin;
+        vDist = cam->getDerivedPosition() - vMid;
+
+        return vDist.squaredLength();
+    }
+}
Index: /code/branches/rocket2/src/libraries/tools/DynamicRenderable.h
===================================================================
--- /code/branches/rocket2/src/libraries/tools/DynamicRenderable.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/DynamicRenderable.h	(revision 6952)
@@ -0,0 +1,116 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Sinbad, Baxissimo, DWORD, TheBren (OGRE Wiki)
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _DynamicRenderable_H__
+#define _DynamicRenderable_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include <OgreSimpleRenderable.h>
+
+namespace Ogre
+{
+    /// Abstract base class providing mechanisms for dynamically growing hardware buffers.
+    class _ToolsExport DynamicRenderable : public SimpleRenderable
+    {
+    public:
+        /// Constructor
+        DynamicRenderable();
+        /// Virtual destructor
+        virtual ~DynamicRenderable();
+
+        /**
+        @brief
+            Initializes the dynamic renderable.
+        @remarks
+            This function should only be called once. It initializes the
+            render operation, and calls the abstract function
+            createVertexDeclaration().
+        @param operationType
+            The type of render operation to perform.
+        @param useIndices
+            Specifies whether to use indices to determine the vertices to use as input.
+        */
+        void initialize(RenderOperation::OperationType operationType,
+        bool useIndices);
+
+        /// Implementation of SimpleRenderable
+        virtual Real getBoundingRadius(void) const;
+        /// Implementation of SimpleRenderable
+        virtual Real getSquaredViewDepth(const Camera* cam) const;
+
+    protected:
+        /// Maximum capacity of the currently allocated vertex buffer.
+        size_t mVertexBufferCapacity;
+        /// Maximum capacity of the currently allocated index buffer.
+        size_t mIndexBufferCapacity;
+
+        /**
+        @brief
+            Creates the vertex declaration.
+        @remarks
+            Override and set mRenderOp.vertexData->vertexDeclaration here.
+            mRenderOp.vertexData will be created for you before this method
+            is called.
+        */
+        virtual void createVertexDeclaration() = 0;
+
+        /**
+        @brief
+            Prepares the hardware buffers for the requested vertex and index counts.
+        @remarks
+            This function must be called before locking the buffers in
+            fillHardwareBuffers(). It guarantees that the hardware buffers
+            are large enough to hold at least the requested number of
+            vertices and indices (if using indices). The buffers are
+            possibly reallocated to achieve this.
+        @par
+            The vertex and index count in the render operation are set to
+            the values of vertexCount and indexCount respectively.
+        @param vertexCount
+            The number of vertices the buffer must hold.
+        @param indexCount
+            The number of indices the buffer must hold. This
+            parameter is ignored if not using indices.
+        */
+        void prepareHardwareBuffers(size_t vertexCount, size_t indexCount);
+
+        /**
+        @brief
+            Fills the hardware vertex and index buffers with data.
+        @remarks
+            This function must call prepareHardwareBuffers() before locking
+            the buffers to ensure the they are large enough for the data to
+            be written. Afterwards the vertex and index buffers (if using
+            indices) can be locked, and data can be written to them.
+        */
+        virtual void fillHardwareBuffers() = 0;
+    };
+}
+
+#endif /* _DynamicRenderable_H__ */
Index: /code/branches/rocket2/src/libraries/tools/Mesh.cc
===================================================================
--- /code/branches/rocket2/src/libraries/tools/Mesh.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/Mesh.cc	(revision 6952)
@@ -0,0 +1,119 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Mesh.h"
+
+#include <cassert>
+#include <sstream>
+#include <string>
+#include <OgreEntity.h>
+#include <OgreSceneManager.h>
+
+#include "util/Convert.h"
+#include "core/GameMode.h"
+
+namespace orxonox
+{
+    unsigned int Mesh::meshCounter_s = 0;
+
+    Mesh::Mesh()
+    {
+        this->entity_ = 0;
+        this->bCastShadows_ = true;
+    }
+
+    Mesh::~Mesh()
+    {
+        if (this->entity_ && this->scenemanager_)
+            this->scenemanager_->destroyEntity(this->entity_);
+    }
+
+    void Mesh::setMeshSource(Ogre::SceneManager* scenemanager, const std::string& meshsource)
+    {
+        assert(scenemanager);
+
+        this->scenemanager_ = scenemanager;
+
+        if (this->entity_)
+            this->scenemanager_->destroyEntity(this->entity_);
+
+        if (GameMode::showsGraphics())
+        {
+            try
+            {
+                this->entity_ = this->scenemanager_->createEntity("Mesh" + multi_cast<std::string>(Mesh::meshCounter_s++), meshsource);
+                this->entity_->setCastShadows(this->bCastShadows_);
+
+#if OGRE_VERSION < 0x010600
+                this->entity_->setNormaliseNormals(true);
+                /*
+                    Excerpt from Ogre forum:
+                    "Note that the above is only for the fixed function pipeline.
+                    If/when you get into shaders, you'll need to manually normalize() the normal inside the vertex or pixel shader."
+
+                    I don't know exactly what this means, but I put this here if there will be problems with shaders.
+                */
+#endif
+            }
+            catch (...)
+            {
+                COUT(1) << "Error: Couln't load mesh \"" << meshsource << '"' << std::endl;
+                this->entity_ = 0;
+            }
+        }
+    }
+
+    void Mesh::setCastShadows(bool bCastShadows)
+    {
+        this->bCastShadows_ = bCastShadows;
+        if (this->entity_)
+            this->entity_->setCastShadows(this->bCastShadows_);
+    }
+
+    const std::string& Mesh::getName() const
+    {
+        if (this->entity_)
+            return this->entity_->getName();
+        else
+            return BLANKSTRING;
+    }
+
+    void Mesh::setVisible(bool bVisible)
+    {
+        if (this->entity_)
+            this->entity_->setVisible(bVisible);
+    }
+
+    bool Mesh::isVisible() const
+    {
+        if (this->entity_)
+            return this->entity_->getVisible();
+        else
+            return false;
+    }
+}
Index: /code/branches/rocket2/src/libraries/tools/Mesh.h
===================================================================
--- /code/branches/rocket2/src/libraries/tools/Mesh.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/Mesh.h	(revision 6952)
@@ -0,0 +1,66 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Mesh_H__
+#define _Mesh_H__
+
+#include "tools/ToolsPrereqs.h"
+#include "util/OgreForwardRefs.h"
+
+namespace orxonox
+{
+    class _ToolsExport Mesh
+    {
+        public:
+            Mesh();
+            ~Mesh();
+
+            void setMeshSource(Ogre::SceneManager* scenemanager, const std::string& file);
+
+            inline Ogre::Entity* getEntity()
+                { return this->entity_; }
+
+            const std::string& getName() const;
+
+            void setVisible(bool bVisible);
+            bool isVisible() const;
+
+            void setCastShadows(bool bCastShadows);
+            inline bool getCastShadows() const
+                { return this->bCastShadows_; }
+
+        private:
+            Ogre::Entity* entity_;
+            bool bCastShadows_;
+            Ogre::SceneManager* scenemanager_;
+
+            static unsigned int meshCounter_s;
+    };
+}
+
+#endif /* _Mesh_H__ */
Index: /code/branches/rocket2/src/libraries/tools/ParticleInterface.cc
===================================================================
--- /code/branches/rocket2/src/libraries/tools/ParticleInterface.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/ParticleInterface.cc	(revision 6952)
@@ -0,0 +1,233 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+* @file
+* @brief class to control praticle effects
+*/
+
+#include "ParticleInterface.h"
+
+#include <cassert>
+#include <string>
+#include <OgreParticleSystem.h>
+#include <OgreParticleEmitter.h>
+#include <OgreSceneManager.h>
+
+#include "util/Convert.h"
+#include "util/Math.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/GameMode.h"
+
+namespace orxonox
+{
+    unsigned int ParticleInterface::counter_s = 0;
+    ParticleInterface* ParticleInterface::currentParticleInterface_s = 0;
+
+    ParticleInterface::ParticleInterface(Ogre::SceneManager* scenemanager, const std::string& templateName, LODParticle::Value detaillevel)
+    {
+        RegisterObject(ParticleInterface);
+
+        assert(scenemanager);
+
+        this->scenemanager_ = scenemanager;
+        this->particleSystem_ = 0;
+
+        this->bEnabled_ = true;
+        this->bVisible_ = true;
+        this->bAllowedByLOD_ = true;
+        this->speedFactor_ = 1.0f;
+
+        this->setDetailLevel(static_cast<unsigned int>(detaillevel));
+
+        this->setConfigValues();
+
+        if (GameMode::showsGraphics())
+        {
+            try
+            {
+                this->particleSystem_ = this->scenemanager_->createParticleSystem("particles" + multi_cast<std::string>(ParticleInterface::counter_s++), templateName);
+                this->setSpeedFactor(1.0f);
+            }
+            catch (...)
+            {
+                COUT(1) << "Error: Couln't load particle system \"" << templateName << '"' << std::endl;
+                this->particleSystem_ = 0;
+            }
+        }
+    }
+
+    ParticleInterface::~ParticleInterface()
+    {
+        if (this->particleSystem_)
+        {
+            this->particleSystem_->removeAllEmitters();
+            this->scenemanager_->destroyParticleSystem(this->particleSystem_);
+        }
+    }
+
+    void ParticleInterface::setConfigValues()
+    {
+        SetConfigValue(globalDetailLevel_, 2)
+            .description("O: off, 1: low, 2: normal, 3: high").callback(this, &ParticleInterface::detailLevelChanged);
+    }
+
+    Ogre::ParticleEmitter* ParticleInterface::createNewEmitter()
+    {
+        if (this->particleSystem_ && this->particleSystem_->getNumEmitters() > 0)
+        {
+            Ogre::ParticleEmitter* newemitter = this->particleSystem_->addEmitter(this->particleSystem_->getEmitter(0)->getType());
+            this->particleSystem_->getEmitter(0)->copyParametersTo(newemitter);
+            return newemitter;
+        }
+        else
+            return 0;
+    }
+    Ogre::ParticleEmitter* ParticleInterface::getEmitter(unsigned int emitterNr) const
+    {
+        if (this->particleSystem_ && (emitterNr < this->particleSystem_->getNumEmitters()))
+            return this->particleSystem_->getEmitter(emitterNr);
+        else
+            return 0;
+    }
+    void ParticleInterface::removeEmitter(unsigned int emitterNr)
+    {
+        if (this->particleSystem_ && (emitterNr < this->particleSystem_->getNumEmitters()))
+            this->particleSystem_->removeEmitter(emitterNr);
+    }
+    void ParticleInterface::removeAllEmitters()
+    {
+        if (this->particleSystem_)
+            this->particleSystem_->removeAllEmitters();
+    }
+    unsigned int ParticleInterface::getNumEmitters() const
+    {
+        if (this->particleSystem_)
+            return this->particleSystem_->getNumEmitters();
+        else
+            return 0;
+    }
+
+    Ogre::ParticleAffector* ParticleInterface::addAffector(const std::string& name)
+    {
+        if (this->particleSystem_)
+            return this->particleSystem_->addAffector(name);
+        else
+            return 0;
+    }
+    Ogre::ParticleAffector* ParticleInterface::getAffector(unsigned int affectorNr)
+    {
+        if (this->particleSystem_ && (affectorNr < this->particleSystem_->getNumAffectors()))
+            return this->particleSystem_->getAffector(affectorNr);
+        else
+            return 0;
+    }
+    void ParticleInterface::removeAffector(unsigned int affectorNr)
+    {
+        if (this->particleSystem_ && (affectorNr < this->particleSystem_->getNumAffectors()))
+            this->particleSystem_->removeAffector(affectorNr);
+    }
+    void ParticleInterface::removeAllAffectors()
+    {
+        if (this->particleSystem_)
+            this->particleSystem_->removeAllAffectors();
+    }
+    unsigned int ParticleInterface::getNumAffectors() const
+    {
+        if (this->particleSystem_)
+            return this->particleSystem_->getNumAffectors();
+        else
+            return 0;
+    }
+
+    void ParticleInterface::setEnabled(bool enable)
+    {
+        this->bEnabled_ = enable;
+
+        if (this->particleSystem_)
+            for (unsigned int i = 0; i < this->particleSystem_->getNumEmitters(); i++)
+                this->particleSystem_->getEmitter(i)->setEnabled(this->bEnabled_ && this->bAllowedByLOD_);
+    }
+
+    void ParticleInterface::setVisible(bool visible)
+    {
+        this->bVisible_ = visible;
+
+        if (this->particleSystem_)
+            this->particleSystem_->setVisible(this->bVisible_ && this->bAllowedByLOD_);
+    }
+
+    void ParticleInterface::setDetailLevel(unsigned int level)
+    {
+        this->detaillevel_ = level;
+        if (GameMode::showsGraphics())
+            this->detailLevelChanged();
+    }
+
+    void ParticleInterface::detailLevelChanged()
+    {
+        if (this->globalDetailLevel_ >= this->detaillevel_)
+            this->bAllowedByLOD_ = true;
+        else
+            this->bAllowedByLOD_ = false;
+
+        this->updateVisibility();
+    }
+
+    void ParticleInterface::updateVisibility()
+    {
+        this->setEnabled(this->isEnabled());
+        this->setVisible(this->isVisible());
+    }
+
+    void ParticleInterface::setSpeedFactor(float factor)
+    {
+        this->speedFactor_ = factor;
+
+        if (this->particleSystem_)
+            this->particleSystem_->setSpeedFactor(factor * this->getTimeFactor());
+    }
+    void ParticleInterface::changedTimeFactor(float factor_new, float factor_old)
+    {
+        this->setSpeedFactor(this->speedFactor_);
+    }
+
+    bool ParticleInterface::getKeepParticlesInLocalSpace() const
+    {
+        if (this->particleSystem_)
+            return this->particleSystem_->getKeepParticlesInLocalSpace();
+        else
+            return false;
+    }
+    void ParticleInterface::setKeepParticlesInLocalSpace(bool keep)
+    {
+        if (this->particleSystem_)
+            this->particleSystem_->setKeepParticlesInLocalSpace(keep);
+    }
+}
Index: /code/branches/rocket2/src/libraries/tools/ParticleInterface.h
===================================================================
--- /code/branches/rocket2/src/libraries/tools/ParticleInterface.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/ParticleInterface.h	(revision 6952)
@@ -0,0 +1,110 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ParticleInterface_H__
+#define _ParticleInterface_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include "util/OgreForwardRefs.h"
+#include "tools/interfaces/TimeFactorListener.h"
+
+#define getAllEmitters() \
+  storeThisAsCurrentParticleInterface(); \
+  for (unsigned int i = 0; i < ParticleInterface::getCurrentParticleInterface()->getNumEmitters(); ++i) \
+    ParticleInterface::getCurrentParticleInterface()->getEmitter(i)
+
+namespace orxonox
+{
+    class _ToolsExport ParticleInterface : public TimeFactorListener
+    {
+        public:
+            ParticleInterface(Ogre::SceneManager* scenemanager, const std::string& templateName, LODParticle::Value detaillevel);
+            virtual ~ParticleInterface();
+            void setConfigValues();
+
+            inline Ogre::ParticleSystem* getParticleSystem()
+                { return this->particleSystem_; }
+
+            Ogre::ParticleEmitter* createNewEmitter();
+            Ogre::ParticleEmitter* getEmitter(unsigned int emitterNr) const;
+            void removeEmitter(unsigned int emitterNr);
+            void removeAllEmitters();
+            unsigned int getNumEmitters() const;
+
+            Ogre::ParticleAffector* addAffector(const std::string& name);
+            Ogre::ParticleAffector* getAffector(unsigned int affectorNr);
+            void removeAffector(unsigned int affectorNr);
+            void removeAllAffectors();
+            unsigned int getNumAffectors() const;
+
+            inline float getSpeedFactor() const
+                { return this->speedFactor_; }
+            void setSpeedFactor(float factor);
+            bool getKeepParticlesInLocalSpace() const;
+            void setKeepParticlesInLocalSpace(bool keep);
+
+            void setEnabled(bool enable);
+            inline bool isEnabled() const
+                { return this->bEnabled_; }
+
+            void setVisible(bool visible);
+            inline bool isVisible() const
+                { return this->bVisible_; }
+
+            void setDetailLevel(unsigned int level);
+
+            inline void storeThisAsCurrentParticleInterface()
+                { ParticleInterface::currentParticleInterface_s = this; }
+            inline static ParticleInterface* getCurrentParticleInterface()
+                { return ParticleInterface::currentParticleInterface_s; }
+
+        protected:
+            virtual void changedTimeFactor(float factor_new, float factor_old);
+
+        private:
+            void updateVisibility();
+            void detailLevelChanged();
+
+            Ogre::ParticleSystem*     particleSystem_;
+            Ogre::SceneManager*       scenemanager_;
+            bool                      bVisible_;
+            bool                      bEnabled_;
+            bool                      bAllowedByLOD_;
+            unsigned int              detaillevel_;       //!< Detail level of this particle effect (0: off, 1: low, 2: normal, 3: high)
+            float                     speedFactor_;
+
+            // config values
+            unsigned int              globalDetailLevel_; //!< Global maximum detail level of particle effects (0: off, 1: low, 2: normal, 3: high)
+
+            static ParticleInterface* currentParticleInterface_s;
+            static unsigned int       counter_s;
+    };
+}
+
+#endif /* _ParticleInterface_H__ */
Index: /code/branches/rocket2/src/libraries/tools/ResourceCollection.cc
===================================================================
--- /code/branches/rocket2/src/libraries/tools/ResourceCollection.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/ResourceCollection.cc	(revision 6952)
@@ -0,0 +1,99 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ResourceCollection.h"
+
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "core/Resource.h"
+#include "core/XMLPort.h"
+#include "ResourceLocation.h"
+
+namespace orxonox
+{
+    CreateFactory(ResourceCollection);
+
+    ResourceCollection::ResourceCollection(BaseObject* creator)
+        : BaseObject(creator)
+    {
+        RegisterObject(ResourceCollection);
+
+        // Default group is "General"
+        this->setResourceGroup(Resource::DEFAULT_GROUP);
+    }
+
+    ResourceCollection::~ResourceCollection()
+    {
+    }
+
+    void ResourceCollection::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        XMLPortParam(ResourceCollection, "resourceGroup", setResourceGroup, getResourceGroup, xmlElement, mode);
+        XMLPortObject(ResourceCollection, ResourceLocation, "", addResourceLocation, getResourceLocation, xmlElement, mode);
+    }
+
+    void ResourceCollection::setResourceGroup(const std::string& resourceGroup)
+    {
+        if (resourceGroup.empty())
+        {
+            COUT(2) << "Warning: \"\" is not a valid resource group." << std::endl;
+            return;
+        }
+        if (!resourceLocations_.empty())
+            ThrowException(InitialisationFailed, "ResourceGroup: Group change not allowed with locations already added!");
+        resourceGroup_ = resourceGroup;
+    }
+
+    void ResourceCollection::addResourceLocation(ResourceLocation* location)
+    {
+        location->load(resourceGroup_);
+        this->resourceLocations_.push_back(location);
+    }
+
+    void ResourceCollection::removeResourceLocation(ResourceLocation* location)
+    {
+        for (std::vector<ResourceLocation*>::iterator it = resourceLocations_.begin(); it != resourceLocations_.end(); )
+        {
+            if (*it == location)
+            {
+                it = resourceLocations_.erase(it);
+                location->unload(); // doesn't throw
+            }
+            else
+                ++it;
+        }
+    }
+
+    ResourceLocation* ResourceCollection::getResourceLocation(unsigned int index) const
+    {
+        if (index >= resourceLocations_.size())
+            return NULL;
+        else
+            return resourceLocations_[index];
+    }
+}
Index: /code/branches/rocket2/src/libraries/tools/ResourceCollection.h
===================================================================
--- /code/branches/rocket2/src/libraries/tools/ResourceCollection.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/ResourceCollection.h	(revision 6952)
@@ -0,0 +1,63 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ResourceCollection_H__
+#define _ResourceCollection_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include <string>
+#include <vector>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _ToolsExport ResourceCollection : public BaseObject
+    {
+    public:
+        ResourceCollection(BaseObject* creator);
+        virtual ~ResourceCollection();
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+
+        void setResourceGroup(const std::string& resourceGroup);
+        const std::string& getResourceGroup() const { return resourceGroup_; }
+
+        void addResourceLocation(ResourceLocation* location);
+        void removeResourceLocation(ResourceLocation* location);
+        ResourceLocation* getResourceLocation(unsigned int index) const;
+
+    private:
+        ResourceCollection(const ResourceCollection&);
+
+        std::string resourceGroup_;
+        std::vector<ResourceLocation*> resourceLocations_;
+    };
+}
+
+#endif /* _ResourceCollection_H__ */
Index: /code/branches/rocket2/src/libraries/tools/ResourceLocation.cc
===================================================================
--- /code/branches/rocket2/src/libraries/tools/ResourceLocation.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/ResourceLocation.cc	(revision 6952)
@@ -0,0 +1,105 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ResourceLocation.h"
+
+#include <OgreResourceGroupManager.h>
+#include <boost/filesystem.hpp>
+
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "core/PathConfig.h"
+#include "core/XMLFile.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(ResourceLocation);
+
+    ResourceLocation::ResourceLocation(BaseObject* creator)
+        : BaseObject(creator)
+    {
+        RegisterObject(ResourceLocation);
+
+        // Default values
+        archiveType_ = "FileSystem";
+        bRecursive_  = true;
+    }
+
+    ResourceLocation::~ResourceLocation()
+    {
+    }
+
+    void ResourceLocation::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        XMLPortParam(ResourceLocation, "path",        setPath,        getPath,        xmlElement, mode);
+        XMLPortParam(ResourceLocation, "archiveType", setArchiveType, getArchiveType, xmlElement, mode);
+        XMLPortParam(ResourceLocation, "recursive",   setRecursive,   getRecursive,   xmlElement, mode);
+        if (path_.empty())
+            ThrowException(AbortLoading, "ResourceLocation: No path given.");
+    }
+
+    void ResourceLocation::load(const std::string& resourceGroup)
+    {
+        if (path_.empty())
+            ThrowException(InitialisationFailed, "ResourceLocation: Trying to add one without the path being set");
+
+        // Find the path
+        namespace bf = boost::filesystem;
+        bf::path path;
+        if (bf::exists(PathConfig::getDataPath() / this->getPath()))
+            path = PathConfig::getDataPath() / this->getPath();
+        else if (PathConfig::isDevelopmentRun() && bf::exists(PathConfig::getExternalDataPath() / this->getPath()))
+            path = PathConfig::getExternalDataPath() / this->getPath();
+        else
+        {
+            COUT(2) << "Warning: ResourceLocation '" << this->getPath() << "' does not seem to exist" << std::endl;
+            return;
+        }
+
+        // Add it to the Ogre paths
+        Ogre::ResourceGroupManager::getSingleton().addResourceLocation(
+            path.string(), this->getArchiveType(), resourceGroup, this->getRecursive());
+        resourceGroup_ = resourceGroup;
+    }
+
+    void ResourceLocation::unload()
+    {
+        // Remove from Ogre paths
+        resourceGroup_.clear();
+        try
+        {
+            Ogre::ResourceGroupManager::getSingleton().removeResourceLocation(
+                this->getPath(), this->getResourceGroup());
+        }
+        catch (...)
+        {
+            COUT(1) << "Removing of a ResourceLocation failed: " << Exception::handleMessage() << std::endl;
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/tools/ResourceLocation.h
===================================================================
--- /code/branches/rocket2/src/libraries/tools/ResourceLocation.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/ResourceLocation.h	(revision 6952)
@@ -0,0 +1,74 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ResourceLocation_H__
+#define _ResourceLocation_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include <string>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _ToolsExport ResourceLocation : public BaseObject
+    {
+        // for load/unload
+        friend class ResourceCollection;
+
+    public:
+        ResourceLocation(BaseObject* creator);
+        virtual ~ResourceLocation();
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+
+        void setPath(const std::string& path) { path_ = path; }
+        const std::string& getPath() const { return path_; }
+
+        void setArchiveType(const std::string& archiveType) { archiveType_ = archiveType; }
+        const std::string& getArchiveType() const { return archiveType_; }
+
+        void setRecursive(bool bRecursive) { bRecursive_ = bRecursive; }
+        bool getRecursive() const { return bRecursive_; }
+
+        const std::string& getResourceGroup() const { return resourceGroup_; }
+
+    private:
+        ResourceLocation(const ResourceLocation&);
+
+        void load(const std::string& resourceGroup);
+        void unload();
+
+        std::string path_;
+        std::string archiveType_;
+        std::string resourceGroup_;
+        bool bRecursive_;
+    };
+}
+
+#endif /* _ResourceLocation_H__ */
Index: /code/branches/rocket2/src/libraries/tools/Shader.cc
===================================================================
--- /code/branches/rocket2/src/libraries/tools/Shader.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/Shader.cc	(revision 6952)
@@ -0,0 +1,329 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Shader.h"
+
+#include <OgreCompositorManager.h>
+#include <OgreCompositorInstance.h>
+#include <OgreSceneManager.h>
+#include <OgreRoot.h>
+#include <OgrePlugin.h>
+#include <OgreMaterial.h>
+#include <OgreTechnique.h>
+#include <OgrePass.h>
+#include <OgreMaterialManager.h>
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/GraphicsManager.h"
+
+namespace orxonox
+{
+    bool Shader::bLoadedCgPlugin_s = false;
+    Shader::MaterialMap Shader::parameters_s;
+
+    Shader::Shader(Ogre::SceneManager* scenemanager) : compositorInstance_(0)
+    {
+        RegisterObject(Shader);
+
+        this->scenemanager_ = scenemanager;
+        this->compositorInstance_ = 0;
+        this->bVisible_ = true;
+        this->bLoadCompositor_ = GameMode::showsGraphics();
+        this->bViewportInitialized_ = false;
+
+        if (this->bLoadCompositor_ && Ogre::Root::getSingletonPtr())
+        {
+            Shader::bLoadedCgPlugin_s = false;
+            const Ogre::Root::PluginInstanceList& plugins = Ogre::Root::getSingleton().getInstalledPlugins();
+            for (size_t i = 0; i < plugins.size(); ++i)
+            {
+                if (plugins[i]->getName() == "Cg Program Manager")
+                {
+                    Shader::bLoadedCgPlugin_s = true;
+                    break;
+                }
+            }
+        }
+
+        this->bLoadCompositor_ &= Shader::bLoadedCgPlugin_s;
+    }
+
+    Shader::~Shader()
+    {
+        if (this->compositorInstance_ && this->bLoadCompositor_)
+        {
+            Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
+            assert(viewport);
+            Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->compositor_);
+        }
+
+    }
+
+    void Shader::setSceneManager(Ogre::SceneManager* scenemanager)
+    {
+        this->scenemanager_ = scenemanager;
+        this->bViewportInitialized_ = false;
+    }
+
+    void Shader::tick(float dt)
+    {
+        SUPER(Shader, tick, dt);
+
+        if (this->bLoadCompositor_ && !this->bViewportInitialized_ && this->scenemanager_ && this->scenemanager_->getCurrentViewport())
+        {
+            this->bViewportInitialized_ = true;
+            this->updateVisibility();
+        }
+    }
+
+    void Shader::changedCompositor()
+    {
+        if (this->bLoadCompositor_)
+        {
+            Ogre::Viewport* viewport = GraphicsManager::getInstance().getViewport();
+            assert(viewport);
+            if (!this->oldcompositor_.empty())
+            {
+                Ogre::CompositorManager::getSingleton().removeCompositor(viewport, this->oldcompositor_);
+                this->compositorInstance_ = 0;
+            }
+            if (!this->compositor_.empty())
+            {
+                this->compositorInstance_ = Ogre::CompositorManager::getSingleton().addCompositor(viewport, this->compositor_);
+                if (!this->compositorInstance_)
+                    COUT(2) << "Warning: Couldn't load compositor with name \"" << this->compositor_ << "\"." << std::endl;
+                Ogre::CompositorManager::getSingleton().setCompositorEnabled(viewport, this->compositor_, this->bViewportInitialized_ && this->isVisible());
+            }
+            this->oldcompositor_ = this->compositor_;
+        }
+    }
+
+    void Shader::updateVisibility()
+    {
+        if (this->compositorInstance_ && this->scenemanager_)
+            this->compositorInstance_->setEnabled(this->scenemanager_->getCurrentViewport() && this->isVisible());
+    }
+
+    void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
+    {
+        if (Shader::_setParameter(material, technique, pass, parameter, value))
+        {
+            if (this->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
+            {
+                this->compositorInstance_->setEnabled(false);
+                this->compositorInstance_->setEnabled(true);
+            }
+        }
+    }
+
+    void Shader::setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
+    {
+        if (Shader::_setParameter(material, technique, pass, parameter, value))
+        {
+            if (this->bViewportInitialized_ && this->compositorInstance_ && this->isVisible())
+            {
+                this->compositorInstance_->setEnabled(false);
+                this->compositorInstance_->setEnabled(true);
+            }
+        }
+    }
+
+    bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value)
+    {
+        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
+        if (pointer)
+        {
+            if (pointer->first)
+            {
+                if ((*static_cast<float*>(pointer->second)) != value)
+                {
+                    (*static_cast<float*>(pointer->second)) = value;
+                    return true;
+                }
+            }
+            else
+            {
+                if ((*static_cast<int*>(pointer->second)) != static_cast<int>(value))
+                {
+                    (*static_cast<int*>(pointer->second)) = static_cast<int>(value);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    bool Shader::_setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value)
+    {
+        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
+        if (pointer)
+        {
+            if (pointer->first)
+            {
+                if ((*static_cast<float*>(pointer->second)) != static_cast<float>(value))
+                {
+                    (*static_cast<float*>(pointer->second)) = static_cast<float>(value);
+                    return true;
+                }
+            }
+            else
+            {
+                if ((*static_cast<int*>(pointer->second)) != value)
+                {
+                    (*static_cast<int*>(pointer->second)) = value;
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    float Shader::getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
+    {
+        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
+        if (pointer)
+        {
+            if (pointer->first)
+                return (*static_cast<float*>(pointer->second));
+            else
+                return static_cast<float>(*static_cast<int*>(pointer->second));
+        }
+        else
+            return 0;
+    }
+
+    bool Shader::getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
+    {
+        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
+        if (pointer)
+            return pointer->first;
+        else
+            return false;
+    }
+
+    bool Shader::getParameterIsInt(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
+    {
+        ParameterPointer* pointer = Shader::getParameterPointer(material, technique, pass, parameter);
+        if (pointer)
+            return (!pointer->first);
+        else
+            return false;
+    }
+
+    Shader::ParameterPointer* Shader::getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter)
+    {
+        if (!GameMode::showsGraphics() || !Shader::bLoadedCgPlugin_s)
+            return 0;
+
+        MaterialMap::iterator material_iterator = Shader::parameters_s.find(material);
+        if (material_iterator != Shader::parameters_s.end())
+        {
+            TechniqueVector& technique_vector = material_iterator->second;
+            if (technique < technique_vector.size())
+            {
+                PassVector& pass_vector = technique_vector[technique];
+                if (pass < pass_vector.size())
+                {
+                    ParameterMap& parameter_map = pass_vector[pass];
+                    ParameterMap::iterator parameter_iterator = parameter_map.find(parameter);
+
+                    if (parameter_iterator != parameter_map.end())
+                        return (&parameter_iterator->second);
+                    else
+                        COUT(2) << "Warning: No shader parameter \"" << parameter << "\" in pass " << pass << " in technique " << technique << " in material \"" << material << "\"." << std::endl;
+                }
+                else
+                    COUT(2) << "Warning: No pass " << pass << " in technique " << technique << " in material \"" << material << "\" or pass has no shader." << std::endl;
+            }
+            else
+                COUT(2) << "Warning: No technique " << technique << " in material \"" << material << "\" or technique has no pass with shader." << std::endl;
+        }
+        else
+        {
+            bool foundAtLeastOneShaderParameter = false;
+            Ogre::MaterialManager::ResourceMapIterator iterator = Ogre::MaterialManager::getSingleton().getResourceIterator();
+            Ogre::Material* material_pointer = 0;
+
+            while (iterator.hasMoreElements())
+            {
+                Ogre::Resource* resource = iterator.getNext().get();
+                if (resource->getName() == material)
+                    material_pointer = (Ogre::Material*)resource;
+            }
+
+            if (!material_pointer)
+            {
+                COUT(2) << "Warning: No material with name \"" << material << "\" found." << std::endl;
+                return 0;
+            }
+
+            for (unsigned int t = 0; t < material_pointer->getNumTechniques(); ++t)
+            {
+                Ogre::Technique* technique_pointer = material_pointer->getTechnique(t);
+                if (!technique_pointer)
+                    continue;
+
+                for (unsigned int p = 0; p < technique_pointer->getNumPasses(); ++p)
+                {
+                    Ogre::Pass* pass_pointer = technique_pointer->getPass(p);
+                    if (!pass_pointer)
+                        continue;
+
+                    if (!pass_pointer->getFragmentProgramName().empty())
+                    {
+                        Ogre::GpuProgramParameters* parameter_pointer = pass_pointer->getFragmentProgramParameters().get();
+                        if (!parameter_pointer)
+                            continue;
+
+                        const Ogre::GpuConstantDefinitionMap& constant_definitions = parameter_pointer->getConstantDefinitions().map;
+                        for (Ogre::GpuConstantDefinitionMap::const_iterator definition_iterator = constant_definitions.begin(); definition_iterator != constant_definitions.end(); ++definition_iterator)
+                        {
+                            void* temp = (definition_iterator->second.isFloat())
+                                            ? static_cast<void*>(parameter_pointer->getFloatPointer(definition_iterator->second.physicalIndex))
+                                            : static_cast<void*>(parameter_pointer->getIntPointer(definition_iterator->second.physicalIndex));
+                            ParameterPointer parameter_pointer = ParameterPointer(definition_iterator->second.isFloat(), temp);
+
+                            TechniqueVector& technique_vector = Shader::parameters_s[material];
+                            technique_vector.resize(technique + 1);
+                            PassVector& pass_vector = technique_vector[technique];
+                            pass_vector.resize(pass + 1);
+                            pass_vector[pass][definition_iterator->first] = parameter_pointer;
+                            foundAtLeastOneShaderParameter = true;
+                        }
+                    }
+                }
+            }
+
+            // recursive call if the material was added to the map
+            if (foundAtLeastOneShaderParameter)
+                return Shader::getParameterPointer(material, technique, pass, parameter);
+        }
+        return 0;
+    }
+}
Index: /code/branches/rocket2/src/libraries/tools/Shader.h
===================================================================
--- /code/branches/rocket2/src/libraries/tools/Shader.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/Shader.h	(revision 6952)
@@ -0,0 +1,109 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Shader_H__
+#define _Shader_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "util/OgreForwardRefs.h"
+#include "tools/interfaces/Tickable.h"
+
+namespace orxonox
+{
+    class _ToolsExport Shader : public Tickable
+    {
+        typedef std::pair<bool, void*>                  ParameterPointer;
+        typedef std::map<std::string, ParameterPointer> ParameterMap;
+        typedef std::vector<ParameterMap>               PassVector;
+        typedef std::vector<PassVector>                 TechniqueVector;
+        typedef std::map<std::string, TechniqueVector>  MaterialMap;
+
+        public:
+            Shader(Ogre::SceneManager* scenemanager = 0);
+            virtual ~Shader();
+
+            virtual void tick(float dt);
+
+            inline void setVisible(bool bVisible)
+            {
+                if (this->bVisible_ != bVisible)
+                {
+                    this->bVisible_ = bVisible;
+                    this->updateVisibility();
+                }
+            }
+            inline bool isVisible() const
+                { return this->bVisible_; }
+            void updateVisibility();
+
+            inline void setCompositor(const std::string& compositor)
+            {
+                if (this->compositor_ != compositor)
+                {
+                    this->compositor_ = compositor;
+                    this->changedCompositor();
+                }
+            }
+            inline const std::string& getCompositor() const
+                { return this->compositor_; }
+            void changedCompositor();
+
+            void setSceneManager(Ogre::SceneManager* scenemanager);
+            inline Ogre::SceneManager* getSceneManager() const
+                { return this->scenemanager_; }
+
+            void setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value);
+            void setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value);
+
+            static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, float value);
+            static bool _setParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter, int value);
+            static float getParameter(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
+            static bool  getParameterIsFloat(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
+            static bool  getParameterIsInt  (const std::string& material, size_t technique, size_t pass, const std::string& parameter);
+            static ParameterPointer* getParameterPointer(const std::string& material, size_t technique, size_t pass, const std::string& parameter);
+
+        private:
+            Ogre::SceneManager* scenemanager_;
+            Ogre::CompositorInstance* compositorInstance_;
+            bool bVisible_;
+            bool bLoadCompositor_;
+            bool bViewportInitialized_;
+            std::string compositor_;
+            std::string oldcompositor_;
+
+            static MaterialMap parameters_s;
+            static bool bLoadedCgPlugin_s;
+    };
+}
+
+#endif /* _Shader_H__ */
Index: /code/branches/rocket2/src/libraries/tools/TextureGenerator.cc
===================================================================
--- /code/branches/rocket2/src/libraries/tools/TextureGenerator.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/TextureGenerator.cc	(revision 6952)
@@ -0,0 +1,87 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the TextureGenerator.
+*/
+
+#include "TextureGenerator.h"
+
+#include <OgreMaterialManager.h>
+#include <OgreTechnique.h>
+#include "util/Convert.h"
+#include "util/Math.h"
+
+namespace std
+{
+    template <>
+    inline bool less<orxonox::ColourValue>::operator()(const orxonox::ColourValue& __x, const orxonox::ColourValue& __y) const
+    {
+        if (__x.r == __y.r)
+        {
+            if (__x.g == __y.g)
+            {
+                if (__x.b == __y.b)
+                {
+                    return __x.a < __y.a;
+                }
+                return __x.b < __y.b;
+            }
+            return __x.g < __y.g;
+        }
+        return __x.r < __y.r;
+    }
+}
+
+namespace orxonox
+{
+    std::map<std::string, std::map<ColourValue, std::string> > TextureGenerator::materials_s;
+    unsigned int TextureGenerator::materialCount_s = 0;
+
+    /*static*/ const std::string& TextureGenerator::getMaterialName(const std::string& textureName, const ColourValue& colour)
+    {
+        std::map<ColourValue, std::string>& colourMap = materials_s[textureName];
+        std::map<ColourValue, std::string>::const_iterator it = colourMap.find(colour);
+
+        if (it == colourMap.end())
+        {
+            const std::string& materialName = textureName + "_Material_" + multi_cast<std::string>(materialCount_s++);
+            Ogre::MaterialPtr material = static_cast<Ogre::MaterialPtr>(Ogre::MaterialManager::getSingleton().create(materialName, "General"));
+            material->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
+            Ogre::TextureUnitState* textureUnitState = material->getTechnique(0)->getPass(0)->createTextureUnitState();
+            textureUnitState->setTextureName(textureName);
+            textureUnitState->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, colour);
+            return (colourMap[colour] = materialName);
+        }
+        else
+        {
+            return it->second;
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/tools/TextureGenerator.h
===================================================================
--- /code/branches/rocket2/src/libraries/tools/TextureGenerator.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/TextureGenerator.h	(revision 6952)
@@ -0,0 +1,60 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+/**
+    @file
+    @brief
+*/
+
+#ifndef _TextureGenerator_H__
+#define _TextureGenerator_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include <map>
+#include <string>
+#include "util/UtilPrereqs.h"
+
+namespace orxonox
+{
+    class _ToolsExport TextureGenerator
+    {
+    public:
+        static const std::string& getMaterialName(const std::string& textureName, const ColourValue& colour);
+
+    private:
+        TextureGenerator();
+        TextureGenerator(const TextureGenerator&);
+        ~TextureGenerator();
+
+        static std::map<std::string, std::map<ColourValue, std::string> > materials_s;
+        static unsigned int materialCount_s;
+    };
+}
+
+#endif /* _TextureGenerator_H__ */
Index: /code/branches/rocket2/src/libraries/tools/Timer.cc
===================================================================
--- /code/branches/rocket2/src/libraries/tools/Timer.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/Timer.cc	(revision 6952)
@@ -0,0 +1,181 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Timer.h"
+
+#include <set>
+
+#include "util/Clock.h"
+#include "core/CoreIncludes.h"
+#include "core/ConsoleCommand.h"
+#include "core/CommandExecutor.h"
+#include "core/Functor.h"
+
+namespace orxonox
+{
+    SetConsoleCommandShortcutExtern(delay);
+    SetConsoleCommandShortcutExtern(killdelays);
+
+    static std::set<Timer*> delaytimerset;
+
+    /**
+        @brief Calls a console command after 'delay' seconds.
+        @param delay The delay in seconds
+        @param command The console command
+    */
+    void delay(float delay, const std::string& command)
+    {
+        Timer* delaytimer = new Timer();
+        delaytimerset.insert(delaytimer);
+
+        ExecutorStatic* delayexecutor = createExecutor(createFunctor(&executeDelayedCommand));
+        delayexecutor->setDefaultValues(delaytimer, command);
+        delaytimer->setTimer(delay, false, delayexecutor);
+    }
+
+    /**
+        @brief Executes the command.
+        @param timer The timer to destroy after the command-execution
+        @param command The command to execute
+    */
+    void executeDelayedCommand(Timer* timer, const std::string& command)
+    {
+        CommandExecutor::execute(command);
+        timer->destroy();
+        delaytimerset.erase(timer);
+    }
+
+    /**
+        @brief Kills all delayed commands.
+    */
+    void killdelays()
+    {
+        for (std::set<Timer*>::iterator it = delaytimerset.begin(); it != delaytimerset.end(); ++it)
+            (*it)->destroy();
+
+        delaytimerset.clear();
+    }
+
+    /**
+        @brief Constructor: Sets the default-values.
+    */
+    Timer::Timer()
+    {
+        this->init();
+        RegisterObject(Timer);
+    }
+
+    /**
+        @brief Constructor: Initializes the Timer with given values.
+        @param interval The timer-interval in seconds
+        @param bLoop If true, the function gets called every 'interval' seconds
+        @param exeuctor A executor of the function to call
+    */
+    Timer::Timer(float interval, bool bLoop, Executor* executor, bool bKillAfterCall)
+    {
+        this->init();
+        RegisterObject(Timer);
+
+        this->setTimer(interval, bLoop, executor, bKillAfterCall);
+    }
+
+    /**
+        @brief Deletes the executor.
+    */
+    Timer::~Timer()
+    {
+        this->deleteExecutor();
+    }
+
+    /**
+        @brief Initializes the Timer
+    */
+    void Timer::init()
+    {
+        this->executor_ = 0;
+        this->interval_ = 0;
+        this->bLoop_ = false;
+        this->bActive_ = false;
+        this->bKillAfterCall_ = false;
+
+        this->time_ = 0;
+    }
+
+    /**
+        @brief Executes the executor.
+    */
+    void Timer::run()
+    {
+        bool temp = this->bKillAfterCall_; // to avoid errors with bKillAfterCall_=false and an exutors which destroy the timer
+
+        (*this->executor_)();
+
+        if (temp)
+            this->destroy();
+    }
+
+    /**
+        @brief Deletes the executor.
+    */
+    void Timer::deleteExecutor()
+    {
+      if (this->executor_)
+          delete this->executor_;
+    }
+
+    /**
+        @brief Updates the timer before the frames are rendered.
+    */
+    void Timer::tick(const Clock& time)
+    {
+        if (this->bActive_)
+        {
+            // If active: Decrease the timer by the duration of the last frame
+            this->time_ -= static_cast<long long>(time.getDeltaTimeMicroseconds() * this->getTimeFactor());
+
+            if (this->time_ <= 0)
+            {
+                // It's time to call the function
+                if (this->bLoop_ && !this->bKillAfterCall_)
+                {
+                    this->time_ += this->interval_; // Q: Why '+=' and not '='? A: Think about it. It's more accurate like that. Seriously.
+                    while (this->time_ <= 0)
+                    {
+                        // The interval was shorter than one tick, so execute the function more than once
+                        this->run();
+                        this->time_ += this->interval_;
+                    }
+                }
+                else
+                    this->stopTimer(); // Stop the timer if we don't want to loop
+
+                this->run();
+            }
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/tools/Timer.h
===================================================================
--- /code/branches/rocket2/src/libraries/tools/Timer.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/Timer.h	(revision 6952)
@@ -0,0 +1,154 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/*!
+    @file
+    @brief Definition and Implementation of the Timer class.
+
+    The Timer is a callback-object, calling a given function after a given time-interval.
+
+    Usage:
+    header.h:
+        class ClassName
+        {
+            public:
+                ClassName();
+                void functionName();
+                Timer myTimer;
+        };
+
+    source.cc:
+        include "core/Executor.h"
+
+        ClassName::ClassName()
+        {
+            myTimer.setTimer(interval_in_seconds, bLoop, createExecutor(createFunctor(&ClassName::functionName, this)));
+        }
+
+        void ClassName::functionName()
+        {
+            whateveryouwant();
+            something(else);
+        }
+*/
+
+#ifndef _Timer_H__
+#define _Timer_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include "core/Executor.h"
+#include "core/OrxonoxClass.h"
+#include "tools/interfaces/TimeFactorListener.h"
+
+namespace orxonox
+{
+    void delay(float delay, const std::string& command);
+    void killdelays();
+    void executeDelayedCommand(Timer* timer, const std::string& command);
+
+    //! The Timer is a callback-object, calling a given function after a given time-interval.
+    class _ToolsExport Timer : public TimeFactorListener
+    {
+        public:
+            Timer();
+            ~Timer();
+
+            Timer(float interval, bool bLoop, Executor* executor, bool bKillAfterCall = false);
+
+            /**
+                @brief Initializes the Timer with given values.
+                @param interval The timer-interval in seconds
+                @param bLoop If true, the function gets called every 'interval' seconds
+                @param object The object owning the timer and the function
+                @param executor A executor of the function to call
+            */
+            void setTimer(float interval, bool bLoop, Executor* executor, bool bKillAfterCall = false)
+            {
+                this->deleteExecutor();
+
+                this->setInterval(interval);
+                this->bLoop_ = bLoop;
+                this->executor_ = executor;
+                this->bActive_ = true;
+
+                this->time_ = this->interval_;
+                this->bKillAfterCall_ = bKillAfterCall;
+            }
+
+            void run();
+            void deleteExecutor();
+
+            /** @brief Starts the Timer: Function-call after 'interval' seconds. */
+            inline void startTimer()
+                { this->bActive_ = true; this->time_ = this->interval_; }
+            /** @brief Stops the Timer. */
+            inline void stopTimer()
+                { this->bActive_ = false; this->time_ = this->interval_; }
+            /** @brief Pauses the Timer - it will continue with the actual state if you unpause it. */
+            inline void pauseTimer()
+                { this->bActive_ = false; }
+            /** @brief Unpauses the Timer - continues with the given state. */
+            inline void unpauseTimer()
+                { this->bActive_ = true; }
+            /** @brief Returns true if the Timer is active (= not stoped, not paused). @return True = Time is active */
+            inline bool isActive() const
+                { return this->bActive_; }
+            /** @brief Returns the remaining time until the Timer calls the function. @return The remaining time */
+            inline float getRemainingTime() const
+                { return static_cast<float>(this->time_ / 1000000.0f); }
+            /** @brief Gives the Timer some extra time. @param time The amount of extra time in seconds */
+            inline void addTime(float time)
+                { if (time > 0.0f) this->time_ += static_cast<long long>(time * 1000000.0f); }
+            /** @brief Decreases the remaining time of the Timer. @param time The amount of time to remove */
+            inline void removeTime(float time)
+                { if (time > 0.0f) this->time_ -= static_cast<long long>(time * 1000000.0f); }
+            /** @brief Sets the interval of the Timer. @param interval The interval */
+            inline void setInterval(float interval)
+                { this->interval_ = static_cast<long long>(interval * 1000000.0f); }
+            /** @brief Sets bLoop to a given value. @param bLoop True = loop */
+            inline void setLoop(bool bLoop)
+                { this->bLoop_ = bLoop; }
+
+            void tick(const Clock& time);
+
+        private:
+            void init();
+
+            Executor* executor_;  //!< The executor of the function that should be called when the time expires
+
+            long long interval_;  //!< The time-interval in micro seconds
+            bool bLoop_;          //!< If true, the function gets called every 'interval' seconds
+            bool bActive_;        //!< If true, the Timer ticks and calls the function if the time's up
+            bool bKillAfterCall_; //!< If true the timer gets deleted after it called the function
+
+            long long time_;      //!< Internal variable, counting the time till the next function-call
+    };
+}
+
+#endif /* _Timer_H__ */
Index: /code/branches/rocket2/src/libraries/tools/ToolsPrereqs.h
===================================================================
--- /code/branches/rocket2/src/libraries/tools/ToolsPrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/ToolsPrereqs.h	(revision 6952)
@@ -0,0 +1,102 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Shared library macros, enums, constants and forward declarations for the tools module
+*/
+
+#ifndef _ToolsPrereqs_H__
+#define _ToolsPrereqs_H__
+
+#include "OrxonoxConfig.h"
+
+//-----------------------------------------------------------------------
+// Shared library settings
+//-----------------------------------------------------------------------
+
+#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined(ORXONOX_STATIC_BUILD)
+#  ifdef TOOLS_SHARED_BUILD
+#    define _ToolsExport __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define _ToolsExport
+#    else
+#      define _ToolsExport __declspec(dllimport)
+#    endif
+#  endif
+#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _ToolsExport  __attribute__ ((visibility("default")))
+#else
+#  define _ToolsExport
+#endif
+
+//-----------------------------------------------------------------------
+// Enums
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    namespace LODParticle
+    {
+        enum Value
+        {
+            Off = 0,
+            Low = 1,
+            Normal = 2,
+            High = 3
+        };
+    }
+}
+
+//-----------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    class BillboardSet;
+    class Mesh;
+    class ParticleInterface;
+    class ResourceCollection;
+    class ResourceLocation;
+    class Shader;
+    class Tickable;
+    class TimeFactorListener;
+    class Timer;
+}
+
+namespace Ogre
+{
+    // OGRE Wiki adapted code
+    class DynamicLines;
+    class DynamicRenderable;
+}
+
+#endif /* _ToolsPrereqs_H__ */
Index: /code/branches/rocket2/src/libraries/tools/interfaces/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/libraries/tools/interfaces/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/interfaces/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,3 @@
+ADD_SOURCE_FILES(TOOLS_SRC_FILES
+  ToolsInterfaceCompilation.cc
+)
Index: /code/branches/rocket2/src/libraries/tools/interfaces/Tickable.h
===================================================================
--- /code/branches/rocket2/src/libraries/tools/interfaces/Tickable.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/interfaces/Tickable.h	(revision 6952)
@@ -0,0 +1,68 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/*!
+    @file
+    @brief Declaration of the Tickable interface.
+
+    The Tickable interface provides a tick(dt) function, that gets called every frame.
+    float dt is the time since the last frame in seconds.
+
+    Attention:
+    Classes derived from a Tickable that want to have a tick(dt) function on their part, MUST call the
+    parent::tick(dt) function explicitly in their implementation of tick(dt) because it's a virtual function.
+*/
+
+#ifndef _Tickable_H__
+#define _Tickable_H__
+
+#include "tools/ToolsPrereqs.h"
+
+#include "core/OrxonoxClass.h"
+#include "core/Super.h"
+
+namespace orxonox
+{
+    //! The Tickable interface provides a tick(dt) function, that gets called every frame.
+    class _ToolsExport Tickable : virtual public OrxonoxClass
+    {
+        public:
+            /**
+                @brief Gets called every frame.
+                @param dt The time since the last frame in seconds
+            */
+            virtual void tick(float dt) { }
+
+        protected:
+            Tickable();
+    };
+
+    SUPER_FUNCTION(1, Tickable, tick, true);
+}
+
+#endif /* _Tickable_H__ */
Index: /code/branches/rocket2/src/libraries/tools/interfaces/TimeFactorListener.h
===================================================================
--- /code/branches/rocket2/src/libraries/tools/interfaces/TimeFactorListener.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/interfaces/TimeFactorListener.h	(revision 6952)
@@ -0,0 +1,55 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TimeFactorListener_H__
+#define _TimeFactorListener_H__
+
+#include "tools/ToolsPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _ToolsExport TimeFactorListener : virtual public OrxonoxClass
+    {
+        public:
+            TimeFactorListener();
+            virtual ~TimeFactorListener() {}
+
+            static void setTimeFactor( float factor );
+            static void setTimeFactorInternal( float factor );
+            static inline float getTimeFactor(){ return TimeFactorListener::timefactor_s; }
+
+        protected:
+            virtual void changedTimeFactor(float factor_new, float factor_old) {}
+
+        private:
+            static float timefactor_s;
+    };
+}
+
+#endif /* _TimeFactorListener_H__ */
Index: /code/branches/rocket2/src/libraries/tools/interfaces/ToolsInterfaceCompilation.cc
===================================================================
--- /code/branches/rocket2/src/libraries/tools/interfaces/ToolsInterfaceCompilation.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/tools/interfaces/ToolsInterfaceCompilation.cc	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Compiles all the interfaces in the tools library with mostly just a constructor.
+*/
+
+#include "Tickable.h"
+#include "TimeFactorListener.h"
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "network/NetworkFunction.h"
+
+namespace orxonox
+{
+    //----------------------------
+    // TimeFactorListener
+    //----------------------------
+    registerStaticNetworkFunction( &TimeFactorListener::setTimeFactorInternal );
+
+    float TimeFactorListener::timefactor_s = 1.0f;
+
+    TimeFactorListener::TimeFactorListener()
+    {
+        RegisterRootObject(TimeFactorListener);
+    }
+
+    /*static*/ void TimeFactorListener::setTimeFactor( float factor )
+    {
+        if ( !GameMode::isStandalone() )
+            callStaticNetworkFunction( &TimeFactorListener::setTimeFactorInternal, CLIENTID_UNKNOWN, factor );
+        TimeFactorListener::setTimeFactorInternal(factor);
+    }
+
+    /*static*/ void TimeFactorListener::setTimeFactorInternal( float factor )
+    {
+        float oldFactor = TimeFactorListener::timefactor_s;
+        TimeFactorListener::timefactor_s = factor;
+        for (ObjectList<TimeFactorListener>::iterator it = ObjectList<TimeFactorListener>::begin(); it != ObjectList<TimeFactorListener>::end(); ++it)
+            it->changedTimeFactor(factor, oldFactor);
+    }
+
+    //----------------------------
+    // Tickable
+    //----------------------------
+    /**
+        @brief Constructor: Registers the object in the Tickable-list
+    */
+    Tickable::Tickable()
+    {
+        RegisterRootObject(Tickable);
+    }
+}
Index: /code/branches/rocket2/src/libraries/util/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/libraries/util/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,58 @@
+ #
+ #             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.
+ #
+
+SET_SOURCE_FILES(UTIL_SRC_FILES
+  Exception.cc
+  Math.cc
+  MultiType.cc
+  Scope.cc
+  StringUtils.cc
+COMPILATION_BEGIN StableCompilation.cc
+  Clipboard.cc
+  Clock.cc
+  CRC32.cc
+  ExprParser.cc
+  OutputHandler.cc
+  SignalHandler.cc
+  Sleep.cc
+  SubString.cc
+COMPILATION_END
+)
+
+IF(GCC_NO_SYSTEM_HEADER_SUPPORT)
+  # Get around displaying a few hundred lines of warning code
+  SET_SOURCE_FILES_PROPERTIES(MultiType.cc PROPERTIES COMPILE_FLAGS "-w")
+ENDIF()
+IF(MSVC)
+  # Simply using #pragma warning(disable:4244) doesn't really disable it
+  # if the warning occurs in a template in another file
+  # Hence promote it manually to a higher warning level (4)
+  SET_SOURCE_FILES_PROPERTIES(MultiType.cc PROPERTIES COMPILE_FLAGS "-w44244")
+ENDIF()
+
+ORXONOX_ADD_LIBRARY(util
+  FIND_HEADER_FILES
+  DEFINE_SYMBOL
+    "UTIL_SHARED_BUILD"
+  LINK_LIBRARIES
+    ${CEGUI_LIBRARY}
+    ${OGRE_LIBRARY}
+  SOURCE_FILES
+    ${UTIL_SRC_FILES}
+)
Index: /code/branches/rocket2/src/libraries/util/CRC32.cc
===================================================================
--- /code/branches/rocket2/src/libraries/util/CRC32.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/CRC32.cc	(revision 6952)
@@ -0,0 +1,59 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      ...
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "CRC32.h"
+
+namespace orxonox
+{
+    void calcCRCBit(uint32_t &crc32, int bit)
+    {
+        int hbit = (crc32 & 0x80000000) ? 1 : 0;
+        if (hbit != bit)
+            crc32 = (crc32 << 1) ^ UTIL_CRC32POLY;
+        else
+            crc32 = crc32 << 1;
+      }
+
+    uint32_t calcCRC(unsigned char *data, unsigned int dataLength)
+    {
+        uint32_t crc32 = 0;
+        for(unsigned int i = 0; i < dataLength; i++)
+        {
+            calcCRCBit(crc32, (data[i] & 0x1) >> 0); // 1st bit
+            calcCRCBit(crc32, (data[i] & 0x2) >> 1); // 2nd bit
+            calcCRCBit(crc32, (data[i] & 0x3) >> 2); // 3rd bit
+            calcCRCBit(crc32, (data[i] & 0x4) >> 3); // 4th bit
+            calcCRCBit(crc32, (data[i] & 0x5) >> 4); // 5th bit
+            calcCRCBit(crc32, (data[i] & 0x6) >> 5); // 6th bit
+            calcCRCBit(crc32, (data[i] & 0x7) >> 6); // 7th bit
+            calcCRCBit(crc32, (data[i] & 0x8) >> 7); // 8th bit
+        }
+        return crc32;
+    }
+}
+
Index: /code/branches/rocket2/src/libraries/util/CRC32.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/CRC32.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/CRC32.h	(revision 6952)
@@ -0,0 +1,43 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      ...
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Util_CRC_H__
+#define _Util_CRC_H__
+
+#include "UtilPrereqs.h"
+
+namespace orxonox
+{
+    const unsigned int UTIL_CRC32POLY = 0x04C11DB7; /* CRC-32 Polynom */
+
+    _UtilExport void calcCRCBit(uint32_t &crc32, int bit);
+
+    _UtilExport uint32_t calcCRC(unsigned char *data, unsigned int dataLength);
+}
+
+#endif /* _Util_CRC_H__ */
Index: /code/branches/rocket2/src/libraries/util/Clipboard.cc
===================================================================
--- /code/branches/rocket2/src/libraries/util/Clipboard.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Clipboard.cc	(revision 6952)
@@ -0,0 +1,144 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ *   Windows version inspired by "Copy Text To Clipboard" by Laszlo Szathmary, 2007
+ *      http://www.loria.fr/~szathmar/off/projects/C/CopyTextToClipboard/index.php
+ */
+
+/**
+    @file
+    @brief OS-specific implementations of the clipboard functions.
+*/
+
+#include "Clipboard.h"
+
+#ifdef ORXONOX_PLATFORM_WINDOWS
+
+/////////////
+// Windows //
+/////////////
+
+#ifndef WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#undef min
+#undef max
+#include "Debug.h"
+
+namespace orxonox
+{
+
+    /**
+        @brief Puts text into the windows-clipboard
+        @param text The text
+        @return True if the action was successful
+    */
+    bool toClipboard(const std::string& text)
+    {
+        try
+        {
+            if (OpenClipboard(0))
+            {
+                EmptyClipboard();
+                HGLOBAL clipbuffer = GlobalAlloc(GMEM_DDESHARE, text.size() + 1);
+                char* buffer = static_cast<char*>(GlobalLock(clipbuffer));
+                strcpy(buffer, text.c_str());
+                GlobalUnlock(clipbuffer);
+                SetClipboardData(CF_TEXT, clipbuffer);
+                CloseClipboard();
+
+                return true;
+            }
+        }
+        catch (...)
+        {
+            COUT(1) << "Error: Unable to copy the following text to the clipboard:" << std::endl;
+            COUT(1) << "       \"" << text << '"' << std::endl;
+        }
+        return false;
+    }
+
+    /**
+        @brief Gets text from the windows-clipboard if there is any text.
+        @return The retrieved text
+    */
+    std::string fromClipboard()
+    {
+        try
+        {
+            if (OpenClipboard(0))
+            {
+                HANDLE hData = GetClipboardData(CF_TEXT);
+                if (hData == NULL)
+                    return "";
+                std::string output(static_cast<char*>(GlobalLock(hData)));
+                GlobalUnlock(hData);
+                CloseClipboard();
+
+                return output;
+            }
+        }
+        catch (...)
+        {
+            COUT(1) << "Error: Unable to retrieve text from the clipboard." << std::endl;
+        }
+        return "";
+    }
+}
+
+#else /* ORXONOX_PLATFORM_WINDOWS */
+
+/////////////
+// Default //
+/////////////
+
+namespace orxonox
+{
+    static std::string clipboard; //!< Keeps the text of our internal clipboard
+
+    /**
+        @brief Default implementation if there is no OS-specific implementation or no clipboard. Copies the text into an internal clipboard.
+        @param text The text
+        @return True
+    */
+    bool toClipboard(const std::string& text)
+    {
+        clipboard = text;
+        return true;
+    }
+
+    /**
+        @brief Default implementation if there is no OS-specific implementation or no clipboard. Gets the text from the internal clipboard.
+        @return The text
+    */
+    std::string fromClipboard()
+    {
+        return clipboard;
+    }
+}
+
+#endif /* ORXONOX_PLATFORM_WINDOWS */
Index: /code/branches/rocket2/src/libraries/util/Clipboard.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/Clipboard.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Clipboard.h	(revision 6952)
@@ -0,0 +1,54 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Some functions to exchange text between the OS clipboard and Orxonox.
+
+    Use fromClipboard() to get text from the clipboard (if there is any text) and
+    toClipboard(text) to put text into the clipboard.
+
+    Those functions can only work properly if there's an OS-specific implementation.
+    If an OS isn't supported, the clipboard only works within Orxonox, but exchange
+    with other programs isn't possible.
+*/
+
+#ifndef _Clipboard_H__
+#define _Clipboard_H__
+
+#include "UtilPrereqs.h"
+#include <string>
+
+namespace orxonox
+{
+    _UtilExport bool toClipboard(const std::string& text);
+    _UtilExport std::string fromClipboard();
+}
+
+#endif /* _Clipboard_H__ */
+
Index: /code/branches/rocket2/src/libraries/util/Clock.cc
===================================================================
--- /code/branches/rocket2/src/libraries/util/Clock.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Clock.cc	(revision 6952)
@@ -0,0 +1,67 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Clock.h"
+#include <OgreTimer.h>
+
+namespace orxonox
+{
+    Clock::Clock()
+        : timer_(new Ogre::Timer())
+        , tickTime_(0)
+        , tickDt_(0)
+        , tickDtFloat_(0.0f)
+    {
+    }
+
+    Clock::~Clock()
+    {
+        delete timer_;
+    }
+
+    /**
+    @remarks
+        Mind the types! Ogre::Timer::getMicroseconds() will return an unsigned
+        long, which will eventually overflow. But if you use the subtraction of
+        the current time minus the last time the timer gave us and sum these up to
+        a 64 bit integer, we get the desired result.
+        Also mind that we don't have to store the last timer's time as unsigned long
+        as well because (unsigned long)tickTime_ will do exactly that.
+    */
+    void Clock::capture()
+    {
+        tickDt_ = timer_->getMicroseconds() - (unsigned long)tickTime_;
+        tickTime_ += tickDt_;
+        tickDtFloat_ = static_cast<float>(tickDt_) / 1000000.0f;
+    }
+
+    unsigned long long Clock::getRealMicroseconds() const
+    {
+        return tickTime_ + (timer_->getMicroseconds() - (unsigned long)tickTime_);
+    }
+}
Index: /code/branches/rocket2/src/libraries/util/Clock.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/Clock.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Clock.h	(revision 6952)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Clock_H__
+#define _Clock_H__
+
+#include "UtilPrereqs.h"
+#include "OgreForwardRefs.h"
+
+namespace orxonox
+{
+    class _UtilExport Clock
+    {
+    public:
+        Clock();
+        ~Clock();
+
+        void capture();
+
+        unsigned long long getMicroseconds()   const { return tickTime_; }
+        unsigned long long getMilliseconds()   const { return tickTime_ / 1000; }
+        unsigned long      getSeconds()        const { return static_cast<long> (tickTime_ / 1000000); }
+        float              getSecondsPrecise() const { return static_cast<float>(tickTime_ / 1000000.0f); }
+
+        float              getDeltaTime()      const { return tickDtFloat_; }
+        long               getDeltaTimeMicroseconds() const { return tickDt_; }
+
+        unsigned long long getRealMicroseconds() const;
+
+    private:
+        Clock(const Clock& instance);
+
+        Ogre::Timer*       timer_;
+        unsigned long long tickTime_;
+        long               tickDt_;
+        float              tickDtFloat_;
+    };
+}
+
+#endif /* _Clock_H__ */
Index: /code/branches/rocket2/src/libraries/util/Convert.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/Convert.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Convert.h	(revision 6952)
@@ -0,0 +1,421 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *      Fabian 'x3n' Landau
+ *      Benjamin Grauer
+ *   Co-authors:
+ *      ...
+ */
+
+/*!
+    @file
+    @brief Definition and Implementation of the Convert class.
+*/
+
+#ifndef _Converter_H__
+#define _Converter_H__
+
+#include "UtilPrereqs.h"
+
+#include <string>
+#include <sstream>
+#include <typeinfo>
+
+#include "Debug.h"
+#include "TemplateUtils.h"
+
+////////////////////////////////////
+//// ACTUAL CONVERSION SEQUENCE ////
+////////////////////////////////////
+/*
+    There is a distinct priority when choosing the right conversion function:
+    Overwrite:
+    1. (Partial) template specialisation of ConverterExplicit::convert()
+    Fallbacks:
+    2. Any possible implicit conversion. This includes 'FooBar' --> 'int' if FooBar defines operator float().
+    3. Global or member operators for stringstream when converting from or to std::string (or FROM const char*)
+    4. (Partial) template specialisation of ConverterFallback::convert()
+    5. Function that simply displays "Could not convert value" with type information obtained from typeid().
+
+    Notes:
+    There has to be an exact type match when using template specialisations.
+    Template specialisations can be defined after including this file. Any implicit cast function or iostream
+    operator has to be declared BEFORE this file gets parsed.
+
+    Defining your own functions:
+    There are obviously 4 ways to specifiy a user defined conversion. What should I use?
+
+    Usually, ConverterFallback fits quite well. You won't have to deal with the conversion from
+    'MyClass' to 'MyClass' by using another explicit template specialisation to avoid ambiguities.
+
+    However if you want to overwrite an implicit conversion or an iostream operator, you really need to
+    make use of ConverterExplicit.
+*/
+
+namespace orxonox
+{
+    namespace detail
+    {
+        //! Little template that maps integers to entire types (Alexandrescu 2001)
+        template <int I>
+        struct Int2Type { };
+    }
+
+
+    ///////////////////
+    // No Conversion //
+    ///////////////////
+
+    // Default template. No conversion available at all.
+    template <class FromType, class ToType>
+    struct ConverterFallback
+    {
+        FORCEINLINE static bool convert(ToType* output, const FromType& input)
+        {
+            COUT(2) << "Could not convert value of type " << typeid(FromType).name()
+                    << " to type " << typeid(ToType).name() << std::endl;
+            return false;
+        }
+    };
+
+    // If all else fails, try a dynamic_cast for pointer types.
+    template <class FromType, class ToType>
+    struct ConverterFallback<FromType*, ToType*>
+    {
+        FORCEINLINE static bool convert(ToType** output, FromType* const input)
+        {
+            ToType* temp = dynamic_cast<ToType*>(input);
+            if (temp)
+            {
+                *output = temp;
+                return true;
+            }
+            else
+                return false;
+        }
+    };
+}
+
+
+///////////////////////
+// ConverterFallback //
+///////////////////////
+
+// Default template for stringstream
+template <class FromType, class ToType>
+struct ConverterStringStream
+{
+    FORCEINLINE static bool convert(ToType* output, const FromType& input)
+    {
+        return orxonox::ConverterFallback<FromType, ToType>::convert(output, input);
+    }
+};
+
+
+/////////////
+// OStream //
+/////////////
+
+namespace fallbackTemplates
+{
+    template <class FromType>
+    FORCEINLINE bool operator <<(std::ostream& outstream,  const FromType& input)
+    {
+        std::string temp;
+        if (orxonox::ConverterFallback<FromType, std::string>::convert(&temp, input))
+        {
+            std::operator <<(outstream, temp);
+            return true;
+        }
+        else
+            return false;
+    }
+}
+
+// template that evaluates whether we can convert to std::string via ostringstream
+template <class FromType>
+struct ConverterStringStream<FromType, std::string>
+{
+    FORCEINLINE static bool convert(std::string* output, const FromType& input)
+    {
+        using namespace fallbackTemplates;
+        // this operator call only chooses fallbackTemplates::operator<< if there's no other fitting function
+        std::ostringstream oss;
+        if (oss << input)
+        {
+            (*output) = oss.str();
+            return true;
+        }
+        else
+            return false;
+    }
+};
+
+
+/////////////
+// IStream //
+/////////////
+
+namespace fallbackTemplates
+{
+    template <class ToType>
+    FORCEINLINE bool operator >>(std::istream& instream, ToType& output)
+    {
+        return orxonox::ConverterFallback<std::string, ToType>
+            ::convert(&output, static_cast<std::istringstream&>(instream).str());
+    }
+}
+
+// template that evaluates whether we can convert from std::string via ostringstream
+template <class ToType>
+struct ConverterStringStream<std::string, ToType>
+{
+    FORCEINLINE static bool convert(ToType* output, const std::string& input)
+    {
+        using namespace fallbackTemplates;
+        std::istringstream iss(input);
+        // this operator call only chooses fallbackTemplates::operator>> if there's no other fitting function
+        if (iss >> (*output))
+        {
+            return true;
+        }
+        else
+            return false;
+    }
+};
+
+namespace orxonox
+{
+
+    ///////////////////
+    // Implicit Cast //
+    ///////////////////
+
+    // implicit cast not possible, try stringstream conversion next
+    template <class FromType, class ToType>
+    FORCEINLINE bool convertImplicitely(ToType* output, const FromType& input, detail::Int2Type<false>)
+    {
+        return ConverterStringStream<FromType, ToType>::convert(output, input);
+    }
+
+    // We can cast implicitely
+    template <class FromType, class ToType>
+    FORCEINLINE bool convertImplicitely(ToType* output, const FromType& input, detail::Int2Type<true>)
+    {
+        (*output) = static_cast<ToType>(input);
+        return true;
+    }
+
+
+    ////////////////////////////////
+    // ConverterExplicit Fallback //
+    ////////////////////////////////
+
+    // Default template if no specialisation is available
+    template <class FromType, class ToType>
+    struct ConverterExplicit
+    {
+        enum { probe = ImplicitConversion<FromType, ToType>::exists };
+        FORCEINLINE static bool convert(ToType* output, const FromType& input)
+        {
+            // Try implict cast and probe first. If a simple cast is not possible, it will not compile
+            // We therefore have to out source it into another template function
+            return convertImplicitely(output, input, detail::Int2Type<probe>());
+        }
+    };
+
+
+    //////////////////////
+    // Public Functions //
+    //////////////////////
+
+    /**
+    @brief
+        Converts any value to any other as long as there exists a conversion.
+        Otherwise, the conversion will generate a runtime warning and return false.
+        For information about the different conversion methods (user defined too), see the section
+        'Actual conversion sequence' in this file above.
+    */
+    template <class FromType, class ToType>
+    FORCEINLINE bool convertValue(ToType* output, const FromType& input)
+    {
+        return ConverterExplicit<FromType, ToType>::convert(output, input);
+    }
+
+    // Calls convertValue and returns true if the conversion was successful.
+    // Otherwise the fallback is used.
+    /**
+    @brief
+        Converts any value to any other as long as there exists a conversion.
+        Otherwise, the conversion will generate a runtime warning and return false.
+        For information about the different conversion methods (user defined too), see the section
+        'Actual conversion sequence' in this file above.
+        If the conversion doesn't succeed, 'fallback' is written to '*output'.
+    @param fallback
+        A default value that gets written to '*output' if there is no conversion.
+    */
+    template<class FromType, class ToType>
+    FORCEINLINE bool convertValue(ToType* output, const FromType& input, const ToType& fallback)
+    {
+        if (convertValue(output, input))
+            return true;
+        else
+        {
+            (*output) = fallback;
+            return false;
+        }
+    }
+
+    // Directly returns the converted value, even if the conversion was not successful.
+    template<class FromType, class ToType>
+    FORCEINLINE ToType getConvertedValue(const FromType& input)
+    {
+        ToType output;
+        convertValue(&output, input);
+        return output;
+    }
+
+    // Directly returns the converted value, but uses the fallback on failure.
+    template<class FromType, class ToType>
+    FORCEINLINE ToType getConvertedValue(const FromType& input, const ToType& fallback)
+    {
+        ToType output;
+        convertValue(&output, input, fallback);
+        return output;
+    }
+
+    // Like getConvertedValue, but the template argument order is in reverse.
+    // That means you can call it exactly like static_cast<ToType>(fromTypeValue).
+    template<class ToType, class FromType>
+    FORCEINLINE ToType multi_cast(const FromType& input)
+    {
+        ToType output;
+        convertValue(&output, input);
+        return output;
+    }
+
+    ////////////////////////////////
+    // Special string conversions //
+    ////////////////////////////////
+
+    // Delegate conversion from const char* to std::string
+    template <class ToType>
+    struct ConverterExplicit<const char*, ToType>
+    {
+        FORCEINLINE static bool convert(ToType* output, const char* input)
+        {
+            return convertValue<std::string, ToType>(output, input);
+        }
+    };
+
+    // These conversions would exhibit ambiguous << or >> operators when using stringstream
+    template <>
+    struct ConverterExplicit<char, std::string>
+    {
+        FORCEINLINE static bool convert(std::string* output, const char input)
+        {
+            *output = input;
+            return true;
+        }
+    };
+    template <>
+    struct ConverterExplicit<unsigned char, std::string>
+    {
+        FORCEINLINE static bool convert(std::string* output, const unsigned char input)
+        {
+            *output = input;
+            return true;
+        }
+    };
+    template <>
+    struct ConverterExplicit<std::string, char>
+    {
+        FORCEINLINE static bool convert(char* output, const std::string& input)
+        {
+            if (!input.empty())
+                *output = input[0];
+            else
+                *output = '\0';
+            return true;
+        }
+    };
+    template <>
+    struct ConverterExplicit<std::string, unsigned char>
+    {
+        FORCEINLINE static bool convert(unsigned char* output, const std::string& input)
+        {
+            if (!input.empty())
+                *output = input[0];
+            else
+                *output = '\0';
+            return true;
+        }
+    };
+
+
+    // bool to std::string
+    template <>
+    struct ConverterExplicit<bool, std::string>
+    {
+        FORCEINLINE static bool convert(std::string* output, const bool& input)
+        {
+            if (input)
+              *output = "true";
+            else
+              *output = "false";
+            return true;
+        }
+    };
+
+    // Declarations to avoid StringUtils.h include
+    _UtilExport std::string removeTrailingWhitespaces(const std::string& str);
+    _UtilExport std::string getLowercase(const std::string& str);
+
+    // std::string to bool
+    template <>
+    struct ConverterExplicit<std::string, bool>
+    {
+        static bool convert(bool* output, const std::string& input)
+        {
+            const std::string& stripped = getLowercase(removeTrailingWhitespaces(input));
+            if (stripped == "true" || stripped == "on" || stripped == "yes")
+            {
+                *output = true;
+                return true;
+            }
+            else if (stripped == "false" || stripped == "off" || stripped == "no")
+            {
+                *output = false;
+                return true;
+            }
+
+            std::istringstream iss(input);
+            if (iss >> (*output))
+                return true;
+            else
+                return false;
+        }
+    };
+}
+
+#endif /* _Convert_H__ */
Index: /code/branches/rocket2/src/libraries/util/Debug.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/Debug.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Debug.h	(revision 6952)
@@ -0,0 +1,114 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Handles different output-levels of errors, warnings, infos and debug information.
+
+    The COUT(level) macro acts like std::cout, but the output is only performed if the given
+    level is <= the soft debug level.
+
+    There are two used values in this file:
+     - The hard debug level is used during compile time. It describes the highest allowed output level.
+     - The soft debug level is used during runtime and is the maximum of the three configurable
+       output-levels for console, log file and in game shell.
+
+    The separation between the three devices is done by the OutputHandler.
+
+    Possible levels are:
+     0: Very important output
+     1: Errors
+     2: Warnings
+     3: Information
+     4: Debug information
+     5: More debug information
+     6: Crazy debug information
+
+@example
+    COUT(0) << "Very important output" << std::endl;
+    COUT(1) << "Error: Something went wrong!" << std::endl;
+    COUT(2) << "Warning: There might be a problem." << std::endl;
+    COUT(3) << "Info: It's Monday" << std::endl;
+    COUT(4) << "Debug: x is 1.23456" << std::endl;
+*/
+
+#ifndef _Util_Debug_H__
+#define _Util_Debug_H__
+
+#include "UtilPrereqs.h"
+#include "OutputHandler.h"
+
+namespace orxonox
+{
+    // Just for convenience
+    using std::endl;
+
+    // Adjust this to discard certain output with level > hardDebugLevel at compile time already
+#ifdef ORXONOX_RELEASE
+    const int hardDebugLevel = OutputLevel::Verbose;
+#elif defined(NDEBUG)
+    const int hardDebugLevel = OutputLevel::Verbose;
+#else
+    //! Maximum level for debug output that should be even processed at run time
+    const int hardDebugLevel = OutputLevel::Ultra;
+#endif
+
+    //! This function simply returns 0 and helps to suppress the "statement has no effect" compiler warning
+    inline int debugDummyFunction()
+    {
+        return 0;
+    }
+}
+
+/**
+@brief
+    Logs text output: use exactly like std::cout, but specify an output
+    level as argument.
+@details
+    (a > b ? 0 : c << "text") is equivalent to (a > b ? 0 : (c << "text"))
+    where (a > b ? 0 : ) stands for COUT(x). This should explain how
+    this macro magic can possibly even work ;)
+@example
+    COUT(3) << "Some info" << std::endl;
+@note
+    The ? : operator requires both possible results to have the type of
+    the first. This is achieved by the int conversion operator dummy
+    in the OutputHandler.
+*/
+#define COUT(level)                                                    \
+    /*if*/ (level > orxonox::hardDebugLevel) ?                         \
+        orxonox::debugDummyFunction()                                  \
+    /*else*/ :                                                         \
+        /*if*/ (level > orxonox::OutputHandler::getSoftDebugLevel()) ? \
+            orxonox::debugDummyFunction()                              \
+        /*else*/ :                                                     \
+            orxonox::OutputHandler::getOutStream(level)
+
+#endif /* _Util_Debug_H__ */
Index: /code/branches/rocket2/src/libraries/util/DisplayStringConversions.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/DisplayStringConversions.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/DisplayStringConversions.h	(revision 6952)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ */
+
+/**
+@file
+@brief
+    std::sring to Ogre::UTFString conversion functions
+*/
+
+#ifndef _DisplayStringConversions_H__
+#define _DisplayStringConversions_H__
+
+#include "UtilPrereqs.h"
+#include <OgreOverlayElement.h>
+
+#if OGRE_UNICODE_SUPPORT
+    #include <OgreUTFString.h>
+
+    namespace orxonox
+    {
+        template <>
+        struct ConverterExplicit<std::string, Ogre::DisplayString>
+        {
+            //! Converts an std::string into an Ogre::UTFString
+            inline static bool convert(Ogre::DisplayString* output, const std::string& input)
+            {
+                Ogre::UTFString::code_point cp;
+                for (unsigned int i = 0; i < input.size(); ++i)
+                {
+                  cp = input[i];
+                  cp &= 0xFF;
+                  output->append(1, cp);
+                }
+                return true;
+            }
+        };
+    }
+#else
+    namespace orxonox
+    {
+        template <>
+        struct ConverterExplicit<std::string, Ogre::DisplayString>
+        {
+            //! Converts an std::string into an Ogre::String
+            inline static bool convert(Ogre::DisplayString* output, const std::string& input)
+            {
+                *output = input;
+                return true;
+            }
+        };
+    }
+#endif
+
+#endif /* _DisplayStringConversions_H__ */
Index: /code/branches/rocket2/src/libraries/util/Exception.cc
===================================================================
--- /code/branches/rocket2/src/libraries/util/Exception.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Exception.cc	(revision 6952)
@@ -0,0 +1,120 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of the Exception class.
+*/
+
+#include "Exception.h"
+#include <CEGUIExceptions.h>
+
+namespace orxonox
+{
+    Exception::Exception(const std::string& description, unsigned int lineNumber,
+                         const char* filename, const char* functionName)
+        : description_(description)
+        , lineNumber_(lineNumber)
+        , functionName_(functionName)
+        , filename_(filename)
+    { }
+
+    Exception::Exception(const std::string& description)
+        : description_(description)
+        , lineNumber_(0)
+    { }
+
+    /**
+    @remarks
+        The composed full description gets stored to fullDescription_. But for compliance
+        with std::exception, this method has to be const. Hence fullDescription_ is declared
+        as mutable.
+    */
+    const std::string& Exception::getFullDescription() const
+    {
+        if (fullDescription_.empty())
+        {
+            std::ostringstream fullDesc;
+
+            fullDesc << this->getTypeName() << "Exception";
+
+            if (!this->filename_.empty())
+            {
+                fullDesc << " in " << this->filename_;
+                if (this->lineNumber_)
+                    fullDesc << '(' << this->lineNumber_ << ')';
+            }
+
+            if (!this->functionName_.empty())
+                fullDesc << " in function '" << this->functionName_ << '\'';
+
+            fullDesc << ": ";
+            if (!this->description_.empty())
+                fullDesc << this->description_;
+            else
+                fullDesc << "No description available.";
+
+            this->fullDescription_ = fullDesc.str();
+        }
+
+        return fullDescription_;
+    }
+
+    //! Returns the error description
+    const char* Exception::what() const throw()
+    {
+        return getDescription().c_str();
+    }
+
+    /*static*/ std::string Exception::handleMessage()
+    {
+        try
+        {
+            // rethrow
+            throw;
+        }
+        catch (const std::exception& ex)
+        {
+            return ex.what();
+        }
+        catch (const CEGUI::Exception& ex)
+        {
+#if CEGUI_VERSION_MAJOR == 0 && CEGUI_VERSION_MINOR < 6
+            return GeneralException(ex.getMessage().c_str()).getDescription();
+#else
+            return GeneralException(ex.getMessage().c_str(), ex.getLine(),
+                ex.getFileName().c_str(), ex.getName().c_str()).getDescription();
+#endif
+        }
+        catch (...)
+        {
+            return "Unknown exception";
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/util/Exception.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/Exception.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Exception.h	(revision 6952)
@@ -0,0 +1,167 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Declaration of facilities to handle exceptions.
+*/
+
+#ifndef _Exception_H__
+#define _Exception_H__
+
+#include "UtilPrereqs.h"
+
+#include <exception>
+#include <sstream>
+#include <string>
+#include "Debug.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Base class for all exceptions (derived from std::exception).
+    @details
+        This class provides support for information about the file, the line
+        and the function the error occured.
+    */
+    class _UtilExport Exception : public std::exception
+    {
+    public:
+        /**
+        @brief
+            Creates the exception but doesn't yet compose the full descrption (because of the virtual functions)
+        @param description
+            Exception description as string. This message is supposed to help developers!
+        */
+        Exception(const std::string& description, unsigned int lineNumber,
+                  const char* filename, const char* functionName);
+        //! Simplified constructor with just a description. If you need more, use the other one.
+        Exception(const std::string& description);
+
+        //! Needed for compatibility with std::exception
+        virtual ~Exception() throw() { }
+        const char* what() const throw();
+
+        //! Returns a full description with type, line, file and function
+        virtual const std::string& getFullDescription() const;
+        //! Returns the string name of the exception type
+        virtual std::string        getTypeName()        const = 0;
+        //! Returns the short developer written exception
+        virtual const std::string& getDescription()     const { return this->description_; }
+        //! Returns the line number on which the exception occurred.
+        virtual const unsigned int getLineNumber()      const { return this->lineNumber_; }
+        //! Returns the function in which the exception occurred.
+        virtual const std::string& getFunctionName()    const { return this->functionName_; }
+        //! Returns the filename in which the exception occurred.
+        virtual const std::string& getFilename()        const { return this->filename_; }
+
+        /**
+        @brief
+            Retrieves information from an exception caught with "..."
+            Works for std::exception and CEGUI::Exception
+        @remarks
+            Never ever call this function without an exception in the stack!
+        */
+        static std::string handleMessage();
+
+    protected:
+        std::string description_;             //!< User typed text about why the exception occurred
+        unsigned int lineNumber_;             //!< Line on which the exception occurred
+        std::string functionName_;            //!< Function (including namespace and class) where the exception occurred
+        std::string filename_;                //!< File where the exception occurred
+        // mutable because "what()" is a const method
+        mutable std::string fullDescription_; //!< Full description with line, file and function
+    };
+
+//! Creates a new type of exception that inherits from tracker::Exception
+#define CREATE_ORXONOX_EXCEPTION(ExceptionName)                                     \
+    class ExceptionName##Exception : public Exception                               \
+    {                                                                               \
+    public:                                                                         \
+        ExceptionName##Exception(const std::string& description,                    \
+                unsigned int lineNumber, const char* filename,                      \
+                const char* functionName)                                           \
+            : Exception(description, lineNumber, filename, functionName)            \
+        { }                                                                         \
+                                                                                    \
+        ExceptionName##Exception(const std::string& description)                    \
+            : Exception(description)                                                \
+        { }                                                                         \
+                                                                                    \
+        ~ExceptionName##Exception() throw() { }                                     \
+                                                                                    \
+        std::string getTypeName() const { return #ExceptionName; }                  \
+    }
+
+    // Creates all possible exception types.
+    // If you want to add a new type, simply copy and adjust a new line here.
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+    CREATE_ORXONOX_EXCEPTION(General);
+    CREATE_ORXONOX_EXCEPTION(FileNotFound);
+    CREATE_ORXONOX_EXCEPTION(Argument);
+    CREATE_ORXONOX_EXCEPTION(PhysicsViolation);
+    CREATE_ORXONOX_EXCEPTION(ParseError);
+    CREATE_ORXONOX_EXCEPTION(PluginsNotFound);
+    CREATE_ORXONOX_EXCEPTION(InitialisationFailed);
+    CREATE_ORXONOX_EXCEPTION(InitialisationAborted);
+    CREATE_ORXONOX_EXCEPTION(NotImplemented);
+    CREATE_ORXONOX_EXCEPTION(GameState);
+    CREATE_ORXONOX_EXCEPTION(NoGraphics);
+    CREATE_ORXONOX_EXCEPTION(AbortLoading);
+#endif
+
+    /**
+    @brief
+        Helper function that forwards an exception and displays the message.
+    @details
+        This is necessary because only when using 'throw' the objects storage is managed.
+    */
+    template <class T>
+    inline const T& exceptionThrowerHelper(const T& exception)
+    {
+        // let the catcher decide whether to display the message below level 4
+        COUT(4) << exception.getFullDescription() << std::endl;
+        return exception;
+    }
+
+/**
+@brief
+    Throws an exception and logs a message beforehand.
+@param type
+    Type of the exception as literal (General, Initialisation, etc.)
+@param description
+    Exception description as string
+*/
+#define ThrowException(type, description) \
+    throw orxonox::exceptionThrowerHelper(type##Exception(static_cast<std::ostringstream&>(std::ostringstream().flush() << description).str(), __LINE__, __FILE__, __FUNCTIONNAME__))
+
+} /* namespace orxonox */
+
+#endif /* _Exception_H__ */
Index: /code/branches/rocket2/src/libraries/util/ExprParser.cc
===================================================================
--- /code/branches/rocket2/src/libraries/util/ExprParser.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/ExprParser.cc	(revision 6952)
@@ -0,0 +1,462 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+  @file
+  @brief Declaration of FloatParser
+*/
+
+#include "ExprParser.h"
+#include <cmath>
+#include <cstring>
+#include <cstdlib>
+
+// macros for easier if, else statements
+#define CASE_1(var) if (!strcmp(SWITCH,var))
+#define CASE(var) else if (!strcmp(SWITCH,var))
+#define CASE_ELSE else
+
+//! skip white spaces
+#define PARSE_BLANKS while (*reading_stream == ' ') ++reading_stream
+
+namespace orxonox
+{
+    ExprParser::ExprParser()
+    {
+        this->failed_ = false;
+        this->variables_["pi"] = 3.1415926535897932;
+        this->variables_["e"] = 2.7182818284590452;
+    }
+
+    void ExprParser::setVariable(const std::string& varname, double value)
+    {
+        this->variables_[varname] = value;
+    }
+
+    void ExprParser::parse(const std::string& str)
+    {
+        this->reading_stream = str.c_str();
+        if (str.size() == 0 || *reading_stream == '\0')
+        {
+            this->failed_ = true;
+            this->result_ = 0.0;
+        }
+        else
+        {
+            this->result_ = parse_expr_8();
+            this->remains_ = reading_stream;
+        }
+    }
+
+    //Private functions:
+    /******************/
+    double ExprParser::parse_argument()
+    {
+        double value = parse_expr_8();
+        if (*reading_stream == ',')
+        {
+            ++reading_stream;
+            return value;
+        }
+        else
+        {
+            this->failed_ = true;
+            return 0;
+        }
+    }
+
+    double ExprParser::parse_last_argument()
+    {
+        double value = parse_expr_8();
+        if (*reading_stream == ')')
+        {
+            ++reading_stream;
+            return value;
+        }
+        else
+        {
+            this->failed_ = true;
+            return 0;
+        }
+    }
+
+    double ExprParser::parse_expr_8()
+    {
+        double value = parse_expr_7();
+        for(;;)
+        {
+            switch (op)
+            {
+            case oder:
+                value = parse_expr_7() || value;
+                break;
+            default: return value;
+            }
+        };
+    }
+
+
+    double ExprParser::parse_expr_7()
+    {
+        double value = parse_expr_6();
+        for(;;)
+        {
+            switch (op)
+            {
+            case und:
+                value = value && parse_expr_6();
+                break;
+            default: return value;
+            }
+        };
+    }
+
+    double ExprParser::parse_expr_6()
+    {
+        double value = parse_expr_5();
+        for(;;)
+        {
+            switch (op)
+            {
+            case gleich:
+                value = (value == parse_expr_5());
+                break;
+            case ungleich:
+                value = (value != parse_expr_5());
+                break;
+            default:
+                return value;
+            }
+        };
+    }
+
+    double ExprParser::parse_expr_5()
+    {
+        double value = parse_expr_4();
+        for(;;)
+        {
+            switch (op)
+            {
+            case kleiner:
+                value = (value < parse_expr_4());
+                break;
+            case kleinergleich:
+                value = (value <= parse_expr_4());
+                break;
+            case groesser:
+                value = (value > parse_expr_4());
+                break;
+            case groessergleich:
+                value = (value >= parse_expr_4());
+                break;
+            default:
+                return value;
+            }
+        };
+    }
+
+    double ExprParser::parse_expr_4()
+    {
+        double value = parse_expr_3();
+        for(;;)
+        {
+            switch (op)
+            {
+            case b_plus:
+                value += parse_expr_3();
+                break;
+            case b_minus:
+                value -= parse_expr_3();
+                break;
+            default:
+                return value;
+            }
+        };
+    }
+
+    double ExprParser::parse_expr_3()
+    {
+        double value = parse_expr_2();
+        for(;;)
+        {
+            switch (op)
+            {
+            case mal:
+                value *= parse_expr_2();
+                break;
+            case durch:
+                value /= parse_expr_2();
+                break;
+            case modulo:
+                {
+                    double temp = parse_expr_2();
+                    value = value - floor(value/temp)*temp;
+                    break;
+                }
+            default:
+                return value;
+            }
+        };
+    }
+
+    double ExprParser::parse_expr_2()
+    {
+        double value = parse_expr_1();
+        while (*reading_stream != '\0')
+        {
+            op = parse_binary_operator();
+            switch (op)
+            {
+            case hoch:
+                value = pow(value,parse_expr_1());
+                break;
+            default:
+                return value;
+            }
+        };
+        op = undef;
+        return value;
+    }
+
+    double ExprParser::parse_expr_1()
+    {
+        PARSE_BLANKS;
+        double value;
+
+        unary_operator op = parse_unary_operator();
+        PARSE_BLANKS;
+
+        if (*reading_stream == '\0')
+        {
+            // end of string
+            this->failed_ = true;
+            return 0;
+        }
+        else if ((*reading_stream > 47 && *reading_stream < 59) || *reading_stream == 46)
+        {  // number
+            value = strtod(reading_stream, const_cast<char**>(&reading_stream));
+        }
+        else if ((*reading_stream > 64 && *reading_stream < 91) || (*reading_stream > 96 && *reading_stream < 123) || *reading_stream == 46)
+        {  // variable or function
+            char* word = new char[256];
+            parse_word(word);
+            PARSE_BLANKS;
+            if (*reading_stream == '(')
+            {
+                ++reading_stream;
+#define SWITCH word
+                CASE_1("sin")
+                    value = sin(parse_last_argument());
+                CASE("asin")
+                    value = asin(parse_last_argument());
+                CASE("sinh")
+                    value = sinh(parse_last_argument());
+                CASE("asinh")
+                {
+                    value = parse_last_argument();
+                    value = log(sqrt(pow(value, 2) + 1) + value);
+                }
+                CASE("cos")
+                    value = cos(parse_last_argument());
+                CASE("acos")
+                    value = acos(parse_last_argument());
+                CASE("cosh")
+                    value = cosh(parse_last_argument());
+                CASE("acosh")
+                {
+                    value = parse_last_argument();
+                    value = log(sqrt(pow(value, 2) - 1) + value);
+                }
+                CASE("tan")
+                    value = tan(parse_last_argument());
+                CASE("atan")
+                    value = atan(parse_last_argument());
+                CASE("atan2")
+                    value = atan2(parse_argument(),parse_last_argument());
+                CASE("tanh")
+                    value = tanh(parse_last_argument());
+                CASE("atanh")
+                {
+                    value = parse_last_argument();
+                    value = 0.5*log((value + 1)/(value - 1));
+                }
+                CASE("int")
+                    value = floor(parse_last_argument());
+                CASE("floor")
+                    value = floor(parse_last_argument());
+                CASE("ceil")
+                    value = ceil(parse_last_argument());
+                CASE("abs")
+                    value = fabs(parse_last_argument());
+                CASE("exp")
+                    value = exp(parse_last_argument());
+                CASE("log")
+                    value = log10(parse_last_argument());
+                CASE("ln")
+                    value = log(parse_last_argument());
+                CASE("sign")
+                {
+                    value = parse_last_argument();
+                    value = (value>0 ? 1 : (value<0 ? -1 : 0));
+                }
+                CASE("sqrt")
+                    value = sqrt(parse_last_argument());
+                CASE("degrees")
+                    value = parse_last_argument()*180/3.1415926535897932;
+                CASE("radians")
+                    value = parse_last_argument()*3.1415926535897932/180;
+                CASE("mod")
+                {
+                    value = parse_argument();
+                    double value2 = parse_last_argument();
+                    value = value - floor(value/value2)*value2;
+                }
+                CASE("pow")
+                    value = pow(parse_argument(),parse_last_argument());
+                CASE("div")
+                    value = floor(parse_argument()/parse_last_argument());
+                CASE("max")
+                    value = std::max(parse_argument(),parse_last_argument());
+                CASE("min")
+                    value = std::min(parse_argument(),parse_last_argument());
+                CASE_ELSE
+                {
+                    this->failed_ = true;
+                    delete[] word;
+                    return 0;
+                }
+            }
+            else
+            {
+                std::map<std::string, double>::const_iterator it = this->variables_.find(word);
+                if (it != this->variables_.end())
+                    value = it->second;
+                else
+                {
+                    this->failed_ = true;
+                    delete[] word;
+                    return 0;
+                }
+            }
+            delete[] word;
+        }
+        else if (*reading_stream == 40)
+        {  // expression in parenthesis
+            ++reading_stream;
+            value = parse_last_argument();
+        }
+        else
+        {
+            this->failed_ = true;
+            return 0;
+        }
+
+        PARSE_BLANKS;
+        switch (op)
+        {
+        case u_nicht: return !value;
+        case u_plus:  return  value;
+        case u_minus: return -value;
+        default:
+            this->failed_ = true;
+            return 0;
+        }
+    }
+
+    char* ExprParser::parse_word(char* str)
+    {
+        char* word = str;
+        int counter = 0;
+        while ((*reading_stream > 47 && *reading_stream < 58) || (*reading_stream > 64 && *reading_stream < 91) || (*reading_stream > 96 && *reading_stream < 123) || *reading_stream == 46)
+        {
+            *word++ = *reading_stream++;
+            counter++;
+            if (counter > 255)
+            {
+                this->failed_ = true;
+                return '\0';
+            }
+        };
+        *word = '\0';
+        return str;
+    }
+
+    ExprParser::binary_operator ExprParser::parse_binary_operator()
+    {
+        binary_operator op;
+        switch (*reading_stream)
+        {
+        case '+': op = b_plus; break;
+        case '-': op = b_minus; break;
+        case '*': op = mal; break;
+        case '/': op = durch; break;
+        case '^': op = hoch; break;
+        case '%': op = modulo; break;
+        case '&': op = und; break;
+        case '|': op = oder; break;
+        case '=': op = gleich; break;
+        case '!': op = b_nicht; break;
+        case '<': op = kleiner; break;
+        case '>': op = groesser; break;
+        default: return undef;
+        }
+        if (*++reading_stream == '=')
+        {
+            if (op > 9)
+            {
+                ++reading_stream;
+                return (binary_operator)(op + 3);
+            }
+            else
+            {
+                --reading_stream;
+                return undef;
+            }
+        }
+        else
+            return op;
+    }
+
+    ExprParser::unary_operator ExprParser::parse_unary_operator()
+    {
+        switch (*reading_stream)
+        {
+        case '!':
+            ++reading_stream;
+            return u_nicht;
+        case '+':
+            ++reading_stream;
+            return u_plus;
+        case '-':
+            ++reading_stream;
+            return u_minus;
+        default :
+            return u_plus;
+        }
+    }
+}
Index: /code/branches/rocket2/src/libraries/util/ExprParser.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/ExprParser.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/ExprParser.h	(revision 6952)
@@ -0,0 +1,115 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+  @file
+  @brief Declaration of FloatParser
+*/
+
+#ifndef _FloatParser_H__
+#define _FloatParser_H__
+
+#include "UtilPrereqs.h"
+
+#include <map>
+#include <string>
+
+namespace orxonox
+{
+    class _UtilExport ExprParser
+    {
+    public:
+        enum binary_operator
+        {
+            b_plus,
+            b_minus,
+            mal,
+            durch,
+            modulo,
+            hoch,
+            undef,
+            oder,
+            und,
+            gleich,
+            b_nicht,
+            kleiner,
+            groesser,
+            ungleich,
+            kleinergleich,
+            groessergleich
+        };
+
+        enum unary_operator
+        {
+            u_plus,
+            u_minus,
+            u_nicht
+        };
+
+
+        ExprParser();
+        void parse(const std::string& str);
+        const std::string& getRemains() { return  this->remains_; }
+        double             getResult()  { return  this->result_; }
+        bool               getSuccess() { return !this->failed_; }
+
+        void setVariable(const std::string& varname, double value);
+
+    private:
+        double parse_expr_1();
+        double parse_expr_2();
+        double parse_expr_3();
+        double parse_expr_4();
+        double parse_expr_5();
+        double parse_expr_6();
+        double parse_expr_7();
+        double parse_expr_8();
+        char* parse_word(char* str);
+        binary_operator parse_binary_operator();
+        unary_operator parse_unary_operator();
+
+        double parse_argument();
+        double parse_last_argument();
+
+        binary_operator op;
+        const char* reading_stream;
+        bool failed_;
+        double result_;
+        std::string remains_;
+        std::map<std::string, double> variables_;
+    };
+
+    //Endzeichen für float expression: ')', '}', ']', ',', ';'
+    _UtilExport bool parse_float(char* const, char**, double*);
+    //Endzeichen angegeben
+    _UtilExport bool parse_float(char* const, char**, char, double*);
+    //Letzter Teil-float eines Vektors parsen (keine Vergleichs- und Logikoperationen)
+    _UtilExport bool parse_vector_float(char* const, char**, bool, double*);
+}
+
+#endif /* _FloatParser_H__ */
Index: /code/branches/rocket2/src/libraries/util/Math.cc
===================================================================
--- /code/branches/rocket2/src/libraries/util/Math.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Math.cc	(revision 6952)
@@ -0,0 +1,358 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of several math-functions.
+*/
+
+#include "Math.h"
+
+#include <OgrePlane.h>
+
+#include "MathConvert.h"
+#include "SubString.h"
+// Do not remove this include, it avoids linker errors.
+#include "mbool.h"
+
+namespace orxonox
+{
+#if OGRE_VERSION < 0x010603
+    /**
+        @brief Function for writing a Radian to a stream.
+    */
+    std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian)
+    {
+        out << radian.valueRadians();
+        return out;
+    }
+
+    /**
+        @brief Function for writing a Degree to a stream.
+    */
+    std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree)
+    {
+        out << degree.valueDegrees();
+        return out;
+    }
+#endif
+
+    /**
+        @brief Function for reading a Radian from a stream.
+    */
+    std::istream& operator>>(std::istream& in, orxonox::Radian& radian)
+    {
+        float temp;
+        in >> temp;
+        radian = temp;
+        return in;
+    }
+
+    /**
+        @brief Function for reading a Degree from a stream.
+    */
+    std::istream& operator>>(std::istream& in, orxonox::Degree& degree)
+    {
+        float temp;
+        in >> temp;
+        degree = temp;
+        return in;
+    }
+
+
+    /**
+        @brief Gets the angle between my viewing direction and the direction to the position of the other object.
+        @param myposition My position
+        @param mydirection My viewing direction
+        @param otherposition The position of the other object
+        @return The angle
+
+        @example
+        If the other object is exactly in front of me, the function returns 0.
+        If the other object is exactly behind me, the function returns pi.
+        If the other object is exactly right/left to me (or above/below), the function returns pi/2.
+    */
+    float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition)
+    {
+        orxonox::Vector3 distance = otherposition - myposition;
+        float distancelength = distance.length();
+        if (distancelength == 0)
+            return 0;
+        else
+            return acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1));
+    }
+
+    /**
+        @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object.
+        @param myposition My position
+        @param mydirection My viewing direction
+        @param myorthonormal My orthonormalvector (pointing upwards through my head)
+        @param otherposition The position of the other object
+        @return The viewing direction
+
+        @example
+        If the other object is exactly in front of me, the function returns Vector2(0, 0).
+        If the other object is exactly at my left, the function returns Vector2(-1, 0).
+        If the other object is exactly at my right, the function returns Vector2(1, 0).
+        If the other object is only a bit at my right, the function still returns Vector2(1, 0).
+        If the other object is exactly above me, the function returns Vector2(0, 1).
+    */
+    orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)
+    {
+        orxonox::Vector3 distance = otherposition - myposition;
+
+        // project difference vector on our plane
+        orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance);
+
+        float projectionlength = projection.length();
+        if (projectionlength == 0)
+        {
+            if (myposition.dotProduct(otherposition) >= 0)
+                return orxonox::Vector2(0, 0);
+            else
+                return orxonox::Vector2(0, 1);
+        }
+
+        float cos_value = clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1);
+        float sin_value = sqrt( 1 - cos_value*cos_value );
+
+        if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0)
+            return orxonox::Vector2( sin_value, cos_value );
+        else
+            return orxonox::Vector2( -sin_value, cos_value );
+    }
+
+    /**
+        @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object, multiplied with the viewing distance to the object (0° = 0, 180° = 1).
+        @param myposition My position
+        @param mydirection My viewing direction
+        @param myorthonormal My orthonormalvector (pointing upwards through my head)
+        @param otherposition The position of the other object
+        @return The viewing direction
+
+        @example
+        If the other object is exactly in front of me, the function returns Vector2(0, 0).
+        If the other object is exactly at my left, the function returns Vector2(-0.5, 0).
+        If the other object is exactly at my right, the function returns Vector2(0.5, 0).
+        If the other object is only a bit at my right, the function still returns Vector2(0.01, 0).
+        If the other object is exactly above me, the function returns Vector2(0, 0.5).
+    */
+    orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)
+    {
+        orxonox::Vector3 distance = otherposition - myposition;
+
+        // project difference vector on our plane
+        orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance);
+
+        float projectionlength = projection.length();
+        if (projectionlength == 0)
+        {
+            if (myposition.dotProduct(otherposition) >= 0)
+                return orxonox::Vector2(0, 0);
+            else
+                return orxonox::Vector2(0, 1);
+        }
+        //float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1));
+
+        float cos_value = clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1);
+        float sin_value = sqrt( 1 - cos_value*cos_value );
+
+        float distancelength = distance.length();
+        if (distancelength == 0) return orxonox::Vector2(0, 0);
+        float radius = acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1)) / Ogre::Math::PI;
+
+        if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0)
+            return orxonox::Vector2( sin_value * radius, cos_value * radius);
+        else
+            return orxonox::Vector2( -sin_value * radius, cos_value * radius);
+    }
+
+    /**
+        @brief Returns the predicted position I have to aim at, if I want to hit a moving target with a moving projectile.
+        @param myposition My position
+        @param projectilespeed The speed of my projectile
+        @param targetposition The position of my target
+        @param targetvelocity The velocity of my target
+        @return The predicted position
+
+        The function predicts the position based on a linear velocity of the target. If the target changes speed or direction, the projectile will miss.
+    */
+    orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity)
+    {
+        float squaredProjectilespeed = projectilespeed * projectilespeed;
+        orxonox::Vector3 distance = targetposition - myposition;
+        float a = distance.squaredLength();
+        float b = 2 * (distance.x + distance.y + distance.z) * (targetvelocity.x + targetvelocity.y + targetvelocity.z);
+        float c = targetvelocity.squaredLength();
+
+        float temp = 4*squaredProjectilespeed*c + a*a - 4*b*c;
+        if (temp < 0)
+            return orxonox::Vector3::ZERO;
+
+        temp = sqrt(temp);
+        float time = (temp + a) / (2 * (squaredProjectilespeed - b));
+        return (targetposition + targetvelocity * time);
+    }
+
+    unsigned long getUniqueNumber()
+    {
+        static unsigned long aNumber = 135;
+        return aNumber++;
+    }
+
+
+    //////////////////////////
+    // Conversion functions //
+    //////////////////////////
+
+    // std::string to Vector2
+    bool ConverterFallback<std::string, orxonox::Vector2>::convert(orxonox::Vector2* output, const std::string& input)
+    {
+        size_t opening_parenthesis, closing_parenthesis = input.find(')');
+        if ((opening_parenthesis = input.find('(')) == std::string::npos)
+            opening_parenthesis = 0;
+        else
+            opening_parenthesis++;
+
+        SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),
+                         ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
+        if (tokens.size() >= 2)
+        {
+            if (!convertValue(&(output->x), tokens[0]))
+                return false;
+            if (!convertValue(&(output->y), tokens[1]))
+                return false;
+
+            return true;
+        }
+        return false;
+    }
+
+    // std::string to Vector3
+    bool ConverterFallback<std::string, orxonox::Vector3>::convert(orxonox::Vector3* output, const std::string& input)
+    {
+        size_t opening_parenthesis, closing_parenthesis = input.find(')');
+        if ((opening_parenthesis = input.find('(')) == std::string::npos)
+            opening_parenthesis = 0;
+        else
+            opening_parenthesis++;
+
+        SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),
+                         ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
+        if (tokens.size() >= 3)
+        {
+            if (!convertValue(&(output->x), tokens[0]))
+                return false;
+            if (!convertValue(&(output->y), tokens[1]))
+                return false;
+            if (!convertValue(&(output->z), tokens[2]))
+                return false;
+
+            return true;
+        }
+        return false;
+    }
+
+    // std::string to Vector4
+    bool ConverterFallback<std::string, orxonox::Vector4>::convert(orxonox::Vector4* output, const std::string& input)
+    {
+        size_t opening_parenthesis, closing_parenthesis = input.find(')');
+        if ((opening_parenthesis = input.find('(')) == std::string::npos)
+            opening_parenthesis = 0;
+        else
+            opening_parenthesis++;
+
+        SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),
+                         ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
+        if (tokens.size() >= 4)
+        {
+            if (!convertValue(&(output->x), tokens[0]))
+                return false;
+            if (!convertValue(&(output->y), tokens[1]))
+                return false;
+            if (!convertValue(&(output->z), tokens[2]))
+                return false;
+            if (!convertValue(&(output->w), tokens[3]))
+                return false;
+
+            return true;
+        }
+        return false;
+    }
+
+    // std::string to Quaternion
+    bool ConverterFallback<std::string, orxonox::Quaternion>::convert(orxonox::Quaternion* output, const std::string& input)
+    {
+        size_t opening_parenthesis, closing_parenthesis = input.find(')');
+        if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
+
+        SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
+        if (tokens.size() >= 4)
+        {
+            if (!convertValue(&(output->w), tokens[0]))
+                return false;
+            if (!convertValue(&(output->x), tokens[1]))
+                return false;
+            if (!convertValue(&(output->y), tokens[2]))
+                return false;
+            if (!convertValue(&(output->z), tokens[3]))
+                return false;
+
+            return true;
+        }
+        return false;
+    }
+
+    // std::string to ColourValue
+    bool ConverterFallback<std::string, orxonox::ColourValue>::convert(orxonox::ColourValue* output, const std::string& input)
+    {
+        size_t opening_parenthesis, closing_parenthesis = input.find(')');
+        if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }
+
+        SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');
+        if (tokens.size() >= 3)
+        {
+            if (!convertValue(&(output->r), tokens[0]))
+                return false;
+            if (!convertValue(&(output->g), tokens[1]))
+                return false;
+            if (!convertValue(&(output->b), tokens[2]))
+                return false;
+            if (tokens.size() >= 4)
+            {
+                if (!convertValue(&(output->a), tokens[3]))
+                    return false;
+            }
+            else
+                output->a = 1.0;
+
+            return true;
+        }
+        return false;
+    }
+}
Index: /code/branches/rocket2/src/libraries/util/Math.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/Math.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Math.h	(revision 6952)
@@ -0,0 +1,272 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Declaration and implementation of several math-functions, typedefs of some Ogre::Math classes to the orxonox namespace.
+*/
+
+#ifndef _Util_Math_H__
+#define _Util_Math_H__
+
+#include "UtilPrereqs.h"
+
+#include <string>
+#include <cmath>
+
+#include <OgreMath.h>
+#include <OgreVector2.h>
+#include <OgreVector3.h>
+#include <OgreVector4.h>
+#include <OgreQuaternion.h>
+#include <OgreColourValue.h>
+
+// Certain headers might define unwanted macros...
+#undef max
+#undef min
+#undef sgn
+#undef clamp
+#undef sqrt
+#undef square
+#undef mod
+#undef rnd
+
+namespace orxonox
+{
+#if OGRE_VERSION < 0x010603
+    _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian);
+    _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree);
+#endif
+    _UtilExport std::istream& operator>>(std::istream& in, orxonox::Radian& radian);
+    _UtilExport std::istream& operator>>(std::istream& in, orxonox::Degree& degree);
+
+    _UtilExport float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition);
+    _UtilExport orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);
+    _UtilExport orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);
+    _UtilExport orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity);
+
+    /**
+        @brief Returns the sign of the given value.
+        @param x The value
+        @return 1 if the value is positive or zero, -1 if the value is negative
+    */
+    template <typename T>
+    inline T sgn(T x)
+    {
+        return (x >= 0) ? (T)1 : (T)-1;
+    }
+
+    /**
+        @brief Keeps a value between a lower and an upper limit.
+        @param x The value
+        @param min The lower limit
+        @param max The upper limit
+    */
+    template <typename T>
+    inline T clamp(T x, T min, T max)
+    {
+        if (x < min)
+            return min;
+
+        if (x > max)
+            return max;
+
+        return x;
+    }
+
+    /**
+        @brief Returns the square value (x^2).
+    */
+    template <typename T>
+    inline T square(T x)
+    {
+        return x*x;
+    }
+
+    /**
+        @brief Returns the cube value (x^3).
+    */
+    template <typename T>
+    inline T cube(T x)
+    {
+        return x*x*x;
+    }
+
+    /**
+        @brief Rounds the value.
+    */
+    template <typename T>
+    inline int round(T x)
+    {
+        return static_cast<int>(x + 0.5);
+    }
+
+    /**
+        @brief The modulo operation, enhanced to work properly with negative values.
+        @param x The value
+        @param max The operand
+    */
+    template <typename T>
+    inline int mod(T x, int max)
+    {
+        if (x >= 0)
+            return (x % max);
+        else
+            return ((x % max) + max);
+    }
+
+    template <typename T>
+    inline T zeroise()
+    {
+        // Default, raise a compiler error without including large boost header cascade.
+        T temp();
+        *********temp; // If you reach this code, you abused zeroise()!
+        return temp;
+    }
+
+    template <> inline char                 zeroise<char>()                 { return 0; }
+    template <> inline unsigned char        zeroise<unsigned char>()        { return 0; }
+    template <> inline short                zeroise<short>()                { return 0; }
+    template <> inline unsigned short       zeroise<unsigned short>()       { return 0; }
+    template <> inline int                  zeroise<int>()                  { return 0; }
+    template <> inline unsigned int         zeroise<unsigned int>()         { return 0; }
+    template <> inline long                 zeroise<long>()                 { return 0; }
+    template <> inline unsigned long        zeroise<unsigned long>()        { return 0; }
+    template <> inline long long            zeroise<long long>()            { return 0; }
+    template <> inline unsigned long long   zeroise<unsigned long long>()   { return 0; }
+    template <> inline float                zeroise<float>()                { return 0; }
+    template <> inline double               zeroise<double>()               { return 0; }
+    template <> inline long double          zeroise<long double>()          { return 0; }
+    template <> inline bool                 zeroise<bool>()                 { return 0; }
+    template <> inline void*                zeroise<void*>()                { return 0; }
+    template <> inline std::string          zeroise<std::string>()          { return std::string(); }
+    template <> inline orxonox::Radian      zeroise<orxonox::Radian>()      { return orxonox::Radian(0.0f); }
+    template <> inline orxonox::Degree      zeroise<orxonox::Degree>()      { return orxonox::Degree(0.0f); }
+    template <> inline orxonox::Vector2     zeroise<orxonox::Vector2>()     { return orxonox::Vector2    (0, 0)      ; }
+    template <> inline orxonox::Vector3     zeroise<orxonox::Vector3>()     { return orxonox::Vector3    (0, 0, 0)   ; }
+    template <> inline orxonox::Vector4     zeroise<orxonox::Vector4>()     { return orxonox::Vector4    (0, 0, 0, 0); }
+    template <> inline orxonox::ColourValue zeroise<orxonox::ColourValue>() { return orxonox::ColourValue(0, 0, 0, 0); }
+    template <> inline orxonox::Quaternion  zeroise<orxonox::Quaternion>()  { return orxonox::Quaternion (0, 0, 0, 0); }
+
+    //! Provides zero value symbols that can be returned as reference
+    template <typename T>
+    struct NilValue
+    {
+        inline operator const T&() const
+        {
+            return value;
+        }
+        static T value;
+    };
+    template <typename T>
+    T NilValue<T>::value = zeroise<T>();
+
+    /**
+        @brief Interpolates between two values for a time between 0 and 1.
+        @param time The time is a value between 0 and 1 - the function returns start if time is 0 and end if time is 1 and interpolates if time is between 0 and 1.
+        @param start The value at time = 0
+        @param end The value at time = 1
+        @return The interpolation at a given time
+    */
+    template <typename T>
+    inline T interpolate(float time, const T& start, const T& end)
+    {
+        return time * (end - start) + start;
+    }
+
+    /**
+        @brief Interpolates smoothly between two values for a time between 0 and 1. The function starts slowly, increases faster and stops slowly again.
+        @param time The time is a value between 0 and 1 - the function returns start if time is 0 and end if time is 1 and interpolates if time is between 0 and 1.
+        @param start The value at time = 0
+        @param end The value at time = 1
+        @return The smoothed interpolation at a given time
+    */
+    template <typename T>
+    inline T interpolateSmooth(float time, const T& start, const T& end)
+    {
+        return (-2 * (end - start) * cube(time)) + (3 * (end - start) * square(time)) + start;
+    }
+
+    /**
+        @brief Returns a random number between 0 and almost 1: 0 <= rnd < 1.
+    */
+    inline float rnd()
+    {
+        return rand() / (RAND_MAX + 1.0f);
+    }
+
+    /**
+        @brief Returns a random number between 0 and almost max: 0 <= rnd < max.
+        @param max The maximum
+    */
+    inline float rnd(float max)
+    {
+        return rnd() * max;
+    }
+
+    /**
+        @brief Returns a random number between min and almost max: min <= rnd < max.
+        @param min The minimum
+        @param max The maximum
+    */
+    inline float rnd(float min, float max)
+    {
+        return rnd(max - min) + min;
+    }
+
+    /**
+        @brief Returns randomly 1 or -1 with equal probability.
+    */
+    inline float rndsgn()
+    {
+        return static_cast<float>((rand() & 0x2) - 1); // rand() & 0x2 is either 2 or 0
+    }
+
+    _UtilExport unsigned long getUniqueNumber();
+
+    class IntVector2
+    {
+    public:
+        IntVector2() : x(0), y(0) { }
+        IntVector2(int _x, int _y) : x(_x), y(_y) { }
+        int x;
+        int y;
+    };
+
+    class IntVector3
+    {
+    public:
+        IntVector3() : x(0), y(0), z(0) { }
+        IntVector3(int _x, int _y, int _z) : x(_x), y(_y), z(_z) { }
+        int x;
+        int y;
+        int z;
+    };
+}
+
+#endif /* _Util_Math_H__ */
Index: /code/branches/rocket2/src/libraries/util/MathConvert.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/MathConvert.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/MathConvert.h	(revision 6952)
@@ -0,0 +1,209 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ */
+
+/**
+    @file
+    @brief
+        Math conversion functions. Definitions are in Math.cc
+*/
+
+#ifndef _MathConvert_H__
+#define _MathConvert_H__
+
+#include "UtilPrereqs.h"
+#include "Math.h"
+#include "Convert.h"
+
+namespace orxonox
+{
+    ////////////////////
+    // Math to string //
+    ////////////////////
+
+    // Vector2 to std::string
+    template <>
+    struct ConverterExplicit<orxonox::Vector2, std::string>
+    {
+        FORCEINLINE static bool convert(std::string* output, const orxonox::Vector2& input)
+        {
+            std::ostringstream ostream;
+            if (ostream << input.x << ',' << input.y)
+            {
+                (*output) = ostream.str();
+                return true;
+            }
+            return false;
+        }
+    };
+
+    // Vector3 to std::string
+    template <>
+    struct ConverterExplicit<orxonox::Vector3, std::string>
+    {
+        FORCEINLINE static bool convert(std::string* output, const orxonox::Vector3& input)
+        {
+            std::ostringstream ostream;
+            if (ostream << input.x << ',' << input.y << ',' << input.z)
+            {
+                (*output) = ostream.str();
+                return true;
+            }
+            return false;
+        }
+    };
+
+    // Vector4 to std::string
+    template <>
+    struct ConverterExplicit<orxonox::Vector4, std::string>
+    {
+        FORCEINLINE static bool convert(std::string* output, const orxonox::Vector4& input)
+        {
+            std::ostringstream ostream;
+            if (ostream << input.x << ',' << input.y << ',' << input.z << ',' << input.w)
+            {
+                (*output) = ostream.str();
+                return true;
+            }
+            return false;
+        }
+    };
+
+    // Quaternion to std::string
+    template <>
+    struct ConverterExplicit<orxonox::Quaternion, std::string>
+    {
+        FORCEINLINE static bool convert(std::string* output, const orxonox::Quaternion& input)
+        {
+            std::ostringstream ostream;
+            if (ostream << input.w << ',' << input.x << ',' << input.y << ',' << input.z)
+            {
+                (*output) = ostream.str();
+                return true;
+            }
+            return false;
+        }
+    };
+
+    // ColourValue to std::string
+    template <>
+    struct ConverterExplicit<orxonox::ColourValue, std::string>
+    {
+        FORCEINLINE static bool convert(std::string* output, const orxonox::ColourValue& input)
+        {
+            std::ostringstream ostream;
+            if (ostream << input.r << ',' << input.g << ',' << input.b << ',' << input.a)
+            {
+                (*output) = ostream.str();
+                return true;
+            }
+            return false;
+        }
+    };
+
+
+    ////////////////////
+    // string to Math //
+    ////////////////////
+
+    // std::string to Vector2
+    template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector2>
+    { static bool convert(orxonox::Vector2*     output, const std::string& input); };
+    // std::string to Vector3
+    template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector3>
+    { static bool convert(orxonox::Vector3*     output, const std::string& input); };
+    // std::string to Vector4
+    template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector4>
+    { static bool convert(orxonox::Vector4*     output, const std::string& input); };
+    // std::string to Quaternion
+    template <> struct _UtilExport ConverterFallback<std::string, orxonox::Quaternion>
+    { static bool convert(orxonox::Quaternion*  output, const std::string& input); };
+    // std::string to ColourValue
+    template <> struct _UtilExport ConverterFallback<std::string, orxonox::ColourValue>
+    { static bool convert(orxonox::ColourValue* output, const std::string& input); };
+
+
+    ///////////////////////////////
+    // From and to Radian/Degree //
+    ///////////////////////////////
+
+    // From Radian
+    template <class ToType>
+    struct ConverterFallback<orxonox::Radian, ToType>
+    {
+        FORCEINLINE static bool convert(ToType* output, const orxonox::Radian& input)
+        {
+            return convertValue<Ogre::Real, ToType>(output, input.valueRadians());
+        }
+    };
+
+    // From Degree
+    template <class ToType>
+    struct ConverterFallback<orxonox::Degree, ToType>
+    {
+        FORCEINLINE static bool convert(ToType* output, const orxonox::Degree& input)
+        {
+            return convertValue<Ogre::Real, ToType>(output, input.valueDegrees());
+        }
+    };
+
+    // To Radian
+    template <class FromType>
+    struct ConverterFallback<FromType, orxonox::Radian>
+    {
+        FORCEINLINE static bool convert(orxonox::Radian* output, const FromType& input)
+        {
+            float temp;
+            if (convertValue(&temp, input))
+            {
+                *output = temp;
+                return true;
+            }
+            else
+                return false;
+        }
+    };
+
+    // To Degree
+    template <class FromType>
+    struct ConverterFallback<FromType, orxonox::Degree>
+    {
+        FORCEINLINE static bool convert(orxonox::Degree* output, const FromType& input)
+        {
+            float temp;
+            if (convertValue(&temp, input))
+            {
+                *output = temp;
+                return true;
+            }
+            else
+                return false;
+        }
+    };
+}
+
+#endif /* _MathConvert_H__ */
Index: /code/branches/rocket2/src/libraries/util/MultiType.cc
===================================================================
--- /code/branches/rocket2/src/libraries/util/MultiType.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/MultiType.cc	(revision 6952)
@@ -0,0 +1,208 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the MultiType.
+*/
+
+#include "MultiType.h"
+#include "MultiTypeValue.h"
+
+namespace orxonox
+{
+    /**
+        @brief Converts the current value of the MultiType to a new type.
+        @param type The type
+    */
+    bool MultiType::convert(MT_Type::Value type)
+    {
+        switch (type)
+        {
+            case MT_Type::Null:
+                this->reset(); return true;
+            case MT_Type::Char:
+                return this->convert<char>(); break;
+            case MT_Type::UnsignedChar:
+                return this->convert<unsigned char>(); break;
+            case MT_Type::Short:
+                return this->convert<short>(); break;
+            case MT_Type::UnsignedShort:
+                return this->convert<unsigned short>(); break;
+            case MT_Type::Int:
+                return this->convert<int>(); break;
+            case MT_Type::UnsignedInt:
+                return this->convert<unsigned int>(); break;
+            case MT_Type::Long:
+                return this->convert<long>(); break;
+            case MT_Type::UnsignedLong:
+                return this->convert<unsigned long>(); break;
+            case MT_Type::LongLong:
+                return this->convert<long long>(); break;
+            case MT_Type::UnsignedLongLong:
+                return this->convert<unsigned long long>(); break;
+            case MT_Type::Float:
+                return this->convert<float>(); break;
+            case MT_Type::Double:
+                return this->convert<double>(); break;
+            case MT_Type::LongDouble:
+                return this->convert<long double>(); break;
+            case MT_Type::Bool:
+                return this->convert<bool>(); break;
+            case MT_Type::VoidPointer:
+                return this->convert<void*>(); break;
+            case MT_Type::String:
+                return this->convert<std::string>(); break;
+            case MT_Type::Vector2:
+                return this->convert<orxonox::Vector2>(); break;
+            case MT_Type::Vector3:
+                return this->convert<orxonox::Vector3>(); break;
+            case MT_Type::Vector4:
+                return this->convert<orxonox::Vector4>(); break;
+            case MT_Type::ColourValue:
+                return this->convert<orxonox::ColourValue>(); break;
+            case MT_Type::Quaternion:
+                return this->convert<orxonox::Quaternion>(); break;
+            case MT_Type::Radian:
+                return this->convert<orxonox::Radian>(); break;
+            case MT_Type::Degree:
+                return this->convert<orxonox::Degree>(); break;
+            default:
+                this->reset(); return false; break;
+        };
+    }
+
+    /**
+        @brief Returns the name of the current type.
+        @return The name
+    */
+    std::string MultiType::getTypename() const
+    {
+        MT_Type::Value type = (this->value_) ? this->value_->type_ : MT_Type::Null;
+
+        switch (type)
+        {
+            case MT_Type::Char:
+                return "char"; break;
+            case MT_Type::UnsignedChar:
+                return "unsigned char"; break;
+            case MT_Type::Short:
+                return "short"; break;
+            case MT_Type::UnsignedShort:
+                return "unsigned short"; break;
+            case MT_Type::Int:
+                return "int"; break;
+            case MT_Type::UnsignedInt:
+                return "unsigned int"; break;
+            case MT_Type::Long:
+                return "long"; break;
+            case MT_Type::UnsignedLong:
+                return "unsigned long"; break;
+            case MT_Type::LongLong:
+                return "long long"; break;
+            case MT_Type::UnsignedLongLong:
+                return "unsigned long long"; break;
+            case MT_Type::Float:
+                return "float"; break;
+            case MT_Type::Double:
+                return "double"; break;
+            case MT_Type::LongDouble:
+                return "long double"; break;
+            case MT_Type::Bool:
+                return "bool"; break;
+            case MT_Type::VoidPointer:
+                return "void*"; break;
+            case MT_Type::String:
+                return "std::string"; break;
+            case MT_Type::Vector2:
+                return "orxonox::Vector2"; break;
+            case MT_Type::Vector3:
+                return "orxonox::Vector3"; break;
+            case MT_Type::Vector4:
+                return "orxonox::Vector4"; break;
+            case MT_Type::ColourValue:
+                return "orxonox::ColourValue"; break;
+            case MT_Type::Quaternion:
+                return "orxonox::Quaternion"; break;
+            case MT_Type::Radian:
+                return "orxonox::Radian"; break;
+            case MT_Type::Degree:
+                return "orxonox::Degree"; break;
+            default:
+                return "unknown"; break;
+        };
+    }
+
+    MultiType::operator char()                 const { return (this->value_) ? ((this->value_->type_ == MT_Type::Char            ) ? (static_cast<MT_Value<char>                *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator unsigned char()        const { return (this->value_) ? ((this->value_->type_ == MT_Type::UnsignedChar    ) ? (static_cast<MT_Value<unsigned char>       *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator short()                const { return (this->value_) ? ((this->value_->type_ == MT_Type::Short           ) ? (static_cast<MT_Value<short>               *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator unsigned short()       const { return (this->value_) ? ((this->value_->type_ == MT_Type::UnsignedShort   ) ? (static_cast<MT_Value<unsigned short>      *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator int()                  const { return (this->value_) ? ((this->value_->type_ == MT_Type::Int             ) ? (static_cast<MT_Value<int>                 *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator unsigned int()         const { return (this->value_) ? ((this->value_->type_ == MT_Type::UnsignedInt     ) ? (static_cast<MT_Value<unsigned int>        *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator long()                 const { return (this->value_) ? ((this->value_->type_ == MT_Type::Long            ) ? (static_cast<MT_Value<long>                *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator unsigned long()        const { return (this->value_) ? ((this->value_->type_ == MT_Type::UnsignedLong    ) ? (static_cast<MT_Value<unsigned long>       *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator long long()            const { return (this->value_) ? ((this->value_->type_ == MT_Type::LongLong        ) ? (static_cast<MT_Value<long long>           *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator unsigned long long()   const { return (this->value_) ? ((this->value_->type_ == MT_Type::UnsignedLongLong) ? (static_cast<MT_Value<unsigned long long>  *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator float()                const { return (this->value_) ? ((this->value_->type_ == MT_Type::Float           ) ? (static_cast<MT_Value<float>               *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator double()               const { return (this->value_) ? ((this->value_->type_ == MT_Type::Double          ) ? (static_cast<MT_Value<double>              *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator long double()          const { return (this->value_) ? ((this->value_->type_ == MT_Type::LongDouble      ) ? (static_cast<MT_Value<long double>         *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator bool()                 const { return (this->value_) ? ((this->value_->type_ == MT_Type::Bool            ) ? (static_cast<MT_Value<bool>                *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator void*()                const { return (this->value_) ? ((this->value_->type_ == MT_Type::VoidPointer     ) ? (static_cast<MT_Value<void*>               *>(this->value_))->value_ : (*this->value_)) : 0;                      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator std::string()          const { return (this->value_) ? ((this->value_->type_ == MT_Type::String          ) ? (static_cast<MT_Value<std::string>         *>(this->value_))->value_ : (*this->value_)) : NilValue<std::string>();          } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator orxonox::Vector2()     const { return (this->value_) ? ((this->value_->type_ == MT_Type::Vector2         ) ? (static_cast<MT_Value<orxonox::Vector2>    *>(this->value_))->value_ : (*this->value_)) : NilValue<orxonox::Vector2>();     } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator orxonox::Vector3()     const { return (this->value_) ? ((this->value_->type_ == MT_Type::Vector3         ) ? (static_cast<MT_Value<orxonox::Vector3>    *>(this->value_))->value_ : (*this->value_)) : NilValue<orxonox::Vector3>();     } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator orxonox::Vector4()     const { return (this->value_) ? ((this->value_->type_ == MT_Type::Vector4         ) ? (static_cast<MT_Value<orxonox::Vector4>    *>(this->value_))->value_ : (*this->value_)) : NilValue<orxonox::Vector4>();     } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator orxonox::ColourValue() const { return (this->value_) ? ((this->value_->type_ == MT_Type::ColourValue     ) ? (static_cast<MT_Value<orxonox::ColourValue>*>(this->value_))->value_ : (*this->value_)) : NilValue<orxonox::ColourValue>(); } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator orxonox::Quaternion()  const { return (this->value_) ? ((this->value_->type_ == MT_Type::Quaternion      ) ? (static_cast<MT_Value<orxonox::Quaternion> *>(this->value_))->value_ : (*this->value_)) : NilValue<orxonox::Quaternion>();  } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator orxonox::Radian()      const { return (this->value_) ? ((this->value_->type_ == MT_Type::Radian          ) ? (static_cast<MT_Value<orxonox::Radian>     *>(this->value_))->value_ : (*this->value_)) : NilValue<orxonox::Radian>();      } /** @brief Returns the current value, converted to the requested type. */
+    MultiType::operator orxonox::Degree()      const { return (this->value_) ? ((this->value_->type_ == MT_Type::Degree          ) ? (static_cast<MT_Value<orxonox::Degree>     *>(this->value_))->value_ : (*this->value_)) : NilValue<orxonox::Degree>();      } /** @brief Returns the current value, converted to the requested type. */
+
+    template <> void MultiType::createNewValueContainer(const char& value)                 { this->value_ = new MT_Value<char>                (value, MT_Type::Char            ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const unsigned char& value)        { this->value_ = new MT_Value<unsigned char>       (value, MT_Type::UnsignedChar    ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const short& value)                { this->value_ = new MT_Value<short>               (value, MT_Type::Short           ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const unsigned short& value)       { this->value_ = new MT_Value<unsigned short>      (value, MT_Type::UnsignedShort   ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const int& value)                  { this->value_ = new MT_Value<int>                 (value, MT_Type::Int             ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const unsigned int& value)         { this->value_ = new MT_Value<unsigned int>        (value, MT_Type::UnsignedInt     ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const long& value)                 { this->value_ = new MT_Value<long>                (value, MT_Type::Long            ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const unsigned long& value)        { this->value_ = new MT_Value<unsigned long>       (value, MT_Type::UnsignedLong    ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const long long& value)            { this->value_ = new MT_Value<long long>           (value, MT_Type::LongLong        ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const unsigned long long& value)   { this->value_ = new MT_Value<unsigned long long>  (value, MT_Type::UnsignedLongLong); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const float& value)                { this->value_ = new MT_Value<float>               (value, MT_Type::Float           ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const double& value)               { this->value_ = new MT_Value<double>              (value, MT_Type::Double          ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const long double& value)          { this->value_ = new MT_Value<long double>         (value, MT_Type::LongDouble      ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const bool& value)                 { this->value_ = new MT_Value<bool>                (value, MT_Type::Bool            ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(      void* const& value)          { this->value_ = new MT_Value<void*>               (value, MT_Type::VoidPointer     ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const std::string& value)          { this->value_ = new MT_Value<std::string>         (value, MT_Type::String          ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const orxonox::Vector2& value)     { this->value_ = new MT_Value<orxonox::Vector2>    (value, MT_Type::Vector2         ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const orxonox::Vector3& value)     { this->value_ = new MT_Value<orxonox::Vector3>    (value, MT_Type::Vector3         ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const orxonox::Vector4& value)     { this->value_ = new MT_Value<orxonox::Vector4>    (value, MT_Type::Vector4         ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const orxonox::ColourValue& value) { this->value_ = new MT_Value<orxonox::ColourValue>(value, MT_Type::ColourValue     ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const orxonox::Quaternion& value)  { this->value_ = new MT_Value<orxonox::Quaternion> (value, MT_Type::Quaternion      ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const orxonox::Radian& value)      { this->value_ = new MT_Value<orxonox::Radian>     (value, MT_Type::Radian          ); } /** @brief Creates a new value container for the given type. */
+    template <> void MultiType::createNewValueContainer(const orxonox::Degree& value)      { this->value_ = new MT_Value<orxonox::Degree>     (value, MT_Type::Degree          ); } /** @brief Creates a new value container for the given type. */
+}
Index: /code/branches/rocket2/src/libraries/util/MultiType.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/MultiType.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/MultiType.h	(revision 6952)
@@ -0,0 +1,561 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Declaration of the MultiType and some helper constructs.
+
+    The MultiType can hold a value of one of the following types:
+     - all primitives
+     - all pointers
+     - string
+     - Vector2, Vector3, Vector4
+     - Quaternion
+     - ColourValue
+     - Radian, Degree
+
+    The MultiType has a "type" determined by the first assigned value, either through
+     - the constructor,
+     - the assignment operator= or
+     - setValue(value).
+    If you assign another value of another type, the MultiType keeps "it's" type and
+    converts the new value to this type.
+
+    If you want to change the type, there are three possibilities:
+     - convert<T>() set's the type to T and converts the currently assigned value
+     - setType<T>() set's the type to T and resets the value
+     - setValue<T>(value) assigns a new value and changes the type to T.
+
+    @example
+    MultiType a = 10;;         // a has now the type int and the value 10
+    a.setValue("3.14");        // a has still the type int and "3.14" gets converted, therefore the value is now 3
+    a.setValue<float>("3.14"); // a has now the type float and "3.14" gets converted to 3.14
+    a.convert<bool>();         // converts 3.14 to bool, which is true
+    a = false;                 // assigns false, this is equivalent to a.setValue(false)
+
+    @note
+    Whenever a value gets converted, there is a boolean return value telling you whether it was
+    successful or not. If it wasn't a zero value is assigned with the help of zeroise<T>().
+*/
+
+#ifndef _MultiType_H__
+#define _MultiType_H__
+
+#include "UtilPrereqs.h"
+
+#include <cassert>
+#include <string>
+#include <OgreVector2.h>
+#include <OgreVector3.h>
+#include <OgreVector4.h>
+#include <OgreQuaternion.h>
+#include <OgreColourValue.h>
+
+#include "TypeTraits.h"
+
+namespace orxonox
+{
+    /**
+        @brief Enum of all possible types of a MultiType.
+    */
+    namespace MT_Type
+    {
+        enum Value
+        {
+            Null,
+            Char,
+            UnsignedChar,
+            Short,
+            UnsignedShort,
+            Int,
+            UnsignedInt,
+            Long,
+            UnsignedLong,
+            LongLong,
+            UnsignedLongLong,
+            Float,
+            Double,
+            LongDouble,
+            Bool,
+            VoidPointer,
+            String,
+            Vector2,
+            Vector3,
+            Vector4,
+            ColourValue,
+            Quaternion,
+            Radian,
+            Degree
+        };
+    }
+
+    /**
+        @brief The MultiType can hold a value of many possible types and convert them to other types.
+
+        The following types are supported by the MultiType:
+         - all primitves
+         - all pointers
+         - string
+         - Vector2, Vector3, Vector4
+         - Quaternion
+         - ColourValue
+         - Radian, Degree
+
+        The internal type of a MultiType is determined by the first assigned value, but can be
+        changed by using setType<T>(), convert<T>() or setValue<T>(value). If a value gets assigned
+        the normal way (operator=, setValue(value)), the value gets converted to the current internal
+        type of the MultiType.
+    */
+    class _UtilExport MultiType
+    {
+        _UtilExport friend std::ostream& operator<<(std::ostream& outstream, const MultiType& mt);
+        template <typename T> friend class MT_Value;
+
+    public:
+        /**
+            @brief MT_ValueBase is an almost pure virtual baseclass of MT_Value<T>, which holds the value of the MultiType.
+            This class is only used within the MultiType.
+        */
+        class _UtilExport MT_ValueBase
+        {
+        public:
+            MT_ValueBase(MT_Type::Value type) : type_(type), bHasDefaultValue_(false) {}
+            virtual ~MT_ValueBase() {}
+
+            virtual MT_ValueBase* clone() const = 0;
+
+            virtual void reset() = 0;
+            virtual bool assimilate(const MultiType& other) = 0;
+
+            /** @brief Returns the type of the current value. */
+            const MT_Type::Value& getType() const { return this->type_; }
+
+            /** @brief Checks whether the value is a default one. */
+            bool hasDefaultValue()   const { return this->bHasDefaultValue_; }
+
+            virtual bool setValue(const char& value)                 = 0;
+            virtual bool setValue(const unsigned char& value)        = 0;
+            virtual bool setValue(const short& value)                = 0;
+            virtual bool setValue(const unsigned short& value)       = 0;
+            virtual bool setValue(const int& value)                  = 0;
+            virtual bool setValue(const unsigned int& value)         = 0;
+            virtual bool setValue(const long& value)                 = 0;
+            virtual bool setValue(const unsigned long& value)        = 0;
+            virtual bool setValue(const long long& value)            = 0;
+            virtual bool setValue(const unsigned long long& value)   = 0;
+            virtual bool setValue(const float& value)                = 0;
+            virtual bool setValue(const double& value)               = 0;
+            virtual bool setValue(const long double& value)          = 0;
+            virtual bool setValue(const bool& value)                 = 0;
+            virtual bool setValue(      void* const& value)          = 0;
+            virtual bool setValue(const std::string& value)          = 0;
+            virtual bool setValue(const orxonox::Vector2& value)     = 0;
+            virtual bool setValue(const orxonox::Vector3& value)     = 0;
+            virtual bool setValue(const orxonox::Vector4& value)     = 0;
+            virtual bool setValue(const orxonox::ColourValue& value) = 0;
+            virtual bool setValue(const orxonox::Quaternion& value)  = 0;
+            virtual bool setValue(const orxonox::Radian& value)      = 0;
+            virtual bool setValue(const orxonox::Degree& value)      = 0;
+
+            virtual bool getValue(char*                 value) const = 0;
+            virtual bool getValue(unsigned char*        value) const = 0;
+            virtual bool getValue(short*                value) const = 0;
+            virtual bool getValue(unsigned short*       value) const = 0;
+            virtual bool getValue(int*                  value) const = 0;
+            virtual bool getValue(unsigned int*         value) const = 0;
+            virtual bool getValue(long*                 value) const = 0;
+            virtual bool getValue(unsigned long*        value) const = 0;
+            virtual bool getValue(long long*            value) const = 0;
+            virtual bool getValue(unsigned long long*   value) const = 0;
+            virtual bool getValue(float*                value) const = 0;
+            virtual bool getValue(double*               value) const = 0;
+            virtual bool getValue(long double*          value) const = 0;
+            virtual bool getValue(bool*                 value) const = 0;
+            virtual bool getValue(void**                value) const = 0;
+            virtual bool getValue(std::string*          value) const = 0;
+            virtual bool getValue(orxonox::Vector2*     value) const = 0;
+            virtual bool getValue(orxonox::Vector3*     value) const = 0;
+            virtual bool getValue(orxonox::Vector4*     value) const = 0;
+            virtual bool getValue(orxonox::ColourValue* value) const = 0;
+            virtual bool getValue(orxonox::Quaternion*  value) const = 0;
+            virtual bool getValue(orxonox::Radian*      value) const = 0;
+            virtual bool getValue(orxonox::Degree*      value) const = 0;
+
+            virtual operator char()                 const = 0;
+            virtual operator unsigned char()        const = 0;
+            virtual operator short()                const = 0;
+            virtual operator unsigned short()       const = 0;
+            virtual operator int()                  const = 0;
+            virtual operator unsigned int()         const = 0;
+            virtual operator long()                 const = 0;
+            virtual operator unsigned long()        const = 0;
+            virtual operator long long()            const = 0;
+            virtual operator unsigned long long()   const = 0;
+            virtual operator float()                const = 0;
+            virtual operator double()               const = 0;
+            virtual operator long double()          const = 0;
+            virtual operator bool()                 const = 0;
+            virtual operator void*()                const = 0;
+            virtual operator std::string()          const = 0;
+            virtual operator orxonox::Vector2()     const = 0;
+            virtual operator orxonox::Vector3()     const = 0;
+            virtual operator orxonox::Vector4()     const = 0;
+            virtual operator orxonox::ColourValue() const = 0;
+            virtual operator orxonox::Quaternion()  const = 0;
+            virtual operator orxonox::Radian()      const = 0;
+            virtual operator orxonox::Degree()      const = 0;
+
+            virtual void toString(std::ostream& outstream) const = 0;
+
+            virtual void importData( uint8_t*& mem )=0;
+            virtual void exportData( uint8_t*& mem ) const=0;
+            virtual uint8_t getSize() const=0;
+
+            MT_Type::Value type_;   //!< The type of the current value
+            bool bHasDefaultValue_; //!< True if the last conversion wasn't successful
+        };
+
+        public:
+            inline MultiType()                                  : value_(0) {}                                      /** @brief Default constructor: Assigns no value and no type. The type will be determined by the first assignment of a value. */
+            inline MultiType(const char& value)                 : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const unsigned char& value)        : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const short& value)                : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const unsigned short& value)       : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const int& value)                  : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const unsigned int& value)         : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const long& value)                 : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const unsigned long& value)        : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const long long& value)            : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const unsigned long long& value)   : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const float& value)                : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const double& value)               : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const long double& value)          : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const bool& value)                 : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(      void* const& value)          : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const std::string& value)          : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const orxonox::Vector2& value)     : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const orxonox::Vector3& value)     : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const orxonox::Vector4& value)     : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const orxonox::ColourValue& value) : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const orxonox::Quaternion& value)  : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const orxonox::Radian& value)      : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const orxonox::Degree& value)      : value_(0) { this->assignValue(value); }           /** @brief Constructor: Assigns the given value and sets the type. */
+            inline MultiType(const char* value)                 : value_(0) { this->setValue(std::string(value)); } /** @brief Constructor: Converts the char array to a std::string, assigns the value and sets the type. */
+            inline MultiType(const MultiType& other)            : value_(0) { this->setValue(other); }              /** @brief Copyconstructor: Assigns value and type of the other MultiType. */
+            inline MultiType(MT_Type::Value type)               : value_(0) { this->setType(type); }                /** @brief Constructor: Sets the type, the next assignment will determine the value. */
+
+            /** @brief Destructor: Deletes the MT_Value. */
+            inline ~MultiType() { if (this->value_) { delete this->value_; } }
+
+            template <typename V> inline const MultiType& operator=(const V& value)         { this->setValue(value); return (*this); } /** @brief Assigns a new value. The value will be converted to the current type of the MultiType. */
+            template <typename V> inline const MultiType& operator=(V* value)               { this->setValue(value); return (*this); } /** @brief Assigns a pointer. */
+            inline                       const MultiType& operator=(const MultiType& other) { this->setValue(other); return (*this); } /** @brief Assigns the value of the other MultiType and converts it to the current type of the MultiType. */
+            inline                       const MultiType& operator=(MT_Type::Value type)    { this->setType(type);   return (*this); } /** @brief Resets the value and changes the type. */
+
+            inline bool                                   setValue(const char& value);
+            inline bool                                   setValue(const unsigned char& value);
+            inline bool                                   setValue(const short& value);
+            inline bool                                   setValue(const unsigned short& value);
+            inline bool                                   setValue(const int& value);
+            inline bool                                   setValue(const unsigned int& value);
+            inline bool                                   setValue(const long& value);
+            inline bool                                   setValue(const unsigned long& value);
+            inline bool                                   setValue(const long long& value);
+            inline bool                                   setValue(const unsigned long long& value);
+            inline bool                                   setValue(const float& value);
+            inline bool                                   setValue(const double& value);
+            inline bool                                   setValue(const long double& value);
+            inline bool                                   setValue(const bool& value);
+            inline bool                                   setValue(      void* const& value);
+            inline bool                                   setValue(const std::string& value);
+            inline bool                                   setValue(const orxonox::Vector2& value);
+            inline bool                                   setValue(const orxonox::Vector3& value);
+            inline bool                                   setValue(const orxonox::Vector4& value);
+            inline bool                                   setValue(const orxonox::ColourValue& value);
+            inline bool                                   setValue(const orxonox::Quaternion& value);
+            inline bool                                   setValue(const orxonox::Radian& value);
+            inline bool                                   setValue(const orxonox::Degree& value);
+            inline bool                                   setValue(const char* value);
+            /** @brief Assigns a pointer. */
+            template <typename V> inline bool setValue(V* value)
+            {
+                if (this->value_)
+                    return this->value_->setValue(static_cast<void*>(const_cast<typename Loki::TypeTraits<V>::UnqualifiedType*>(value)));
+                else
+                    return this->assignValue     (static_cast<void*>(const_cast<typename Loki::TypeTraits<V>::UnqualifiedType*>(value)));
+            }
+            /** @brief Assigns the value of the other MultiType and converts it to the current type. */
+            bool                                          setValue(const MultiType& other) { if (this->value_) { return this->value_->assimilate(other); } else { if (other.value_) { this->value_ = other.value_->clone(); } return true; } }
+            /** @brief Changes the type to T and assigns the new value (which might be of another type than T - it gets converted). */
+            template <typename T, typename V> inline bool setValue(const V& value) { this->setType<T>(); return this->setValue(value); }
+
+
+            /** @brief Copies the other MultiType by assigning value and type. */
+            inline void                       copy(const MultiType& other)    { if (this == &other) { return; } if (this->value_) { delete this->value_; } this->value_ = (other.value_) ? other.value_->clone() : 0; }
+
+            template <typename T> inline bool convert()                       { return this->setValue<T>((T)(*this));  } /** @brief Converts the current value to type T. */
+            inline bool                       convert(const MultiType& other) { return this->convert(other.getType()); } /** @brief Converts the current value to the type of the other MultiType. */
+            bool                              convert(MT_Type::Value type);
+
+            /** @brief Current content gets deleted. New type is MT_Type::Null */
+            inline void                       reset()                         { if (this->value_) delete this->value_; this->value_ = 0; }
+            /** @brief Current content gets overridden with default zero value */
+            inline void                       resetValue()                    { if (this->value_) this->value_->reset(); }
+
+            template <typename T> inline void setType()                       { this->assignValue(typename Loki::TypeTraits<T>::UnqualifiedReferredType()); } /** @brief Resets the value and changes the internal type to T. */
+            inline void                       setType(const MultiType& other) { this->setType(other.getType());                                             } /** @brief Resets the value and changes the internal type to the type of the other MultiType. */
+            inline void                       setType(MT_Type::Value type)    { this->reset(); this->convert(type); this->resetValue();                     } /** @brief Resets the value and changes the internal type to the given type. */
+
+            /** @brief Returns the current type. */
+            inline MT_Type::Value             getType()                   const { return (this->value_) ? this->value_->type_ : MT_Type::Null; }
+            /** @brief Returns true if the current type equals the given type. */
+            inline bool                       isType(MT_Type::Value type) const { return (this->value_) ? (this->value_->type_ == type) : (type == MT_Type::Null); }
+            /** @brief Returns true if the current type is T. */
+            template <typename T> inline bool isType()                    const { return false; } // Only works for specialized values - see below
+            std::string                       getTypename()               const;
+
+            /** @brief Saves the value of the MT to a bytestream (pointed at by mem) and increases mem pointer by size of MT */
+            inline void                       exportData(uint8_t*& mem) const { assert(sizeof(MT_Type::Value)<=8); *static_cast<uint8_t*>(mem) = this->getType(); mem+=sizeof(uint8_t); this->value_->exportData(mem); }
+            /** @brief Loads the value of the MT from a bytestream (pointed at by mem) and increases mem pointer by size of MT */
+            inline void                       importData(uint8_t*& mem) { assert(sizeof(MT_Type::Value)<=8); this->setType(static_cast<MT_Type::Value>(*static_cast<uint8_t*>(mem))); mem+=sizeof(uint8_t); this->value_->importData(mem); }
+            /** @brief Saves the value of the MT to a bytestream and increases pointer to bytestream by size of MT */
+            inline uint8_t*&                  operator << (uint8_t*& mem) { importData(mem); return mem; }
+            /** @brief Loads the value of the MT to a bytestream and increases pointer to bytestream by size of MT */
+            inline void                       operator >> (uint8_t*& mem) const { exportData(mem); }
+            inline uint32_t                   getNetworkSize() const { assert(this->value_); return this->value_->getSize() + sizeof(uint8_t); }
+
+            /** @brief Checks whether the value is a default one. */
+            bool                              hasDefaultValue()         const { return this->value_->hasDefaultValue(); }
+
+            operator char()                  const;
+            operator unsigned char()         const;
+            operator short()                 const;
+            operator unsigned short()        const;
+            operator int()                   const;
+            operator unsigned int()          const;
+            operator long()                  const;
+            operator unsigned long()         const;
+            operator long long()             const;
+            operator unsigned long long()    const;
+            operator float()                 const;
+            operator double()                const;
+            operator long double()           const;
+            operator bool()                  const;
+            operator void*()                 const;
+            operator std::string()           const;
+            operator orxonox::Vector2()      const;
+            operator orxonox::Vector3()      const;
+            operator orxonox::Vector4()      const;
+            operator orxonox::ColourValue()  const;
+            operator orxonox::Quaternion()   const;
+            operator orxonox::Radian()       const;
+            operator orxonox::Degree()       const;
+            /** @brief Returns the current value, converted to a T* pointer. */
+            template <class T> operator T*() const { return (static_cast<T*>(this->operator void*())); }
+
+            inline bool getValue(char*                 value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(unsigned char*        value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(short*                value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(unsigned short*       value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(int*                  value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(unsigned int*         value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(long*                 value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(unsigned long*        value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(long long*            value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(unsigned long long*   value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(float*                value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(double*               value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(long double*          value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(bool*                 value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(void**                value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(std::string*          value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(orxonox::Vector2*     value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(orxonox::Vector3*     value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(orxonox::Vector4*     value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(orxonox::ColourValue* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(orxonox::Quaternion*  value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(orxonox::Radian*      value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+            inline bool getValue(orxonox::Degree*      value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+
+            inline char                     getChar()             const { return this->operator char();                 } /** @brief Returns the current value, converted to the requested type. */
+            inline unsigned char            getUnsignedChar()     const { return this->operator unsigned char();        } /** @brief Returns the current value, converted to the requested type. */
+            inline short                    getShort()            const { return this->operator short();                } /** @brief Returns the current value, converted to the requested type. */
+            inline unsigned short           getUnsignedShort()    const { return this->operator unsigned short();       } /** @brief Returns the current value, converted to the requested type. */
+            inline int                      getInt()              const { return this->operator int();                  } /** @brief Returns the current value, converted to the requested type. */
+            inline unsigned int             getUnsignedInt()      const { return this->operator unsigned int();         } /** @brief Returns the current value, converted to the requested type. */
+            inline long                     getLong()             const { return this->operator long();                 } /** @brief Returns the current value, converted to the requested type. */
+            inline unsigned long            getUnsignedLong()     const { return this->operator unsigned long();        } /** @brief Returns the current value, converted to the requested type. */
+            inline long long                getLongLong()         const { return this->operator long long();            } /** @brief Returns the current value, converted to the requested type. */
+            inline unsigned long long       getUnsignedLongLong() const { return this->operator unsigned long long();   } /** @brief Returns the current value, converted to the requested type. */
+            inline float                    getFloat()            const { return this->operator float();                } /** @brief Returns the current value, converted to the requested type. */
+            inline double                   getDouble()           const { return this->operator double();               } /** @brief Returns the current value, converted to the requested type. */
+            inline long double              getLongDouble()       const { return this->operator long double();          } /** @brief Returns the current value, converted to the requested type. */
+            inline bool                     getBool()             const { return this->operator bool();                 } /** @brief Returns the current value, converted to the requested type. */
+            inline void*                    getVoid()             const { return this->operator void*();                } /** @brief Returns the current value, converted to the requested type. */
+            inline std::string              getString()           const { return this->operator std::string();          } /** @brief Returns the current value, converted to the requested type. */
+            inline orxonox::Vector2         getVector2()          const { return this->operator orxonox::Vector2();     } /** @brief Returns the current value, converted to the requested type. */
+            inline orxonox::Vector3         getVector3()          const { return this->operator orxonox::Vector3();     } /** @brief Returns the current value, converted to the requested type. */
+            inline orxonox::Vector4         getVector4()          const { return this->operator orxonox::Vector4();     } /** @brief Returns the current value, converted to the requested type. */
+            inline orxonox::ColourValue     getColourValue()      const { return this->operator orxonox::ColourValue(); } /** @brief Returns the current value, converted to the requested type. */
+            inline orxonox::Quaternion      getQuaternion()       const { return this->operator orxonox::Quaternion();  } /** @brief Returns the current value, converted to the requested type. */
+            inline orxonox::Radian          getRadian()           const { return this->operator orxonox::Radian();      } /** @brief Returns the current value, converted to the requested type. */
+            inline orxonox::Degree          getDegree()           const { return this->operator orxonox::Degree();      } /** @brief Returns the current value, converted to the requested type. */
+            template <typename T> inline T* getPointer()          const { return static_cast<T*>(this->getVoid());      } /** @brief Returns the current value, converted to a T* pointer. */
+
+        private:
+            inline bool assignValue(const char& value)                 { if (this->value_ && this->value_->type_ == MT_Type::Char)             { return this->value_->setValue(value); } else { this->changeValueContainer<char>(value);                 return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const unsigned char& value)        { if (this->value_ && this->value_->type_ == MT_Type::UnsignedChar)     { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned char>(value);        return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const short& value)                { if (this->value_ && this->value_->type_ == MT_Type::Short)            { return this->value_->setValue(value); } else { this->changeValueContainer<short>(value);                return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const unsigned short& value)       { if (this->value_ && this->value_->type_ == MT_Type::UnsignedShort)    { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned short>(value);       return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const int& value)                  { if (this->value_ && this->value_->type_ == MT_Type::Int)              { return this->value_->setValue(value); } else { this->changeValueContainer<int>(value);                  return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const unsigned int& value)         { if (this->value_ && this->value_->type_ == MT_Type::UnsignedInt)      { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned int>(value);         return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const long& value)                 { if (this->value_ && this->value_->type_ == MT_Type::Long)             { return this->value_->setValue(value); } else { this->changeValueContainer<long>(value);                 return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const unsigned long& value)        { if (this->value_ && this->value_->type_ == MT_Type::UnsignedLong)     { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned long>(value);        return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const long long& value)            { if (this->value_ && this->value_->type_ == MT_Type::LongLong)         { return this->value_->setValue(value); } else { this->changeValueContainer<long long>(value);            return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const unsigned long long& value)   { if (this->value_ && this->value_->type_ == MT_Type::UnsignedLongLong) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned long long>(value);   return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const float& value)                { if (this->value_ && this->value_->type_ == MT_Type::Float)            { return this->value_->setValue(value); } else { this->changeValueContainer<float>(value);                return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const double& value)               { if (this->value_ && this->value_->type_ == MT_Type::Double)           { return this->value_->setValue(value); } else { this->changeValueContainer<double>(value);               return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const long double& value)          { if (this->value_ && this->value_->type_ == MT_Type::LongDouble)       { return this->value_->setValue(value); } else { this->changeValueContainer<long double>(value);          return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const bool& value)                 { if (this->value_ && this->value_->type_ == MT_Type::Bool)             { return this->value_->setValue(value); } else { this->changeValueContainer<bool>(value);                 return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(      void* const& value)          { if (this->value_ && this->value_->type_ == MT_Type::VoidPointer)      { return this->value_->setValue(value); } else { this->changeValueContainer<void*>(value);                return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const std::string& value)          { if (this->value_ && this->value_->type_ == MT_Type::String)           { return this->value_->setValue(value); } else { this->changeValueContainer<std::string>(value);          return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const orxonox::Vector2& value)     { if (this->value_ && this->value_->type_ == MT_Type::Vector2)          { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector2>(value);     return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const orxonox::Vector3& value)     { if (this->value_ && this->value_->type_ == MT_Type::Vector3)          { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector3>(value);     return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const orxonox::Vector4& value)     { if (this->value_ && this->value_->type_ == MT_Type::Vector4)          { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector4>(value);     return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const orxonox::ColourValue& value) { if (this->value_ && this->value_->type_ == MT_Type::ColourValue)      { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::ColourValue>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const orxonox::Quaternion& value)  { if (this->value_ && this->value_->type_ == MT_Type::Quaternion)       { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Quaternion>(value);  return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const orxonox::Radian& value)      { if (this->value_ && this->value_->type_ == MT_Type::Radian)           { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Radian>(value);      return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+            inline bool assignValue(const orxonox::Degree& value)      { if (this->value_ && this->value_->type_ == MT_Type::Degree)           { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Degree>(value);      return true; } } /** @brief Assigns a new value by changing type and creating a new container. */
+
+            /** @brief Changes the value container. */
+            template <typename T> inline void changeValueContainer(const T& value) { if (this->value_) { delete this->value_; } this->createNewValueContainer<T>(value); }
+            /** @brief Creates a new value container (works only with specialized types). */
+            template <typename T>        void createNewValueContainer(const T& value) { /* STATIC ASSERT */ *****value; return false; }
+
+            MT_ValueBase* value_; //!< A pointer to the value container
+    };
+
+    /** @brief Puts the MultiType on a stream by using the native << operator of the current type. */
+    _UtilExport inline std::ostream& operator<<(std::ostream& outstream, const MultiType& mt) { if (mt.value_) { mt.value_->toString(outstream); } return outstream; }
+
+    template <> inline bool MultiType::isType<char>()                 const { return (this->value_ && this->value_->type_ == MT_Type::Char);             } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<unsigned char>()        const { return (this->value_ && this->value_->type_ == MT_Type::UnsignedChar);     } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<short>()                const { return (this->value_ && this->value_->type_ == MT_Type::Short);            } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<unsigned short>()       const { return (this->value_ && this->value_->type_ == MT_Type::UnsignedShort);    } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<int>()                  const { return (this->value_ && this->value_->type_ == MT_Type::Int);              } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<unsigned int>()         const { return (this->value_ && this->value_->type_ == MT_Type::UnsignedInt);      } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<long>()                 const { return (this->value_ && this->value_->type_ == MT_Type::Long);             } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<unsigned long>()        const { return (this->value_ && this->value_->type_ == MT_Type::UnsignedLong);     } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<long long>()            const { return (this->value_ && this->value_->type_ == MT_Type::LongLong);         } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<unsigned long long>()   const { return (this->value_ && this->value_->type_ == MT_Type::UnsignedLongLong); } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<float>()                const { return (this->value_ && this->value_->type_ == MT_Type::Float);            } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<double>()               const { return (this->value_ && this->value_->type_ == MT_Type::Double);           } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<long double>()          const { return (this->value_ && this->value_->type_ == MT_Type::LongDouble);       } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<bool>()                 const { return (this->value_ && this->value_->type_ == MT_Type::Bool);             } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<void*>()                const { return (this->value_ && this->value_->type_ == MT_Type::VoidPointer);      } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<std::string>()          const { return (this->value_ && this->value_->type_ == MT_Type::String);           } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<orxonox::Vector2>()     const { return (this->value_ && this->value_->type_ == MT_Type::Vector2);          } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<orxonox::Vector3>()     const { return (this->value_ && this->value_->type_ == MT_Type::Vector3);          } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<orxonox::Vector4>()     const { return (this->value_ && this->value_->type_ == MT_Type::Vector4);          } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<orxonox::ColourValue>() const { return (this->value_ && this->value_->type_ == MT_Type::ColourValue);      } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<orxonox::Quaternion>()  const { return (this->value_ && this->value_->type_ == MT_Type::Quaternion);       } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<orxonox::Radian>()      const { return (this->value_ && this->value_->type_ == MT_Type::Radian);           } /** @brief Returns true if the current type equals the given type. */
+    template <> inline bool MultiType::isType<orxonox::Degree>()      const { return (this->value_ && this->value_->type_ == MT_Type::Degree);           } /** @brief Returns true if the current type equals the given type. */
+
+    // Specialization to avoid ambiguities with the conversion operator
+    template <> inline bool MultiType::convert<std::string>()          { return this->setValue<std::string>         (this->operator std::string());          } /** @brief Converts the current value to the given type. */
+    template <> inline bool MultiType::convert<orxonox::Vector2>()     { return this->setValue<orxonox::Vector2>    (this->operator orxonox::Vector2());     } /** @brief Converts the current value to the given type. */
+    template <> inline bool MultiType::convert<orxonox::Vector3>()     { return this->setValue<orxonox::Vector3>    (this->operator orxonox::Vector3());     } /** @brief Converts the current value to the given type. */
+    template <> inline bool MultiType::convert<orxonox::Vector4>()     { return this->setValue<orxonox::Vector4>    (this->operator orxonox::Vector4());     } /** @brief Converts the current value to the given type. */
+    template <> inline bool MultiType::convert<orxonox::ColourValue>() { return this->setValue<orxonox::ColourValue>(this->operator orxonox::ColourValue()); } /** @brief Converts the current value to the given type. */
+    template <> inline bool MultiType::convert<orxonox::Quaternion>()  { return this->setValue<orxonox::Quaternion> (this->operator orxonox::Quaternion());  } /** @brief Converts the current value to the given type. */
+    template <> inline bool MultiType::convert<orxonox::Radian>()      { return this->setValue<orxonox::Radian>     (this->operator orxonox::Radian());      } /** @brief Converts the current value to the given type. */
+    template <> inline bool MultiType::convert<orxonox::Degree>()      { return this->setValue<orxonox::Degree>     (this->operator orxonox::Degree());      } /** @brief Converts the current value to the given type. */
+
+    // Specialization to avoid ambiguities with the conversion operator
+    template <> inline bool MultiType::convert<const std::string&>()          { return this->convert<std::string>();          } /** @brief Converts the current value to the given type. */
+    template <> inline bool MultiType::convert<const orxonox::Vector2&>()     { return this->convert<orxonox::Vector2>();     } /** @brief Converts the current value to the given type. */
+    template <> inline bool MultiType::convert<const orxonox::Vector3&>()     { return this->convert<orxonox::Vector3>();     } /** @brief Converts the current value to the given type. */
+    template <> inline bool MultiType::convert<const orxonox::Vector4&>()     { return this->convert<orxonox::Vector4>();     } /** @brief Converts the current value to the given type. */
+    template <> inline bool MultiType::convert<const orxonox::ColourValue&>() { return this->convert<orxonox::ColourValue>(); } /** @brief Converts the current value to the given type. */
+    template <> inline bool MultiType::convert<const orxonox::Quaternion&>()  { return this->convert<orxonox::Quaternion>();  } /** @brief Converts the current value to the given type. */
+    template <> inline bool MultiType::convert<const orxonox::Radian&>()      { return this->convert<orxonox::Radian>();      } /** @brief Converts the current value to the given type. */
+    template <> inline bool MultiType::convert<const orxonox::Degree&>()      { return this->convert<orxonox::Degree>();      } /** @brief Converts the current value to the given type. */
+
+    template <> void MultiType::createNewValueContainer(const char& value);
+    template <> void MultiType::createNewValueContainer(const unsigned char& value);
+    template <> void MultiType::createNewValueContainer(const short& value);
+    template <> void MultiType::createNewValueContainer(const unsigned short& value);
+    template <> void MultiType::createNewValueContainer(const int& value);
+    template <> void MultiType::createNewValueContainer(const unsigned int& value);
+    template <> void MultiType::createNewValueContainer(const long& value);
+    template <> void MultiType::createNewValueContainer(const unsigned long& value);
+    template <> void MultiType::createNewValueContainer(const long long& value);
+    template <> void MultiType::createNewValueContainer(const unsigned long long& value);
+    template <> void MultiType::createNewValueContainer(const float& value);
+    template <> void MultiType::createNewValueContainer(const double& value);
+    template <> void MultiType::createNewValueContainer(const bool& value);
+    template <> void MultiType::createNewValueContainer(const long double& value);
+    template <> void MultiType::createNewValueContainer(      void* const& value);
+    template <> void MultiType::createNewValueContainer(const std::string& value);
+    template <> void MultiType::createNewValueContainer(const orxonox::Vector2& value);
+    template <> void MultiType::createNewValueContainer(const orxonox::Vector3& value);
+    template <> void MultiType::createNewValueContainer(const orxonox::Vector4& value);
+    template <> void MultiType::createNewValueContainer(const orxonox::ColourValue& value);
+    template <> void MultiType::createNewValueContainer(const orxonox::Quaternion& value);
+    template <> void MultiType::createNewValueContainer(const orxonox::Radian& value);
+    template <> void MultiType::createNewValueContainer(const orxonox::Degree& value);
+
+    inline bool MultiType::setValue(const char& value)                  { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const unsigned char& value)         { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const short& value)                 { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const unsigned short& value)        { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const int& value)                   { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const unsigned int& value)          { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const long& value)                  { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const unsigned long& value)         { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const long long& value)             { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const unsigned long long& value)    { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const float& value)                 { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const double& value)                { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const long double& value)           { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const bool& value)                  { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(      void* const& value)           { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const std::string& value)           { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const orxonox::Vector2& value)      { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const orxonox::Vector3& value)      { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const orxonox::Vector4& value)      { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const orxonox::ColourValue& value)  { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const orxonox::Quaternion& value)   { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const orxonox::Radian& value)       { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+    inline bool MultiType::setValue(const orxonox::Degree& value)       { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */
+
+    inline bool MultiType::setValue(const char* value)                  { if (this->value_) { return this->value_->setValue(std::string(value)); } else { return this->assignValue(std::string(value)); } }  /** @brief Assigns the given value and converts it to the current type. */
+}
+
+#endif /* _MultiType_H__ */
Index: /code/branches/rocket2/src/libraries/util/MultiTypeValue.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/MultiTypeValue.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/MultiTypeValue.h	(revision 6952)
@@ -0,0 +1,267 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Declaration and Implementation of the MT_Value<T> class.
+
+    The MT_Value<T> class is used to hold a value of type T within a MultiType.
+*/
+
+#ifndef _MultiTypeValue_H__
+#define _MultiTypeValue_H__
+
+#include "UtilPrereqs.h"
+
+#include <cassert>
+#include "MathConvert.h"
+#include "MultiType.h"
+#include "Serialise.h"
+
+namespace orxonox
+{
+    /**
+        @brief The MT_Value<T> class is used to hold a value of type T within a MultiType.
+    */
+    template <typename T>
+    class MT_Value : public MultiType::MT_ValueBase
+    {
+    public:
+        /** @brief Constructor: Assigns the value and the type identifier. */
+        MT_Value(const T& value, MT_Type::Value type) : MT_ValueBase(type), value_(value) {}
+
+        /** @brief Creates a copy of itself. */
+        inline MT_ValueBase* clone() const { return new MT_Value<T>(this->value_, this->type_); }
+
+        /** @brief Resets the current value to the default. */
+        inline void reset() { this->value_ = zeroise<T>(); bHasDefaultValue_ = true; }
+
+        /** @brief Assigns the value of the other MultiType, converted to T. @param other The other MultiType */
+        inline bool assimilate(const MultiType& other)
+        {
+            if (other.value_)
+            {
+                return !(bHasDefaultValue_ = !other.value_->getValue(&value_));
+            }
+            else
+            {
+                this->value_ = zeroise<T>();
+                return !(bHasDefaultValue_ = true);
+            }
+        }
+
+        inline bool getValue(char*                 value) const { return convertValue<T, char                >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(unsigned char*        value) const { return convertValue<T, unsigned char       >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(short*                value) const { return convertValue<T, short               >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(unsigned short*       value) const { return convertValue<T, unsigned short      >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(int*                  value) const { return convertValue<T, int                 >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(unsigned int*         value) const { return convertValue<T, unsigned int        >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(long*                 value) const { return convertValue<T, long                >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(unsigned long*        value) const { return convertValue<T, unsigned long       >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(long long*            value) const { return convertValue<T, long long           >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(unsigned long long*   value) const { return convertValue<T, unsigned long long  >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(float*                value) const { return convertValue<T, float               >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(double*               value) const { return convertValue<T, double              >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(long double*          value) const { return convertValue<T, long double         >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(bool*                 value) const { return convertValue<T, bool                >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(void**                value) const { return convertValue<T, void*               >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(std::string*          value) const { return convertValue<T, std::string         >(value, value_, zeroise<std::string>         ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(orxonox::Vector2*     value) const { return convertValue<T, orxonox::Vector2    >(value, value_, zeroise<orxonox::Vector2>    ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(orxonox::Vector3*     value) const { return convertValue<T, orxonox::Vector3    >(value, value_, zeroise<orxonox::Vector3>    ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(orxonox::Vector4*     value) const { return convertValue<T, orxonox::Vector4    >(value, value_, zeroise<orxonox::Vector4>    ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(orxonox::ColourValue* value) const { return convertValue<T, orxonox::ColourValue>(value, value_, zeroise<orxonox::ColourValue>()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(orxonox::Quaternion*  value) const { return convertValue<T, orxonox::Quaternion >(value, value_, zeroise<orxonox::Quaternion> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(orxonox::Radian*      value) const { return convertValue<T, orxonox::Radian     >(value, value_, zeroise<orxonox::Radian>     ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+        inline bool getValue(orxonox::Degree*      value) const { return convertValue<T, orxonox::Degree     >(value, value_, zeroise<orxonox::Degree>     ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */
+
+        inline bool setValue(const char& value)                 { return !(bHasDefaultValue_ = !convertValue<char                , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const unsigned char& value)        { return !(bHasDefaultValue_ = !convertValue<unsigned char       , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const short& value)                { return !(bHasDefaultValue_ = !convertValue<short               , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const unsigned short& value)       { return !(bHasDefaultValue_ = !convertValue<unsigned short      , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const int& value)                  { return !(bHasDefaultValue_ = !convertValue<int                 , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const unsigned int& value)         { return !(bHasDefaultValue_ = !convertValue<unsigned int        , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const long& value)                 { return !(bHasDefaultValue_ = !convertValue<long                , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const unsigned long& value)        { return !(bHasDefaultValue_ = !convertValue<unsigned long       , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const long long& value)            { return !(bHasDefaultValue_ = !convertValue<long long           , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const unsigned long long& value)   { return !(bHasDefaultValue_ = !convertValue<unsigned long long  , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const float& value)                { return !(bHasDefaultValue_ = !convertValue<float               , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const double& value)               { return !(bHasDefaultValue_ = !convertValue<double              , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const long double& value)          { return !(bHasDefaultValue_ = !convertValue<long double         , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const bool& value)                 { return !(bHasDefaultValue_ = !convertValue<bool                , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(      void* const& value)          { return !(bHasDefaultValue_ = !convertValue<void*               , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const std::string& value)          { return !(bHasDefaultValue_ = !convertValue<std::string         , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const orxonox::Vector2& value)     { return !(bHasDefaultValue_ = !convertValue<orxonox::Vector2    , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const orxonox::Vector3& value)     { return !(bHasDefaultValue_ = !convertValue<orxonox::Vector3    , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const orxonox::Vector4& value)     { return !(bHasDefaultValue_ = !convertValue<orxonox::Vector4    , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const orxonox::ColourValue& value) { return !(bHasDefaultValue_ = !convertValue<orxonox::ColourValue, T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const orxonox::Quaternion& value)  { return !(bHasDefaultValue_ = !convertValue<orxonox::Quaternion , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const orxonox::Radian& value)      { return !(bHasDefaultValue_ = !convertValue<orxonox::Radian     , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+        inline bool setValue(const orxonox::Degree& value)      { return !(bHasDefaultValue_ = !convertValue<orxonox::Degree     , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */
+
+        inline operator char()                 const { return getConvertedValue<T, char>                (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator unsigned char()        const { return getConvertedValue<T, unsigned char>       (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator short()                const { return getConvertedValue<T, short>               (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator unsigned short()       const { return getConvertedValue<T, unsigned short>      (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator int()                  const { return getConvertedValue<T, int>                 (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator unsigned int()         const { return getConvertedValue<T, unsigned int>        (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator long()                 const { return getConvertedValue<T, long>                (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator unsigned long()        const { return getConvertedValue<T, unsigned long>       (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator long long()            const { return getConvertedValue<T, long long>           (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator unsigned long long()   const { return getConvertedValue<T, unsigned long long>  (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator float()                const { return getConvertedValue<T, float>               (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator double()               const { return getConvertedValue<T, double>              (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator long double()          const { return getConvertedValue<T, long double>         (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator bool()                 const { return getConvertedValue<T, bool>                (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator void*()                const { return getConvertedValue<T, void*>               (this->value_, 0); }     /** @brief Returns the current value, converted to the requested type. */
+        inline operator std::string()          const { return getConvertedValue<T, std::string>         (this->value_, NilValue<std::string         >()); } /** @brief Returns the current value, converted to the requested type. */
+        inline operator orxonox::Vector2()     const { return getConvertedValue<T, orxonox::Vector2>    (this->value_, NilValue<orxonox::Vector2    >()); } /** @brief Returns the current value, converted to the requested type. */
+        inline operator orxonox::Vector3()     const { return getConvertedValue<T, orxonox::Vector3>    (this->value_, NilValue<orxonox::Vector3    >()); } /** @brief Returns the current value, converted to the requested type. */
+        inline operator orxonox::Vector4()     const { return getConvertedValue<T, orxonox::Vector4>    (this->value_, NilValue<orxonox::Vector4    >()); } /** @brief Returns the current value, converted to the requested type. */
+        inline operator orxonox::ColourValue() const { return getConvertedValue<T, orxonox::ColourValue>(this->value_, NilValue<orxonox::ColourValue>()); } /** @brief Returns the current value, converted to the requested type. */
+        inline operator orxonox::Quaternion()  const { return getConvertedValue<T, orxonox::Quaternion> (this->value_, NilValue<orxonox::Quaternion >()); } /** @brief Returns the current value, converted to the requested type. */
+        inline operator orxonox::Radian()      const { return getConvertedValue<T, orxonox::Radian>     (this->value_, NilValue<orxonox::Radian     >()); } /** @brief Returns the current value, converted to the requested type. */
+        inline operator orxonox::Degree()      const { return getConvertedValue<T, orxonox::Degree>     (this->value_, NilValue<orxonox::Degree     >()); } /** @brief Returns the current value, converted to the requested type. */
+
+        /** @brief Puts the current value on the stream */
+        inline void toString(std::ostream& outstream) const { outstream << this->value_; }
+
+        /** @brief loads data from the bytestream (mem) into the MT and increases the bytestream pointer by the size of the data */
+        inline void importData( uint8_t*& mem )         { loadAndIncrease( /*(const T&)*/this->value_, mem ); }
+        /** @brief saves data from the MT into the bytestream (mem) and increases the bytestream pointer by the size of the data */
+        inline void exportData( uint8_t*& mem ) const   { saveAndIncrease( /*(const T&)*/this->value_, mem ); }
+        /** @brief returns the size of the data that would be saved by exportData */
+        inline uint8_t getSize() const { return returnSize( this->value_ ); }
+
+        T value_; //!< The stored value
+    };
+
+    // Import / Export specialisation
+    // ColourValue
+    template <> inline void MT_Value<ColourValue>::importData( uint8_t*& mem )
+    {
+        loadAndIncrease( this->value_.r, mem );
+        loadAndIncrease( this->value_.g, mem );
+        loadAndIncrease( this->value_.b, mem );
+        loadAndIncrease( this->value_.a, mem );
+    }
+    template <> inline void MT_Value<ColourValue>::exportData( uint8_t*& mem ) const
+    {
+        saveAndIncrease( this->value_.r, mem );
+        saveAndIncrease( this->value_.g, mem );
+        saveAndIncrease( this->value_.b, mem );
+        saveAndIncrease( this->value_.a, mem );
+    }
+    template <> inline uint8_t MT_Value<ColourValue>::getSize() const
+    {
+        return 4*returnSize(this->value_.r);
+    }
+    // Ogre::Quaternion
+    template <> inline void MT_Value<Ogre::Quaternion>::importData( uint8_t*& mem )
+    {
+        loadAndIncrease( this->value_.x, mem );
+        loadAndIncrease( this->value_.y, mem );
+        loadAndIncrease( this->value_.z, mem );
+        loadAndIncrease( this->value_.w, mem );
+    }
+    template <> inline void MT_Value<Ogre::Quaternion>::exportData( uint8_t*& mem ) const
+    {
+        saveAndIncrease( this->value_.x, mem );
+        saveAndIncrease( this->value_.y, mem );
+        saveAndIncrease( this->value_.z, mem );
+        saveAndIncrease( this->value_.w, mem );
+    }
+    template <> inline uint8_t MT_Value<Ogre::Quaternion>::getSize() const
+    {
+        return 4*returnSize(this->value_.x);
+    }
+    // Ogre::Vector2
+    template <> inline void MT_Value<Ogre::Vector2>::importData( uint8_t*& mem )
+    {
+        loadAndIncrease( this->value_.x, mem );
+        loadAndIncrease( this->value_.y, mem );
+    }
+    template <> inline void MT_Value<Ogre::Vector2>::exportData( uint8_t*& mem ) const
+    {
+        saveAndIncrease( this->value_.x, mem );
+        saveAndIncrease( this->value_.y, mem );
+    }
+    template <> inline uint8_t MT_Value<Ogre::Vector2>::getSize() const
+    {
+        return 2*returnSize(this->value_.x);
+    }
+    // Ogre::Vector3
+    template <> inline void MT_Value<Ogre::Vector3>::importData( uint8_t*& mem )
+    {
+        loadAndIncrease( this->value_.x, mem );
+        loadAndIncrease( this->value_.y, mem );
+        loadAndIncrease( this->value_.z, mem );
+    }
+    template <> inline void MT_Value<Ogre::Vector3>::exportData( uint8_t*& mem ) const
+    {
+        saveAndIncrease( this->value_.x, mem );
+        saveAndIncrease( this->value_.y, mem );
+        saveAndIncrease( this->value_.z, mem );
+    }
+    template <> inline uint8_t MT_Value<Ogre::Vector3>::getSize() const
+    {
+        return 3*returnSize(this->value_.x);
+    }
+    // Ogre::Vector4
+    template <> inline void MT_Value<Ogre::Vector4>::importData( uint8_t*& mem )
+    {
+        loadAndIncrease( this->value_.x, mem );
+        loadAndIncrease( this->value_.y, mem );
+        loadAndIncrease( this->value_.z, mem );
+        loadAndIncrease( this->value_.w, mem );
+    }
+    template <> inline void MT_Value<Ogre::Vector4>::exportData( uint8_t*& mem ) const
+    {
+        saveAndIncrease( this->value_.x, mem );
+        saveAndIncrease( this->value_.y, mem );
+        saveAndIncrease( this->value_.z, mem );
+        saveAndIncrease( this->value_.w, mem );
+    }
+    template <> inline uint8_t MT_Value<Ogre::Vector4>::getSize() const
+    {
+        return 4*returnSize(this->value_.x);
+    }
+    template <> inline void MT_Value<void*>::importData( uint8_t*& mem )
+    {
+        assert(0);
+    }
+    template <> inline void MT_Value<void*>::exportData( uint8_t*& mem ) const
+    {
+        assert(0);
+    }
+    template <> inline uint8_t MT_Value<void*>::getSize() const
+    {
+        assert(0); return 0;
+    }
+}
+
+#endif /* _MultiTypeValue_H__ */
Index: /code/branches/rocket2/src/libraries/util/OgreForwardRefs.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/OgreForwardRefs.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/OgreForwardRefs.h	(revision 6952)
@@ -0,0 +1,227 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _OgreForwardRefs_H__
+#define _OgreForwardRefs_H__
+
+#include "UtilPrereqs.h"
+
+namespace Ogre
+{
+    class Angle;
+    class Animation;
+    class AnimationState;
+    class AnimationStateSet;
+    class AnimationTrack;
+    class Archive;
+    class ArchiveFactory;
+    class ArchiveManager;
+    class AutoParamDataSource;
+    class AxisAlignedBox;
+    class AxisAlignedBoxSceneQuery;
+    class Billboard;
+    class BillboardChain;
+    class BillboardSet;
+    class Bone;
+    class Camera;
+    class Codec;
+    class ColourValue;
+    class ConfigDialog;
+    template <typename T> class Controller;
+    template <typename T> class ControllerFunction;
+    class ControllerManager;
+    template <typename T> class ControllerValue;
+    class Degree;
+    class DynLib;
+    class DynLibManager;
+    class EdgeData;
+    class EdgeListBuilder;
+    class Entity;
+    class ErrorDialog;
+    class ExternalTextureSourceManager;
+    class Factory;
+    class Font;
+    class FontPtr;
+    class FontManager;
+    struct FrameEvent;
+    class FrameListener;
+    class Frustum;
+    class GpuProgram;
+    class GpuProgramPtr;
+    class GpuProgramManager;
+	class GpuProgramUsage;
+    class HardwareIndexBuffer;
+    class HardwareOcclusionQuery;
+    class HardwareVertexBuffer;
+	class HardwarePixelBuffer;
+    class HardwarePixelBufferSharedPtr;
+	class HighLevelGpuProgram;
+    class HighLevelGpuProgramPtr;
+	class HighLevelGpuProgramManager;
+	class HighLevelGpuProgramFactory;
+    class IndexData;
+    class IntersectionSceneQuery;
+    class IntersectionSceneQueryListener;
+    class Image;
+    class KeyFrame;
+    class Light;
+    class Log;
+    class LogManager;
+	class ManualResourceLoader;
+	class ManualObject;
+    class Material;
+    class MaterialPtr;
+    class MaterialManager;
+    class MaterialScriptCompiler;
+    class Math;
+    class Matrix3;
+    class Matrix4;
+    class MemoryManager;
+    class Mesh;
+    class MeshPtr;
+    class MeshSerializer;
+    class MeshSerializerImpl;
+    class MeshManager;
+    class MovableObject;
+    class MovablePlane;
+    class Node;
+	class NodeAnimationTrack;
+	class NodeKeyFrame;
+	class NumericAnimationTrack;
+	class NumericKeyFrame;
+    class Overlay;
+    class OverlayContainer;
+    class OverlayElement;
+    class OverlayElementFactory;
+    class OverlayManager;
+    class Particle;
+    class ParticleAffector;
+    class ParticleAffectorFactory;
+    class ParticleEmitter;
+    class ParticleEmitterFactory;
+    class ParticleSystem;
+    class ParticleSystemManager;
+    class ParticleSystemRenderer;
+    class ParticleSystemRendererFactory;
+    class ParticleVisualData;
+    class Pass;
+    class PatchMesh;
+    class PixelBox;
+    class Plane;
+    class PlaneBoundedVolume;
+	class Plugin;
+    class Pose;
+    class ProgressiveMesh;
+    class Profile;
+	class Profiler;
+    class Quaternion;
+	class Radian;
+    class Ray;
+    class RaySceneQuery;
+    class RaySceneQueryListener;
+    class Renderable;
+    class RenderPriorityGroup;
+    class RenderQueue;
+    class RenderQueueGroup;
+	class RenderQueueInvocation;
+	class RenderQueueInvocationSequence;
+    class RenderQueueListener;
+    class RenderSystem;
+    class RenderSystemCapabilities;
+    class RenderTarget;
+    class RenderTargetListener;
+    class RenderTexture;
+	class MultiRenderTarget;
+    class RenderWindow;
+    class RenderOperation;
+    class Resource;
+	class ResourceBackgroundQueue;
+	class ResourceGroupManager;
+    class ResourceManager;
+    class RibbonTrail;
+	class Root;
+    class SceneManager;
+    class SceneManagerEnumerator;
+    class SceneNode;
+    class SceneQuery;
+    class SceneQueryListener;
+	class ScriptLoader;
+    class Serializer;
+    class ShadowCaster;
+    class ShadowRenderable;
+	class ShadowTextureManager;
+    class SimpleRenderable;
+    class SimpleSpline;
+    class Skeleton;
+    class SkeletonPtr;
+    class SkeletonInstance;
+    class SkeletonManager;
+    class Sphere;
+    class SphereSceneQuery;
+	class StaticGeometry;
+    class StringConverter;
+    class StringInterface;
+    class SubEntity;
+    class SubMesh;
+	class TagPoint;
+    class Technique;
+	class TempBlendedBufferInfo;
+	class ExternalTextureSource;
+    class TextureUnitState;
+    class Texture;
+    class TexturePtr;
+	class TextureFont;
+    class TextureManager;
+    class TransformKeyFrame;
+	class Timer;
+    class UserDefinedObject;
+    class Vector2;
+    class Vector3;
+    class Vector4;
+    class Viewport;
+	class VertexAnimationTrack;
+    class VertexBufferBinding;
+    class VertexData;
+    class VertexDeclaration;
+	class VertexMorphKeyFrame;
+    class WireBoundingBox;
+    class Compositor;
+    class CompositorManager;
+    class CompositorChain;
+    class CompositorInstance;
+    class CompositionTechnique;
+    class CompositionPass;
+    class CompositionTargetPass;
+
+    // Originally not in OgrePrerequisites.h
+    class BorderPanelOverlayElement;
+    class PanelOverlayElement;
+    class TextAreaOverlayElement;
+}
+
+#endif /* _OgreForwardRefs_H__ */
Index: /code/branches/rocket2/src/libraries/util/OrxAssert.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/OrxAssert.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/OrxAssert.h	(revision 6952)
@@ -0,0 +1,52 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Declaration of custom assertion facilities
+*/
+
+#ifndef _OrxAssert_H__
+#define _OrxAssert_H__
+
+#include "UtilPrereqs.h"
+
+#include <cassert>
+#include "OutputHandler.h"
+
+// define an assert macro that can display a message
+#ifndef NDEBUG
+#define OrxAssert(Assertion, ErrorMessage) \
+    Assertion ? ((void)0) : (void)(orxonox::OutputHandler::getOutStream(1) << ErrorMessage << std::endl); \
+    assert(Assertion)
+#else
+#define OrxAssert(condition, errorMessage)  ((void)0)
+#endif
+
+#endif /* _OrxAssert_H__ */
Index: /code/branches/rocket2/src/libraries/util/OrxEnum.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/OrxEnum.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/OrxEnum.h	(revision 6952)
@@ -0,0 +1,67 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Declaration of the OrxEnum class.
+*/
+
+#ifndef _OrxEnum_H__
+#define _OrxEnum_H__
+
+#include "UtilPrereqs.h"
+
+namespace orxonox
+{
+    template <class T>
+    struct OrxEnum
+    {
+        public:
+            OrxEnum() { }
+            OrxEnum(int type)                  { type_ = type; }
+            OrxEnum(const T& instance)   { type_ = instance.type_; }
+
+            operator int()                     { return type_; }
+            T& operator =(int type)      { type_ = type; return *this; }
+            bool operator <(const T& right) const { return (type_ < right.type_); }
+            bool operator >(const T& right) const { return (type_ > right.type_); }
+
+        private:
+            OrxEnum(const OrxEnum& instance);
+            int type_;
+    };
+}
+
+#define OrxEnumConstructors(enumName)                        \
+enumName() { }                                               \
+enumName(int type) : OrxEnum<enumName>(type)             { } \
+enumName(const enumName& inst) : OrxEnum<enumName>(inst) { } \
+void dummyFunction()
+
+#endif /* _OrxEnum_H__ */
Index: /code/branches/rocket2/src/libraries/util/OutputHandler.cc
===================================================================
--- /code/branches/rocket2/src/libraries/util/OutputHandler.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/OutputHandler.cc	(revision 6952)
@@ -0,0 +1,308 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+/**
+@file
+@brief
+    Definition of classes related to output (logging).
+*/
+
+#include "OutputHandler.h"
+
+#include <algorithm>
+#include <ctime>
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <sstream>
+
+#include "Debug.h"
+
+namespace orxonox
+{
+    //! How the log file shall be named on the filesystem
+    const std::string logFileBaseName_g = "orxonox.log";
+
+    /////////////////////////
+    ///// LogFileWriter /////
+    /////////////////////////
+    /**
+    @brief
+        Writes the output to the log file.
+    @note
+        As long as the correct log path is not yet known (for pre main code), the
+        LogFileWriter will write to a temporary file in /temp (Unix) or %TEMP% (Windows).
+        As soon as you set the correct path setLogPath the content of the temporary file
+        is read and put into the new file as well.
+    */
+    class LogFileWriter : public OutputListener
+    {
+    public:
+        /**
+        @brief
+            Gets temporary log path and starts the log file
+        @param outputHandler
+            This is only required to avoid another call to getInstance (this c'tor was
+            called from getInstance!)
+        */
+        LogFileWriter()
+            : OutputListener(OutputHandler::logFileOutputListenerName_s)
+        {
+            // Get path for a temporary file
+#ifdef ORXONOX_PLATFORM_WINDOWS
+            char* pTempDir = getenv("TEMP");
+            this->logFilename_ = std::string(pTempDir) + '/' + logFileBaseName_g;
+#else
+            this->logFilename_ = std::string("/tmp/") + logFileBaseName_g;
+#endif
+
+            // Get current time
+            time_t rawtime;
+            struct tm* timeinfo;
+            time(&rawtime);
+            timeinfo = localtime(&rawtime);
+
+            this->logFile_.open(this->logFilename_.c_str(), std::fstream::out);
+            this->logFile_ << "Started log on " << asctime(timeinfo) << std::endl;
+            this->logFile_.flush();
+
+            this->outputStream_ = &this->logFile_;
+        }
+
+        //! Closes the log file
+        ~LogFileWriter()
+        {
+            this->logFile_ << "Closed log" << std::endl;
+            this->logFile_.close();
+        }
+
+        //! Changes the log path
+        void setLogPath(const std::string& path)
+        {
+            this->logFile_.close();
+            // Read old file into a buffer
+            std::ifstream old(this->logFilename_.c_str());
+            this->logFilename_ = path + logFileBaseName_g;
+            // Open the new file and feed it the content of the old one
+            this->logFile_.open(this->logFilename_.c_str(), std::fstream::out);
+            this->logFile_ << old.rdbuf();
+            this->logFile_.flush();
+            old.close();
+        }
+
+    private:
+        std::ofstream logFile_;     //! File handle for the log file
+        std::string   logFilename_; //! Filename of the log file
+    };
+
+
+    /////////////////////////
+    ///// ConsoleWriter /////
+    /////////////////////////
+    /**
+    @brief
+        Writes the output to std::cout.
+    @note
+        This listener will usually be disable once an actual shell with console is instantiated.
+    */
+    class ConsoleWriter : public OutputListener
+    {
+    public:
+        //! Only assigns the output stream with std::cout
+        ConsoleWriter()
+            : OutputListener("consoleLog")
+        {
+            this->outputStream_ = &std::cout;
+        }
+    };
+
+
+    ///////////////////////////
+    ///// MemoryLogWriter /////
+    ///////////////////////////
+    /**
+    @brief
+        OutputListener that writes all the output piece by piece to an array
+        associated with the corresponding output level.
+    @note
+        Only output below or equal to the current soft debug level is written
+        to minimise huge arrays for the normal run.
+    */
+    class MemoryLogWriter : public OutputListener
+    {
+    public:
+        friend class OutputHandler;
+
+        /**
+        @brief
+            Sets the right soft debug level and registers itself
+        @param outputHandler
+            This is only required to avoid another call to getInstance (this c'tor was
+            called from getInstance!)
+        */
+        MemoryLogWriter()
+            : OutputListener("memoryLog")
+        {
+            this->outputStream_ = &this->buffer_;
+        }
+
+        //! Pushed the just written output to the internal array
+        void outputChanged(int level)
+        {
+            if (!this->buffer_.str().empty())
+            {
+                // Read ostringstream and store it
+                this->output_.push_back(std::make_pair(level, this->buffer_.str()));
+                // Clear content and flags
+                this->buffer_.str(std::string());
+            }
+            this->buffer_.clear();
+        }
+
+    private:
+        std::ostringstream                        buffer_; //! Stream object used to process the output
+        std::vector<std::pair<int, std::string> > output_; //! Vector containing ALL output
+    };
+
+
+    /////////////////////////
+    ///// OutputHandler /////
+    /////////////////////////
+    const std::string OutputHandler::logFileOutputListenerName_s = "logFile";
+          int         OutputHandler::softDebugLevel_s = hardDebugLevel;
+
+    //! Creates the LogFileWriter and the MemoryLogWriter
+    OutputHandler::OutputHandler()
+        : outputLevel_(OutputLevel::Verbose)
+    {
+#ifdef ORXONOX_RELEASE
+        const OutputLevel::Value defaultLevelConsole = OutputLevel::Error;
+        const OutputLevel::Value defaultLevelLogFile = OutputLevel::Info;
+#else
+        const OutputLevel::Value defaultLevelConsole = OutputLevel::Info;
+        const OutputLevel::Value defaultLevelLogFile = OutputLevel::Debug;
+#endif
+
+        this->logFile_ = new LogFileWriter();
+        // Use default level until we get the configValue from the Core
+        this->logFile_->softDebugLevel_ = defaultLevelLogFile;
+        this->registerOutputListener(this->logFile_);
+
+        this->consoleWriter_ = new ConsoleWriter();
+        this->consoleWriter_->softDebugLevel_ = defaultLevelConsole;
+        this->registerOutputListener(this->consoleWriter_);
+
+        this->output_ = new MemoryLogWriter();
+        // We capture as much input as the listener with the highest level
+        this->output_->softDebugLevel_ = getSoftDebugLevel();
+        this->registerOutputListener(this->output_);
+    }
+
+    //! Destroys the LogFileWriter and the MemoryLogWriter
+    OutputHandler::~OutputHandler()
+    {
+        delete this->logFile_;
+        delete this->consoleWriter_;
+        delete this->output_;
+    }
+
+    OutputHandler& OutputHandler::getInstance()
+    {
+        static OutputHandler orxout;
+        return orxout;
+    }
+
+    void OutputHandler::registerOutputListener(OutputListener* listener)
+    {
+        for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        {
+            if ((*it)->name_ == listener->name_)
+            {
+                COUT(2) << "OutputHandler, Warning: Trying to register two listeners with the same name!" << std::endl;
+                return;
+            }
+        }
+        this->listeners_.push_back(listener);
+        // Update global soft debug level
+        this->setSoftDebugLevel(listener->getOutputListenerName(), listener->getSoftDebugLevel());
+    }
+
+    void OutputHandler::unregisterOutputListener(OutputListener* listener)
+    {
+        this->listeners_.remove(listener);
+    }
+
+    void OutputHandler::setLogPath(const std::string& path)
+    {
+        this->logFile_->setLogPath(path);
+    }
+
+    void OutputHandler::disableCout()
+    {
+        this->unregisterOutputListener(this->consoleWriter_);
+    }
+
+    void OutputHandler::enableCout()
+    {
+        this->registerOutputListener(this->consoleWriter_);
+    }
+
+    OutputHandler::OutputVectorIterator OutputHandler::getOutputVectorBegin() const
+    {
+        return this->output_->output_.begin();
+    }
+
+    OutputHandler::OutputVectorIterator OutputHandler::getOutputVectorEnd() const
+    {
+        return this->output_->output_.end();
+    }
+
+    int OutputHandler::getSoftDebugLevel(const std::string& name) const
+    {
+        for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        {
+            if ((*it)->name_ == name)
+                return (*it)->softDebugLevel_;
+        }
+        return -1;
+    }
+
+    void OutputHandler::setSoftDebugLevel(const std::string& name, int level)
+    {
+        int globalSoftDebugLevel = -1;
+        for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        {
+            if ((*it)->name_ == name)
+                (*it)->softDebugLevel_ = level;
+            if ((*it)->softDebugLevel_ > globalSoftDebugLevel)
+                globalSoftDebugLevel = (*it)->softDebugLevel_;
+        }
+        // Update global soft debug level
+        OutputHandler::softDebugLevel_s = globalSoftDebugLevel;
+    }
+}
Index: /code/branches/rocket2/src/libraries/util/OutputHandler.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/OutputHandler.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/OutputHandler.h	(revision 6952)
@@ -0,0 +1,282 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+/**
+@file
+@brief
+    Declaration of classes related to output (logging).
+*/
+
+#ifndef _OutputHandler_H__
+#define _OutputHandler_H__
+
+#include "UtilPrereqs.h"
+
+#include <list>
+#include <ostream>
+#include <string>
+#include <vector>
+#include <utility>
+
+namespace orxonox
+{
+    /**
+    @brief
+        Denotes different levels of text output (log output)
+
+        0, None   : Very important output
+        1, Error  : Errors
+        2, Warning: Warnings
+        3, Info   : Information
+        4, Debug  : Debug information
+        5, Verbose: More debug information
+        6, Ultra  : Crazy debug information
+    */
+    namespace OutputLevel
+    {
+        enum Value
+        {
+            None    = 0,
+            Error   = 1,
+            Warning = 2,
+            Info    = 3,
+            Debug   = 4,
+            Verbose = 5,
+            Ultra   = 6,
+        };
+    }
+
+    // Forward declarations for classes in the source file
+    class LogFileWriter;
+    class ConsoleWriter;
+    class MemoryLogWriter;
+
+    /**
+    @brief
+        The OutputHandler acts like std::cout, but output isn't only shown in the console.
+
+        You can register your own listener for output by inheriting from OutputListner.
+        And if you need the output previously processed, iterate over it with
+        OutputHandler::getOutputVector[Begin/End].
+        The way to output text is to first set the desired output level with
+        OutputHandler::getOutStream(level) and then use the "<<" operator like with std::cout.
+    */
+    class _UtilExport OutputHandler
+    {
+        public:
+            //! Returns a reference to the only existing instance of the OutputHandler class.
+            static OutputHandler& getInstance();
+
+            //! Sets the output level and returns a stream to be used with "<<"
+            static inline OutputHandler& getOutStream(int level)
+                { return OutputHandler::getInstance().setOutputLevel(level); }
+
+            typedef std::vector<std::pair<int, std::string> >::const_iterator OutputVectorIterator;
+            //! Returns an iterator to the beginning of the all-output vector
+            OutputVectorIterator getOutputVectorBegin() const;
+            //! Returns an iterator to the end of the all-output vector
+            OutputVectorIterator getOutputVectorEnd() const;
+
+            //! Writes to all output devices
+            static inline const std::string& log(const std::string& text)
+                { OutputHandler::getOutStream(0).output(text) << std::endl; return text; }
+
+            //! Writes an error message to the output
+            static inline const std::string& error(const std::string& text)
+                { OutputHandler::getOutStream(1).output(text) << std::endl; return text; }
+
+            //! Writes a warning message to the output
+            static inline const std::string& warning(const std::string& text)
+                { OutputHandler::getOutStream(2).output(text) << std::endl; return text; }
+
+            //! Writes an informational message to the output
+            static inline const std::string& info(const std::string& text)
+                { OutputHandler::getOutStream(3).output(text) << std::endl; return text; }
+
+            //! Writes a debug message to the output
+            static inline const std::string& debug(const std::string& text)
+                { OutputHandler::getOutStream(4).output(text) << std::endl; return text; }
+
+            //! Registers an object that receives output via a provided std::ostream
+            void registerOutputListener(OutputListener* listener);
+            //! Unregisters an object that receives output via a provided std::ostream
+            void unregisterOutputListener(OutputListener* listener);
+
+            //! Set the log path once the program has been properly initialised
+            void setLogPath(const std::string& path);
+            //! Disables the std::cout stream for output
+            void disableCout();
+            //! Enables the std::cout stream for output (startup behaviour)
+            void enableCout();
+
+            //! Sets the level of the incoming output and returns the OutputHandler
+            inline OutputHandler& setOutputLevel(int level)
+                { this->outputLevel_ = level; return *this; }
+
+            //! Returns the level of the incoming output
+            inline int getOutputLevel() const
+                { return this->outputLevel_; }
+
+            //! Returns the maximum debug level over all registered listeners (devices)
+            static int getSoftDebugLevel() { return softDebugLevel_s; }
+            //! Returns the soft debug level for a device by its name   @return The level or -1 if the listener was not found
+            int  getSoftDebugLevel(const std::string& name) const;
+            //! Sets the soft debug level for a listener by its name   @remarks Only works for registered listeners!
+            void setSoftDebugLevel(const std::string& name, int level);
+
+            /**
+            @brief
+                General template that copes with all output.
+                Required because operator << might be ambiguous.
+                @a output will be streamed into every listener with an appropriate debug level
+            @return
+                Returns a reference to the OutputHandler so you can use it again directly
+            */
+            template <class T>
+            OutputHandler& output(const T& output);
+
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(unsigned char val)      { return this->output(val); }
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(short val)              { return this->output(val); }
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(unsigned short val)     { return this->output(val); }
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(int val)                { return this->output(val); }
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(unsigned int val)       { return this->output(val); }
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(long val)               { return this->output(val); }
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(unsigned long val)      { return this->output(val); }
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(long long val)          { return this->output(val); }
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(unsigned long long val) { return this->output(val); }
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(float val)              { return this->output(val); }
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(double val)             { return this->output(val); }
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(long double val)        { return this->output(val); }
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(const void* val)        { return this->output(val); }
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(bool val)               { return this->output(val); }
+
+            //! Overloaded << operator, redirects the output to the listeners
+            inline OutputHandler& operator<<(std::streambuf* sb)     { return this->output(sb); }
+
+            //! Overloaded << operator, redirect the output of classes with self defined 'operator <<' to the listeners
+            template <class T>
+            inline OutputHandler& operator<<(const T& val)           { return this->output(val); }
+
+            //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners
+            inline OutputHandler& operator<<(std::ostream&  (*manip)(std::ostream&))  { return this->output(manip); }
+            //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners
+            inline OutputHandler& operator<<(std::ios&      (*manip)(std::ios&))      { return this->output(manip); }
+            //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners
+            inline OutputHandler& operator<<(std::ios_base& (*manip)(std::ios_base&)) { return this->output(manip); }
+
+            //! Dummy operator required by Debug.h for the ternary operator
+            inline operator int() const { return 0; }
+
+            //! Name of the OutputListener that writes to the log file
+            static const std::string logFileOutputListenerName_s;
+
+        private:
+            OutputHandler();
+            ~OutputHandler();
+            OutputHandler(const OutputHandler& rhs); //! Unused and undefined
+
+            std::list<OutputListener*> listeners_;        //!< Array with all registered output listeners
+            int                        outputLevel_;      //!< The level of the incoming output
+            LogFileWriter*             logFile_;          //!< Listener that writes to the log file
+            ConsoleWriter*             consoleWriter_;    //!< Listener for std::cout (just program beginning)
+            MemoryLogWriter*           output_;           //!< Listener that Stores ALL output below the current soft debug level
+            static int                 softDebugLevel_s;  //!< Maximum of all soft debug levels. @note This is only static for faster access
+    };
+
+    /**
+    @brief
+        Interface for listening to output.
+    @remarks
+        Remember to register the listener (not done automatically!)
+    */
+    class OutputListener
+    {
+        friend class OutputHandler;
+
+    public:
+        OutputListener(const std::string& name)
+            : outputStream_(NULL)
+            , name_(name)
+            , softDebugLevel_(OutputLevel::Info)
+        {}
+        virtual ~OutputListener() {}
+
+        //! Gets called whenever output is put into the stream
+        virtual void outputChanged(int level) {}
+        //! Returns the name of this output listener
+        const std::string& getOutputListenerName() const { return this->name_; }
+        //! Returns the soft debug level of the listener
+        int getSoftDebugLevel() const { return this->softDebugLevel_; }
+        //! Sets the soft debug level of the listener
+        void setSoftDebugLevel(int level)
+        {
+            this->softDebugLevel_ = level;
+            OutputHandler::getInstance().setSoftDebugLevel(this->name_, level);
+        }
+
+    protected:
+        std::ostream*     outputStream_;   //!< Pointer to the associated output stream, can be NULL
+
+    private:
+        const std::string name_;           //!< Name of the listener, constant and unique!
+        int               softDebugLevel_; //!< Current soft debug level that defines what kind of output is written to the stream
+    };
+
+    template<class T>
+    inline OutputHandler& OutputHandler::output(const T& output)
+    {
+        for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
+        {
+            if (this->outputLevel_ <= (*it)->softDebugLevel_ && (*it)->outputStream_ != NULL)
+            {
+                std::ostream& stream = *((*it)->outputStream_);
+                stream << output;
+                stream.flush();
+                (*it)->outputChanged(this->outputLevel_);
+            }
+        }
+
+        return *this;
+    }
+}
+
+#endif /* _OutputHandler_H__ */
Index: /code/branches/rocket2/src/libraries/util/RefToValue.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/RefToValue.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/RefToValue.h	(revision 6952)
@@ -0,0 +1,70 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2006 Richard Sposato
+// Copyright (c) 2006 Peter Kümmel
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The authors make no representations about the 
+//     suitability of this software for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+#ifndef LOKI_REFTOVALUE_INC_
+#define LOKI_REFTOVALUE_INC_
+
+// $Id: RefToValue.h 751 2006-10-17 19:50:37Z syntheticpp $
+
+
+namespace Loki
+{
+
+    ////////////////////////////////////////////////////////////////////////////////
+    ///  \class RefToValue
+    ///
+    ///  \ingroup SmartPointerGroup 
+    ///  Transports a reference as a value
+    ///  Serves to implement the Colvin/Gibbons trick for SmartPtr/ScopeGuard
+    ////////////////////////////////////////////////////////////////////////////////
+
+    template <class T>
+    class RefToValue
+    {   
+    public:
+    
+        RefToValue(T& ref) : ref_(ref) 
+        {}
+
+        RefToValue(const RefToValue& rhs) : ref_(rhs.ref_)
+        {}
+
+        operator T& () const 
+        {
+            return ref_;
+        }
+
+    private:
+        // Disable - not implemented
+        RefToValue();
+        RefToValue& operator=(const RefToValue&);
+        
+        T& ref_;
+    };
+
+
+    ////////////////////////////////////////////////////////////////////////////////
+    ///  \ingroup ExceptionGroup 
+    ///  RefToValue creator.
+    ////////////////////////////////////////////////////////////////////////////////
+
+    template <class T>
+    inline RefToValue<T> ByRef(T& t)
+    {
+        return RefToValue<T>(t);
+    }    
+    
+}
+
+
+#endif // end file guardian
+
Index: /code/branches/rocket2/src/libraries/util/Scope.cc
===================================================================
--- /code/branches/rocket2/src/libraries/util/Scope.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Scope.cc	(revision 6952)
@@ -0,0 +1,35 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Scope.h"
+
+namespace orxonox
+{
+    std::map<ScopeID::Value, int> ScopeManager::instanceCounts_s;
+    std::map<ScopeID::Value, std::set<ScopeListener*> > ScopeManager::listeners_s;
+}
Index: /code/branches/rocket2/src/libraries/util/Scope.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/Scope.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Scope.h	(revision 6952)
@@ -0,0 +1,157 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef __Util_Scope_H__
+#define __Util_Scope_H__
+
+#include "UtilPrereqs.h"
+
+#include <cassert>
+#include <map>
+#include <set>
+
+#include "Debug.h"
+#include "ScopeGuard.h"
+
+namespace orxonox
+{
+    /**
+        @brief The ScopeManager stores the variables of the scope templates in a statically linked context.
+    */
+    class _UtilExport ScopeManager
+    {
+        template <ScopeID::Value scope>
+        friend class Scope;
+        friend class ScopeListener;
+
+        private:
+            static std::map<ScopeID::Value, int> instanceCounts_s;                  //!< Counts the number of active instances (>0 means active) for a scope
+            static std::map<ScopeID::Value, std::set<ScopeListener*> > listeners_s; //!< Stores all listeners for a scope
+    };
+
+    /**
+        @brief ScopeListeners register themselves in the corresponding scope and wait for notifications.
+    */
+    class _UtilExport ScopeListener
+    {
+        template <ScopeID::Value scope>
+        friend class Scope;
+
+        protected:
+            //! Constructor: Registers the instance.
+            ScopeListener(ScopeID::Value scope) : scope_(scope), bActivated_(false)
+                { ScopeManager::listeners_s[this->scope_].insert(this); }
+            //! Destructor: Unregisters the instance.
+            virtual ~ScopeListener()
+                { ScopeManager::listeners_s[this->scope_].erase(this); }
+
+            //! Gets called if the scope is activated
+            virtual void activated() = 0;
+            //! Gets called if the scope is deactivated
+            virtual void deactivated() = 0;
+
+        private:
+            ScopeID::Value scope_; //!< Store the scope to unregister on destruction
+            bool bActivated_;
+    };
+
+    /**
+        @brief A scope for a given template argument is either active or not.
+
+        Objects inheriting from a ScopeListener are registered in a list (different for each scope).
+        If the scope gets activated or deactivated, all objects in this list are notified.
+    */
+    template <ScopeID::Value scope>
+    class Scope
+    {
+        public:
+            //! Constructor: Increases the instance counter and activates the scope if the count went from 0 to 1. Counts >1 don't change anything.
+            Scope()
+            {
+                try
+                {
+                    ScopeManager::instanceCounts_s[scope]++;
+                    assert(ScopeManager::instanceCounts_s[scope] > 0);
+                    if (ScopeManager::instanceCounts_s[scope] == 1)
+                    {
+                        Loki::ScopeGuard deactivator = Loki::MakeObjGuard(*this, &Scope::deactivateListeners);
+                        for (typename std::set<ScopeListener*>::iterator it = ScopeManager::listeners_s[scope].begin(); it != ScopeManager::listeners_s[scope].end(); )
+                        {
+                            (*it)->activated();
+                            (*(it++))->bActivated_ = true;
+                        }
+                        deactivator.Dismiss();
+                    }
+                }
+                catch (...)
+                {
+                    ScopeManager::instanceCounts_s[scope]--;
+                    throw;
+                }
+            }
+
+            //! Destructor: Decreases the instance counter and deactivates the scope if the count went from 1 to 0. Counts >0 don't change anything.
+            ~Scope()
+            {
+                ScopeManager::instanceCounts_s[scope]--;
+
+                // This shouldn't happen but just to be sure: check if the count is positive
+                assert(ScopeManager::instanceCounts_s[scope] >= 0);
+                if (ScopeManager::instanceCounts_s[scope] < 0)
+                    ScopeManager::instanceCounts_s[scope] = 0;
+
+                if (ScopeManager::instanceCounts_s[scope] == 0)
+                    this->deactivateListeners();
+            }
+
+            void deactivateListeners()
+            {
+                for (typename std::set<ScopeListener*>::iterator it = ScopeManager::listeners_s[scope].begin(); it != ScopeManager::listeners_s[scope].end(); )
+                {
+                    if ((*it)->bActivated_)
+                    {
+                        try
+                            { (*it)->deactivated(); }
+                        catch (...)
+                            { COUT(0) << "ScopeListener::deactivated() failed! This MUST NOT happen, fix it!" << std::endl; }
+                        (*(it++))->bActivated_ = false;
+                    }
+                    else
+                        ++it;
+                }
+            }
+
+            //! Returns true if the scope is active.
+            static bool isActive()
+            {
+                return (ScopeManager::instanceCounts_s[scope] > 0);
+            }
+    };
+}
+
+#endif /* __Util_Scope_H__ */
Index: /code/branches/rocket2/src/libraries/util/ScopeGuard.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/ScopeGuard.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/ScopeGuard.h	(revision 6952)
@@ -0,0 +1,666 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2000 Andrei Alexandrescu
+// Copyright (c) 2000 Petru Marginean
+// Copyright (c) 2005 Joshua Lehrer
+//
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the 
+//     suitability of this software for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+#ifndef LOKI_SCOPEGUARD_INC_
+#define LOKI_SCOPEGUARD_INC_
+
+// $Id: ScopeGuard.h 799 2006-12-20 00:37:13Z rich_sposato $
+
+
+#include "RefToValue.h"
+
+/// \defgroup ExceptionGroup Exception-safe code
+
+namespace Loki
+{
+
+    ////////////////////////////////////////////////////////////////
+    ///
+    /// \class ScopeGuardImplBase
+    /// \ingroup ExceptionGroup
+    ///
+    /// Base class used by all ScopeGuard implementations.  All commonly used
+    /// functions are in this class (e.g. - Dismiss and SafeExecute).
+    ///
+    /// See Andrei's and Petru Marginean's CUJ article
+    /// http://www.cuj.com/documents/s=8000/cujcexp1812alexandr/alexandr.htm
+    ///
+    /// Changes to the original code by Joshua Lehrer:
+    /// http://www.lehrerfamily.com/scopeguard.html
+    ////////////////////////////////////////////////////////////////
+
+    class ScopeGuardImplBase
+    {
+        /// Copy-assignment operator is not implemented and private.
+        ScopeGuardImplBase& operator =(const ScopeGuardImplBase&);
+
+    protected:
+
+        ~ScopeGuardImplBase()
+        {}
+
+        /// Copy-constructor takes over responsibility from other ScopeGuard.
+        ScopeGuardImplBase(const ScopeGuardImplBase& other) throw() 
+            : dismissed_(other.dismissed_)
+        {
+            other.Dismiss();
+        }
+
+        template <typename J>
+        static void SafeExecute(J& j) throw() 
+        {
+            if (!j.dismissed_)
+                try
+                {
+                    j.Execute();
+                }
+                catch(...)
+                {}
+        }
+        
+        mutable bool dismissed_;
+
+    public:
+        ScopeGuardImplBase() throw() : dismissed_(false) 
+        {}
+
+        void Dismiss() const throw() 
+        {
+            dismissed_ = true;
+        }
+    };
+
+    ////////////////////////////////////////////////////////////////
+    ///
+    /// \typedef typedef const ScopeGuardImplBase& ScopeGuard
+    /// \ingroup ExceptionGroup
+    ///
+    ////////////////////////////////////////////////////////////////
+
+    typedef const ScopeGuardImplBase& ScopeGuard;
+
+    ////////////////////////////////////////////////////////////////
+    ///
+    /// \class ScopeGuardImpl0
+    /// \ingroup ExceptionGroup
+    ///
+    /// Implementation class for a standalone function or class static function
+    /// with no parameters.  ScopeGuard ignores any value returned from the
+    /// call within the Execute function.
+    ///
+    /// This class has a single standalone helper function, MakeGuard which
+    /// creates and returns a ScopeGuard.
+    ///
+    ////////////////////////////////////////////////////////////////
+
+    template <typename F>
+    class ScopeGuardImpl0 : public ScopeGuardImplBase
+    {
+    public:
+        static ScopeGuardImpl0<F> MakeGuard(F fun)
+        {
+            return ScopeGuardImpl0<F>(fun);
+        }
+
+        ~ScopeGuardImpl0() throw() 
+        {
+            SafeExecute(*this);
+        }
+
+        void Execute() 
+        {
+            fun_();
+        }
+
+        ScopeGuardImpl0(F fun) : fun_(fun) 
+        {}
+
+    protected:
+        F fun_;
+    };
+
+    template <typename F> 
+    inline ScopeGuardImpl0<F> MakeGuard(F fun)
+    {
+        return ScopeGuardImpl0<F>::MakeGuard(fun);
+    }
+
+    ////////////////////////////////////////////////////////////////
+    ///
+    /// \class ScopeGuardImpl1
+    /// \ingroup ExceptionGroup
+    ///
+    /// Implementation class for a standalone function or class static function
+    /// with one parameter.  Each parameter is copied by value - use
+    /// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
+    /// any value returned from the call within the Execute function.
+    ///
+    /// This class has a single standalone helper function, MakeGuard which
+    /// creates and returns a ScopeGuard.
+    ///
+    ////////////////////////////////////////////////////////////////
+
+    template <typename F, typename P1>
+    class ScopeGuardImpl1 : public ScopeGuardImplBase
+    {
+    public:
+        static ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
+        {
+            return ScopeGuardImpl1<F, P1>(fun, p1);
+        }
+
+        ~ScopeGuardImpl1() throw() 
+        {
+            SafeExecute(*this);
+        }
+
+        void Execute()
+        {
+            fun_(p1_);
+        }
+
+        ScopeGuardImpl1(F fun, P1 p1) : fun_(fun), p1_(p1) 
+        {}
+
+    protected:
+        F fun_;
+        const P1 p1_;
+    };
+
+    template <typename F, typename P1> 
+    inline ScopeGuardImpl1<F, P1> MakeGuard(F fun, P1 p1)
+    {
+        return ScopeGuardImpl1<F, P1>::MakeGuard(fun, p1);
+    }
+
+    ////////////////////////////////////////////////////////////////
+    ///
+    /// \class ScopeGuardImpl2
+    /// \ingroup ExceptionGroup
+    ///
+    /// Implementation class for a standalone function or class static function
+    /// with two parameters.  Each parameter is copied by value - use
+    /// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
+    /// any value returned from the call within the Execute function.
+    ///
+    /// This class has a single standalone helper function, MakeGuard which
+    /// creates and returns a ScopeGuard.
+    ///
+    ////////////////////////////////////////////////////////////////
+
+    template <typename F, typename P1, typename P2>
+    class ScopeGuardImpl2: public ScopeGuardImplBase
+    {
+    public:
+        static ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
+        {
+            return ScopeGuardImpl2<F, P1, P2>(fun, p1, p2);
+        }
+
+        ~ScopeGuardImpl2() throw() 
+        {
+            SafeExecute(*this);
+        }
+
+        void Execute()
+        {
+            fun_(p1_, p2_);
+        }
+
+        ScopeGuardImpl2(F fun, P1 p1, P2 p2) : fun_(fun), p1_(p1), p2_(p2) 
+        {}
+
+    protected:
+        F fun_;
+        const P1 p1_;
+        const P2 p2_;
+    };
+
+    template <typename F, typename P1, typename P2>
+    inline ScopeGuardImpl2<F, P1, P2> MakeGuard(F fun, P1 p1, P2 p2)
+    {
+        return ScopeGuardImpl2<F, P1, P2>::MakeGuard(fun, p1, p2);
+    }
+
+    ////////////////////////////////////////////////////////////////
+    ///
+    /// \class ScopeGuardImpl3
+    /// \ingroup ExceptionGroup
+    ///
+    /// Implementation class for a standalone function or class static function
+    /// with three parameters.  Each parameter is copied by value - use
+    /// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
+    /// any value returned from the call within the Execute function.
+    ///
+    /// This class has a single standalone helper function, MakeGuard which
+    /// creates and returns a ScopeGuard.
+    ///
+    ////////////////////////////////////////////////////////////////
+
+    template <typename F, typename P1, typename P2, typename P3>
+    class ScopeGuardImpl3 : public ScopeGuardImplBase
+    {
+    public:
+        static ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
+        {
+            return ScopeGuardImpl3<F, P1, P2, P3>(fun, p1, p2, p3);
+        }
+
+        ~ScopeGuardImpl3() throw() 
+        {
+            SafeExecute(*this);
+        }
+
+        void Execute()
+        {
+            fun_(p1_, p2_, p3_);
+        }
+
+        ScopeGuardImpl3(F fun, P1 p1, P2 p2, P3 p3) : fun_(fun), p1_(p1), p2_(p2), p3_(p3) 
+        {}
+
+    protected:
+        F fun_;
+        const P1 p1_;
+        const P2 p2_;
+        const P3 p3_;
+    };
+
+    template <typename F, typename P1, typename P2, typename P3>
+    inline ScopeGuardImpl3<F, P1, P2, P3> MakeGuard(F fun, P1 p1, P2 p2, P3 p3)
+    {
+        return ScopeGuardImpl3<F, P1, P2, P3>::MakeGuard(fun, p1, p2, p3);
+    }
+
+    ////////////////////////////////////////////////////////////////
+    ///
+    /// \class ScopeGuardImpl4
+    /// \ingroup ExceptionGroup
+    ///
+    /// Implementation class for a standalone function or class static function
+    /// with four parameters.  Each parameter is copied by value - use
+    /// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
+    /// any value returned from the call within the Execute function.
+    ///
+    /// This class has a single standalone helper function, MakeGuard which
+    /// creates and returns a ScopeGuard.
+    ///
+    ////////////////////////////////////////////////////////////////
+
+    template < typename F, typename P1, typename P2, typename P3, typename P4 >
+    class ScopeGuardImpl4 : public ScopeGuardImplBase
+    {
+    public:
+        static ScopeGuardImpl4< F, P1, P2, P3, P4 > MakeGuard(
+            F fun, P1 p1, P2 p2, P3 p3, P4 p4 )
+        {
+            return ScopeGuardImpl4< F, P1, P2, P3, P4 >( fun, p1, p2, p3, p4 );
+        }
+
+        ~ScopeGuardImpl4() throw() 
+        {
+            SafeExecute( *this );
+        }
+
+        void Execute()
+        {
+            fun_( p1_, p2_, p3_, p4_ );
+        }
+
+        ScopeGuardImpl4( F fun, P1 p1, P2 p2, P3 p3, P4 p4 ) :
+             fun_( fun ), p1_( p1 ), p2_( p2 ), p3_( p3 ), p4_( p4 )
+        {}
+
+    protected:
+        F fun_;
+        const P1 p1_;
+        const P2 p2_;
+        const P3 p3_;
+        const P4 p4_;
+    };
+
+    template < typename F, typename P1, typename P2, typename P3, typename P4 >
+    inline ScopeGuardImpl4< F, P1, P2, P3, P4 > MakeGuard( F fun, P1 p1, P2 p2, P3 p3, P4 p4 )
+    {
+        return ScopeGuardImpl4< F, P1, P2, P3, P4 >::MakeGuard( fun, p1, p2, p3, p4 );
+    }
+
+    ////////////////////////////////////////////////////////////////
+    ///
+    /// \class ScopeGuardImpl5
+    /// \ingroup ExceptionGroup
+    ///
+    /// Implementation class for a standalone function or class static function
+    /// with five parameters.  Each parameter is copied by value - use
+    /// ::Loki::ByRef if you must use a reference instead.  ScopeGuard ignores
+    /// any value returned from the call within the Execute function.
+    ///
+    /// This class has a single standalone helper function, MakeGuard which
+    /// creates and returns a ScopeGuard.
+    ///
+    ////////////////////////////////////////////////////////////////
+
+    template < typename F, typename P1, typename P2, typename P3, typename P4, typename P5 >
+    class ScopeGuardImpl5 : public ScopeGuardImplBase
+    {
+    public:
+        static ScopeGuardImpl5< F, P1, P2, P3, P4, P5 > MakeGuard(
+            F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 )
+        {
+            return ScopeGuardImpl5< F, P1, P2, P3, P4, P5 >( fun, p1, p2, p3, p4, p5 );
+        }
+
+        ~ScopeGuardImpl5() throw() 
+        {
+            SafeExecute( *this );
+        }
+
+        void Execute()
+        {
+            fun_( p1_, p2_, p3_, p4_, p5_ );
+        }
+
+        ScopeGuardImpl5( F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 ) :
+             fun_( fun ), p1_( p1 ), p2_( p2 ), p3_( p3 ), p4_( p4 ), p5_( p5 )
+        {}
+
+    protected:
+        F fun_;
+        const P1 p1_;
+        const P2 p2_;
+        const P3 p3_;
+        const P4 p4_;
+        const P5 p5_;
+    };
+
+    template < typename F, typename P1, typename P2, typename P3, typename P4, typename P5 >
+    inline ScopeGuardImpl5< F, P1, P2, P3, P4, P5 > MakeGuard( F fun, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5 )
+    {
+        return ScopeGuardImpl5< F, P1, P2, P3, P4, P5 >::MakeGuard( fun, p1, p2, p3, p4, p5 );
+    }
+
+    ////////////////////////////////////////////////////////////////
+    ///
+    /// \class ObjScopeGuardImpl0
+    /// \ingroup ExceptionGroup
+    ///
+    /// Implementation class for a class per-instance member function with no
+    /// parameters.  ScopeGuard ignores any value returned from the call within
+    /// the Execute function.
+    ///
+    /// This class has 3 standalone helper functions which create a ScopeGuard.
+    /// One is MakeObjGuard, which is deprecated but provided for older code.
+    /// The other two are MakeGuard overloads, one which takes a pointer to an
+    /// object, and the other which takes a reference.
+    ///
+    ////////////////////////////////////////////////////////////////
+
+    template <class Obj, typename MemFun>
+    class ObjScopeGuardImpl0 : public ScopeGuardImplBase
+    {
+    public:
+        static ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
+        {
+            return ObjScopeGuardImpl0<Obj, MemFun>(obj, memFun);
+        }
+
+        ~ObjScopeGuardImpl0() throw() 
+        {
+            SafeExecute(*this);
+        }
+
+        void Execute() 
+        {
+            (obj_.*memFun_)();
+        }
+
+        ObjScopeGuardImpl0(Obj& obj, MemFun memFun) : obj_(obj), memFun_(memFun) 
+        {}
+
+    protected:
+        Obj& obj_;
+        MemFun memFun_;
+    };
+
+    template <class Obj, typename MemFun>
+    inline ObjScopeGuardImpl0<Obj, MemFun> MakeObjGuard(Obj& obj, MemFun memFun)
+    {
+        return ObjScopeGuardImpl0<Obj, MemFun>::MakeObjGuard(obj, memFun);
+    }
+
+    template <typename Ret, class Obj1, class Obj2>
+    inline ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1 &obj) 
+    {
+      return ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()>::MakeObjGuard(obj,memFun);
+    }
+
+    template <typename Ret, class Obj1, class Obj2>
+    inline ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()> MakeGuard(Ret(Obj2::*memFun)(), Obj1 *obj) 
+    {
+      return ObjScopeGuardImpl0<Obj1,Ret(Obj2::*)()>::MakeObjGuard(*obj,memFun);
+    }
+
+    ////////////////////////////////////////////////////////////////
+    ///
+    /// \class ObjScopeGuardImpl1
+    /// \ingroup ExceptionGroup
+    ///
+    /// Implementation class for a class per-instance member function with one
+    /// parameter.  The parameter is copied by value - use ::Loki::ByRef if you
+    /// must use a reference instead.  ScopeGuard ignores any value returned
+    /// from the call within the Execute function.
+    ///
+    /// This class has 3 standalone helper functions which create a ScopeGuard.
+    /// One is MakeObjGuard, which is deprecated but provided for older code.
+    /// The other two are MakeGuard overloads, one which takes a pointer to an
+    /// object, and the other which takes a reference.
+    ///
+    ////////////////////////////////////////////////////////////////
+
+    template <class Obj, typename MemFun, typename P1>
+    class ObjScopeGuardImpl1 : public ScopeGuardImplBase
+    {
+    public:
+        static ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
+        {
+            return ObjScopeGuardImpl1<Obj, MemFun, P1>(obj, memFun, p1);
+        }
+
+        ~ObjScopeGuardImpl1() throw() 
+        {
+            SafeExecute(*this);
+        }
+
+        void Execute() 
+        {
+            (obj_.*memFun_)(p1_);
+        }
+
+        ObjScopeGuardImpl1(Obj& obj, MemFun memFun, P1 p1) : obj_(obj), memFun_(memFun), p1_(p1) 
+        {}
+        
+    protected:
+        Obj& obj_;
+        MemFun memFun_;
+        const P1 p1_;
+    };
+
+    template <class Obj, typename MemFun, typename P1>
+    inline ObjScopeGuardImpl1<Obj, MemFun, P1> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1)
+    {
+        return ObjScopeGuardImpl1<Obj, MemFun, P1>::MakeObjGuard(obj, memFun, p1);
+    }
+
+    template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
+    inline ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b> MakeGuard(Ret(Obj2::*memFun)(P1a), Obj1 &obj, P1b p1) 
+    {
+      return ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b>::MakeObjGuard(obj,memFun,p1);
+    }
+
+    template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b>
+    inline ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b> MakeGuard(Ret(Obj2::*memFun)(P1a), Obj1 *obj, P1b p1) 
+    {
+      return ObjScopeGuardImpl1<Obj1,Ret(Obj2::*)(P1a),P1b>::MakeObjGuard(*obj,memFun,p1);
+    }
+
+    ////////////////////////////////////////////////////////////////
+    ///
+    /// \class ObjScopeGuardImpl2
+    /// \ingroup ExceptionGroup
+    ///
+    /// Implementation class for a class per-instance member function with two
+    /// parameters.  Each parameter is copied by value - use ::Loki::ByRef if you
+    /// must use a reference instead.  ScopeGuard ignores any value returned
+    /// from the call within the Execute function.
+    ///
+    /// This class has 3 standalone helper functions which create a ScopeGuard.
+    /// One is MakeObjGuard, which is deprecated but provided for older code.
+    /// The other two are MakeGuard overloads, one which takes a pointer to an
+    /// object, and the other which takes a reference.
+    ///
+    ////////////////////////////////////////////////////////////////
+
+    template <class Obj, typename MemFun, typename P1, typename P2>
+    class ObjScopeGuardImpl2 : public ScopeGuardImplBase
+    {
+    public:
+        static ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
+        {
+            return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>(obj, memFun, p1, p2);
+        }
+
+        ~ObjScopeGuardImpl2() throw() 
+        {
+            SafeExecute(*this);
+        }
+
+        void Execute() 
+        {
+            (obj_.*memFun_)(p1_, p2_);
+        }
+
+        ObjScopeGuardImpl2(Obj& obj, MemFun memFun, P1 p1, P2 p2) : obj_(obj), memFun_(memFun), p1_(p1), p2_(p2) 
+        {}
+
+    protected:
+        Obj& obj_;
+        MemFun memFun_;
+        const P1 p1_;
+        const P2 p2_;
+    };
+
+    template <class Obj, typename MemFun, typename P1, typename P2>
+    inline ObjScopeGuardImpl2<Obj, MemFun, P1, P2> MakeObjGuard(Obj& obj, MemFun memFun, P1 p1, P2 p2)
+    {
+        return ObjScopeGuardImpl2<Obj, MemFun, P1, P2>::MakeObjGuard(obj, memFun, p1, p2);
+    }
+
+    template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a, typename P2b>
+    inline ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b> MakeGuard(Ret(Obj2::*memFun)(P1a,P2a), Obj1 &obj, P1b p1, P2b p2) 
+    {
+      return ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b>::MakeObjGuard(obj,memFun,p1,p2);
+    }
+
+    template <typename Ret, class Obj1, class Obj2, typename P1a, typename P1b, typename P2a, typename P2b>
+    inline ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b> MakeGuard(Ret(Obj2::*memFun)(P1a,P2a), Obj1 *obj, P1b p1, P2b p2) 
+    {
+      return ObjScopeGuardImpl2<Obj1,Ret(Obj2::*)(P1a,P2a),P1b,P2b>::MakeObjGuard(*obj,memFun,p1,p2);
+    }
+
+    ////////////////////////////////////////////////////////////////
+    ///
+    /// \class ObjScopeGuardImpl3
+    /// \ingroup ExceptionGroup
+    ///
+    /// Implementation class for a class per-instance member function with three
+    /// parameters.  Each parameter is copied by value - use ::Loki::ByRef if you
+    /// must use a reference instead.  ScopeGuard ignores any value returned
+    /// from the call within the Execute function.
+    ///
+    /// This class has 3 standalone helper functions which create a ScopeGuard.
+    /// One is MakeObjGuard, which is deprecated but provided for older code.
+    /// The other two are MakeGuard overloads, one which takes a pointer to an
+    /// object, and the other which takes a reference.
+    ///
+    ////////////////////////////////////////////////////////////////
+
+    template < class Obj, typename MemFun, typename P1, typename P2, typename P3 >
+    class ObjScopeGuardImpl3 : public ScopeGuardImplBase
+    {
+    public:
+        static ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 > MakeObjGuard(
+            Obj & obj, MemFun memFun, P1 p1, P2 p2, P3 p3 )
+        {
+            return ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 >( obj, memFun, p1, p2, p3 );
+        }
+
+        ~ObjScopeGuardImpl3() throw() 
+        {
+            SafeExecute( *this );
+        }
+
+        void Execute() 
+        {
+            ( obj_.*memFun_ )( p1_, p2_, p3_ );
+        }
+
+        ObjScopeGuardImpl3( Obj & obj, MemFun memFun, P1 p1, P2 p2, P3 p3 ) :
+             obj_( obj ), memFun_( memFun ), p1_( p1 ), p2_( p2 ), p3_( p3 )
+        {}
+
+    protected:
+        Obj& obj_;
+        MemFun memFun_;
+        const P1 p1_;
+        const P2 p2_;
+        const P3 p3_;
+    };
+
+    template < class Obj, typename MemFun, typename P1, typename P2, typename P3 >
+    inline ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 > MakeObjGuard(
+        Obj & obj, MemFun memFun, P1 p1, P2 p2, P3 p3 )
+    {
+        return ObjScopeGuardImpl3< Obj, MemFun, P1, P2, P3 >::MakeObjGuard(
+            obj, memFun, p1, p2, p3 );
+    }
+
+    template < typename Ret, class Obj1, class Obj2, typename P1a, typename P1b,
+        typename P2a, typename P2b, typename P3a, typename P3b >
+    inline ObjScopeGuardImpl3< Obj1, Ret( Obj2::* )( P1a, P2a, P3a ), P1b, P2b, P3b >
+        MakeGuard( Ret( Obj2::*memFun )( P1a, P2a, P3a ), Obj1 & obj, P1b p1, P2b p2, P3b p3 )
+    {
+      return ObjScopeGuardImpl3< Obj1, Ret( Obj2::* )( P1a, P2a, P3a ), P1b, P2b, P3b >
+          ::MakeObjGuard( obj, memFun, p1, p2, p3 );
+    }
+
+    template < typename Ret, class Obj1, class Obj2, typename P1a, typename P1b,
+        typename P2a, typename P2b, typename P3a, typename P3b >
+    inline ObjScopeGuardImpl3< Obj1, Ret( Obj2::* )( P1a, P2a, P3a ), P1b, P2b, P3b >
+        MakeGuard( Ret( Obj2::*memFun )( P1a, P2a, P3a ), Obj1 * obj, P1b p1, P2b p2, P3b p3 )
+    {
+      return ObjScopeGuardImpl3< Obj1, Ret( Obj2::* )( P1a, P2a, P3a ), P1b, P2b, P3b >
+          ::MakeObjGuard( *obj, memFun, p1, p2, p3 );
+    }
+
+} // namespace Loki
+
+#define LOKI_CONCATENATE_DIRECT(s1, s2)  s1##s2
+#define LOKI_CONCATENATE(s1, s2)         LOKI_CONCATENATE_DIRECT(s1, s2)
+#define LOKI_ANONYMOUS_VARIABLE(str)     LOKI_CONCATENATE(str, __LINE__)
+
+#define LOKI_ON_BLOCK_EXIT      ::Loki::ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = ::Loki::MakeGuard
+#define LOKI_ON_BLOCK_EXIT_OBJ  ::Loki::ScopeGuard LOKI_ANONYMOUS_VARIABLE(scopeGuard) = ::Loki::MakeObjGuard
+
+#endif // end file guardian
+
Index: /code/branches/rocket2/src/libraries/util/Serialise.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/Serialise.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Serialise.h	(revision 6952)
@@ -0,0 +1,640 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Functions to serialise most of the types/classed used in Orxonox
+*/
+
+#ifndef _Serialise_H__
+#define _Serialise_H__
+
+#include "UtilPrereqs.h"
+
+#include <cstring>
+#include "Math.h"
+#include "mbool.h"
+
+namespace orxonox{
+
+    /** @brief returns the size of the variable in a datastream */
+    template <class T> inline uint32_t returnSize( const T& variable );
+    /** @brief loads the value of a variable out of the bytestream and increases the mem pointer */
+    template <class T> inline void loadAndIncrease( const T& variable, uint8_t*& mem );
+    /** @brief saves the value of a variable into the bytestream and increases the mem pointer */
+    template <class T> inline void saveAndIncrease( const T& variable, uint8_t*& mem );
+    /** @brief checks whether the variable of type T is the same as in the bytestream */
+    template <class T> inline bool checkEquality( const T& variable, uint8_t* mem );
+
+// =================== Template specialisation stuff =============
+
+// =========== bool
+
+    template <> inline uint32_t returnSize( const bool& variable )
+    {
+        return sizeof(uint8_t);
+    }
+
+    template <> inline void loadAndIncrease( const bool& variable, uint8_t*& mem )
+    {
+        *(uint8_t*)( &variable ) = *static_cast<uint8_t*>(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const bool& variable, uint8_t*& mem )
+    {
+        *static_cast<uint8_t*>(mem) = *(uint8_t*)( &variable );
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const bool& variable, uint8_t* mem )
+    {
+        return *static_cast<uint8_t*>(mem) == *(uint8_t*)( &variable );
+    }
+
+// =========== char
+
+    template <> inline uint32_t returnSize( const char& variable )
+    {
+        return sizeof(uint8_t);
+    }
+
+    template <> inline void loadAndIncrease( const char& variable, uint8_t*& mem )
+    {
+        *(uint8_t*)( &variable ) = *static_cast<uint8_t*>(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const char& variable, uint8_t*& mem )
+    {
+        *static_cast<uint8_t*>(mem) = *(uint8_t*)( &variable );
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const char& variable, uint8_t* mem )
+    {
+        return *static_cast<uint8_t*>(mem) == *(uint8_t*)( &variable );
+    }
+
+// =========== unsigned char
+
+    template <> inline uint32_t returnSize( const unsigned char& variable )
+    {
+        return sizeof(uint8_t);
+    }
+
+    template <> inline void loadAndIncrease( const unsigned char& variable, uint8_t*& mem )
+    {
+        *(uint8_t*)( &variable ) = *static_cast<uint8_t*>(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const unsigned char& variable, uint8_t*& mem )
+    {
+        *static_cast<uint8_t*>(mem) = *(uint8_t*)( &variable );
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const unsigned char& variable, uint8_t* mem )
+    {
+        return *static_cast<uint8_t*>(mem) == *(uint8_t*)( &variable );
+    }
+
+// =========== short
+
+    template <> inline uint32_t returnSize( const short& variable )
+    {
+        return sizeof(int16_t);
+    }
+
+    template <> inline void loadAndIncrease( const short& variable, uint8_t*& mem )
+    {
+        *(short*)( &variable ) = *(int16_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const short& variable, uint8_t*& mem )
+    {
+        *(int16_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const short& variable, uint8_t* mem )
+    {
+        return *(int16_t*)(mem) == static_cast<int16_t>(variable);
+    }
+
+// =========== unsigned short
+
+    template <> inline uint32_t returnSize( const unsigned short& variable )
+    {
+        return sizeof(uint16_t);
+    }
+
+    template <> inline void loadAndIncrease( const unsigned short& variable, uint8_t*& mem )
+    {
+        *(unsigned short*)( &variable ) = *(uint16_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const unsigned short& variable, uint8_t*& mem )
+    {
+        *(uint16_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const unsigned short& variable, uint8_t* mem )
+    {
+        return *(uint16_t*)(mem) == variable;
+    }
+
+// =========== int
+
+    template <> inline uint32_t returnSize( const int& variable )
+    {
+        return sizeof(int32_t);
+    }
+
+    template <> inline void loadAndIncrease( const int& variable, uint8_t*& mem )
+    {
+        *(int *)( &variable ) = *(int32_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const int& variable, uint8_t*& mem )
+    {
+        *(int32_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const int& variable, uint8_t* mem )
+    {
+        return *(int32_t*)(mem) == variable;
+    }
+
+// =========== unsigned int
+
+    template <> inline uint32_t returnSize( const unsigned int& variable )
+    {
+        return sizeof(uint32_t);
+    }
+
+    template <> inline void loadAndIncrease( const unsigned int& variable, uint8_t*& mem )
+    {
+        *(unsigned int*)( &variable ) = *(uint32_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const unsigned int& variable, uint8_t*& mem )
+    {
+        *(uint32_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const unsigned int& variable, uint8_t* mem )
+    {
+        return *(uint32_t*)(mem) == variable;
+    }
+
+// =========== long
+
+    template <> inline uint32_t returnSize( const long& variable )
+    {
+        return sizeof(int32_t);
+    }
+
+    template <> inline void loadAndIncrease( const long& variable, uint8_t*& mem )
+    {
+        *(long*)( &variable ) = *(int32_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const long& variable, uint8_t*& mem )
+    {
+        *(int32_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const long& variable, uint8_t* mem )
+    {
+        return *(int32_t*)(mem) == variable;
+    }
+
+// =========== unsigned long
+
+    template <> inline uint32_t returnSize( const unsigned long& variable )
+    {
+        return sizeof(uint32_t);
+    }
+
+    template <> inline void loadAndIncrease( const unsigned long& variable, uint8_t*& mem )
+    {
+        *(unsigned long*)( &variable ) = *(uint32_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const unsigned long& variable, uint8_t*& mem )
+    {
+        *(uint32_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const unsigned long& variable, uint8_t* mem )
+    {
+        return *(uint32_t*)(mem) == variable;
+    }
+
+// =========== long long
+
+    template <> inline uint32_t returnSize( const long long& variable )
+    {
+        return sizeof(int64_t);
+    }
+
+    template <> inline void loadAndIncrease( const long long& variable, uint8_t*& mem )
+    {
+        *(long long*)( &variable ) = *(int64_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const long long& variable, uint8_t*& mem )
+    {
+        *(int64_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const long long& variable, uint8_t* mem )
+    {
+        return *(int64_t*)(mem) == variable;
+    }
+
+// =========== unsigned long long
+
+    template <> inline uint32_t returnSize( const unsigned long long& variable )
+    {
+        return sizeof(uint64_t);
+    }
+
+    template <> inline void loadAndIncrease( const unsigned long long& variable, uint8_t*& mem )
+    {
+        *(unsigned long long*)( &variable ) = *(uint64_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const unsigned long long& variable, uint8_t*& mem )
+    {
+        *(uint64_t*)(mem) = variable;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const unsigned long long& variable, uint8_t* mem )
+    {
+        return *(uint64_t*)(mem) == variable;
+    }
+
+// =========== float
+
+    template <> inline uint32_t returnSize( const float& variable )
+    {
+        return sizeof(uint32_t);
+    }
+
+    template <> inline void loadAndIncrease( const float& variable, uint8_t*& mem )
+    {
+        *(uint32_t*)( &variable ) = *(uint32_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const float& variable, uint8_t*& mem )
+    {
+        *(uint32_t*)(mem) = *(uint32_t*)( &variable );
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const float& variable, uint8_t* mem )
+    {
+        return *(uint32_t*)(mem) == *(uint32_t*)( &variable );
+    }
+
+// =========== double
+
+    template <> inline uint32_t returnSize( const double& variable )
+    {
+        return sizeof(uint64_t);
+    }
+
+    template <> inline void loadAndIncrease( const double& variable, uint8_t*& mem )
+    {
+        *(uint64_t*)( &variable ) = *(uint64_t*)(mem);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const double& variable, uint8_t*& mem )
+    {
+        *(uint64_t*)(mem) = *(uint64_t*)( &variable );
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const double& variable, uint8_t* mem )
+    {
+        return *(uint64_t*)(mem) == *(uint64_t*)( &variable );
+    }
+
+// =========== long double
+
+    template <> inline uint32_t returnSize( const long double& variable )
+    {
+        return sizeof(uint64_t);
+    }
+
+    template <> inline void loadAndIncrease( const long double& variable, uint8_t*& mem )
+    {
+        double temp;
+        memcpy(&temp, mem, sizeof(uint64_t));
+        *(long double*)( &variable ) = static_cast<long double>(temp);
+        mem += returnSize( variable );
+    }
+
+    template <> inline void saveAndIncrease( const long double& variable, uint8_t*& mem )
+    {
+        double temp = static_cast<double>(variable);
+        memcpy(mem, &temp, sizeof(uint64_t));
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const long double& variable, uint8_t* mem )
+    {
+        double temp = static_cast<double>(variable);
+        return memcmp(&temp, mem, sizeof(uint64_t))==0;
+    }
+
+// =========== string
+
+    template <> inline uint32_t returnSize( const std::string& variable )
+    {
+        return variable.length()+1;
+    }
+
+    template <> inline void saveAndIncrease( const std::string& variable, uint8_t*& mem )
+    {
+        memcpy(mem, variable.c_str(), variable.length()+1);
+        mem += variable.length()+1;
+    }
+
+    template <> inline void loadAndIncrease( const std::string& variable, uint8_t*& mem )
+    {
+        *(std::string*)( &variable ) = (const char *)mem;
+        mem += variable.length()+1;
+    }
+
+    template <> inline bool checkEquality( const std::string& variable, uint8_t* mem )
+    {
+        //return std::string((const char*)mem)==variable;
+        return (const char*)mem==variable;
+    }
+
+// =========== Degree
+
+    template <> inline uint32_t returnSize( const Degree& variable )
+    {
+        return sizeof(Ogre::Real);
+    }
+
+    template <> inline void saveAndIncrease( const Degree& variable, uint8_t*& mem )
+    {
+        Ogre::Real r = variable.valueDegrees();
+        memcpy(mem, &r, returnSize( variable ));
+        mem += returnSize( variable );
+    }
+
+    template <> inline void loadAndIncrease( const Degree& variable, uint8_t*& mem )
+    {
+        Ogre::Real* r = (Ogre::Real*)mem;
+        (Degree&)variable = *r;
+        mem += returnSize( variable );
+    }
+
+     template <> inline bool checkEquality( const Degree& variable, uint8_t* mem )
+    {
+        Ogre::Real* r = (Ogre::Real*)mem;
+        return variable==Degree(*r);
+    }
+
+// =========== Radian
+
+    template <> inline uint32_t returnSize( const Radian& variable )
+    {
+        return sizeof(Ogre::Real);
+    }
+
+    template <> inline void saveAndIncrease( const Radian& variable, uint8_t*& mem )
+    {
+        Ogre::Real r = variable.valueRadians();
+        memcpy(mem, &r, returnSize( variable ));
+        mem += returnSize( variable );
+    }
+
+    template <> inline void loadAndIncrease( const Radian& variable, uint8_t*& mem )
+    {
+        Ogre::Real* r = (Ogre::Real*)mem;
+        (Radian&)variable = *r;
+        mem += returnSize( variable );
+    }
+
+    template <> inline bool checkEquality( const Radian& variable, uint8_t* mem )
+    {
+        Ogre::Real* r = (Ogre::Real*)mem;
+        return variable==Degree(*r);
+    }
+
+    // =========== Vector2
+
+    template <> inline uint32_t returnSize( const Vector2& variable )
+    {
+        return returnSize( variable.x )+returnSize( variable.y );
+    }
+
+    template <> inline void saveAndIncrease( const Vector2& variable, uint8_t*& mem )
+    {
+        saveAndIncrease( variable.x, mem );
+        saveAndIncrease( variable.y, mem );
+    }
+
+    template <> inline void loadAndIncrease( const Vector2& variable, uint8_t*& mem )
+    {
+        loadAndIncrease( variable.x, mem );
+        loadAndIncrease( variable.y, mem );
+    }
+
+    template <> inline bool checkEquality( const Vector2& variable, uint8_t* mem )
+    {
+        return checkEquality(variable.x, mem) && checkEquality(variable.y, mem+returnSize(variable.x));
+    }
+
+    // =========== Vector3
+
+    template <> inline uint32_t returnSize( const Vector3& variable )
+    {
+        return returnSize( variable.x )+returnSize( variable.y )+returnSize( variable.z );
+    }
+
+    template <> inline void saveAndIncrease( const Vector3& variable, uint8_t*& mem )
+    {
+        saveAndIncrease( variable.x, mem );
+        saveAndIncrease( variable.y, mem );
+        saveAndIncrease( variable.z, mem );
+    }
+
+    template <> inline void loadAndIncrease( const Vector3& variable, uint8_t*& mem )
+    {
+        loadAndIncrease( variable.x, mem );
+        loadAndIncrease( variable.y, mem );
+        loadAndIncrease( variable.z, mem );
+    }
+
+    template <> inline bool checkEquality( const Vector3& variable, uint8_t* mem )
+    {
+        return checkEquality(variable.x, mem) && checkEquality(variable.y, mem+returnSize(variable.x)) &&
+            checkEquality(variable.z, mem+returnSize(variable.x)+returnSize(variable.y));
+    }
+
+    // =========== Vector4
+
+    template <> inline uint32_t returnSize( const Vector4& variable )
+    {
+        return returnSize( variable.w )+returnSize( variable.x )+returnSize( variable.y )+returnSize( variable.z );
+    }
+
+    template <> inline void saveAndIncrease( const Vector4& variable, uint8_t*& mem )
+    {
+        saveAndIncrease( variable.w, mem );
+        saveAndIncrease( variable.x, mem );
+        saveAndIncrease( variable.y, mem );
+        saveAndIncrease( variable.z, mem );
+    }
+
+    template <> inline void loadAndIncrease( const Vector4& variable, uint8_t*& mem )
+    {
+        loadAndIncrease( variable.w, mem );
+        loadAndIncrease( variable.x, mem );
+        loadAndIncrease( variable.y, mem );
+        loadAndIncrease( variable.z, mem );
+    }
+
+    template <> inline bool checkEquality( const Vector4& variable, uint8_t* mem )
+    {
+        return checkEquality(variable.w, mem) && checkEquality(variable.x, mem+returnSize(variable.w)) &&
+            checkEquality(variable.y, mem+returnSize(variable.w)+returnSize(variable.x)) &&
+            checkEquality(variable.z, mem+returnSize(variable.w)+returnSize(variable.x)+returnSize(variable.y));
+    }
+
+    // =========== Quaternion
+
+    template <> inline uint32_t returnSize( const Quaternion& variable )
+    {
+        return returnSize( variable.w )+returnSize( variable.x )+returnSize( variable.y )+returnSize( variable.z );
+    }
+
+    template <> inline void saveAndIncrease( const Quaternion& variable, uint8_t*& mem )
+    {
+        saveAndIncrease( variable.w, mem );
+        saveAndIncrease( variable.x, mem );
+        saveAndIncrease( variable.y, mem );
+        saveAndIncrease( variable.z, mem );
+    }
+
+    template <> inline void loadAndIncrease( const Quaternion& variable, uint8_t*& mem )
+    {
+        loadAndIncrease( variable.w, mem );
+        loadAndIncrease( variable.x, mem );
+        loadAndIncrease( variable.y, mem );
+        loadAndIncrease( variable.z, mem );
+    }
+
+    template <> inline bool checkEquality( const Quaternion& variable, uint8_t* mem )
+    {
+        return checkEquality(variable.w, mem) && checkEquality(variable.x, mem+returnSize(variable.w)) &&
+            checkEquality(variable.y, mem+returnSize(variable.w)+returnSize(variable.x)) &&
+            checkEquality(variable.z, mem+returnSize(variable.w)+returnSize(variable.x)+returnSize(variable.y));
+    }
+
+    // =========== ColourValue
+
+    template <> inline uint32_t returnSize( const ColourValue& variable )
+    {
+        return returnSize( variable.r )+returnSize( variable.g )+returnSize( variable.b )+returnSize( variable.a );
+    }
+
+    template <> inline void saveAndIncrease( const ColourValue& variable, uint8_t*& mem )
+    {
+        saveAndIncrease( variable.r, mem );
+        saveAndIncrease( variable.g, mem );
+        saveAndIncrease( variable.b, mem );
+        saveAndIncrease( variable.a, mem );
+    }
+
+    template <> inline void loadAndIncrease( const ColourValue& variable, uint8_t*& mem )
+    {
+        loadAndIncrease( variable.r, mem );
+        loadAndIncrease( variable.g, mem );
+        loadAndIncrease( variable.b, mem );
+        loadAndIncrease( variable.a, mem );
+    }
+
+    template <> inline bool checkEquality( const ColourValue& variable, uint8_t* mem )
+    {
+        return checkEquality(variable.r, mem) && checkEquality(variable.g, mem+returnSize(variable.r)) &&
+            checkEquality(variable.b, mem+returnSize(variable.r)+returnSize(variable.g)) &&
+            checkEquality(variable.a, mem+returnSize(variable.r)+returnSize(variable.g)+returnSize(variable.b));
+    }
+
+    // =========== mbool
+
+    template <> inline uint32_t returnSize( const mbool& variable )
+    {
+        return returnSize( (unsigned char&)((mbool&)variable).getMemory() );
+    }
+
+    template <> inline void saveAndIncrease( const mbool& variable, uint8_t*& mem )
+    {
+        saveAndIncrease( (unsigned char&)((mbool&)variable).getMemory(), mem );
+    }
+
+    template <> inline void loadAndIncrease( const mbool& variable, uint8_t*& mem )
+    {
+        loadAndIncrease( (unsigned char&)((mbool&)variable).getMemory(), mem );
+    }
+
+    template <> inline bool checkEquality( const mbool& variable, uint8_t* mem )
+    {
+        return checkEquality( (unsigned char&)((mbool&)variable).getMemory(), mem );
+    }
+}
+
+
+#endif
Index: /code/branches/rocket2/src/libraries/util/SignalHandler.cc
===================================================================
--- /code/branches/rocket2/src/libraries/util/SignalHandler.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/SignalHandler.cc	(revision 6952)
@@ -0,0 +1,330 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Christoph Renner
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the SignalHandler class.
+*/
+
+#include "SignalHandler.h"
+
+#include <iostream>
+#include <cstdlib>
+#include <cstring>
+#include "Debug.h"
+
+namespace orxonox
+{
+    SignalHandler* SignalHandler::singletonPtr_s = NULL;
+}
+
+#ifdef ORXONOX_PLATFORM_LINUX
+
+#include <wait.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+
+namespace orxonox
+{
+    /**
+     * register signal handlers for SIGSEGV and SIGABRT
+     * @param appName path to executable eg argv[0]
+     * @param filename filename to append backtrace to
+     */
+    void SignalHandler::doCatch( const std::string & appName, const std::string & filename )
+    {
+      this->appName = appName;
+      this->filename = filename;
+
+      // make sure doCatch is only called once without calling dontCatch
+      assert( sigRecList.size() == 0 );
+
+      catchSignal( SIGSEGV );
+      catchSignal( SIGABRT );
+      catchSignal( SIGILL );
+    }
+
+    /**
+     * restore previous signal handlers
+     */
+    void SignalHandler::dontCatch()
+    {
+      for ( SignalRecList::iterator it = sigRecList.begin(); it != sigRecList.end(); it++ )
+      {
+        signal( it->signal, it->handler );
+      }
+
+      sigRecList.clear();
+    }
+
+    /**
+     * catch signal sig
+     * @param sig signal to catch
+     */
+    void SignalHandler::catchSignal( int sig )
+    {
+      sig_t handler = signal( sig, SignalHandler::sigHandler );
+
+      assert( handler != SIG_ERR );
+
+      SignalRec rec;
+      rec.signal = sig;
+      rec.handler = handler;
+
+      sigRecList.push_front( rec );
+    }
+
+    /**
+     * sigHandler is called when receiving signals
+     * @param sig
+     */
+    void SignalHandler::sigHandler( int sig )
+    {
+      std::string sigName = "UNKNOWN";
+
+      switch ( sig )
+      {
+        case SIGSEGV:
+          sigName = "SIGSEGV";
+          break;
+        case SIGABRT:
+          sigName = "SIGABRT";
+          break;
+        case SIGILL:
+          sigName = "SIGILL";
+          break;
+      }
+      // if the signalhandler has already been destroyed then don't do anything
+      if( SignalHandler::singletonPtr_s == 0 )
+      {
+        COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "can't write backtrace because SignalHandler already destroyed" << std::endl;
+        exit(EXIT_FAILURE);
+      }
+
+      for ( SignalCallbackList::iterator it = SignalHandler::getInstance().callbackList.begin(); it != SignalHandler::getInstance().callbackList.end(); it++  )
+      {
+        (*(it->cb))( it->someData );
+      }
+
+
+      COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "try to write backtrace to file orxonox_crash.log" << std::endl;
+
+      int sigPipe[2];
+      if ( pipe(sigPipe) == -1 )
+      {
+        perror("pipe failed!\n");
+        exit(EXIT_FAILURE);
+      }
+
+      int sigPid = fork();
+
+      if ( sigPid == -1 )
+      {
+        perror("fork failed!\n");
+        exit(EXIT_FAILURE);
+      }
+
+      // gdb will be attached to this process
+      if ( sigPid == 0 )
+      {
+        getInstance().dontCatch();
+        // wait for message from parent when it has attached gdb
+        int someData;
+
+        read( sigPipe[0], &someData, sizeof(someData) );
+
+        if ( someData != 0x12345678 )
+        {
+          COUT(0) << "something went wrong :(" << std::endl;
+        }
+
+        return;
+      }
+
+      int gdbIn[2];
+      int gdbOut[2];
+      int gdbErr[2];
+
+      if ( pipe(gdbIn) == -1 || pipe(gdbOut) == -1 || pipe(gdbErr) == -1 )
+      {
+        perror("pipe failed!\n");
+        kill( sigPid, SIGTERM );
+        waitpid( sigPid, NULL, 0 );
+        exit(EXIT_FAILURE);
+      }
+
+      int gdbPid = fork();
+      // this process will run gdb
+
+      if ( gdbPid == -1 )
+      {
+        perror("fork failed\n");
+        kill( sigPid, SIGTERM );
+        waitpid( sigPid, NULL, 0 );
+        exit(EXIT_FAILURE);
+      }
+
+      if ( gdbPid == 0 )
+      {
+        // start gdb
+
+        close(gdbIn[1]);
+        close(gdbOut[0]);
+        close(gdbErr[0]);
+
+        dup2( gdbIn[0], STDIN_FILENO );
+        dup2( gdbOut[1], STDOUT_FILENO );
+        dup2( gdbErr[1], STDERR_FILENO );
+
+        execlp( "sh", "sh", "-c", "gdb", static_cast<void*>(NULL));
+      }
+
+      char cmd[256];
+      snprintf( cmd, 256, "file %s\nattach %d\nc\n", getInstance().appName.c_str(), sigPid );
+      write( gdbIn[1], cmd, strlen(cmd) );
+
+      int charsFound = 0;
+      int promptFound = 0;
+      char byte;
+      while ( read( gdbOut[0], &byte, 1 ) == 1 )
+      {
+        if (
+          (charsFound == 0 && byte == '(') ||
+          (charsFound == 1 && byte == 'g') ||
+          (charsFound == 2 && byte == 'd') ||
+          (charsFound == 3 && byte == 'b') ||
+          (charsFound == 4 && byte == ')') ||
+          (charsFound == 5 && byte == ' ')
+            )
+              charsFound++;
+        else
+          charsFound = 0;
+
+        if ( charsFound == 6 )
+        {
+          promptFound++;
+          charsFound = 0;
+        }
+
+        if ( promptFound == 3 )
+        {
+          break;
+        }
+      }
+
+      int someData = 0x12345678;
+      write( sigPipe[1], &someData, sizeof(someData) );
+
+      write( gdbIn[1], "bt\nk\nq\n", 7 );
+
+
+      charsFound = 0;
+      promptFound = 0;
+      std::string bt;
+      while ( read( gdbOut[0], &byte, 1 ) == 1 )
+      {
+        bt += std::string( &byte, 1 );
+
+        if (
+          (charsFound == 0 && byte == '(') ||
+          (charsFound == 1 && byte == 'g') ||
+          (charsFound == 2 && byte == 'd') ||
+          (charsFound == 3 && byte == 'b') ||
+          (charsFound == 4 && byte == ')') ||
+          (charsFound == 5 && byte == ' ')
+            )
+              charsFound++;
+        else
+          charsFound = 0;
+
+        if ( charsFound == 6 )
+        {
+          promptFound++;
+          charsFound = 0;
+          bt += "\n";
+        }
+
+        if ( promptFound == 3 )
+        {
+          break;
+        }
+      }
+
+
+      waitpid( sigPid, NULL, 0 );
+      waitpid( gdbPid, NULL, 0 );
+
+      int wsRemoved = 0;
+
+      while ( wsRemoved < 2 && bt.length() > 0 )
+      {
+        if ( bt[1] == '\n' )
+          wsRemoved++;
+        bt.erase(0, 1);
+      }
+
+      if ( bt.length() > 0 )
+        bt.erase(0, 1);
+
+      time_t now = time(NULL);
+
+      std::string timeString =
+                         "=======================================================\n"
+                         "= time: " + std::string(ctime(&now)) +
+                         "=======================================================\n";
+      bt.insert(0, timeString);
+
+      FILE * f = fopen( getInstance().filename.c_str(), "w" );
+
+      if ( !f )
+      {
+        perror( ( std::string( "could not append to " ) + getInstance().filename ).c_str() );
+        exit(EXIT_FAILURE);
+      }
+
+      if ( fwrite( bt.c_str(), 1, bt.length(), f ) != bt.length() )
+      {
+        COUT(0) << "could not write " << bt.length() << " byte to " << getInstance().filename << std::endl;
+        exit(EXIT_FAILURE);
+      }
+
+      exit(EXIT_FAILURE);
+    }
+
+    void SignalHandler::registerCallback( SignalCallback cb, void * someData )
+    {
+      SignalCallbackRec rec;
+      rec.cb = cb;
+      rec.someData = someData;
+
+      callbackList.push_back(rec);
+    }
+}
+
+#endif /* ORXONOX_PLATFORM_LINUX */
Index: /code/branches/rocket2/src/libraries/util/SignalHandler.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/SignalHandler.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/SignalHandler.h	(revision 6952)
@@ -0,0 +1,118 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Christoph Renner
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Declaration of the SignalHandler class.
+*/
+
+#ifndef _SignalHandler_H__
+#define _SignalHandler_H__
+
+#include "UtilPrereqs.h"
+
+#include <cassert>
+#include <list>
+#include <string>
+#include "Singleton.h"
+
+namespace orxonox
+{
+    typedef int (*SignalCallback)( void * someData );
+}
+
+#ifdef ORXONOX_PLATFORM_LINUX
+#include <signal.h>
+
+namespace orxonox
+{
+    struct SignalRec
+    {
+        int signal;
+        sig_t handler;
+    };
+
+    struct SignalCallbackRec
+    {
+        SignalCallback cb;
+        void * someData;
+    };
+
+
+    typedef std::list<SignalRec> SignalRecList;
+    typedef std::list<SignalCallbackRec> SignalCallbackList;
+
+    class SignalHandler : public Singleton<SignalHandler>
+    {
+        friend class Singleton<SignalHandler>;
+    public:
+        SignalHandler()  { }
+        ~SignalHandler() { }
+
+        void registerCallback( SignalCallback cb, void * someData );
+
+        void doCatch( const std::string & appName, const std::string & filename );
+        void dontCatch();
+
+    private:
+        static void sigHandler( int sig );
+
+        void catchSignal( int sig );
+        SignalRecList sigRecList;
+
+        SignalCallbackList callbackList;
+
+        static SignalHandler* singletonPtr_s;
+
+        std::string appName;
+        std::string filename;
+    };
+}
+
+#else /* ORXONOX_PLATFORM_LINUX */
+
+namespace orxonox
+{
+    class _UtilExport SignalHandler : public Singleton<SignalHandler>
+    {
+        friend class Singleton<SignalHandler>;
+    public:
+        SignalHandler()  { }
+        ~SignalHandler() { }
+        void doCatch( const std::string & appName, const std::string & filename ) {}
+        void dontCatch() {}
+        void registerCallback( SignalCallback cb, void * someData ) {}
+
+    private:
+        static SignalHandler* singletonPtr_s;
+    };
+}
+
+#endif /* ORXONOX_PLATFORM_LINUX */
+
+#endif /* _SignalHandler_H__ */
Index: /code/branches/rocket2/src/libraries/util/Singleton.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/Singleton.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Singleton.h	(revision 6952)
@@ -0,0 +1,92 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef __Util_Singleton_H__
+#define __Util_Singleton_H__
+
+#include "UtilPrereqs.h"
+#include <cassert>
+
+namespace orxonox
+{
+    /**
+    @brief
+        Base for singleton classes.
+
+        Usage:
+        Inherit publicly from Singleton<MyClass> and provide access to
+        MyClass::singletonPtr_s.
+        This can easily be done with a friend declaration.
+    */
+    template <class T>
+    class Singleton
+    {
+    public:
+        //! Returns a reference to the singleton instance
+        static T& getInstance()
+        {
+            assert(T::singletonPtr_s != NULL);
+            return *T::singletonPtr_s;
+        }
+
+        //! Tells whether the singleton has been created
+        static bool exists()
+        {
+            return (T::singletonPtr_s != NULL);
+        }
+
+        //! Update method called by ClassSingletonManager (if used)
+        void preUpdateSingleton(const Clock& time) { static_cast<T*>(T::singletonPtr_s)->preUpdate(time); }
+        //! Empty update method for the static polymorphism
+        void preUpdate(const Clock& time) { }
+        //! Update method called by ClassSingletonManager (if used)
+        void postUpdateSingleton(const Clock& time) { static_cast<T*>(T::singletonPtr_s)->postUpdate(time); }
+        //! Empty update method for the static polymorphism
+        void postUpdate(const Clock& time) { }
+
+    protected:
+        //! Constructor sets the singleton instance pointer
+        Singleton()
+        {
+            assert(T::singletonPtr_s == NULL);
+            T::singletonPtr_s = static_cast<T*>(this);
+        }
+
+        //! Constructor resets the singleton instance pointer
+        ~Singleton()
+        {
+            assert(T::singletonPtr_s != NULL);
+            T::singletonPtr_s = NULL;
+        }
+
+    private:
+        Singleton(const Singleton& rhs); //!< Don't use (undefined)
+    };
+}
+
+#endif /* __Util_Singleton_H__ */
Index: /code/branches/rocket2/src/libraries/util/Sleep.cc
===================================================================
--- /code/branches/rocket2/src/libraries/util/Sleep.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Sleep.cc	(revision 6952)
@@ -0,0 +1,85 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of three sleep functions. Avoids including windows.h
+*/
+
+#include "Sleep.h"
+#include "Debug.h"
+
+#ifdef ORXONOX_PLATFORM_WINDOWS
+#ifndef WIN32_LEAN_AND_MEAN
+#  define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#undef min
+#undef max
+
+namespace orxonox
+{
+    void usleep(unsigned long microseconds)
+    {
+        //if (microseconds < 1000)
+        //    COUT(2) << "Warning: Windows cannot sleep less than 1ms, ignoring" << std::endl;
+        Sleep(microseconds / 1000);
+    }
+
+    void msleep(unsigned long milliseconds)
+    {
+        Sleep(milliseconds);
+    }
+
+    void sleep(unsigned long seconds)
+    {
+        Sleep(seconds * 1000);
+    }
+}
+
+#else /* Linux/Apple */
+#include <unistd.h>
+
+namespace orxonox
+{
+    void usleep(unsigned long usec)
+    {
+        ::usleep(usec);
+    }
+    void msleep(unsigned long msec)
+    {
+        ::usleep(msec * 1000);
+    }
+    void sleep(unsigned long sec)
+    {
+        ::usleep(sec * 1000000);
+    }
+}
+
+#endif
Index: /code/branches/rocket2/src/libraries/util/Sleep.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/Sleep.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/Sleep.h	(revision 6952)
@@ -0,0 +1,50 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Functions declarations to make the current thread sleep.
+ */
+
+#ifndef _Sleep_H__
+#define _Sleep_H__
+
+#include "UtilPrereqs.h"
+
+namespace orxonox
+{
+    //! Makes the thread sleep for a few @a microseconds
+    _UtilExport void usleep(unsigned long microseconds);
+    //! Makes the thread sleep for a few @a milliseconds
+    _UtilExport void msleep(unsigned long milliseconds);
+    //! Makes the thread sleep for a few @a seconds
+    _UtilExport void sleep (unsigned long seconds);
+}
+
+#endif /* _Sleep_H__ */
Index: /code/branches/rocket2/src/libraries/util/StringUtils.cc
===================================================================
--- /code/branches/rocket2/src/libraries/util/StringUtils.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/StringUtils.cc	(revision 6952)
@@ -0,0 +1,529 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Benjamin Grauer
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of several string manipulation functions.
+*/
+
+#include "StringUtils.h"
+
+#include <cctype>
+#include "Convert.h"
+#include "Math.h"
+
+namespace orxonox
+{
+    std::string BLANKSTRING;
+
+    std::string getUniqueNumberString()
+    {
+        return multi_cast<std::string>(getUniqueNumber());
+    }
+
+    /**
+        @brief Removes all whitespaces from a string.
+        @param str The string to strip
+    */
+    void strip(std::string* str)
+    {
+        size_t pos;
+        while ((pos = str->find(' ')) < str->length())
+            str->erase(pos, 1);
+        while ((pos = str->find('\t')) < str->length())
+            str->erase(pos, 1);
+        while ((pos = str->find('\n')) < str->length())
+            str->erase(pos, 1);
+    }
+
+    /**
+        @brief Returns a copy of a string without whitespaces.
+        @param str The string to strip
+        @return The stripped line
+    */
+    std::string getStripped(const std::string& str)
+    {
+        std::string output(str);
+        strip(&output);
+        return output;
+    }
+
+    /**
+        @brief Returns a copy of a string without trailing whitespaces.
+        @param str The string
+        @return The modified copy
+    */
+    std::string removeTrailingWhitespaces(const std::string& str)
+    {
+        size_t pos1 = 0;
+        int pos2 = static_cast<int>(str.size() - 1);
+        for (; pos1 < str.size() && (str[pos1] == ' ' || str[pos1] == '\t' || str[pos1] == '\n'); pos1++);
+        for (; pos2 > 0         && (str[pos2] == ' ' || str[pos2] == '\t' || str[pos2] == '\n'); pos2--);
+        return str.substr(pos1, pos2 - pos1 + 1);
+    }
+
+    /**
+        @brief Returns the position of the next quote in the string, starting with start.
+        @param str The string
+        @param start The startposition
+        @return The position of the next quote (std::string::npos if there is no next quote)
+    */
+    size_t getNextQuote(const std::string& str, size_t start)
+    {
+        size_t quote = start - 1;
+
+        while ((quote = str.find('"', quote + 1)) != std::string::npos)
+        {
+            size_t backslash = quote;
+            size_t numbackslashes = 0;
+            for (; backslash > 0; backslash--, numbackslashes++)
+                if (str[backslash - 1] != '\\')
+                    break;
+
+            if (numbackslashes % 2 == 0)
+                break;
+        }
+
+        return quote;
+    }
+
+    /**
+        @brief Returns true if pos is between two quotes.
+        @param str The string
+        @param pos The position to check
+        @return True if pos is between two quotes
+    */
+    bool isBetweenQuotes(const std::string& str, size_t pos)
+    {
+        if (pos == std::string::npos)
+            return false;
+
+        size_t quotecount = 0;
+        size_t quote = static_cast<size_t>(-1);
+        while ((quote = getNextQuote(str, quote + 1)) < pos)
+        {
+            if (quote == pos)
+                return false;
+            quotecount++;
+        }
+
+        if (quote == std::string::npos)
+            return false;
+
+        return ((quotecount % 2) == 1);
+    }
+
+    /**
+        @brief Returns true if the string contains something like '..."between quotes"...'.
+        @param The string
+        @return True if there is something between quotes
+    */
+    bool hasStringBetweenQuotes(const std::string& str)
+    {
+        size_t pos1 = getNextQuote(str, 0);
+        size_t pos2 = getNextQuote(str, pos1 + 1);
+        return (pos1 != std::string::npos && pos2 != std::string::npos && pos2 > pos1 + 1);
+    }
+
+    /**
+        @brief If the string contains something like '..."between quotes"...' then 'between quotes' gets returned (without quotes).
+        @param The string
+        @param The string between the quotes
+    */
+    std::string getStringBetweenQuotes(const std::string& str)
+    {
+        size_t pos1 = getNextQuote(str, 0);
+        size_t pos2 = getNextQuote(str, pos1 + 1);
+        if (pos1 != std::string::npos && pos2 != std::string::npos)
+            return str.substr(pos1, pos2 - pos1 + 1);
+        else
+            return "";
+    }
+
+    /**
+        @brief Removes enclosing quotes if available (including whitespaces at the outside of the quotes).
+        @brief str The string to strip
+        @return The string with removed quotes
+    */
+    std::string stripEnclosingQuotes(const std::string& str)
+    {
+        size_t start = std::string::npos;
+        size_t end = 0;
+
+        for (size_t pos = 0; (pos < str.size()) && (pos < std::string::npos); pos++)
+        {
+            if (str[pos] == '"')
+            {
+                start = pos;
+                break;
+            }
+
+            if ((str[pos] != ' ') && (str[pos] != '\t') && (str[pos] != '\n'))
+                return str;
+        }
+
+        for (size_t pos = str.size() - 1; pos < std::string::npos; pos--)
+        {
+            if (str[pos] == '"')
+            {
+                end = pos;
+                break;
+            }
+
+            if ((str[pos] != ' ') && (str[pos] != '\t') && (str[pos] != '\n'))
+                return str;
+        }
+
+        if ((start != std::string::npos) && (end != 0))
+            return str.substr(start + 1, end - start - 1);
+        else
+            return str;
+    }
+
+    /**
+        @brief Removes enclosing {braces} (braces must be exactly on the beginning and the end of the string).
+        @param str The string to strip
+        @return The striped string
+    */
+    std::string stripEnclosingBraces(const std::string& str)
+    {
+        std::string output = str;
+
+        while (output.size() >= 2 && output[0] == '{' && output[output.size() - 1] == '}')
+            output = output.substr(1, output.size() - 2);
+
+        return output;
+    }
+
+    /**
+        @brief Determines if a string is a comment (starts with a comment-symbol).
+        @param str The string to check
+        @return True = it's a comment
+
+        A comment is defined by a leading '#', '%', ';' or '//'.
+    */
+    bool isComment(const std::string& str)
+    {
+        // Strip the line, whitespaces are disturbing
+        const std::string& teststring = getStripped(str);
+
+        // There are four possible comment-symbols:
+        //  1) #comment in script-language style
+        //  2) %comment in matlab style
+        //  3) ;comment in unreal tournament config-file style
+        //  4) //comment in code style
+        if (teststring.size() >= 2)
+        {
+            if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';' || (teststring[0] == '/' && teststring[1] == '/'))
+                return true;
+        }
+        else if (teststring.size() == 1)
+        {
+            if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';')
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+        @brief Determines if a string is empty (contains only whitespaces).
+        @param str The string to check
+        @return True = it's empty
+    */
+    bool isEmpty(const std::string& str)
+    {
+        return getStripped(str).empty();
+    }
+
+    /**
+        @brief Determines if a string contains only numbers and maximal one '.'.
+        @param str The string to check
+        @return True = it's a number
+    */
+    bool isNumeric(const std::string& str)
+    {
+        bool foundPoint = false;
+
+        for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)
+        {
+            if (((*it) < '0' || (*it) > '9'))
+            {
+                if ((*it) != '.' && !foundPoint)
+                    foundPoint = true;
+                else
+                    return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+        @brief Adds backslashes to the given string which makes special chars visible. Existing slashes will be doubled.
+        @param str The string to manipulate
+        @return The string with added slashes
+    */
+    std::string addSlashes(const std::string& str)
+    {
+        std::string output(str.size() * 2, ' ');
+        size_t i = 0;
+        for (size_t pos = 0; pos < str.size(); ++pos)
+        {
+            switch (str[pos])
+            {
+            case '\\': output[i] = '\\'; output[i + 1] = '\\'; break;
+            case '\n': output[i] = '\\'; output[i + 1] =  'n'; break;
+            case '\t': output[i] = '\\'; output[i + 1] =  't'; break;
+            case '\v': output[i] = '\\'; output[i + 1] =  'v'; break;
+            case '\b': output[i] = '\\'; output[i + 1] =  'b'; break;
+            case '\r': output[i] = '\\'; output[i + 1] =  'r'; break;
+            case '\f': output[i] = '\\'; output[i + 1] =  'f'; break;
+            case '\a': output[i] = '\\'; output[i + 1] =  'a'; break;
+            case  '"': output[i] = '\\'; output[i + 1] =  '"'; break;
+            case '\0': output[i] = '\\'; output[i + 1] =  '0'; break;
+            default  : output[i] = str[pos]; ++i; continue;
+            }
+            i += 2;
+        }
+        output.resize(i);
+
+        return output;
+    }
+
+    /**
+        @brief Removes backslashes from the given string. Double backslashes are interpreted as one backslash.
+        @param str The string to manipulate
+        @return The string with removed slashes
+    */
+    std::string removeSlashes(const std::string& str)
+    {
+        if (str.size() <= 1)
+            return str;
+
+        std::string output(str.size(), ' ');
+        size_t i = 0;
+        size_t pos = 0;
+        while (pos < str.size() - 1)
+        {
+            if (str[pos] == '\\')
+            {
+                switch (str[pos + 1])
+                {
+                case '\\': output[i] = '\\'; break;
+                case  'n': output[i] = '\n'; break;
+                case  't': output[i] = '\t'; break;
+                case  'v': output[i] = '\v'; break;
+                case  'b': output[i] = '\b'; break;
+                case  'r': output[i] = '\r'; break;
+                case  'f': output[i] = '\f'; break;
+                case  'a': output[i] = '\a'; break;
+                case  '"': output[i] =  '"'; break;
+                case  '0': output[i] = '\0'; break;
+                default: ++pos; continue;
+                }
+                pos += 2; ++i;
+            }
+            else
+                output[i++] = str[pos++];
+        }
+        if (pos < str.size())
+            output[i++] = str[pos];
+        output.resize(i);
+
+        return output;
+    }
+
+    /**
+        @brief Replaces each char between A and Z with its lowercase equivalent.
+        @param str The string to convert
+    */
+    void lowercase(std::string* str)
+    {
+        for (size_t i = 0; i < str->size(); ++i)
+        {
+            (*str)[i] = static_cast<char>(tolower((*str)[i]));
+        }
+    }
+
+    /**
+        @brief Returns a copy of the given string without uppercase chars.
+        @param str The string
+        @return The copy
+    */
+    std::string getLowercase(const std::string& str)
+    {
+        std::string output(str);
+        lowercase(&output);
+        return output;
+    }
+
+    /**
+        @brief Replaces each char between a and z with its uppercase equivalent.
+        @param str The string to convert
+    */
+    void uppercase(std::string* str)
+    {
+        for (size_t i = 0; i < str->size(); ++i)
+        {
+            (*str)[i] = static_cast<char>(toupper((*str)[i]));
+        }
+    }
+
+    /**
+        @brief Returns a copy of the given string without lowercase chars.
+        @param str The string
+        @return The copy
+    */
+    std::string getUppercase(const std::string& str)
+    {
+        std::string output(str);
+        uppercase(&output);
+        return output;
+    }
+
+    /**
+        @brief Compares two strings ignoring different casing.
+        @param s1 First string
+        @param s2 Second string
+    */
+    int nocaseCmp(const std::string& s1, const std::string& s2)
+    {
+        std::string::const_iterator it1=s1.begin();
+        std::string::const_iterator it2=s2.begin();
+
+        //stop when either string's end has been reached
+        while ( (it1!=s1.end()) && (it2!=s2.end()) )
+        {
+            if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
+                // return -1 to indicate smaller than, 1 otherwise
+                return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1;
+            //proceed to the next character in each string
+            ++it1;
+            ++it2;
+        }
+        size_t size1=s1.size(), size2=s2.size();// cache lengths
+        //return -1,0 or 1 according to strings' lengths
+        if (size1==size2)
+            return 0;
+        return (size1<size2) ? -1 : 1;
+    }
+
+
+    /**
+        @brief Compares the first 'len' chars of two strings ignoring different casing.
+        @param s1 First string
+        @param s2 Second string
+        @param len Maximal number of chars to compare
+    */
+    int nocaseCmp(const std::string& s1, const std::string& s2, size_t len)
+    {
+        if (len == 0)
+            return 0;
+        std::string::const_iterator it1=s1.begin();
+        std::string::const_iterator it2=s2.begin();
+
+        //stop when either string's end has been reached
+        while ( (it1!=s1.end()) && (it2!=s2.end()) && len-- > 0)
+        {
+            if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
+                // return -1 to indicate smaller than, 1 otherwise
+                return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1;
+            //proceed to the next character in each string
+            ++it1;
+            ++it2;
+        }
+        return 0;
+    }
+
+    /**
+        @brief Returns true if the string contains a comment, introduced by #, %, ; or //.
+        @param str The string
+        @return True if the string contains a comment
+    */
+    bool hasComment(const std::string& str)
+    {
+        return (getCommentPosition(str) != std::string::npos);
+    }
+
+    /**
+        @brief If the string contains a comment, the comment gets returned (including the comment symbol), an empty string otherwise.
+        @param str The string
+        @return The comment
+    */
+    std::string getComment(const std::string& str)
+    {
+        return str.substr(getCommentPosition(str));
+    }
+
+    /**
+        @brief If the string contains a comment, the position of the comment-symbol gets returned, std::string::npos otherwise.
+        @param str The string
+        @return The position
+    */
+    size_t getCommentPosition(const std::string& str)
+    {
+        return getNextCommentPosition(str, 0);
+    }
+
+    /**
+        @brief Returns the position of the next comment-symbol, starting with start.
+        @param str The string
+        @param start The startposition
+        @return The position
+    */
+    size_t getNextCommentPosition(const std::string& str, size_t start)
+    {
+        for (size_t i = start; i < str.size(); i++)
+            if (isComment(str.substr(i)))
+                return i;
+
+        return std::string::npos;
+    }
+
+    /**
+        @brief Replaces individual charaters
+        @param str String to be manipulated
+        @param target Character to be replaced
+        @param replacement Replacement character
+        @return Number of replacements
+    */
+    _UtilExport size_t replaceCharacters(std::string& str, char target, char replacement)
+    {
+        size_t j = 0;
+        for (size_t i = 0; i < str.size(); ++i)
+        {
+            if (str[i] == target)
+            {
+                str[i] = replacement;
+                ++j;
+            }
+        }
+        return j;
+    }
+}
Index: /code/branches/rocket2/src/libraries/util/StringUtils.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/StringUtils.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/StringUtils.h	(revision 6952)
@@ -0,0 +1,83 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Declaration of several string manipulation functions, used in many parts of the game.
+*/
+
+#ifndef _StringUtils_H__
+#define _StringUtils_H__
+
+#include "UtilPrereqs.h"
+#include <string>
+
+namespace orxonox
+{
+    extern _UtilExport std::string BLANKSTRING;
+    _UtilExport std::string getUniqueNumberString();
+
+    _UtilExport void        strip(std::string* str);
+    _UtilExport std::string getStripped(const std::string& str);
+
+    _UtilExport std::string removeTrailingWhitespaces(const std::string& str);
+
+    _UtilExport size_t      getNextQuote(const std::string& str, size_t start);
+    _UtilExport bool        isBetweenQuotes(const std::string& str, size_t pos);
+
+    _UtilExport bool        hasStringBetweenQuotes(const std::string& str);
+    _UtilExport std::string getStringBetweenQuotes(const std::string& str);
+
+    _UtilExport std::string stripEnclosingQuotes(const std::string& str);
+    _UtilExport std::string stripEnclosingBraces(const std::string& str);
+
+    _UtilExport bool        isEmpty(const std::string& str);
+    _UtilExport bool        isComment(const std::string& str);
+    _UtilExport bool        isNumeric(const std::string& str);
+
+    _UtilExport std::string addSlashes(const std::string& str);
+    _UtilExport std::string removeSlashes(const std::string& str);
+
+    _UtilExport void        lowercase(std::string* str);
+    _UtilExport std::string getLowercase(const std::string& str);
+
+    _UtilExport void        uppercase(std::string* str);
+    _UtilExport std::string getUppercase(const std::string& str);
+
+    _UtilExport int         nocaseCmp(const std::string& s1, const std::string& s2);
+    _UtilExport int         nocaseCmp(const std::string& s1, const std::string& s2, size_t len);
+
+    _UtilExport bool        hasComment(const std::string& str);
+    _UtilExport std::string getComment(const std::string& str);
+    _UtilExport size_t      getCommentPosition(const std::string& str);
+    _UtilExport size_t      getNextCommentPosition(const std::string& str, size_t start = 0);
+
+    _UtilExport size_t      replaceCharacters(std::string& str, char target, char replacement);
+}
+
+#endif /* _StringUtils_H__ */
Index: /code/branches/rocket2/src/libraries/util/SubString.cc
===================================================================
--- /code/branches/rocket2/src/libraries/util/SubString.cc	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/SubString.cc	(revision 6952)
@@ -0,0 +1,561 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Christian Meyer
+ *   Co-authors:
+ *      Benjamin Grauer
+ *
+
+//
+//  splitLine
+//  STL string tokenizer
+//
+//  Created by Clemens Wacha.
+//  Version 1.0
+//  Copyright (c) 2005 Clemens Wacha. All rights reserved.
+//
+
+ *   Extended by Fabian 'x3n' Landau by the SL_PARENTHESES mode.
+ */
+
+#include "SubString.h"
+#include <cstdio>
+
+namespace orxonox
+{
+    /**
+     * @brief default constructor
+     */
+    SubString::SubString()
+    {}
+
+
+    /**
+     * @brief create a SubString from
+     * @param string the String to Split
+     * @param delimiter the Character at which to split string (delimiter)
+     */
+    SubString::SubString(const std::string& string, char delimiter)
+    {
+        this->split(string, delimiter);
+    }
+
+
+    /**
+     * @brief Splits a String into multiple splitters.
+     * @param string the String to split
+     * @param delimiters multiple set of characters at what to split. (delimiters)
+     * @param delimiterNeighbours neighbours of the delimiters, that will be erased only when near a delimiter.
+     * @param emptyEntries If empty entries should be allewed or removed.
+     * @param escapeChar The Escape Character that overrides splitters commends and so on...
+     * @param safemode_char within these characters splitting won't happen
+     * @param comment_char the Comment character.
+     */
+    SubString::SubString(const std::string& string,
+                         const std::string& delimiters, const std::string& delimiterNeighbours, bool emptyEntries,
+                         char escapeChar, bool removeEscapeChar, char safemode_char, bool removeSafemodeChar,
+                         char openparenthesis_char, char closeparenthesis_char, bool removeParenthesisChars, char comment_char)
+    {
+        SubString::splitLine(this->strings, this->bInSafemode, string, delimiters, delimiterNeighbours, emptyEntries, escapeChar, removeEscapeChar, safemode_char, removeSafemodeChar, openparenthesis_char, closeparenthesis_char, removeParenthesisChars, comment_char);
+    }
+
+    /**
+     * @brief creates a SubSet of a SubString.
+     * @param subString the SubString to take a set from.
+     * @param subSetBegin the beginning to the end
+     */
+    SubString::SubString(const SubString& subString, unsigned int subSetBegin)
+    {
+        for (unsigned int i = subSetBegin; i < subString.size(); i++)
+        {
+            this->strings.push_back(subString[i]);
+            this->bInSafemode.push_back(subString.isInSafemode(i));
+        }
+    }
+
+
+    /**
+     * @brief creates a SubSet of a SubString.
+     * @param subString the SubString to take a Set from
+     * @param subSetBegin the beginning to the end
+     * @param subSetEnd the end of the SubSet (max subString.size() will be checked internaly)
+     */
+    SubString::SubString(const SubString& subString, unsigned int subSetBegin, unsigned int subSetEnd)
+    {
+        for (unsigned int i = subSetBegin; i < subString.size() && i < subSetEnd; i++)
+        {
+            this->strings.push_back(subString[i]);
+            this->bInSafemode.push_back(subString.isInSafemode(i));
+        }
+    }
+
+    /**
+     * @brief creates a Substring from a count and values set.
+     * @param argc: the Arguments Count.
+     * @param argv: Argument Values.
+     */
+    SubString::SubString(unsigned int argc, const char** argv)
+    {
+        for(unsigned int i = 0; i < argc; ++i)
+        {
+            this->strings.push_back(std::string(argv[i]));
+            this->bInSafemode.push_back(false);
+        }
+    }
+
+    /**
+     * @brief removes the object from memory
+     */
+    SubString::~SubString()
+    { }
+
+    /** @brief An empty String */
+    // const std::string SubString::emptyString = "";
+    /** @brief Helper that gets you a String consisting of all White Spaces */
+    const std::string SubString::WhiteSpaces = " \n\t";
+    /** @brief Helper that gets you a String consisting of all WhiteSpaces and the Comma */
+    const std::string SubString::WhiteSpacesWithComma = " \n\t,";
+    /** An Empty SubString */
+    const SubString SubString::NullSubString = SubString();
+
+    /**
+     * @brief stores the Value of subString in this SubString
+     * @param subString will be copied into this String.
+     * @returns this SubString.
+     */
+    SubString& SubString::operator=(const SubString& subString)
+    {
+        this->strings = subString.strings;
+        this->bInSafemode = subString.bInSafemode;
+        return *this;
+    }
+
+
+    /**
+     * @brief comparator.
+     * @param subString the SubString to compare against this one.
+     * @returns true if the Stored Strings match
+     */
+    bool SubString::operator==(const SubString& subString) const
+    {
+        return ((this->strings == subString.strings) && (this->bInSafemode == subString.bInSafemode));
+    }
+
+    /**
+     * @brief comparator.
+     * @param subString the SubString to compare against this one.
+     * @returns true if the Stored Strings match
+     */
+    bool SubString::compare(const SubString& subString) const
+    {
+        return (*this == subString);
+    }
+
+    /**
+     * @brief comparator.
+     * @param subString the SubString to compare against this one.
+     * @param length how many entries to compare. (from 0 to length)
+     * @returns true if the Stored Strings match
+     */
+    bool SubString::compare(const SubString& subString, unsigned int length) const
+    {
+        if (length > this->size() || length > subString.size())
+            return false;
+
+        for (unsigned int i = 0; i < length; i++)
+            if ((this->strings[i] != subString.strings[i]) || (this->bInSafemode[i] != subString.bInSafemode[i]))
+                return false;
+        return true;
+    }
+
+
+    /**
+     * @brief append operator
+     * @param subString the String to append.
+     * @returns a SubString where this and subString are appended.
+     */
+    SubString SubString::operator+(const SubString& subString) const
+    {
+        return SubString(*this) += subString;
+    }
+
+
+    /**
+     * @brief append operator.
+     * @param subString append subString to this SubString.
+     * @returns this substring appended with subString
+     */
+    SubString& SubString::operator+=(const SubString& subString)
+    {
+        for (unsigned int i = 0; i < subString.size(); i++)
+        {
+            this->strings.push_back(subString[i]);
+            this->bInSafemode.push_back(subString.isInSafemode(i));
+        }
+        return *this;
+    }
+
+
+    /**
+     * @brief Split the String at
+     * @param string where to split
+     * @param splitter delimiter.
+     */
+    unsigned int SubString::split(const std::string& string, char splitter)
+    {
+        this->strings.clear();
+        this->bInSafemode.clear();
+        char split[2];
+        split[0] = splitter;
+        split[1] = '\0';
+        SubString::splitLine(this->strings, this->bInSafemode, string, split);
+        return strings.size();
+    }
+
+
+    /**
+     * @brief Splits a String into multiple splitters.
+     * @param string the String to split
+     * @param delimiters multiple set of characters at what to split. (delimiters)
+     * @param delimiterNeighbours: Neighbours to the Delimiters that will be erased too.
+     * @param emptyEntries: If empty entries are added to the List of SubStrings
+     * @param escapeChar The Escape Character that overrides splitters commends and so on...
+     * @param safemode_char within these characters splitting won't happen
+     * @param comment_char the Comment character.
+     */
+    unsigned int SubString::split(const std::string& string,
+                                  const std::string& delimiters, const std::string& delimiterNeighbours, bool emptyEntries,
+                                  char escapeChar, bool removeExcapeChar, char safemode_char, bool removeSafemodeChar,
+                                  char openparenthesis_char, char closeparenthesis_char, bool removeParenthesisChars, char comment_char)
+    {
+        this->strings.clear();
+        this->bInSafemode.clear();
+        SubString::splitLine(this->strings, this->bInSafemode, string, delimiters, delimiterNeighbours, emptyEntries, escapeChar, removeExcapeChar, safemode_char, removeSafemodeChar, openparenthesis_char, closeparenthesis_char, removeParenthesisChars, comment_char);
+        return this->strings.size();
+    }
+
+
+    /**
+     * @brief joins together all Strings of this Substring.
+     * @param delimiter the String between the subStrings.
+     * @returns the joined String.
+     */
+    std::string SubString::join(const std::string& delimiter) const
+    {
+        if (!this->strings.empty())
+        {
+            std::string retVal = this->strings[0];
+            for (unsigned int i = 1; i < this->strings.size(); i++)
+                retVal += delimiter + this->strings[i];
+            return retVal;
+        }
+        else
+            return "";
+    }
+
+
+    /**
+     * @brief creates a SubSet of a SubString.
+     * @param subSetBegin the beginning to the end
+     * @returns the SubSet
+     *
+     * This function is added for your convenience, and does the same as
+     * SubString::SubString(const SubString& subString, unsigned int subSetBegin)
+     */
+    SubString SubString::subSet(unsigned int subSetBegin) const
+    {
+        return SubString(*this, subSetBegin);
+    }
+
+
+    /**
+     * @brief creates a SubSet of a SubString.
+     * @param subSetBegin the beginning to
+     * @param subSetEnd the end of the SubSet to select (if bigger than subString.size() it will be downset.)
+     * @returns the SubSet
+     *
+     * This function is added for your convenience, and does the same as
+     * SubString::SubString(const SubString& subString, unsigned int subSetBegin)
+     */
+    SubString SubString::subSet(unsigned int subSetBegin, unsigned int subSetEnd) const
+    {
+        return SubString(*this, subSetBegin, subSetEnd);
+    }
+
+
+    /**
+     * @brief splits line into tokens and stores them in ret.
+     * @param ret the Array, where the Splitted strings will be stored in
+     * to the beginning of the current token is stored
+     * @param line the inputLine to split
+     * @param delimiters a String of Delimiters (here the input will be splitted)
+     * @param delimiterNeighbours Naighbours to the Delimitter, that will be removed if they are to the left or the right of a Delimiter.
+     * @param emptyEntries: if empty Strings are added to the List of Strings.
+     * @param escape_char: Escape carater (escapes splitters)
+     * @param safemode_char: the beginning of the safemode is marked with this
+     * @param removeSafemodeChar removes the safemode_char from the beginning and the ending of a token
+     * @param openparenthesis_char the beginning of a safemode is marked with this
+     * @param closeparenthesis_char the ending of a safemode is marked with this
+     * @param removeParenthesisChars removes the parenthesis from the beginning and the ending of a token
+     * @param comment_char: the beginning of a comment is marked with this: (until the end of a Line)
+     * @param start_state: the Initial state on how to parse the String.
+     * @return SPLIT_LINE_STATE the parser was in when returning
+     *
+     * This is the Actual Splitting Algorithm from Clemens Wacha
+     * Supports delimiters, escape characters,
+     * ignores special  characters between safemode_char and between comment_char and linend '\n'.
+     */
+    SubString::SPLIT_LINE_STATE
+    SubString::splitLine(std::vector<std::string>& ret,
+                         std::vector<bool>& bInSafemode,
+                         const std::string& line,
+                         const std::string& delimiters,
+                         const std::string& delimiterNeighbours,
+                         bool emptyEntries,
+                         char escape_char,
+                         bool removeExcapeChar,
+                         char safemode_char,
+                         bool removeSafemodeChar,
+                         char openparenthesis_char,
+                         char closeparenthesis_char,
+                         bool removeParenthesisChars,
+                         char comment_char,
+                         SPLIT_LINE_STATE start_state)
+    {
+        SPLIT_LINE_STATE state = start_state;
+        unsigned int i = 0;
+        unsigned int fallBackNeighbours = 0;
+
+        std::string token;
+        bool inSafemode = false;
+
+        if(start_state != SL_NORMAL && ret.size() > 0)
+        {
+            token = ret[ret.size()-1];
+            ret.pop_back();
+        }
+        if(start_state != SL_NORMAL && bInSafemode.size() > 0)
+        {
+            inSafemode = bInSafemode[bInSafemode.size()-1];
+            bInSafemode.pop_back();
+        }
+
+        while(i < line.size())
+        {
+            switch(state)
+            {
+            case SL_NORMAL:
+                if(line[i] == escape_char)
+                {
+                    state = SL_ESCAPE;
+                    if (!removeExcapeChar)
+                        token += line[i];
+                }
+                else if(line[i] == safemode_char)
+                {
+                    state = SL_SAFEMODE;
+                    inSafemode = true;
+                    if (!removeSafemodeChar)
+                        token += line[i];
+                }
+                else if(line[i] == openparenthesis_char)
+                {
+                    state = SL_PARENTHESES;
+                    inSafemode = true;
+                    if (!removeParenthesisChars)
+                        token += line[i];
+                }
+                else if(line[i] == comment_char)
+                {
+                    if (fallBackNeighbours > 0)
+                        token = token.substr(0, token.size() - fallBackNeighbours);
+                    /// FINISH
+                    if(emptyEntries || token.size() > 0)
+                    {
+                        ret.push_back(token);
+                        token.clear();
+                        bInSafemode.push_back(inSafemode);
+                        inSafemode = false;
+                    }
+                    token += line[i];       // EAT
+                    state = SL_COMMENT;
+                }
+                else if(delimiters.find(line[i]) != std::string::npos)
+                {
+                    // line[i] is a delimiter
+                    if (fallBackNeighbours > 0)
+                        token = token.substr(0, token.size() - fallBackNeighbours);
+                    /// FINISH
+                    if(emptyEntries || token.size() > 0)
+                    {
+                        ret.push_back(token);
+                        token.clear();
+                        bInSafemode.push_back(inSafemode);
+                        inSafemode = false;
+                    }
+                    state = SL_NORMAL;
+                }
+                else
+                {
+                    if (delimiterNeighbours.find(line[i]) != std::string::npos)
+                    {
+                        if (token.size() > 0)
+                            ++fallBackNeighbours;
+                        else
+                        {
+                            i++;
+                            continue;
+                        }
+                    }
+                    else
+                        fallBackNeighbours = 0;
+                    token += line[i];       // EAT
+                }
+                break;
+            case SL_ESCAPE:
+                if (!removeSafemodeChar)
+                    token += line[i];
+                else
+                {
+                    if(line[i] == 'n') token += '\n';
+                    else if(line[i] == 't') token += '\t';
+                    else if(line[i] == 'v') token += '\v';
+                    else if(line[i] == 'b') token += '\b';
+                    else if(line[i] == 'r') token += '\r';
+                    else if(line[i] == 'f') token += '\f';
+                    else if(line[i] == 'a') token += '\a';
+                    else if(line[i] == '?') token += '\?';
+                    else token += line[i];  // EAT
+                }
+                state = SL_NORMAL;
+                break;
+            case SL_SAFEMODE:
+                if(line[i] == safemode_char)
+                {
+                    state = SL_NORMAL;
+                    if (!removeSafemodeChar)
+                        token += line[i];
+                }
+                else if(line[i] == escape_char)
+                {
+                    state = SL_SAFEESCAPE;
+                }
+                else
+                {
+                    token += line[i];       // EAT
+                }
+                break;
+
+            case SL_SAFEESCAPE:
+                if(line[i] == 'n') token += '\n';
+                else if(line[i] == 't') token += '\t';
+                else if(line[i] == 'v') token += '\v';
+                else if(line[i] == 'b') token += '\b';
+                else if(line[i] == 'r') token += '\r';
+                else if(line[i] == 'f') token += '\f';
+                else if(line[i] == 'a') token += '\a';
+                else if(line[i] == '?') token += '\?';
+                else token += line[i];  // EAT
+                state = SL_SAFEMODE;
+                break;
+
+            case SL_PARENTHESES:
+                if(line[i] == closeparenthesis_char)
+                {
+                    state = SL_NORMAL;
+                    if (!removeParenthesisChars)
+                        token += line[i];
+                }
+                else if(line[i] == escape_char)
+                {
+                    state = SL_PARENTHESESESCAPE;
+                }
+                else
+                {
+                    token += line[i];       // EAT
+                }
+                break;
+
+            case SL_PARENTHESESESCAPE:
+                if(line[i] == 'n') token += '\n';
+                else if(line[i] == 't') token += '\t';
+                else if(line[i] == 'v') token += '\v';
+                else if(line[i] == 'b') token += '\b';
+                else if(line[i] == 'r') token += '\r';
+                else if(line[i] == 'f') token += '\f';
+                else if(line[i] == 'a') token += '\a';
+                else if(line[i] == '?') token += '\?';
+                else token += line[i];  // EAT
+                state = SL_PARENTHESES;
+                break;
+
+            case SL_COMMENT:
+                if(line[i] == '\n')
+                {
+                    /// FINISH
+                    if(token.size() > 0)
+                    {
+                        ret.push_back(token);
+                        token.clear();
+                        bInSafemode.push_back(inSafemode);
+                        inSafemode = false;
+                    }
+                    state = SL_NORMAL;
+                }
+                else
+                {
+                    token += line[i];       // EAT
+                }
+                break;
+
+            default:
+                // nothing
+                break;
+            }
+            i++;
+        }
+
+        /// FINISH
+        if (fallBackNeighbours > 0)
+            token = token.substr(0, token.size() - fallBackNeighbours);
+        if(emptyEntries || token.size() > 0)
+        {
+            ret.push_back(token);
+            token.clear();
+            bInSafemode.push_back(inSafemode);
+            inSafemode = false;
+        }
+        return(state);
+    }
+
+
+    /**
+     * @brief Some nice debug information about this SubString
+     */
+    void SubString::debug() const
+    {
+        printf("Substring-information::count=%zd ::", this->strings.size());
+        for (unsigned int i = 0; i < this->strings.size(); i++)
+            printf("s%d='%s'::", i, this->strings[i].c_str());
+        printf("\n");
+    }
+}
Index: /code/branches/rocket2/src/libraries/util/SubString.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/SubString.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/SubString.h	(revision 6952)
@@ -0,0 +1,176 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Christian Meyer
+ *   Co-authors:
+ *      Benjamin Grauer
+ *      Fabian 'x3n' Landau
+ *
+
+//  splitLine
+//  STL string tokenizer
+//
+//  Created by Clemens Wacha.
+//  Version 1.0
+//  Copyright (c) 2005 Clemens Wacha. All rights reserved.
+
+ *   Extended by Fabian 'x3n' Landau by the SL_PARENTHESES mode.
+ */
+
+ /*!
+ * @file
+ * @brief a small class to get the parts of a string separated by commas
+ *
+ * This class is also identified as a Tokenizer. It splits up one long
+ * String into multiple small ones by a designated Delimiter.
+ *
+ * Substring is Advanced, and it is possible, to split a string by ','
+ * but also removing leading and trailing spaces around the comma.
+ *
+ * @example
+ * Split the String std::string st = "1345, The new empire   , is , orxonox"
+ * is splitted with:
+ * SubString(st, ',', " \n\t")
+ * into
+ * "1345", "The new empire", "is", "orxonox"
+ * As you can see, the useless spaces around ',' were removed.
+ */
+
+#ifndef __SubString_H__
+#define __SubString_H__
+
+#include "UtilPrereqs.h"
+
+#include <vector>
+#include <string>
+
+namespace orxonox
+{
+    //! A class that can load one string and split it in multipe ones
+    /**
+     * SubString is a very Powerfull way to create a SubSet from a String
+     * It can be used, to Split strings append them and join them again.
+     */
+    class _UtilExport SubString
+    {
+    public:
+        //! An enumerator for the State the Parser is in
+        typedef enum {
+            SL_NORMAL,            //!< Normal state
+            SL_ESCAPE,            //!< After an escape character
+            SL_SAFEMODE,          //!< In safe mode (between "" mostly).
+            SL_SAFEESCAPE,        //!< In safe mode with the internal escape character, that escapes even the savemode character.
+            SL_COMMENT,           //!< In Comment mode.
+            SL_PARENTHESES,       //!< Between parentheses (usually '(' and ')')
+            SL_PARENTHESESESCAPE, //!< Between parentheses with the internal escape character, that escapes even the closing paranthesis character.
+        } SPLIT_LINE_STATE;
+
+
+    public:
+        SubString();
+        SubString(const std::string& string, char delimiter = ',');
+        SubString(const std::string& string,
+                  const std::string& delimiters, const std::string& delimiterNeighbours = "", bool emptyEntries=false,
+                  char escapeChar ='\\', bool removeEscapeChar = true, char safemode_char = '"', bool removeSafemodeChar = true,
+                  char openparenthesis_char = '(', char closeparenthesis_char = ')',  bool removeParenthesisChars = true, char comment_char = '\0');
+        SubString(unsigned int argc, const char** argv);
+        /** @brief create a Substring as a copy of another one. @param subString the SubString to copy. */
+        SubString(const SubString& subString) { *this = subString; };
+        SubString(const SubString& subString, unsigned int subSetBegin);
+        SubString(const SubString& subString, unsigned int subSetBegin, unsigned int subSetEnd);
+        ~SubString();
+
+        // operate on the SubString
+        SubString& operator=(const SubString& subString);
+        bool operator==(const SubString& subString) const;
+        bool compare(const SubString& subString) const;
+        bool compare(const SubString& subString, unsigned int length) const;
+        SubString operator+(const SubString& subString) const;
+        SubString& operator+=(const SubString& subString);
+        /** @param subString the String to append @returns appended String. @brief added for convenience */
+        SubString& append(const SubString subString) { return (*this += subString); };
+
+        /////////////////////////////////////////
+        // Split and Join the any String. ///////
+        unsigned int split(const std::string& string = "", char delimiter = ',');
+        unsigned int split(const std::string& string,
+                           const std::string& delimiters, const std::string& delimiterNeighbours = "", bool emptyEntries = false,
+                           char escapeChar ='\\', bool removeExcapeChar = true, char safemode_char = '"', bool removeSafemodeChar = true,
+                           char openparenthesis_char = '(', char closeparenthesis_char = ')',  bool removeParenthesisChars = true, char comment_char = '\0');
+        std::string join(const std::string& delimiter = " ") const;
+        ////////////////////////////////////////
+
+        // retrieve a SubSet from the String
+        SubString subSet(unsigned int subSetBegin) const;
+        SubString subSet(unsigned int subSetBegin, unsigned int subSetEnd) const;
+
+        // retrieve Information from within
+        /** @brief Returns true if the SubString is empty */
+        inline bool empty() const { return this->strings.empty(); };
+        /** @brief Returns the count of Strings stored in this substring */
+        inline unsigned int size() const { return this->strings.size(); };
+        /** @brief Returns the i'th string from the subset of Strings @param i the i'th String */
+        inline const std::string& operator[](unsigned int i) const { return this->strings[i]; };
+        /** @brief Returns the i'th string from the subset of Strings @param i the i'th String */
+        inline const std::string& getString(unsigned int i) const { return (*this)[i]; };
+        /** @brief Returns all Strings as std::vector */
+        inline const std::vector<std::string>& getAllStrings() const { return this->strings; }
+        /** @brief Returns true if the token is in safemode. @param i the i'th token */
+        inline bool isInSafemode(unsigned int i) const { return this->bInSafemode[i]; }
+        /** @brief Returns the front of the StringList. */
+        inline const std::string& front() const { return this->strings.front(); };
+        /** @brief Returns the back of the StringList. */
+        inline const std::string& back() const { return this->strings.back(); };
+        /** @brief removes the back of the strings list. */
+        inline void pop_back() { this->strings.pop_back(); this->bInSafemode.pop_back(); };
+
+        // the almighty algorithm.
+        static SPLIT_LINE_STATE splitLine(std::vector<std::string>& ret,
+                                          std::vector<bool>& bInSafemode,
+                                          const std::string& line,
+                                          const std::string& delimiters = SubString::WhiteSpaces,
+                                          const std::string& delimiterNeighbours = "",
+                                          bool emptyEntries = false,
+                                          char escape_char = '\\',
+                                          bool removeExcapeChar = true,
+                                          char safemode_char = '"',
+                                          bool removeSafemodeChar = true,
+                                          char openparenthesis_char = '(',
+                                          char closeparenthesis_char = ')',
+                                          bool removeParenthesisChars = true,
+                                          char comment_char = '\0',
+                                          SPLIT_LINE_STATE start_state = SL_NORMAL);
+        // debugging.
+        void debug() const;
+
+    public:
+        static const std::string WhiteSpaces;
+        static const std::string WhiteSpacesWithComma;
+        static const SubString   NullSubString;
+
+    private:
+        std::vector<std::string>  strings;                      //!< strings produced from a single string splitted in multiple strings
+        std::vector<bool>         bInSafemode;
+    };
+}
+
+#endif /* __SubString_H__ */
Index: /code/branches/rocket2/src/libraries/util/TemplateUtils.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/TemplateUtils.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/TemplateUtils.h	(revision 6952)
@@ -0,0 +1,88 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Declaration of various helper templates.
+*/
+
+#ifndef _TemplateUtils_H__
+#define _TemplateUtils_H__
+
+#include "UtilPrereqs.h"
+
+namespace orxonox
+{
+    ///////////////////////////////////////////////////
+    // Static detection of implicit type conversions //
+    ///////////////////////////////////////////////////
+
+// disable warnings about possible loss of data
+#ifdef ORXONOX_COMPILER_MSVC
+#  pragma warning(push)
+#  pragma warning(disable:4244)
+#endif
+// GCC generates warnings when implicitely casting from float to int for instance.
+#ifdef ORXONOX_COMPILER_GCC
+#  pragma GCC system_header
+#endif
+
+    /**
+    @brief
+        Detects whether you can implicitely cast FromType to ToType.
+
+        Usage: ImplicitConversion<FromType, ToType>::exists
+        This gives you a compile time constant boolean in the form of an enum value.
+    @note
+        The idea to use the sizeof() operator on return values to determine function existance
+        is described in 'Modern C++ design' by Alexandrescu (2001).
+    */
+    template <class FromType, class ToType>
+    class ImplicitConversion
+    {
+    private:
+        ImplicitConversion(); ImplicitConversion(const ImplicitConversion&); ~ImplicitConversion();
+        // Gets chosen only if there is an implicit conversion from FromType to ToType.
+        static char test(ToType);
+        // Accepts any argument. Why do we not use a template? The reason is that with templates,
+        // the function above is only taken iff it is an exact type match. But since we want to
+        // check for implicit conversion, we have to use the ellipsis.
+        static long long test(...);
+        static FromType object; // helper object to handle private c'tor and d'tor
+    public:
+        // test(object) only has 'long long' return type iff the compiler doesn't choose test(...)
+        enum { exists = (sizeof(test(object)) == sizeof(char)) };
+    };
+
+#ifdef ORXONOX_COMPILER_MSVC
+#  pragma warning(pop)
+#endif
+
+}
+
+#endif /* _TemplateUtils_H__ */
Index: /code/branches/rocket2/src/libraries/util/TriBool.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/TriBool.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/TriBool.h	(revision 6952)
@@ -0,0 +1,49 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TriBool_H__
+#define _TriBool_H__
+
+#include "UtilPrereqs.h"
+
+// tolua_begin
+namespace orxonox
+{
+    namespace TriBool
+    {
+        enum Value
+        {
+            False    =  0,
+            True     =  1,
+            Dontcare =  2
+        };
+    }
+}
+// tolua_end
+
+#endif /* _TriBool_H__ */
Index: /code/branches/rocket2/src/libraries/util/TypeTraits.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/TypeTraits.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/TypeTraits.h	(revision 6952)
@@ -0,0 +1,285 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2001 by Andrei Alexandrescu
+// This code accompanies the book:
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
+//     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author or Addison-Wesley Longman make no representations about the 
+//     suitability of this software for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+//
+// Changes by Orxonox (Reto)
+//     Removed all stdInt, etc. type traits and function pointer traits
+//     and added UnqualifiedReferredType.
+////////////////////////////////////////////////////////////////////////////////
+#ifndef LOKI_TYPETRAITS_INC_
+#define LOKI_TYPETRAITS_INC_
+
+// $Id: TypeTraits.h 835 2007-08-02 19:39:02Z syntheticpp $
+
+
+#if (defined _MSC_VER) && (_MSC_VER < 1400)
+#include <string>
+#endif
+
+
+#ifdef _MSC_VER
+#pragma warning( push ) 
+#pragma warning( disable : 4180 ) //qualifier applied to function type has no meaning; ignored
+#endif
+
+namespace Loki
+{
+////////////////////////////////////////////////////////////////////////////////
+// class NullType
+// Used as a placeholder for "no type here"
+// Useful as an end marker in typelists 
+////////////////////////////////////////////////////////////////////////////////
+
+    class NullType {};
+
+////////////////////////////////////////////////////////////////////////////////
+// class template IsCustomUnsignedInt
+// Offers a means to integrate nonstandard built-in unsigned integral types
+// (such as unsigned __int64 or unsigned long long int) with the TypeTraits 
+//     class template defined below.
+// Invocation: IsCustomUnsignedInt<T> where T is any type
+// Defines 'value', an enum that is 1 iff T is a custom built-in unsigned
+//     integral type
+// Specialize this class template for nonstandard unsigned integral types
+//     and define value = 1 in those specializations
+////////////////////////////////////////////////////////////////////////////////
+
+    template <typename T>
+    struct IsCustomUnsignedInt
+    {
+        enum { value = 0 };
+    };        
+
+////////////////////////////////////////////////////////////////////////////////
+// class template IsCustomSignedInt
+// Offers a means to integrate nonstandard built-in unsigned integral types
+// (such as unsigned __int64 or unsigned long long int) with the TypeTraits 
+//     class template defined below.
+// Invocation: IsCustomSignedInt<T> where T is any type
+// Defines 'value', an enum that is 1 iff T is a custom built-in signed
+//     integral type
+// Specialize this class template for nonstandard unsigned integral types
+//     and define value = 1 in those specializations
+////////////////////////////////////////////////////////////////////////////////
+
+    template <typename T>
+    struct IsCustomSignedInt
+    {
+        enum { value = 0 };
+    };        
+
+////////////////////////////////////////////////////////////////////////////////
+// class template IsCustomFloat
+// Offers a means to integrate nonstandard floating point types with the
+//     TypeTraits class template defined below.
+// Invocation: IsCustomFloat<T> where T is any type
+// Defines 'value', an enum that is 1 iff T is a custom built-in
+//     floating point type
+// Specialize this class template for nonstandard unsigned integral types
+//     and define value = 1 in those specializations
+////////////////////////////////////////////////////////////////////////////////
+
+    template <typename T>
+    struct IsCustomFloat
+    {
+        enum { value = 0 };
+    };        
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper types for class template TypeTraits defined below
+////////////////////////////////////////////////////////////////////////////////
+
+    namespace Private
+    {
+        template <typename U> struct AddPointer
+        {
+            typedef U* Result;
+        };
+
+        template <typename U> struct AddPointer<U&>
+        {
+            typedef U* Result;
+        };
+
+        template <class U> struct AddReference
+        {
+            typedef U & Result;
+        };
+
+        template <class U> struct AddReference<U &>
+        {
+            typedef U & Result;
+        };
+
+        template <> struct AddReference<void>
+        {
+            typedef NullType Result;
+        };
+
+        template <class U> struct AddParameterType
+        {
+            typedef const U & Result;
+        };
+
+        template <class U> struct AddParameterType<U &>
+        {
+            typedef U & Result;
+        };
+
+        template <> struct AddParameterType<void>
+        {
+            typedef NullType Result;
+        };
+    }// namespace Private
+        
+////////////////////////////////////////////////////////////////////////////////
+// class template TypeTraits
+//
+// Figures out at compile time various properties of any given type
+// Invocations (T is a type, TypeTraits<T>::Property):
+//
+// - isPointer       : returns true if T is a pointer type
+// - PointeeType     : returns the type to which T points if T is a pointer 
+//                     type, NullType otherwise
+// - isReference     : returns true if T is a reference type
+// - ReferredType    : returns the type to which T refers if T is a reference 
+//                     type, NullType otherwise
+// - ParameterType   : returns the optimal type to be used as a parameter for 
+//                     functions that take Ts
+// - isConst         : returns true if T is a const-qualified type
+// - NonConstType    : Type with removed 'const' qualifier from T, if any
+// - isVolatile      : returns true if T is a volatile-qualified type
+// - NonVolatileType : Type with removed 'volatile' qualifier from T, if any
+// - UnqualifiedType : Type with removed 'const' and 'volatile' qualifiers from 
+//                     T, if any
+// - ParameterType   : returns the optimal type to be used as a parameter 
+//                       for functions that take 'const T's
+//
+////////////////////////////////////////////////////////////////////////////////
+
+    template <typename T>
+    class TypeTraits
+    {
+    private:
+    
+        template <class U> struct ReferenceTraits
+        {
+            enum { result = false };
+            typedef U ReferredType;
+        };
+        
+        template <class U> struct ReferenceTraits<U&>
+        {
+            enum { result = true };
+            typedef U ReferredType;
+        };
+               
+        template <class U> struct PointerTraits
+        {
+            enum { result = false };
+            typedef NullType PointeeType;
+        };
+        
+        template <class U> struct PointerTraits<U*>
+        {
+            enum { result = true };
+            typedef U PointeeType;
+        };
+        
+        template <class U> struct PointerTraits<U*&>
+        {
+            enum { result = true };
+            typedef U PointeeType;
+        };
+          
+        template <class U> struct PToMTraits
+        {
+            enum { result = false };
+        };
+        
+        template <class U, class V> struct PToMTraits<U V::*>
+        {
+            enum { result = true };
+        };
+        
+        template <class U, class V> struct PToMTraits<U V::*&>
+        {
+            enum { result = true };
+        };
+        
+        template <class U> struct UnConst
+        {
+            typedef U Result;
+            enum { isConst = 0 };
+        };
+        
+        template <class U> struct UnConst<const U>
+        {
+            typedef U Result;
+            enum { isConst = 1 };
+        };
+
+        template <class U> struct UnConst<const U&>
+        {
+            typedef U& Result;
+            enum { isConst = 1 };
+        };
+  
+        template <class U> struct UnVolatile
+        {
+            typedef U Result;
+            enum { isVolatile = 0 };
+        };
+       
+        template <class U> struct UnVolatile<volatile U>
+        {
+            typedef U Result;
+            enum { isVolatile = 1 };
+        };
+
+        template <class U> struct UnVolatile<volatile U&>
+        {
+            typedef U& Result;
+            enum { isVolatile = 1 };
+        };
+        
+    public:
+        typedef typename UnConst<T>::Result 
+            NonConstType;
+        typedef typename UnVolatile<T>::Result 
+            NonVolatileType;
+        typedef typename UnVolatile<typename UnConst<T>::Result>::Result 
+            UnqualifiedType;
+        typedef typename PointerTraits<UnqualifiedType>::PointeeType 
+            PointeeType;
+        typedef typename ReferenceTraits<T>::ReferredType 
+            ReferredType;
+        typedef typename ReferenceTraits<typename UnVolatile<typename UnConst<T>::Result>::Result>::ReferredType
+            UnqualifiedReferredType;
+
+        enum { isConst          = UnConst<T>::isConst };
+        enum { isVolatile       = UnVolatile<T>::isVolatile };
+        enum { isReference      = ReferenceTraits<UnqualifiedType>::result };
+        enum { isPointer        = PointerTraits<
+                                        typename ReferenceTraits<UnqualifiedType>::ReferredType >::result};
+                
+    };
+}
+
+#ifdef _MSC_VER
+#pragma warning( pop )
+#endif // _MSC_VER
+
+
+#endif // end file guardian
+
Index: /code/branches/rocket2/src/libraries/util/UtilPrereqs.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/UtilPrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/UtilPrereqs.h	(revision 6952)
@@ -0,0 +1,140 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      Fabian 'x3n' Landau
+ *
+ */
+
+/**
+@file
+@brief
+    Shared library macros, enums, constants and forward declarations for the util library
+*/
+
+#ifndef _UtilPrereqs_H__
+#define _UtilPrereqs_H__
+
+#include "OrxonoxConfig.h"
+
+//-----------------------------------------------------------------------
+// Shared library settings
+//-----------------------------------------------------------------------
+
+#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined( UTIL_STATIC_BUILD )
+#  ifdef UTIL_SHARED_BUILD
+#    define _UtilExport __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define _UtilExport
+#    else
+#      define _UtilExport __declspec(dllimport)
+#    endif
+#  endif
+#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _UtilExport  __attribute__ ((visibility("default")))
+#else
+#  define _UtilExport
+#endif
+
+//-----------------------------------------------------------------------
+// Enums
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    namespace ScopeID
+    {
+        //!A list of available scopes for the Scope template.
+        enum Value
+        {
+            Root,
+            Graphics
+        };
+    }
+}
+
+//-----------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    class Clock;
+    class Exception;
+    class ExprParser;
+    class IntVector2;
+    class IntVector3;
+    class MultiType;
+    class OutputHandler;
+    class OutputListener;
+    template <ScopeID::Value>
+    class Scope;
+    template <class, ScopeID::Value>
+    class ScopedSingleton;
+    class ScopeListener;
+    class SignalHandler;
+    template <class T>
+    class Singleton;
+    class SubString;
+}
+
+namespace Ogre
+{
+    class Radian;
+    class Degree;
+    class Vector2;
+    class Vector3;
+    class Vector4;
+    class Matrix3;
+    class Matrix4;
+    class Quaternion;
+    class ColourValue;
+}
+namespace orxonox
+{
+    using Ogre::Radian;
+    using Ogre::Degree;
+    using Ogre::Vector2;
+    using Ogre::Vector3;
+    using Ogre::Vector4;
+    using Ogre::Matrix3;
+    using Ogre::Matrix4;
+    using Ogre::Quaternion;
+    using Ogre::ColourValue;
+}
+
+namespace Loki
+{
+    class ScopeGuardImplBase;
+    typedef const ScopeGuardImplBase& ScopeGuard;
+}
+
+// Just so you don't have to include StringUtils.h everywhere just for this
+namespace orxonox
+{
+    extern _UtilExport std::string BLANKSTRING;
+}
+
+
+#endif /* _UtilPrereqs_H__ */
Index: /code/branches/rocket2/src/libraries/util/mbool.h
===================================================================
--- /code/branches/rocket2/src/libraries/util/mbool.h	(revision 6952)
+++ /code/branches/rocket2/src/libraries/util/mbool.h	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _mbool_H__
+#define _mbool_H__
+
+#include "UtilPrereqs.h"
+
+namespace orxonox
+{
+    struct _UtilExport mbool
+    {
+        public:
+            inline mbool(bool value = false)
+                { this->value_.memory_ = 0; this->value_.bool_ = value; }
+            inline mbool(const mbool& value)
+                { this->value_.memory_ = value.value_.memory_; }
+
+            inline const mbool& operator=(bool value)
+                { if (value != this->value_.bool_) { ++this->value_.memory_; } return (*this); }
+            inline const mbool& operator=(const mbool& value)
+                { this->value_.memory_ = value.value_.memory_; return (*this); }
+
+            inline mbool& operator++()
+                { ++this->value_.memory_; return (*this); }
+            inline mbool operator++(int i)
+                { mbool temp = (*this); ++this->value_.memory_; return temp; }
+
+            inline operator bool() const
+                { return this->value_.bool_; }
+
+            inline bool operator==(bool other) const
+                { return this->value_.bool_ == other; }
+            inline bool operator!=(bool other) const
+                { return this->value_.bool_ != other; }
+
+            inline bool operator==(const mbool& other) const
+                { return this->value_.memory_ == other.value_.memory_; }
+            inline bool operator!=(const mbool& other) const
+                { return this->value_.memory_ != other.value_.memory_; }
+
+            inline bool operator!() const
+                { return (!this->value_.bool_); }
+
+            inline unsigned char& getMemory(){ return value_.memory_; }
+
+        private:
+            union
+            {
+                bool bool_ : 1;
+                unsigned char memory_;
+            } value_;
+    };
+}
+
+#endif /* _mbool_H__ */
Index: /code/branches/rocket2/src/modules/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,34 @@
+ #
+ #             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.
+ #
+
+INCLUDE_DIRECTORIES(
+  ${CMAKE_SOURCE_DIR}/src/external
+  ${CMAKE_SOURCE_DIR}/src/libraries
+  ${CMAKE_SOURCE_DIR}/src/orxonox
+  ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+################ Sub Directories ################
+
+ADD_SUBDIRECTORY(objects)
+ADD_SUBDIRECTORY(overlays)
+ADD_SUBDIRECTORY(pickup)
+ADD_SUBDIRECTORY(pong)
+ADD_SUBDIRECTORY(questsystem)
+ADD_SUBDIRECTORY(weapons)
Index: /code/branches/rocket2/src/modules/objects/Attacher.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/Attacher.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/Attacher.cc	(revision 6952)
@@ -0,0 +1,125 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Attacher.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(Attacher);
+
+    Attacher::Attacher(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(Attacher);
+
+        this->target_ = 0;
+    }
+
+    void Attacher::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Attacher, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Attacher, "target", setTarget, getTarget, xmlelement, mode);
+        XMLPortObject(Attacher, WorldEntity, "", addObject, getObject, xmlelement, mode);
+    }
+
+    void Attacher::processEvent(Event& event)
+    {
+        if (this->target_)
+            this->target_->processEvent(event);
+    }
+
+    void Attacher::changedActivity()
+    {
+        SUPER(Attacher, changedActivity);
+
+        for (std::list<WorldEntity*>::iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
+            (*it)->setActive(this->isActive());
+    }
+
+    void Attacher::changedVisibility()
+    {
+        SUPER(Attacher, changedVisibility);
+
+        for (std::list<WorldEntity*>::iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
+            (*it)->setVisible(this->isVisible());
+    }
+
+    void Attacher::addObject(WorldEntity* object)
+    {
+        this->objects_.push_back(object);
+
+        this->attach(object);
+    }
+
+    WorldEntity* Attacher::getObject(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::list<WorldEntity*>::const_iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+
+            ++i;
+        }
+        return 0;
+    }
+
+    void Attacher::setTarget(const std::string& target)
+    {
+        this->targetname_ = target;
+        this->target_ = 0;
+
+        if (this->targetname_.empty())
+            return;
+
+        for (ObjectList<WorldEntity>::iterator it = ObjectList<WorldEntity>::begin(); it != ObjectList<WorldEntity>::end(); ++it)
+        {
+            if (it->getName() == this->targetname_)
+            {
+                this->target_ = *it;
+                this->attachToParent(*it);
+            }
+        }
+    }
+
+    void Attacher::loadedNewXMLName(BaseObject* object)
+    {
+        if (this->target_ || this->targetname_.empty())
+            return;
+
+        WorldEntity* entity = orxonox_cast<WorldEntity*>(object);
+        if (entity && entity->getName() == this->targetname_)
+        {
+            this->target_ = entity;
+            this->attachToParent(entity);
+        }
+    }
+}
Index: /code/branches/rocket2/src/modules/objects/Attacher.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/Attacher.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/Attacher.h	(revision 6952)
@@ -0,0 +1,69 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Attacher_H__
+#define _Attacher_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include <list>
+#include <string>
+#include "core/XMLNameListener.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _ObjectsExport Attacher : public StaticEntity, public XMLNameListener
+    {
+        public:
+            Attacher(BaseObject* creator);
+            virtual ~Attacher() {}
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            virtual void processEvent(Event& event);
+            virtual void changedActivity();
+            virtual void changedVisibility();
+
+            void addObject(WorldEntity* object);
+            WorldEntity* getObject(unsigned int index) const;
+
+            void setTarget(const std::string& target);
+            inline const std::string& getTarget() const
+                { return this->targetname_; }
+
+            void loadedNewXMLName(BaseObject* object);
+
+        private:
+            WorldEntity* target_;
+            std::string targetname_;
+            std::list<WorldEntity*> objects_;
+    };
+}
+
+#endif /* _Attacher_H__ */
Index: /code/branches/rocket2/src/modules/objects/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/objects/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,22 @@
+SET_SOURCE_FILES(OBJECTS_SRC_FILES
+  Attacher.cc
+  ForceField.cc
+  Planet.cc
+  Script.cc
+)
+
+ADD_SUBDIRECTORY(collisionshapes)
+ADD_SUBDIRECTORY(eventsystem)
+ADD_SUBDIRECTORY(triggers)
+
+ORXONOX_ADD_LIBRARY(objects
+  MODULE
+  FIND_HEADER_FILES
+  PCH_FILE
+    ObjectsPrecompiledHeaders.h
+  DEFINE_SYMBOL
+    "OBJECTS_SHARED_BUILD"
+  LINK_LIBRARIES
+    orxonox
+  SOURCE_FILES ${OBJECTS_SRC_FILES}
+)
Index: /code/branches/rocket2/src/modules/objects/ForceField.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/ForceField.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/ForceField.cc	(revision 6952)
@@ -0,0 +1,87 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Aurelian Jaggi
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ForceField.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "worldentities/MobileEntity.h"
+
+namespace orxonox
+{
+    CreateFactory(ForceField);
+
+    ForceField::ForceField(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(ForceField);
+
+        //Standard Values
+        this->setDirection(Vector3::ZERO);
+        velocity_ = 100;
+        diameter_ = 500;
+        length_ = 5000;
+    }
+
+    ForceField::~ForceField() {}
+
+    void ForceField::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(ForceField, XMLPort, xmlelement, mode);
+
+        //For correct xml import use: position, direction, velocity, scale
+        XMLPortParam(ForceField, "velocity", setVelocity, getVelocity, xmlelement, mode).defaultValues(100);
+        XMLPortParam(ForceField, "diameter", setDiameter, getDiameter, xmlelement, mode).defaultValues(500);
+        XMLPortParam(ForceField, "length"  , setLength  , getLength  , xmlelement, mode).defaultValues(2000);
+    }
+
+    void ForceField::tick(float dt)
+    {
+        for (ObjectList<MobileEntity>::iterator it = ObjectList<MobileEntity>::begin(); it != ObjectList<MobileEntity>::end(); ++it)
+        {
+            //calculate from
+            Vector3 directionVec = this->getOrientation() * WorldEntity::FRONT;
+            directionVec.normalise();
+
+            Vector3 distanceVec = it->getWorldPosition() - (this->getWorldPosition() + (this->length_ / 2 * directionVec));
+
+            //distance from centervector of the field (
+            float distFromCenterVec = ((it->getWorldPosition() - this->getWorldPosition()).crossProduct(directionVec)).length();
+
+            if (distanceVec.length() < this->length_ / 2 && distFromCenterVec < diameter_ / 2)
+            {
+                //normalize distance from center
+                it->applyCentralForce(((diameter_ / 2 - distFromCenterVec) / (diameter_ / 2)) * directionVec * velocity_);
+            }
+        }
+    }
+}
+
+
+
+
+
Index: /code/branches/rocket2/src/modules/objects/ForceField.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/ForceField.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/ForceField.h	(revision 6952)
@@ -0,0 +1,74 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Aurelian Jaggi
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#ifndef _ForceField_H__
+#define _ForceField_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include "tools/interfaces/Tickable.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _ObjectsExport ForceField : public StaticEntity, public Tickable
+    {
+    public:
+        ForceField(BaseObject* creator);
+        virtual ~ForceField();
+        virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+        virtual void tick(float dt);
+
+        inline void setVelocity(float vel)
+            { this->velocity_ = vel; }
+
+        inline float getVelocity()
+            { return velocity_; }
+
+        inline void setDiameter(float diam)
+            { this->diameter_ = diam; }
+
+        inline float getDiameter()
+            { return diameter_; }
+
+        inline void setLength(float l)
+            { this->length_ = l; }
+
+        inline float getLength()
+            { return length_; }
+
+    private:
+        float velocity_;
+        float diameter_;
+        float length_;
+  };
+}
+
+#endif
+
Index: /code/branches/rocket2/src/modules/objects/ObjectsPrecompiledHeaders.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/ObjectsPrecompiledHeaders.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/ObjectsPrecompiledHeaders.h	(revision 6952)
@@ -0,0 +1,64 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Compilation of the most often used header files in the objects module
+@details
+    Updated: 19. September 2009
+    Total Files: 15
+*/
+
+#include "OrxonoxConfig.h"
+
+///////////////////////////////////////////
+/////          Stable Headers         /////
+///////////////////////////////////////////
+
+#include <LinearMath/btTransform.h> // 11
+
+///////////////////////////////////////////
+/////       All Rebuild Headers       /////
+///////////////////////////////////////////
+
+#include "core/BaseObject.h"   // 15
+#include "core/CoreIncludes.h" // 15
+#include "core/XMLPort.h"      // 13
+
+///////////////////////////////////////////
+/////      Not so Stable Headers      /////
+///////////////////////////////////////////
+
+#include "network/synchronisable/Synchronisable.h" // 11
+//#include "orxonox/worldentities/StaticEntity.h" // 7
+
+
+// Just in case some header included windows.h
+#undef min
+#undef max
Index: /code/branches/rocket2/src/modules/objects/ObjectsPrereqs.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/ObjectsPrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/ObjectsPrereqs.h	(revision 6952)
@@ -0,0 +1,97 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Shared library macros, enums, constants and forward declarations for the objects module
+*/
+
+#ifndef _ObjectsPrereqs_H__
+#define _ObjectsPrereqs_H__
+
+#include "OrxonoxConfig.h"
+#include "OrxonoxPrereqs.h"
+
+//-----------------------------------------------------------------------
+// Shared library settings
+//-----------------------------------------------------------------------
+
+#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined(ORXONOX_STATIC_BUILD)
+#  ifdef OBJECTS_SHARED_BUILD
+#    define _ObjectsExport __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define _ObjectsExport
+#    else
+#      define _ObjectsExport __declspec(dllimport)
+#    endif
+#  endif
+#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _ObjectsExport  __attribute__ ((visibility("default")))
+#else
+#  define _ObjectsExport
+#endif
+
+//-----------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    class Attacher;
+    class ForceField;
+    class Planet;
+    class Script;
+
+    // collisionshapes
+    class BoxCollisionShape;
+    class ConeCollisionShape;
+    class PlaneCollisionShape;
+    class SphereCollisionShape;
+
+    // eventsystem
+    class EventDispatcher;
+    class EventFilter;
+    class EventListener;
+    class EventName;
+    class EventTarget;
+
+    // triggers
+    class CheckPoint;
+    class DistanceMultiTrigger;
+    class DistanceTrigger;
+    class DistanceTriggerBeacon;
+    class EventMultiTrigger;
+    class EventTrigger;
+    class MultiTrigger;
+    class MultiTriggerContainer;
+    class Trigger;
+}
+
+#endif /* _ObjectsPrereqs_H__ */
Index: /code/branches/rocket2/src/modules/objects/Planet.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/Planet.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/Planet.cc	(revision 6952)
@@ -0,0 +1,181 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Marian Runo
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Planet.h"
+
+#include <OgreEntity.h>
+#include <OgreBillboardSet.h>
+#include <OgreProgressiveMesh.h>
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+#include "graphics/Camera.h"
+#include "CameraManager.h"
+
+namespace orxonox
+{
+    CreateFactory(Planet);
+
+    /**
+     * @brief Constructor
+     */
+    Planet::Planet(BaseObject* creator) : MovableEntity(creator)
+    {
+        RegisterObject(Planet);
+        this->registerVariables();
+    }
+
+    /**
+     * @brief Destructor
+     */
+    Planet::~Planet()
+    {
+        if (this->isInitialized() && this->mesh_.getEntity())
+            this->detachOgreObject(this->mesh_.getEntity());
+    }
+
+    void Planet::tick(float dt)
+    {
+        if (!this->isVisible())
+            return;
+
+        if (GameMode::showsGraphics())
+        {
+            Camera* activeCamera = CameraManager::getInstance().getActiveCamera();
+            if (activeCamera)
+            {
+                float distance = this->getPosition().distance( activeCamera->getWorldPosition() );
+                //             COUT(2) << distance << std::endl;
+                float planetRadius = this->getScale();
+
+                float newScale = 2 * distance / sqrt(distance*distance - planetRadius*planetRadius);
+                float tempTest = newScale*(1+float(this->atmosphereSize)/float(this->imageSize));
+                newScale = tempTest;
+
+                this->billboard_.getBillboardSet()->setDefaultDimensions(newScale, newScale);
+            }
+        }
+
+        SUPER(Planet, tick, dt);
+    }
+
+    void Planet::init()
+    {
+        float scaleFactor = this->getScale();
+
+#if OGRE_VERSION >= 0x010700
+        Ogre::Mesh::LodValueList distList;
+#else
+        Ogre::Mesh::LodDistanceList distList;
+#endif
+
+        distList.push_back(10.0f*scaleFactor);
+        distList.push_back(19.0f*scaleFactor);
+        distList.push_back(27.0f*scaleFactor);
+        distList.push_back(34.0f*scaleFactor);
+        distList.push_back(40.0f*scaleFactor);
+        distList.push_back(45.0f*scaleFactor);
+        distList.push_back(49.0f*scaleFactor);
+        distList.push_back(52.0f*scaleFactor);
+        distList.push_back(54.0f*scaleFactor);
+        distList.push_back(55.0f*scaleFactor);
+
+        float reductionValue = 0.2f;
+
+        this->mesh_.getEntity()->getMesh()->generateLodLevels(distList, Ogre::ProgressiveMesh::VRQ_PROPORTIONAL, reductionValue);
+        billboard_.setBillboardSet(this->getScene()->getSceneManager(), this->atmosphere_, Vector3(0,0,0));
+
+        this->attachOgreObject(this->billboard_.getBillboardSet());
+        this->billboard_.getBillboardSet()->setUseAccurateFacing(true);
+        this->setCastShadows(true);
+        this->billboard_.getBillboardSet()->setRenderQueueGroup(this->mesh_.getEntity()->getRenderQueueGroup());
+        this->mesh_.setCastShadows(true);
+    }
+
+    void Planet::changedMesh()
+    {
+        if (this->mesh_.getEntity())
+            this->detachOgreObject(this->mesh_.getEntity());
+
+        this->mesh_.setMeshSource(this->getScene()->getSceneManager(), this->meshSrc_);
+
+        if (this->mesh_.getEntity())
+        {
+            this->attachOgreObject(this->mesh_.getEntity());
+            this->mesh_.getEntity()->setCastShadows(this->bCastShadows_);
+            this->mesh_.setVisible(this->isVisible());
+        }
+        this->init();
+    }
+
+    void Planet::changedShadows()
+    {
+        this->mesh_.setCastShadows(this->bCastShadows_);
+    }
+
+    /**
+        @brief XML loading and saving.
+        @param xmlelement The XML-element
+        @param loading Loading (true) or saving (false)
+        @return The XML-element
+    */
+    void Planet::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Planet, XMLPort, xmlelement, mode);
+
+        if (GameMode::showsGraphics())
+        {
+            XMLPortParam(Planet, "atmosphere", setAtmosphere, getAtmosphere, xmlelement, mode).defaultValues("planet/Atmosphere");
+            XMLPortParam(Planet, "atmospheresize", setAtmosphereSize, getAtmosphereSize, xmlelement,mode);
+            XMLPortParam(Planet, "imagesize", setImageSize, getImageSize, xmlelement,mode);
+            XMLPortParam(Planet, "mesh", setMeshSource, getMeshSource, xmlelement, mode);
+            XMLPortParam(Planet, "shadow", setCastShadows, getCastShadows, xmlelement, mode).defaultValues(true);
+        }
+    }
+
+    void Planet::registerVariables()
+    {
+        registerVariable(this->atmosphere_, VariableDirection::ToClient);
+        registerVariable(this->meshSrc_, VariableDirection::ToClient, new NetworkCallback<Planet>(this, &Planet::changedMesh));
+        registerVariable(this->bCastShadows_, VariableDirection::ToClient, new NetworkCallback<Planet>(this, &Planet::changedShadows));
+        registerVariable(this->atmosphereSize, VariableDirection::ToClient);
+        registerVariable(this->imageSize, VariableDirection::ToClient);
+    }
+
+    void Planet::changedVisibility()
+    {
+        SUPER(Planet, changedVisibility);
+        if (this->isInitialized())
+        {
+            this->mesh_.setVisible(this->isVisible());
+            this->billboard_.setVisible(this->isVisible());
+        }
+    }
+}
Index: /code/branches/rocket2/src/modules/objects/Planet.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/Planet.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/Planet.h	(revision 6952)
@@ -0,0 +1,115 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Marian Runo
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Planet_H__
+#define _Planet_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include <string>
+#include "tools/BillboardSet.h"
+#include "tools/Mesh.h"
+#include "worldentities/MovableEntity.h"
+
+namespace orxonox
+{
+    class _ObjectsExport Planet : public MovableEntity
+    {
+        public:
+            Planet(BaseObject* creator);
+
+            virtual ~Planet();
+
+            void init();
+            virtual void tick(float dt);
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            virtual void changedVisibility();
+
+            inline void setMeshSource(const std::string& meshname)
+                { this->meshSrc_ = meshname; this->changedMesh(); }
+
+            inline const std::string& getMeshSource() const
+                { return this->meshSrc_; }
+
+            inline void setCastShadows(bool bCastShadows)
+                { this->bCastShadows_ = bCastShadows; this->changedShadows(); }
+
+            inline bool getCastShadows() const
+                { return this->bCastShadows_; }
+
+            inline const std::string& getMesh() const{
+                return this->meshSrc_;
+            }
+
+            inline void setAtmosphereSize(float size){
+                this->atmosphereSize = size;
+            }
+
+            inline float getAtmosphereSize(){
+                return this->atmosphereSize;
+            }
+
+            inline void setAtmosphere(const std::string& atmosphere){
+                this->atmosphere_ = atmosphere;
+            }
+
+            inline const std::string& getAtmosphere(){
+                return this->atmosphere_;
+            }
+
+            inline void setImageSize(float size){
+                this->imageSize = size;
+            }
+
+            inline float getImageSize(){
+                return this->imageSize;
+            }
+
+        protected:
+            void registerVariables();
+
+        private:
+
+            void changedMesh();
+            void changedShadows();
+
+            std::string meshSrc_;
+            std::string atmosphere_;
+            Mesh mesh_;
+            float atmosphereSize;
+            float imageSize;
+            BillboardSet billboard_;
+            bool bCastShadows_;
+
+    };
+}
+
+#endif
+
Index: /code/branches/rocket2/src/modules/objects/Script.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/Script.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/Script.cc	(revision 6952)
@@ -0,0 +1,64 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Script.h"
+
+#include "core/CoreIncludes.h"
+#include "core/LuaState.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(Script);
+
+    Script::Script(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(Script);
+
+        // Get a new LuaState
+        luaState_ = new LuaState();
+    }
+
+    Script::~Script()
+    {
+        if (this->isInitialized())
+            delete luaState_;
+    }
+
+    void Script::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        BaseObject::XMLPort(xmlelement, mode);
+
+        XMLPortParam(Script, "code", setCode, getCode, xmlelement, mode);
+    }
+
+    void Script::execute()
+    {
+        luaState_->doString(code_);
+    }
+}
Index: /code/branches/rocket2/src/modules/objects/Script.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/Script.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/Script.h	(revision 6952)
@@ -0,0 +1,56 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Script_H__
+#define _Script_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include <string>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _ObjectsExport Script : public BaseObject
+    {
+    public:
+        Script(BaseObject* creator);
+        ~Script();
+        void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+        void execute();
+
+        void setCode(const std::string& code) { code_ = code; }
+        const std::string& getCode() const { return code_; }
+
+    private:
+        std::string code_;
+        LuaState* luaState_;
+    };
+}
+
+#endif /* _Script_H__ */
Index: /code/branches/rocket2/src/modules/objects/collisionshapes/BoxCollisionShape.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/collisionshapes/BoxCollisionShape.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/collisionshapes/BoxCollisionShape.cc	(revision 6952)
@@ -0,0 +1,76 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "BoxCollisionShape.h"
+
+#include <BulletCollision/CollisionShapes/btBoxShape.h>
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "tools/BulletConversions.h"
+
+namespace orxonox
+{
+    CreateFactory(BoxCollisionShape);
+
+    BoxCollisionShape::BoxCollisionShape(BaseObject* creator) : CollisionShape(creator)
+    {
+        RegisterObject(BoxCollisionShape);
+
+        this->halfExtents_ = Vector3(1, 1, 1);
+        updateShape();
+
+        this->registerVariables();
+    }
+
+    BoxCollisionShape::~BoxCollisionShape()
+    {
+        if (this->isInitialized())
+            delete this->collisionShape_;
+    }
+
+    void BoxCollisionShape::registerVariables()
+    {
+        registerVariable(this->halfExtents_, VariableDirection::ToClient, new NetworkCallback<CollisionShape>(this, &CollisionShape::updateShape));
+    }
+
+    void BoxCollisionShape::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(BoxCollisionShape, XMLPort, xmlelement, mode);
+
+        XMLPortParam(BoxCollisionShape, "halfExtents",  setHalfExtents,  getHalfExtents,  xmlelement, mode);
+        XMLPortParamLoadOnly(BoxCollisionShape, "width",  setWidth,  xmlelement, mode);
+        XMLPortParamLoadOnly(BoxCollisionShape, "height", setHeight, xmlelement, mode);
+        XMLPortParamLoadOnly(BoxCollisionShape, "length", setLength, xmlelement, mode);
+    }
+
+    btCollisionShape* BoxCollisionShape::createNewShape() const
+    {
+        return new btBoxShape(multi_cast<btVector3>(this->halfExtents_));
+    }
+}
Index: /code/branches/rocket2/src/modules/objects/collisionshapes/BoxCollisionShape.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/collisionshapes/BoxCollisionShape.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/collisionshapes/BoxCollisionShape.h	(revision 6952)
@@ -0,0 +1,75 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _BoxCollisionShape_H__
+#define _BoxCollisionShape_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include "util/Math.h"
+#include "collisionshapes/CollisionShape.h"
+
+namespace orxonox
+{
+    class _ObjectsExport BoxCollisionShape : public CollisionShape
+    {
+        public:
+            BoxCollisionShape(BaseObject* creator);
+            virtual ~BoxCollisionShape();
+
+            void registerVariables();
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            inline void setHalfExtents(const Vector3& extents)
+                { this->halfExtents_ = extents; updateShape(); }
+            inline const Vector3& getHalfExtents() const
+                { return halfExtents_;}
+
+            inline void setWidth(float value)
+                { this->halfExtents_.z = value / 2; updateShape(); }
+            inline float getWidth() const
+                { return this->halfExtents_.z * 2; }
+
+            inline void setHeight(float value)
+                { this->halfExtents_.y = value / 2; updateShape(); }
+            inline float getHeight() const
+                { return this->halfExtents_.y * 2; }
+
+            inline void setLength(float value)
+                { this->halfExtents_.x = value / 2; updateShape(); }
+            inline float getLength() const
+                { return this->halfExtents_.x * 2; }
+
+        private:
+            btCollisionShape* createNewShape() const;
+
+            Vector3 halfExtents_;
+     };
+}
+
+#endif /* _BoxCollisionShape_H__ */
Index: /code/branches/rocket2/src/modules/objects/collisionshapes/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/objects/collisionshapes/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/collisionshapes/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,6 @@
+ADD_SOURCE_FILES(OBJECTS_SRC_FILES
+  BoxCollisionShape.cc
+  ConeCollisionShape.cc
+  PlaneCollisionShape.cc
+  SphereCollisionShape.cc
+)
Index: /code/branches/rocket2/src/modules/objects/collisionshapes/ConeCollisionShape.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/collisionshapes/ConeCollisionShape.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/collisionshapes/ConeCollisionShape.cc	(revision 6952)
@@ -0,0 +1,75 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ConeCollisionShape.h"
+
+#include <BulletCollision/CollisionShapes/btConeShape.h>
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(ConeCollisionShape);
+
+    ConeCollisionShape::ConeCollisionShape(BaseObject* creator) : CollisionShape(creator)
+    {
+        RegisterObject(ConeCollisionShape);
+
+        this->radius_ = 1.0f;
+        this->height_ = 1.0f;
+        updateShape();
+
+        this->registerVariables();
+    }
+
+    ConeCollisionShape::~ConeCollisionShape()
+    {
+        if (this->isInitialized())
+            delete this->collisionShape_;
+    }
+
+    void ConeCollisionShape::registerVariables()
+    {
+        registerVariable(this->radius_, VariableDirection::ToClient, new NetworkCallback<CollisionShape>(this, &CollisionShape::updateShape));
+        registerVariable(this->height_, VariableDirection::ToClient, new NetworkCallback<CollisionShape>(this, &CollisionShape::updateShape));
+    }
+
+    void ConeCollisionShape::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(ConeCollisionShape, XMLPort, xmlelement, mode);
+
+        XMLPortParam(ConeCollisionShape, "radius", setRadius, getRadius, xmlelement, mode);
+        XMLPortParam(ConeCollisionShape, "height", setHeight, getHeight, xmlelement, mode);
+    }
+
+    btCollisionShape* ConeCollisionShape::createNewShape() const
+    {
+        return new btConeShape(this->radius_, this->height_);
+    }
+}
Index: /code/branches/rocket2/src/modules/objects/collisionshapes/ConeCollisionShape.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/collisionshapes/ConeCollisionShape.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/collisionshapes/ConeCollisionShape.h	(revision 6952)
@@ -0,0 +1,64 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ConeCollisionShape_H__
+#define _ConeCollisionShape_H__
+
+#include "objects/ObjectsPrereqs.h"
+#include "collisionshapes/CollisionShape.h"
+
+namespace orxonox
+{
+    class _ObjectsExport ConeCollisionShape : public CollisionShape
+    {
+        public:
+            ConeCollisionShape(BaseObject* creator);
+            virtual ~ConeCollisionShape();
+
+            void registerVariables();
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            inline void setRadius(float value)
+                { this->radius_ = value; updateShape(); }
+            inline float getRadius() const
+                { return radius_; }
+
+            inline void setHeight(float value)
+                { this->height_ = value; updateShape(); }
+            inline float getHeight() const
+                { return this->height_; }
+
+        private:
+            btCollisionShape* createNewShape() const;
+
+            float radius_;
+            float height_;
+     };
+}
+
+#endif /* _ConeCollisionShape_H__ */
Index: /code/branches/rocket2/src/modules/objects/collisionshapes/PlaneCollisionShape.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/collisionshapes/PlaneCollisionShape.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/collisionshapes/PlaneCollisionShape.cc	(revision 6952)
@@ -0,0 +1,76 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Stypinski
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "PlaneCollisionShape.h"
+
+#include <BulletCollision/CollisionShapes/btStaticPlaneShape.h>
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "tools/BulletConversions.h"
+
+namespace orxonox
+{
+    CreateFactory(PlaneCollisionShape);
+
+    PlaneCollisionShape::PlaneCollisionShape(BaseObject* creator) : CollisionShape(creator)
+    {
+        RegisterObject(PlaneCollisionShape);
+
+        this->normal_ = Vector3(0, 1, 0);
+        this->offset_ = 0.0f;
+        updateShape();
+
+        this->registerVariables();
+    }
+
+    PlaneCollisionShape::~PlaneCollisionShape()
+    {
+        if (this->isInitialized())
+            delete this->collisionShape_;
+    }
+
+    void PlaneCollisionShape::registerVariables()
+    {
+        registerVariable(this->normal_, VariableDirection::ToClient, new NetworkCallback<CollisionShape>(this, &CollisionShape::updateShape));
+        registerVariable(this->offset_, VariableDirection::ToClient, new NetworkCallback<CollisionShape>(this, &CollisionShape::updateShape));
+    }
+
+    void PlaneCollisionShape::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(PlaneCollisionShape, XMLPort, xmlelement, mode);
+
+        XMLPortParam(PlaneCollisionShape, "normal", setNormal, getNormal, xmlelement, mode);
+        XMLPortParam(PlaneCollisionShape, "offset", setOffset, getOffset, xmlelement, mode);
+    }
+
+    btCollisionShape* PlaneCollisionShape::createNewShape() const
+    {
+        return new btStaticPlaneShape(multi_cast<btVector3>(this->normal_), this->offset_);
+    }
+}
Index: /code/branches/rocket2/src/modules/objects/collisionshapes/PlaneCollisionShape.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/collisionshapes/PlaneCollisionShape.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/collisionshapes/PlaneCollisionShape.h	(revision 6952)
@@ -0,0 +1,66 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Stypinski
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PlaneCollisionShape_H__
+#define _PlaneCollisionShape_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include "util/Math.h"
+#include "collisionshapes/CollisionShape.h"
+
+namespace orxonox
+{
+    class _ObjectsExport PlaneCollisionShape : public CollisionShape
+    {
+        public:
+            PlaneCollisionShape(BaseObject* creator);
+            virtual ~PlaneCollisionShape();
+
+            void registerVariables();
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            inline void setNormal(const Vector3& normal)
+                { this->normal_ = normal; updateShape(); }
+            inline const Vector3& getNormal()
+                { return normal_;}
+
+            inline void setOffset(float offset)
+                { this->offset_ = offset; updateShape(); }
+            inline float getOffset()
+                { return this->offset_;}
+
+        private:
+            btCollisionShape* createNewShape()const;
+
+            Vector3 normal_;
+            float   offset_;
+     };
+}
+
+#endif /* _PlaneCollisionShape_H__ */
Index: /code/branches/rocket2/src/modules/objects/collisionshapes/SphereCollisionShape.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/collisionshapes/SphereCollisionShape.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/collisionshapes/SphereCollisionShape.cc	(revision 6952)
@@ -0,0 +1,72 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "SphereCollisionShape.h"
+
+#include <BulletCollision/CollisionShapes/btSphereShape.h>
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(SphereCollisionShape);
+
+    SphereCollisionShape::SphereCollisionShape(BaseObject* creator) : CollisionShape(creator)
+    {
+        RegisterObject(SphereCollisionShape);
+
+        this->radius_ = 1.0f;
+        updateShape();
+
+        this->registerVariables();
+    }
+
+    SphereCollisionShape::~SphereCollisionShape()
+    {
+        if (this->isInitialized())
+            delete this->collisionShape_;
+    }
+
+    void SphereCollisionShape::registerVariables()
+    {
+        registerVariable(this->radius_, VariableDirection::ToClient, new NetworkCallback<CollisionShape>(this, &CollisionShape::updateShape));
+    }
+
+    void SphereCollisionShape::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(SphereCollisionShape, XMLPort, xmlelement, mode);
+
+        XMLPortParam(SphereCollisionShape, "radius", setRadius, getRadius, xmlelement, mode);
+    }
+
+    btCollisionShape* SphereCollisionShape::createNewShape() const
+    {
+        return new btSphereShape(this->radius_);
+    }
+}
Index: /code/branches/rocket2/src/modules/objects/collisionshapes/SphereCollisionShape.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/collisionshapes/SphereCollisionShape.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/collisionshapes/SphereCollisionShape.h	(revision 6952)
@@ -0,0 +1,58 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _SphereCollisionShape_H__
+#define _SphereCollisionShape_H__
+
+#include "objects/ObjectsPrereqs.h"
+#include "collisionshapes/CollisionShape.h"
+
+namespace orxonox
+{
+    class _ObjectsExport SphereCollisionShape : public CollisionShape
+    {
+        public:
+            SphereCollisionShape(BaseObject* creator);
+            virtual ~SphereCollisionShape();
+
+            void registerVariables();
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            inline void setRadius(float radius)
+                { this->radius_ = radius; updateShape(); }
+            inline float getRadius() const
+                { return this->radius_; }
+
+        private:
+            btCollisionShape* createNewShape() const;
+
+            float radius_;
+    };
+}
+
+#endif /* _SphereCollisionShape_H__ */
Index: /code/branches/rocket2/src/modules/objects/eventsystem/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/objects/eventsystem/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/eventsystem/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,7 @@
+ADD_SOURCE_FILES(OBJECTS_SRC_FILES
+  EventDispatcher.cc
+  EventFilter.cc
+  EventListener.cc
+  EventName.cc
+  EventTarget.cc
+)
Index: /code/branches/rocket2/src/modules/objects/eventsystem/EventDispatcher.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/eventsystem/EventDispatcher.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/eventsystem/EventDispatcher.cc	(revision 6952)
@@ -0,0 +1,83 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "EventDispatcher.h"
+
+#include "core/CoreIncludes.h"
+#include "core/EventIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(EventDispatcher);
+
+    EventDispatcher::EventDispatcher(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(EventDispatcher);
+    }
+
+    EventDispatcher::~EventDispatcher()
+    {
+        if (this->isInitialized())
+            for (std::list<BaseObject*>::iterator it = this->targets_.begin(); it != this->targets_.end(); ++it)
+                (*it)->destroy();
+    }
+
+    void EventDispatcher::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(EventDispatcher, XMLPort, xmlelement, mode);
+
+        XMLPortObject(EventDispatcher, BaseObject, "targets", addTarget, getTarget, xmlelement, mode);
+
+        // since we need event sources mapped to any state, we have to parse XML by ourselves
+        this->loadAllEventStates(xmlelement, mode, this, Class(EventDispatcher));
+    }
+
+    void EventDispatcher::processEvent(Event& event)
+    {
+        for (std::list<BaseObject*>::iterator it = this->targets_.begin(); it != this->targets_.end(); ++it)
+            (*it)->processEvent(event);
+    }
+
+    void EventDispatcher::addTarget(BaseObject* target)
+    {
+        this->targets_.push_back(target);
+    }
+
+    BaseObject* EventDispatcher::getTarget(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::list<BaseObject*>::const_iterator it = this->targets_.begin(); it != this->targets_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+            ++i;
+        }
+        return 0;
+    }
+}
Index: /code/branches/rocket2/src/modules/objects/eventsystem/EventDispatcher.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/eventsystem/EventDispatcher.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/eventsystem/EventDispatcher.h	(revision 6952)
@@ -0,0 +1,57 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _EventDispatcher_H__
+#define _EventDispatcher_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include <list>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _ObjectsExport EventDispatcher : public BaseObject
+    {
+        public:
+            EventDispatcher(BaseObject* creator);
+            virtual ~EventDispatcher();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            virtual void processEvent(Event& event);
+
+            void addTarget(BaseObject* target);
+            BaseObject* getTarget(unsigned int index) const;
+
+        private:
+            std::list<BaseObject*> targets_;
+    };
+}
+
+#endif /* _EventDispatcher_H__ */
Index: /code/branches/rocket2/src/modules/objects/eventsystem/EventFilter.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/eventsystem/EventFilter.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/eventsystem/EventFilter.cc	(revision 6952)
@@ -0,0 +1,122 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "EventFilter.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "EventName.h"
+
+namespace orxonox
+{
+    CreateFactory(EventFilter);
+
+    EventFilter::EventFilter(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(EventFilter);
+
+        this->bActive_ = false;
+    }
+
+    EventFilter::~EventFilter()
+    {
+        for (std::list<EventName*>::const_iterator it = this->names_.begin(); it != this->names_.end(); )
+            (*(it++))->destroy();
+    }
+
+    void EventFilter::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(EventFilter, XMLPort, xmlelement, mode);
+
+        XMLPortObject(EventFilter, BaseObject, "", addFilterSource, getFilterSource, xmlelement, mode);
+        XMLPortObject(EventFilter, EventName, "names", addEventName, getEventName, xmlelement, mode);
+    }
+
+    void EventFilter::processEvent(Event& event)
+    {
+        if (this->bActive_)
+        {
+            COUT(2) << "Warning: Detected Event loop in EventFilter \"" << this->getName() << '"' << std::endl;
+            return;
+        }
+
+        if (this->names_.size() > 0)
+        {
+            bool success = false;
+            for (std::list<EventName*>::const_iterator it = this->names_.begin(); it != this->names_.end(); ++it)
+            {
+                if ((*it)->getName() == event.name_)
+                {
+                    success = true;
+                    break;
+                }
+            }
+            if (!success)
+                return;
+        }
+
+        this->bActive_ = true;
+        this->fireEvent(event.activate_, event.originator_, event.name_);
+        this->bActive_ = false;
+    }
+
+    void EventFilter::addFilterSource(BaseObject* source)
+    {
+        this->sources_.push_back(source);
+        this->addEventSource(source, "");
+    }
+
+    BaseObject* EventFilter::getFilterSource(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::list<BaseObject*>::const_iterator it = this->sources_.begin(); it != this->sources_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+            ++i;
+        }
+        return 0;
+    }
+
+    void EventFilter::addEventName(EventName* eventname)
+    {
+        this->names_.push_back(eventname);
+    }
+
+    EventName* EventFilter::getEventName(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::list<EventName*>::const_iterator it = this->names_.begin(); it != this->names_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+            ++i;
+        }
+        return 0;
+    }
+}
Index: /code/branches/rocket2/src/modules/objects/eventsystem/EventFilter.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/eventsystem/EventFilter.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/eventsystem/EventFilter.h	(revision 6952)
@@ -0,0 +1,62 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _EventFilter_H__
+#define _EventFilter_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include <list>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _ObjectsExport EventFilter : public BaseObject
+    {
+        public:
+            EventFilter(BaseObject* creator);
+            virtual ~EventFilter();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            virtual void processEvent(Event& event);
+
+            void addFilterSource(BaseObject* source);
+            BaseObject* getFilterSource(unsigned int index) const;
+
+            void addEventName(EventName* eventname);
+            EventName* getEventName(unsigned int index) const;
+
+        private:
+            std::list<BaseObject*> sources_;
+            std::list<EventName*> names_;
+            bool bActive_;
+    };
+}
+
+#endif /* _EventFilter_H__ */
Index: /code/branches/rocket2/src/modules/objects/eventsystem/EventListener.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/eventsystem/EventListener.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/eventsystem/EventListener.cc	(revision 6952)
@@ -0,0 +1,92 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "EventListener.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(EventListener);
+
+    EventListener::EventListener(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(EventListener);
+
+        this->bActive_ = false;
+    }
+
+    EventListener::~EventListener()
+    {
+    }
+
+    void EventListener::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(EventListener, XMLPort, xmlelement, mode);
+
+        XMLPortParam(EventListener, "event", setEventName, getEventName, xmlelement, mode);
+    }
+
+    void EventListener::processEvent(Event& event)
+    {
+        if (this->bActive_)
+        {
+            COUT(2) << "Warning: Detected Event loop in EventListener \"" << this->getName() << '"' << std::endl;
+            return;
+        }
+        
+        COUT(4) << "EventListener, processing event: originator: " << event.originator_->getIdentifier()->getName() << " (&" << event.originator_ << ")" << ", activate: " << event.activate_ << ", name: " << event.name_ << std::endl;
+
+        this->bActive_ = true;
+        //TODO: Why not this->fireEvent(event)?
+        this->fireEvent(event.activate_, event.originator_, event.name_);
+        this->bActive_ = false;
+    }
+
+    void EventListener::setEventName(const std::string& eventname)
+    {
+        this->eventName_ = eventname;
+
+        if (this->eventName_.empty())
+            return;
+
+        for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it != ObjectList<BaseObject>::end(); ++it)
+            if (it->getName() == this->eventName_)
+                this->addEventSource(*it, "");
+    }
+
+    void EventListener::loadedNewXMLName(BaseObject* object)
+    {
+        if (this->eventName_.empty())
+            return;
+
+        if (object->getName() == this->eventName_)
+            this->addEventSource(object, "");
+    }
+}
Index: /code/branches/rocket2/src/modules/objects/eventsystem/EventListener.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/eventsystem/EventListener.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/eventsystem/EventListener.h	(revision 6952)
@@ -0,0 +1,62 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _EventListener_H__
+#define _EventListener_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include <string>
+#include "core/BaseObject.h"
+#include "core/XMLNameListener.h"
+
+namespace orxonox
+{
+    class _ObjectsExport EventListener : public BaseObject, public XMLNameListener
+    {
+        public:
+            EventListener(BaseObject* creator);
+            virtual ~EventListener();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            virtual void processEvent(Event& event);
+
+            void setEventName(const std::string& eventname);
+            inline const std::string& getEventName() const
+                { return this->eventName_; }
+
+        private:
+            virtual void loadedNewXMLName(BaseObject* object);
+
+            std::string eventName_;
+            bool bActive_;
+    };
+}
+
+#endif /* _EventListener_H__ */
Index: /code/branches/rocket2/src/modules/objects/eventsystem/EventName.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/eventsystem/EventName.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/eventsystem/EventName.cc	(revision 6952)
@@ -0,0 +1,40 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "EventName.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    CreateFactory(EventName);
+
+    EventName::EventName(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(EventName);
+    }
+}
Index: /code/branches/rocket2/src/modules/objects/eventsystem/EventName.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/eventsystem/EventName.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/eventsystem/EventName.h	(revision 6952)
@@ -0,0 +1,46 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _EventName_H__
+#define _EventName_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _ObjectsExport EventName : public BaseObject
+    {
+        public:
+            EventName(BaseObject* creator);
+            virtual ~EventName() {}
+    };
+}
+
+#endif /* _EventName_H__ */
Index: /code/branches/rocket2/src/modules/objects/eventsystem/EventTarget.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/eventsystem/EventTarget.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/eventsystem/EventTarget.cc	(revision 6952)
@@ -0,0 +1,94 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "EventTarget.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(EventTarget);
+
+    EventTarget::EventTarget(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(EventTarget);
+
+        this->bActive_ = false;
+    }
+
+    EventTarget::~EventTarget()
+    {
+    }
+
+    void EventTarget::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(EventTarget, XMLPort, xmlelement, mode);
+
+        XMLPortParam(EventTarget, "target", setTargetName, getTargetName, xmlelement, mode);
+
+        // since we need event sources mapped to any state, we have to parse XML by ourselves
+        this->loadAllEventStates(xmlelement, mode, this, Class(EventTarget));
+    }
+
+    void EventTarget::processEvent(Event& event)
+    {
+        if (this->bActive_)
+        {
+            COUT(2) << "Warning: Detected Event loop in EventTarget \"" << this->getName() << '"' << std::endl;
+            return;
+        }
+
+        this->bActive_ = true;
+        this->fireEvent(event);
+        this->bActive_ = false;
+    }
+
+    void EventTarget::setTargetName(const std::string& name)
+    {
+        this->target_ = name;
+
+        for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it != ObjectList<BaseObject>::end(); ++it)
+            if (it->getName() == this->target_)
+                this->addEventTarget(*it);
+    }
+
+    void EventTarget::loadedNewXMLName(BaseObject* object)
+    {
+        if (this->target_.empty())
+            return;
+
+        if (object->getName() == this->target_)
+            this->addEventTarget(object);
+    }
+
+    void EventTarget::addEventTarget(BaseObject* object)
+    {
+        if (object != static_cast<BaseObject*>(this))
+            object->addEventSource(this, "");
+    }
+}
Index: /code/branches/rocket2/src/modules/objects/eventsystem/EventTarget.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/eventsystem/EventTarget.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/eventsystem/EventTarget.h	(revision 6952)
@@ -0,0 +1,62 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _EventTarget_H__
+#define _EventTarget_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include "core/BaseObject.h"
+#include "core/XMLNameListener.h"
+
+namespace orxonox
+{
+    class _ObjectsExport EventTarget : public BaseObject, public XMLNameListener
+    {
+        public:
+            EventTarget(BaseObject* creator);
+            virtual ~EventTarget();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            virtual void processEvent(Event& event);
+
+            void setTargetName(const std::string& name);
+            inline const std::string& getTargetName() const
+                { return this->target_; }
+
+        private:
+            virtual void loadedNewXMLName(BaseObject* object);
+            void addEventTarget(BaseObject* object);
+
+            std::string target_;
+            bool bActive_;
+    };
+}
+
+#endif /* _EventTarget_H__ */
Index: /code/branches/rocket2/src/modules/objects/triggers/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,11 @@
+ADD_SOURCE_FILES(OBJECTS_SRC_FILES
+  CheckPoint.cc
+  DistanceMultiTrigger.cc
+  DistanceTrigger.cc
+  DistanceTriggerBeacon.cc
+  EventMultiTrigger.cc
+  EventTrigger.cc
+  MultiTrigger.cc
+  MultiTriggerContainer.cc
+  Trigger.cc
+)
Index: /code/branches/rocket2/src/modules/objects/triggers/CheckPoint.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/CheckPoint.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/CheckPoint.cc	(revision 6952)
@@ -0,0 +1,122 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Aurelian Jaggi
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "CheckPoint.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "gametypes/Asteroids.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateFactory(CheckPoint);
+
+    CheckPoint::CheckPoint(BaseObject* creator) 
+        : DistanceTrigger(creator)
+        , RadarViewable(creator)
+    {
+        RegisterObject(CheckPoint);
+
+        this->setStayActive(true);
+        this->setDistance(50);
+        this->bIsFirst_ = false;
+        this->bIsDestination_ = false;
+
+        this->setRadarObjectColour(ColourValue::Green);
+        this->setRadarObjectShape(RadarViewable::Dot);
+        this->setRadarVisibility(false);
+
+        this->notifyMaskUpdate();
+    }
+
+    CheckPoint::~CheckPoint()
+    {
+    }
+
+    void CheckPoint::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(CheckPoint, XMLPort, xmlelement, mode);
+
+        XMLPortParam(CheckPoint, "isfirst", setFirst, getFirst, xmlelement, mode).defaultValues(false);
+        XMLPortParam(CheckPoint, "isdestination", setDestination, getDestination, xmlelement, mode).defaultValues(false);
+        XMLPortParam(CheckPoint, "addtime", setAddTime, getAddTime, xmlelement, mode).defaultValues(30);
+    }
+
+    void CheckPoint::changedActivity()
+    {
+        SUPER(CheckPoint, changedActivity);
+
+        if (this->BaseObject::isActive())
+        {
+            this->setRadarVisibility(true);
+        }
+        else
+        {
+            this->setRadarVisibility(false);
+        }
+    }
+
+    void CheckPoint::triggered(bool bIsTriggered)
+    {
+        DistanceTrigger::triggered(bIsTriggered);
+
+        Asteroids* gametype = orxonox_cast<Asteroids*>(this->getGametype().get());
+        if (gametype)
+        {
+            gametype->addTime(addTime_);
+            this->setRadarVisibility(false);
+
+            if (bIsTriggered)
+            {
+                if (bIsFirst_)
+                {
+                    gametype->setTimeLimit(addTime_);
+                    gametype->firstCheckpointReached(true);
+                }
+
+                if (bIsDestination_)
+                {
+                    const_cast<GametypeInfo*>(gametype->getGametypeInfo())->sendAnnounceMessage("Congratulations - you have won the match!");
+                    gametype->end();
+                }
+
+                if (!bIsFirst_ && !bIsDestination_)
+                {
+                    const_cast<GametypeInfo*>(gametype->getGametypeInfo())->sendAnnounceMessage("Checkpoint reached");
+                }
+            }
+        }
+    }
+
+    void CheckPoint::notifyMaskUpdate()
+    {
+        this->targetMask_.exclude(Class(BaseObject));
+        this->targetMask_.include(Class(Pawn));
+    }
+}
Index: /code/branches/rocket2/src/modules/objects/triggers/CheckPoint.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/CheckPoint.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/CheckPoint.h	(revision 6952)
@@ -0,0 +1,84 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Aurelian Jaggi
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief
+*/
+
+#ifndef _CheckPoint_H__
+#define _CheckPoint_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include "interfaces/RadarViewable.h"
+#include "DistanceTrigger.h"
+
+namespace orxonox
+{
+    class _ObjectsExport CheckPoint : public DistanceTrigger, public RadarViewable
+    {
+    public:
+        CheckPoint(BaseObject* creator);
+        virtual ~CheckPoint();
+
+        virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a CheckPoint object through XML.
+        virtual void changedActivity();
+
+    private:
+        virtual void triggered(bool bIsTriggered);
+        virtual void notifyMaskUpdate();
+
+        inline void setDestination(bool isDestination)
+            { bIsDestination_ = isDestination; }
+
+        inline const WorldEntity* getWorldEntity() const
+            { return this; }
+
+        inline bool getDestination()
+            { return bIsDestination_; }
+
+        inline void setFirst(bool isFirst)
+            { this->bIsFirst_ = isFirst; }
+
+        inline bool getFirst()
+            { return this->bIsFirst_; }
+
+        inline void setAddTime(float time)
+            { this->addTime_ = time; }
+
+        inline bool getAddTime()
+            { return this->addTime_; }
+
+        bool bIsFirst_;
+        bool bIsDestination_;
+        float addTime_;
+    };
+}
+
+#endif /* _CheckPoint_H__ */
Index: /code/branches/rocket2/src/modules/objects/triggers/DistanceMultiTrigger.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/DistanceMultiTrigger.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/DistanceMultiTrigger.cc	(revision 6952)
@@ -0,0 +1,172 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+/**
+    @file DistanceMultiTrigger.cc
+    @brief Implementation of the DistanceMultiTrigger class.
+*/
+
+#include "DistanceMultiTrigger.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "DistanceTriggerBeacon.h"
+
+namespace orxonox
+{
+    
+    CreateFactory(DistanceMultiTrigger);
+
+    /**
+    @brief
+        Default Constructor. Registers the object and initializes default values. 
+    */
+    DistanceMultiTrigger::DistanceMultiTrigger(BaseObject* creator) : MultiTrigger(creator)
+    {
+        RegisterObject(DistanceMultiTrigger);
+        
+        this->distance_ = 100.0f;
+        this->targetName_ = BLANKSTRING;
+        this->singleTargetMode_ = false;
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    DistanceMultiTrigger::~DistanceMultiTrigger()
+    {
+    }
+
+    /**
+    @brief
+        Method for creating a DistanceMultiTrigger object through XML.
+    */
+    void DistanceMultiTrigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(DistanceMultiTrigger, XMLPort, xmlelement, mode);
+
+        XMLPortParam(DistanceMultiTrigger, "distance", setDistance, getDistance, xmlelement, mode);
+        XMLPortParam(DistanceMultiTrigger, "targetname", setTargetName, getTargetName, xmlelement, mode);
+    }
+
+    /**
+    @brief
+        This method is called by the MultiTrigger to get information about new trigger events that need to be looked at.
+
+        In this implementation we iterate through all possible objects and check whether the fact that they are in range or not has changed and fire and hand a state ofer to the MultiTrigger if so.
+    */
+    std::queue<MultiTriggerState*>* DistanceMultiTrigger::letTrigger(void)
+    {
+
+        std::queue<MultiTriggerState*>* queue = NULL;
+
+        // Check for objects that were in range but no longer are. Iterate through all objects, that are in range.
+        for(std::map<WorldEntity*, WeakPtr<WorldEntity>* >::iterator it = this->range_.begin(); it != this->range_.end(); )
+        {
+            WorldEntity* entity = it->second->get();
+            WorldEntity* key = it->first;
+            if(entity == NULL)
+            {
+                ++it;
+                this->removeFromRange(key);
+                continue;
+            }
+            
+            Vector3 distanceVec = entity->getWorldPosition() - this->getWorldPosition();
+            // If the object is no longer in range.
+            if (distanceVec.length() > this->distance_)
+            {
+                if(!this->removeFromRange(key))
+                {
+                    ++it;
+                    continue;
+                }
+
+                // If no queue has been created, yet.
+                if(queue == NULL)
+                    queue = new std::queue<MultiTriggerState*>();
+
+                // Create a state and append it to the queue.
+                MultiTriggerState* state = new MultiTriggerState;
+                state->bTriggered = false;
+                state->originator = entity;
+                queue->push(state);
+            }
+            else
+                ++it;
+        }
+
+        ClassTreeMask& targetMask = this->getTargetMask();
+
+        // Check for new objects that are in range
+        for(ClassTreeMaskObjectIterator it = targetMask.begin(); it != targetMask.end(); ++it)
+        {
+            WorldEntity* entity = static_cast<WorldEntity*>(*it);
+            if (entity == NULL) //If the object is no WorldEntity or is already in range.
+                continue;
+
+            // If the DistanceMultiTrigger is in single-target-mode.
+            if(this->singleTargetMode_)
+            {
+                // If the object that is a target is no DistanceTriggerBeacon, then the DistanceMultiTrigger can't be in single-target-mode.
+                if(!(*it)->isA(ClassIdentifier<DistanceTriggerBeacon>::getIdentifier()))
+                    this->singleTargetMode_ = false;
+                // If the target name and the name of the DistancTriggreBeacon don't match.
+                else if(entity->getName().compare(this->targetName_) != 0)
+                    continue;
+            }
+
+            Vector3 distanceVec = entity->getWorldPosition() - this->getWorldPosition();
+            // If the object is in range.
+            if (distanceVec.length() <= this->distance_)
+            {
+                // Add the object to the objects that are in range.
+                if(!this->addToRange(entity))
+                    continue;
+
+                // Change the entity to the parent of the DistanceTriggerBeacon (if in single-target-mode), which is the entity to which the beacon is attached.
+                if(this->singleTargetMode_)
+                    entity = entity->getParent();
+                
+                // If no queue has been created, yet.
+                if(queue == NULL)
+                    queue = new std::queue<MultiTriggerState*>();
+
+                // Create a state and append it to the queue.
+                MultiTriggerState* state = new MultiTriggerState;
+                state->bTriggered = true;
+                state->originator = entity;
+                queue->push(state);
+            }
+        }
+        
+        return queue;
+    }
+    
+}
Index: /code/branches/rocket2/src/modules/objects/triggers/DistanceMultiTrigger.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/DistanceMultiTrigger.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/DistanceMultiTrigger.h	(revision 6952)
@@ -0,0 +1,120 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+/**
+    @file DistanceMultiTrigger.h
+    @brief Definition of the DistanceMultiTrigger class.
+*/
+
+#ifndef _DistanceMultiTrigger_H__
+#define _DistanceMultiTrigger_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include "worldentities/WorldEntity.h"
+#include "core/WeakPtr.h"
+#include <map>
+
+#include "MultiTrigger.h"
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        The DistanceMultiTrigger is a trigger that triggers whenever an object (that is of the specified target type) is in a specified range of the DistanceMultiTrigger. The object can be specified further by adding a DistanceTriggerBeacon (just attaching it) to the objects that can trigger this DistanceMultiTrigger and specify the name of the DistanceTriggerBeacon with the parameter targetname and only objects that hav a DistanceTriggerBeacon with that name attached will trigger the DistanceMultiTrigger.
+    @see MultiTrigger.h
+        For more information on MultiTriggers.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _ObjectsExport DistanceMultiTrigger : public MultiTrigger
+    {
+        
+        public:
+            DistanceMultiTrigger(BaseObject* creator); //!< Default Constructor. Registers the object and initializes default values.
+            ~DistanceMultiTrigger(); //!< Destructor.
+            
+            void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a DistanceMultiTrigger object through XML.
+
+            /**
+            @brief Set the target name of DistanceTriggerBeacons that triggers this DistanceMultiTrigger.
+            @param targename The name of the DistanceTriggerBeacon as a string.
+            */
+            inline void setTargetName(const std::string& targetname)
+                { if(targetname.compare(BLANKSTRING) != 0) this->singleTargetMode_ = true; else this->singleTargetMode_ = false; this->targetName_ = targetname; }
+            /**
+            @brief Get the target name of the DistanceTriggerbeacon, that triggers this DistanceMultiTrigger.
+            @return Returns the target name as a string.
+            */
+            inline const std::string& getTargetName(void)
+                { return this->targetName_; }
+            
+            /**
+            @brief Set the distance at which the DistanceMultiTrigger triggers.
+            @param distance The distance.
+            */
+            inline void setDistance(float distance)
+                { if(distance >= 0) this->distance_ = distance; }
+            /**
+            @brief Get the distance at which the DistanceMultiTrigger triggers.
+            @return Returns the distance.
+            */
+            inline float getDistance() const
+                { return this->distance_; }
+                
+        protected:
+            virtual std::queue<MultiTriggerState*>* letTrigger(void); //!< This method is called by the MultiTrigger to get information about new trigger events that need to be looked at.
+
+            /**
+            @brief Add a given entity to the entities, that currently are in range of the DistanceMultiTrigger.
+            @param entity A pointer to the entity.
+            @return Returns true if successful, false if not.
+            */
+            inline bool addToRange(WorldEntity* entity)
+                { std::pair<std::map<WorldEntity*, WeakPtr<WorldEntity>* >::iterator, bool> pair = this->range_.insert(std::pair<WorldEntity*, WeakPtr<WorldEntity>* >(entity, new WeakPtr<WorldEntity>(entity))); return pair.second; }
+            /**
+            @brief Remove a given entity from the set of entities, that currently are in range of the DistanceMultiTrigger.
+            @param entity A pointer ot the entity.
+            @return Returns true if successful.
+            */
+            inline bool removeFromRange(WorldEntity* entity)
+                { WeakPtr<WorldEntity>* weakptr = this->range_.find(entity)->second; bool erased = this->range_.erase(entity) > 0; if(erased) delete weakptr; return erased; }
+                
+        private:
+            float distance_; //!< The distance at which the DistanceMultiTrigger triggers.
+            std::string targetName_; //!< The target name, used in singleTargetMode.
+            bool singleTargetMode_; //!< To indicate whe the MultiDistanceTrigger is in single-target-mode.
+            
+            std::map<WorldEntity*, WeakPtr<WorldEntity>* > range_; //!< The set of entities that currently are in range of the DistanceMultiTrigger.
+        
+    };
+    
+}
+
+#endif // _DistanceMultiTrigger_H__
Index: /code/branches/rocket2/src/modules/objects/triggers/DistanceTrigger.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/DistanceTrigger.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/DistanceTrigger.cc	(revision 6952)
@@ -0,0 +1,170 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "DistanceTrigger.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "worldentities/pawns/Pawn.h"
+#include "DistanceTriggerBeacon.h"
+
+namespace orxonox
+{
+  CreateFactory(DistanceTrigger);
+
+  DistanceTrigger::DistanceTrigger(BaseObject* creator) : Trigger(creator)
+  {
+    RegisterObject(DistanceTrigger);
+
+    this->distance_ = 100;
+    this->targetMask_.exclude(Class(BaseObject));
+    this->targetName_ = BLANKSTRING;
+    this->singleTargetMode_ = false;
+    this->setForPlayer(false); //!< Normally hasn't just players as targets.
+  }
+
+  DistanceTrigger::~DistanceTrigger()
+  {
+  }
+
+  void DistanceTrigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+  {
+    SUPER(DistanceTrigger, XMLPort, xmlelement, mode);
+
+    XMLPortParam(DistanceTrigger, "distance", setDistance, getDistance, xmlelement, mode).defaultValues(100.0f);
+    XMLPortParamLoadOnly(DistanceTrigger, "target", addTargets, xmlelement, mode).defaultValues("Pawn");
+    XMLPortParam(DistanceTrigger, "targetname", setTargetName, getTargetName, xmlelement, mode);
+  }
+
+  void DistanceTrigger::addTarget(Ogre::Node* targetNode)
+  {
+    this->targetSet_.insert(targetNode);
+  }
+
+  void DistanceTrigger::removeTarget(Ogre::Node* targetNode)
+  {
+    int returnval = this->targetSet_.erase(targetNode);
+    if (returnval == 0)
+    {
+      COUT(2) << "Warning: Node " << targetNode << " did not exist in targetSet of trigger " << this << " !" << std::endl;
+      COUT(4) << "Content of targetSet of trigger " << this << " :" << std::endl;
+      std::set<Ogre::Node*>::iterator it;
+      for (it = this->targetSet_.begin(); it != this->targetSet_.end(); ++it)
+      {
+        COUT(4) << *it << std::endl;
+      }
+      COUT(4) << "End of targetSet of trigger " << this << std::endl;
+    }
+  }
+
+  void DistanceTrigger::addTargets(const std::string& targets)
+  {
+    Identifier* targetId = ClassByString(targets);
+
+    //! Checks whether the target is (or is derived from) a ControllableEntity.
+    Identifier* pawnId = Class(Pawn);
+    Identifier* distanceTriggerBeaconId = Class(DistanceTriggerBeacon);
+    if(targetId->isA(pawnId) || targetId->isA(distanceTriggerBeaconId))
+    {
+      this->setForPlayer(true);
+    }
+
+    if (!targetId)
+    {
+        COUT(1) << "Error: \"" << targets << "\" is not a valid class name to include in ClassTreeMask (in " << this->getName() << ", class " << this->getIdentifier()->getName() << ')' << std::endl;
+        return;
+    }
+
+    this->targetMask_.include(targetId);
+
+    // trigger shouldn't react on itself or other triggers
+    this->targetMask_.exclude(Class(Trigger), true);
+
+    // we only want WorldEntities
+    ClassTreeMask WEMask;
+    WEMask.include(Class(WorldEntity));
+    this->targetMask_ *= WEMask;
+
+    this->notifyMaskUpdate();
+  }
+
+  void DistanceTrigger::removeTargets(const std::string& targets)
+  {
+    Identifier* targetId = ClassByString(targets);
+    this->targetMask_.exclude(targetId);
+  }
+
+  bool DistanceTrigger::checkDistance()
+  {
+    // Iterate through all objects
+    for (ClassTreeMaskObjectIterator it = this->targetMask_.begin(); it != this->targetMask_.end(); ++it)
+    {
+      WorldEntity* entity = orxonox_cast<WorldEntity*>(*it);
+      if (!entity)
+        continue;
+
+      if(this->singleTargetMode_)
+      {
+        if(!(*it)->isA(ClassIdentifier<DistanceTriggerBeacon>::getIdentifier()))
+          this->singleTargetMode_ = false;
+        else if(entity->getName().compare(this->targetName_) != 0)
+          continue;
+      }
+      
+      Vector3 distanceVec = entity->getWorldPosition() - this->getWorldPosition();
+      if (distanceVec.length() < this->distance_)
+      {
+
+        // If the target is a player (resp. is a, or is derived from a, ControllableEntity) the triggeringPlayer is set to the target entity.
+        if(this->isForPlayer())
+        {
+
+          if(this->singleTargetMode_)
+            entity = entity->getParent();
+
+          Pawn* player = orxonox_cast<Pawn*>(entity);
+          this->setTriggeringPlayer(player);
+        }
+
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  bool DistanceTrigger::isTriggered(TriggerMode::Value mode)
+  {
+    if (Trigger::isTriggered(mode))
+    {
+      return checkDistance();
+    }
+    else
+      return false;
+  }
+}
Index: /code/branches/rocket2/src/modules/objects/triggers/DistanceTrigger.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/DistanceTrigger.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/DistanceTrigger.h	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _DistanceTrigger_H__
+#define _DistanceTrigger_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include <set>
+#include "core/ClassTreeMask.h"
+#include "Trigger.h"
+#include "interfaces/PlayerTrigger.h"
+
+namespace orxonox
+{
+  class _ObjectsExport DistanceTrigger : public Trigger, public PlayerTrigger
+  {
+    public:
+      DistanceTrigger(BaseObject* creator);
+      virtual ~DistanceTrigger();
+
+      virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+      void addTarget(Ogre::Node* targetNode);
+      void addTargets(const std::string& targets);
+      void removeTarget(Ogre::Node* targetNode);
+      void removeTargets(const std::string& targets);
+
+      inline void setTargetName(const std::string& targetname)
+        { if(targetname.compare(BLANKSTRING) != 0) this->singleTargetMode_ = true; else this->singleTargetMode_ = false; this->targetName_ = targetname; }
+      inline const std::string& getTargetName(void)
+        { return this->targetName_; }
+
+      inline void setDistance(float distance)
+        { this->distance_ = distance; }
+      inline float getDistance() const
+        { return this->distance_; }
+
+      bool checkDistance();
+
+    protected:
+      virtual bool isTriggered(TriggerMode::Value mode);
+      virtual void notifyMaskUpdate() {}
+
+      ClassTreeMask targetMask_;
+
+    private:
+      std::set<Ogre::Node*> targetSet_;
+      std::string targetName_;
+      float distance_;
+      bool singleTargetMode_;
+
+  };
+}
+
+#endif /* _DistanceTrigger_H__ */
Index: /code/branches/rocket2/src/modules/objects/triggers/DistanceTriggerBeacon.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/DistanceTriggerBeacon.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/DistanceTriggerBeacon.cc	(revision 6952)
@@ -0,0 +1,43 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+#include "DistanceTriggerBeacon.h"
+
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+
+    CreateFactory(DistanceTriggerBeacon);
+    
+    DistanceTriggerBeacon::DistanceTriggerBeacon(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(DistanceTriggerBeacon);
+    }
+    
+}
Index: /code/branches/rocket2/src/modules/objects/triggers/DistanceTriggerBeacon.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/DistanceTriggerBeacon.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/DistanceTriggerBeacon.h	(revision 6952)
@@ -0,0 +1,51 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+#ifndef _DistanceTriggerBeacon_H__
+#define _DistanceTriggerBeacon_H__
+
+#include "objects/ObjectsPrereqs.h"
+#include "core/XMLPort.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+
+    class _ObjectsExport DistanceTriggerBeacon : public StaticEntity
+    {
+        
+        public:
+
+            DistanceTriggerBeacon(BaseObject* creator);
+            ~DistanceTriggerBeacon() {}
+
+    };
+
+}
+
+#endif // _DistanceTriggerBeacon_H__
Index: /code/branches/rocket2/src/modules/objects/triggers/EventMultiTrigger.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/EventMultiTrigger.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/EventMultiTrigger.cc	(revision 6952)
@@ -0,0 +1,72 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file EventMultiTrigger.cc
+    @brief Implementation of the EventMultiTrigger class.
+*/
+
+#include "EventMultiTrigger.h"
+
+#include "core/CoreIncludes.h"
+#include "core/EventIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+
+    CreateFactory(EventMultiTrigger);
+
+    EventMultiTrigger::EventMultiTrigger(BaseObject* creator) : MultiTrigger(creator)
+    {
+        RegisterObject(EventMultiTrigger);
+
+        this->bEventTriggered_ = false;
+    }
+
+    EventMultiTrigger::~EventMultiTrigger()
+    {
+        
+    }
+
+    void EventMultiTrigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(EventMultiTrigger, XMLPort, xmlelement, mode);
+
+        this->setBroadcast(true);
+    }
+    
+    void EventMultiTrigger::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(EventMultiTrigger, XMLEventPort, xmlelement, mode);
+
+        XMLPortEventState(EventMultiTrigger, BaseObject, "trigger", trigger, xmlelement, mode);
+    }
+
+}
+
Index: /code/branches/rocket2/src/modules/objects/triggers/EventMultiTrigger.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/EventMultiTrigger.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/EventMultiTrigger.h	(revision 6952)
@@ -0,0 +1,63 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file EventMultiTrigger.h
+    @brief Definition of the EventMultiTrigger class.
+*/
+
+#ifndef _EventMultiTrigger_H__
+#define _EventMultiTrigger_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include "MultiTrigger.h"
+
+namespace orxonox
+{
+
+    class _ObjectsExport EventMultiTrigger : public MultiTrigger
+    {
+        
+        public:
+            EventMultiTrigger(BaseObject* creator);
+            ~EventMultiTrigger();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating an EventMultiTrigger object through XML.
+            virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
+
+            inline void trigger(bool bTriggered)
+                { this->bEventTriggered_ = bTriggered; this->changeTriggered(); }
+
+        private:
+            bool bEventTriggered_;
+    };
+
+}
+
+#endif // _EventMultiTrigger_H__
Index: /code/branches/rocket2/src/modules/objects/triggers/EventTrigger.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/EventTrigger.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/EventTrigger.cc	(revision 6952)
@@ -0,0 +1,63 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "EventTrigger.h"
+
+#include "core/CoreIncludes.h"
+#include "core/EventIncludes.h"
+
+namespace orxonox
+{
+    CreateFactory(EventTrigger);
+
+    EventTrigger::EventTrigger(BaseObject* creator) : Trigger(creator)
+    {
+        RegisterObject(EventTrigger);
+
+        this->bEventTriggered_ = false;
+    }
+
+    EventTrigger::~EventTrigger()
+    {
+    }
+
+    void EventTrigger::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(EventTrigger, XMLEventPort, xmlelement, mode);
+
+        XMLPortEventState(EventTrigger, BaseObject, "trigger", trigger, xmlelement, mode);
+    }
+
+    bool EventTrigger::isTriggered(TriggerMode::Value mode)
+    {
+        if (Trigger::isTriggered(mode))
+            return this->bEventTriggered_;
+        else
+            return false;
+    }
+}
Index: /code/branches/rocket2/src/modules/objects/triggers/EventTrigger.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/EventTrigger.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/EventTrigger.h	(revision 6952)
@@ -0,0 +1,56 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _EventTrigger_H__
+#define _EventTrigger_H__
+
+#include "objects/ObjectsPrereqs.h"
+#include "Trigger.h"
+
+namespace orxonox
+{
+    class _ObjectsExport EventTrigger : public Trigger
+    {
+        public:
+            EventTrigger(BaseObject* creator);
+            virtual ~EventTrigger();
+
+            virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
+
+            inline void trigger(bool bTriggered)
+                { this->bEventTriggered_ = bTriggered; this->tick(0); }
+
+        protected:
+            virtual bool isTriggered(TriggerMode::Value mode);
+
+        private:
+            bool bEventTriggered_;
+    };
+}
+
+#endif /* _EventTrigger_H__ */
Index: /code/branches/rocket2/src/modules/objects/triggers/MultiTrigger.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/MultiTrigger.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/MultiTrigger.cc	(revision 6952)
@@ -0,0 +1,653 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      Benjamin Knecht
+ *
+*/
+
+/**
+    @file MultiTrigger.cc
+    @brief Implementation of the MultiTrigger class.
+*/
+
+#include "MultiTrigger.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+#include "MultiTriggerContainer.h"
+
+namespace orxonox
+{
+
+    // Initialization of some static (magic) variables.
+    /*static*/ const int MultiTrigger::INF_s = -1;
+    /*static*/ const std::string MultiTrigger::and_s = "and";
+    /*static*/ const std::string MultiTrigger::or_s = "or";
+    /*static*/ const std::string MultiTrigger::xor_s = "xor";
+    
+    CreateFactory(MultiTrigger);
+
+    /**
+    @brief
+        Constructor. Registers the objects and initializes default values.
+    @param creator
+        The creator.
+    */
+    MultiTrigger::MultiTrigger(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(MultiTrigger);
+
+        this->bFirstTick_ = true;
+
+        this->delay_ = 0.0f;
+        this->bSwitch_ = false;
+        this->bStayActive_ = false;
+        
+        this->remainingActivations_ = INF_s;
+        this->maxNumSimultaniousTriggerers_ = INF_s;
+
+        this->bInvertMode_ = false;
+        this->mode_ = MultiTriggerMode::EventTriggerAND;
+
+        this->bBroadcast_ = false;
+
+        this->parentTrigger_ = NULL;
+        
+        this->targetMask_.exclude(Class(BaseObject));
+
+        this->setSyncMode(0x0);
+    }
+    
+    /**
+    @brief
+        Destructor. Cleans up the state queue.
+    */
+    MultiTrigger::~MultiTrigger()
+    {
+        COUT(4) << "Destroying MultiTrigger &" << this << ". " << this->stateQueue_.size() << " states still in queue. Deleting." << std::endl;
+        while(this->stateQueue_.size() > 0)
+        {
+            MultiTriggerState* state = this->stateQueue_.front().second;
+            this->stateQueue_.pop_front();
+            delete state;
+        }
+    }
+    
+    /**
+    @brief
+        Method for creating a MultiTrigger object through XML.
+        For a detailed description of the parameters please see the class description in the header file.
+    */
+    void MultiTrigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(MultiTrigger, XMLPort, xmlelement, mode);
+
+        XMLPortParam(MultiTrigger, "delay", setDelay, getDelay, xmlelement, mode);
+        XMLPortParam(MultiTrigger, "switch", setSwitch, getSwitch, xmlelement, mode);
+        XMLPortParam(MultiTrigger, "stayactive", setStayActive, getStayActive, xmlelement, mode);
+        XMLPortParam(MultiTrigger, "activations", setActivations, getActivations, xmlelement, mode);
+        XMLPortParam(MultiTrigger, "simultaniousTriggerers", setSimultaniousTriggerers, getSimultaniousTriggerers, xmlelement, mode);
+        XMLPortParam(MultiTrigger, "invert", setInvert, getInvert, xmlelement, mode);
+        XMLPortParamTemplate(MultiTrigger, "mode", setMode, getModeString, xmlelement, mode, const std::string&);
+        XMLPortParam(MultiTrigger, "broadcast", setBroadcast, getBroadcast, xmlelement, mode);
+        XMLPortParamLoadOnly(MultiTrigger, "target", addTargets, xmlelement, mode).defaultValues("Pawn"); //TODO: Remove load only
+
+        //TODO: Maybe nicer with explicit subgroup, e.g. triggers
+        XMLPortObject(MultiTrigger, MultiTrigger, "", addTrigger, getTrigger, xmlelement, mode);
+        
+        COUT(4) << "MultiTrigger '" << this->getName() << "' (&" << this << ") created." << std::endl;
+    }
+    
+
+    /**
+    @brief
+        A method that is executed each tick.
+    @param dt
+        The duration of the last tick.
+    */
+    void MultiTrigger::tick(float dt)
+    {
+        // If this is the first tick.
+        //TODO: Determine need for this, else kick it out. 
+        if(this->bFirstTick_)
+        {
+            this->bFirstTick_ = false;
+            this->fire(false);
+        }
+
+        // Check if the object is active (this is NOT MultiTrigger::isActive()!)
+        if (!this->BaseObject::isActive())
+            return;
+
+        SUPER(MultiTrigger, tick, dt);
+
+        // Let the MultiTrigger return the states that trigger and process the new states if there are any.
+        std::queue<MultiTriggerState*>* queue  = this->letTrigger();
+        if(queue != NULL)
+        {
+            while(queue->size() > 0)
+            {
+                MultiTriggerState* state = queue->front();
+                // If the state is NULL. (This really shouldn't happen)
+                if(state == NULL)
+                {
+                    COUT(1) << "In MultiTrigger '" << this->getName() << "' (&" << this << "), Error: State of new states queue was NULL." << std::endl;
+                    queue->pop();
+                    continue;
+                }
+
+                // The new triggered state dependent on the requested state, the mode and the invert-mode.
+                bool bTriggered = (state->bTriggered & this->isModeTriggered(state->originator)) ^ this->bInvertMode_;
+
+                // If the 'triggered' state has changed a new state is added to the state queue.
+                //TODO: Do something against flooding, when there is delay.
+                if(this->delay_ != 0.0f || bTriggered ^ this->isTriggered(state->originator))
+                {
+                    state->bTriggered = bTriggered;
+                    this->addState(state);
+                }
+                else
+                {
+                    COUT(1) << "BUH" << std::endl;
+                    delete state;
+                }
+                
+                queue->pop();
+            }
+            delete queue;
+        }
+
+        // Go through the state queue and activate all pending states whose remaining time has expired.
+        if (this->stateQueue_.size() > 0)
+        {
+            MultiTriggerState* state;
+            float timeRemaining;
+            
+            // Go through all pending states.
+            for(int size = this->stateQueue_.size(); size >= 1; size--)
+            {
+                timeRemaining = this->stateQueue_.front().first;
+                state = this->stateQueue_.front().second;
+
+                // If the remaining time has expired, the state has to be set as the state of the MultiTrigger.
+                if(timeRemaining <= dt)
+                {
+                    // If the maximum number of objects simultaniously triggering this MultiTrigger is not exceeded.
+                    if(this->maxNumSimultaniousTriggerers_ == INF_s || this->triggered_.size() < (unsigned int)this->maxNumSimultaniousTriggerers_)
+                    {
+                        bool bStateChanged = false;
+                        // If the 'triggered' state is different form what it is now, change it.
+                        if(state->bTriggered ^ this->isTriggered(state->originator))
+                        {
+                            // Add the originator to the objects triggering this MultiTrigger.
+                            if(state->bTriggered == true)
+                            {
+                                this->triggered_.insert(state->originator);
+                            }
+                            // Remove the originator from the objects triggering this MultiTrigger.
+                            else
+                            {
+                                this->triggered_.erase(state->originator);
+                            }
+                            
+                            bStateChanged = true;
+                        }
+
+                        // Get the activity of the new state.
+                        bool bActive;
+                        // If the MultiTrigger is in switch mode.
+                        if(this->bSwitch_ && !state->bTriggered)
+                            bActive = this->isActive(state->originator);
+                        else
+                            bActive = !this->isActive(state->originator);
+
+                        // If the activity is different from what it is now, change it and fire an Event.
+                        if(bActive ^ this->isActive(state->originator))
+                        {
+
+                            bool bFire = true;
+                            
+                            // Add the originator to the objects activating this MultiTrigger.
+                            if(bActive == true)
+                            {
+                                if(this->remainingActivations_ != 0)
+                                {
+                                    this->active_.insert(state->originator);
+                                    if(this->remainingActivations_ != INF_s)
+                                        this->remainingActivations_--; // Decrement the remaining activations.
+                                }
+                                else
+                                {
+                                    bFire = false;
+                                }
+                            }
+                            // Remove the originator from the objects activating this MultiTrigger.
+                            else
+                            {
+                                if(!this->bStayActive_ || this->remainingActivations_ != 0)
+                                {
+                                    this->active_.erase(state->originator);
+                                }
+                                else
+                                {
+                                    bFire = false;
+                                }
+                            }
+
+                            // Fire the Event if the activity has changed.
+                            if(bFire)
+                            {
+                                if(this->bBroadcast_ && state->originator == NULL)
+                                {
+                                    this->broadcast(bActive);
+                                }
+                                else
+                                    this->fire(bActive, state->originator);
+                                
+                                bStateChanged = true;
+                            }
+                        }
+
+                        // Print some debug output if the state has changed.
+                        if(bStateChanged)
+                        {
+                            if(state->originator != NULL)
+                                COUT(4) << "MultiTrigger '" << this->getName() << "' (&" << this << ") changed state. originator: " << state->originator->getIdentifier()->getName() << " (&" << state->originator << "), active: " << bActive << ", triggered: " << state->bTriggered << "." << std::endl;
+                            else
+                                COUT(4) << "MultiTrigger '" << this->getName() << "' (&" << this << ") changed state. originator: NULL, active: " << bActive << ", triggered: " << state->bTriggered << "." << std::endl;
+                            if(this->parentTrigger_ != NULL)
+                                this->parentTrigger_->subTrigggerActivityChanged(state->originator);
+                        }
+
+                        // If the MultiTrigger has exceeded its amount of activations and it doesn't stay active, it has to be destroyed,
+                        if(this->remainingActivations_ == 0 && !bActive)
+                        {
+                            this->BaseObject::setActive(false);
+                            COUT(4) << "MultiTrigger '" << this->getName() << "' (&" << this << ") ran out of activations. Setting it to inactive." << std::endl;
+                        }
+                    }
+                    
+                    // Remove the state from the state queue.
+                    this->stateQueue_.pop_front();
+                    delete state;
+                    size -= 1;
+                }
+                // If the remaining time has not yet expired. Decrement the remainig time.
+                else
+                {
+                    this->stateQueue_.push_back(std::pair<float, MultiTriggerState*>(timeRemaining-dt, state));
+                    this->stateQueue_.pop_front();
+                }
+            }
+        }
+    }
+
+    /**
+    @brief
+        Get whether the MultiTrigger is active for a given object.
+    @param triggerers
+        A pointer to the object.
+    @return
+        Returns true if the MultiTrigger is active, false if not.
+    */
+    bool MultiTrigger::isActive(BaseObject* triggerer)
+    {
+        std::set<BaseObject*>::iterator it = this->active_.find(triggerer);
+        if(it == this->active_.end())
+            return false;
+        return true;
+    }
+
+    /**
+    @brief
+        Set the mode of the MultiTrigger.
+    @param modeName
+        The name of the mode as a string.
+    */
+    void MultiTrigger::setMode(const std::string& modeName)
+    {
+        if (modeName == MultiTrigger::and_s)
+            this->setMode(MultiTriggerMode::EventTriggerAND);
+        else if (modeName == MultiTrigger::or_s)
+            this->setMode(MultiTriggerMode::EventTriggerOR);
+        else if (modeName == MultiTrigger::xor_s)
+            this->setMode(MultiTriggerMode::EventTriggerXOR);
+    }
+
+    /**
+    @brief
+        Get the mode of the MultiTrigger.
+    @return
+        Returns the mode as a string.
+    */
+    const std::string& MultiTrigger::getModeString() const
+    {
+        if (this->mode_ == MultiTriggerMode::EventTriggerAND)
+            return MultiTrigger::and_s;
+        else if (this->mode_ == MultiTriggerMode::EventTriggerOR)
+            return MultiTrigger::or_s;
+        else if (this->mode_ == MultiTriggerMode::EventTriggerXOR)
+            return MultiTrigger::xor_s;
+        else
+            return MultiTrigger::and_s;
+    }
+
+    /**
+    @brief
+        Add some target to the MultiTrigger.
+    @param targetStr
+        The target as a string.
+    */
+    void MultiTrigger::addTargets(const std::string& targetStr)
+    {
+        Identifier* target = ClassByString(targetStr);
+
+        if (target == NULL)
+        {
+            COUT(1) << "Error: \"" << targetStr << "\" is not a valid class name to include in ClassTreeMask (in " << this->getName() << ", class " << this->getIdentifier()->getName() << ')' << std::endl;
+            return;
+        }
+
+        this->targetMask_.include(target);
+
+        // A MultiTriggers shouldn't react to itself or other MultiTriggers.
+        this->targetMask_.exclude(Class(MultiTrigger), true);
+
+        // We only want WorldEntities
+        ClassTreeMask WEMask;
+        WEMask.include(Class(WorldEntity));
+        this->targetMask_ *= WEMask;
+
+        this->notifyMaskUpdate();
+    }
+
+    /**
+    @brief
+        Remove some target from the MultiTrigger.
+    @param targetStr
+        The target to be removed as a string.
+    */
+    void MultiTrigger::removeTargets(const std::string& targetStr)
+    {
+        Identifier* target = ClassByString(targetStr);
+        this->targetMask_.exclude(target);
+    }
+
+    /**
+    @brief
+        Adds a MultiTrigger as a sub-trigger to the trigger.
+        Beware: Loops are not prevented and potentially very bad, so just don't create any loops.
+    @param trigger
+        The trigger to be added.
+    */
+    void MultiTrigger::addTrigger(MultiTrigger* trigger)
+    {
+        if (this != trigger && trigger != NULL)
+            this->subTriggers_.insert(trigger);
+        trigger->addParentTrigger(this);
+    }
+
+    /**
+    @brief
+        Get the sub-trigger of this MultiTrigger at the given index.
+    @param index
+        The index.
+    @return
+        Returns a pointer ot the MultiTrigger. NULL if no such trigger exists.
+    */
+    const MultiTrigger* MultiTrigger::getTrigger(unsigned int index) const
+    {
+        // If the index is greater than the number of sub-triggers.
+        if (this->subTriggers_.size() <= index)
+            return NULL;
+
+        std::set<MultiTrigger*>::const_iterator it;
+        it = this->subTriggers_.begin();
+
+        for (unsigned int i = 0; i != index; ++i)
+            ++it;
+
+        return (*it);
+    }
+
+    /**
+    @brief
+        This method is called by the MultiTrigger to get information about new trigger events that need to be looked at.
+        This method is the device for the behaviour (the conditions under which the MultiTrigger triggers) of any derived class from MultiTrigger.
+    @return
+        A pointer to a queue of MultiTriggerState pointers is returned, containing all the neccessary information to decide whether these states should indeed become new states of the MultiTrigger.
+        Please be aware that both the queue and the states in the queue need to be deleted one they have been used. This is already done in the tick() method of this class but would have to be done by any method calling this method.
+    */
+    std::queue<MultiTriggerState*>* MultiTrigger::letTrigger(void)
+    {
+        return NULL;
+    }
+
+    /**
+    @brief
+        This method can be called by any class inheriting from MultiTrigger to change it's triggered status for a specified originator.
+
+        Compared to the letTrigger mode, which just polls and lets the pollee send it's state changed back, the changeTriggered method lets the trigger advertise its state changes just as they happen so it's much like the interrupt version of letTrigger.
+    @param originator
+        The originator which triggered the state change.
+    */
+    void MultiTrigger::changeTriggered(BaseObject* originator)
+    {
+        MultiTriggerState* state = new MultiTriggerState;
+        state->bTriggered = (!this->isTriggered(originator) & this->isModeTriggered(originator)) ^ this->bInvertMode_;
+        state->originator = originator;
+        this->addState(state);
+    }
+
+    /**
+    @brief
+        This method is called by any sub-trigger to advertise changes in it's state to it's parent-trigger.
+    @param originator
+        The object that caused the change in activity.
+    */
+    void MultiTrigger::subTrigggerActivityChanged(BaseObject* originator)
+    {
+        MultiTriggerState* state = new MultiTriggerState;
+        state->bTriggered = (this->isTriggered(originator) & this->isModeTriggered(originator)) ^ this->bInvertMode_;
+        state->originator = originator;
+        this->addState(state);
+    }
+
+    /**
+    @brief
+        Checks whether the sub-triggers are in such a way that, according to the mode of the MultiTrigger, the MultiTrigger is triggered (only considering the sub-triggers, not the state of MultiTrigger itself), for a given object.
+        To make an example: When the mode is 'and', then this would be true or a given object if all the sub-triggers were triggered ofr the given object.
+    @param triggerer
+        The object.
+    @return
+        Returns true if the MultiTrigger is triggered concerning it's sub-triggers.
+    */
+    bool MultiTrigger::isModeTriggered(BaseObject* triggerer)
+    {
+        if (this->subTriggers_.size() != 0)
+        {
+            bool returnVal = false;
+
+            switch (this->mode_)
+            {
+                case MultiTriggerMode::EventTriggerAND:
+                    returnVal = checkAnd(triggerer);
+                    break;
+                case MultiTriggerMode::EventTriggerOR:
+                    returnVal = checkOr(triggerer);
+                    break;
+                case MultiTriggerMode::EventTriggerXOR:
+                    returnVal = checkXor(triggerer);
+                    break;
+                default:
+                    returnVal = false;
+                    break;
+            }
+
+            return returnVal;
+        }
+        
+        return true;
+    }
+    
+    /**
+    @brief
+        Get whether the MultiTrigger is triggered for a given object.
+    @param triggerer
+        The object.
+    @return
+        Returns true if the MultiTrigger is triggered for the given object.
+    */
+    bool MultiTrigger::isTriggered(BaseObject* triggerer)
+    {
+        std::set<BaseObject*>::iterator it = this->triggered_.find(triggerer);
+        if(it == this->triggered_.end())
+            return false;
+        return true;
+    }
+
+    /**
+    @brief
+        Helper method. Creates an Event for the given status and originator and fires it.
+        Or more precisely creates a MultiTriggerContainer to encompass all neccesary information and creates an Event from that and sends it.
+    @param status
+        The status of the Event to be fired. This is equivalent to the activity of the MultiTrigger.
+    @param originator
+        The object that triggered the MultiTrigger to fire this Event.
+    */
+    void MultiTrigger::fire(bool status, BaseObject* originator)
+    {
+        // If the originator is NULL, a normal event without MultiTriggerContainer is sent.
+        if(originator == NULL)
+        {
+            this->fireEvent(status);
+            COUT(4) << "MultiTrigger '" <<  this->getName() << "' (&" << this << "): Fired event. status: " << status << "." << std::endl;
+            return;
+        }
+        
+        MultiTriggerContainer* container = new MultiTriggerContainer(this, this, originator);
+        this->fireEvent(status, container);
+        COUT(4) << "MultiTrigger '" <<  this->getName() << "' (&" << this << "): Fired event. originator: " << originator->getIdentifier()->getName() << " (&" << originator << "), status: " << status << "." << std::endl;
+        delete container;
+    }
+
+    /**
+    @brief
+        Helper method. Broadcasts an Event for every object that is a target.
+    @param status
+        The status of the Events to be fired. This is equivalent to the activity of the MultiTrigger.
+    */
+    void MultiTrigger::broadcast(bool status)
+    {
+        ClassTreeMask& targetMask = this->getTargetMask();
+        
+        for(ClassTreeMaskObjectIterator it = targetMask.begin(); it != targetMask.end(); ++it)
+        {
+            BaseObject* object = static_cast<BaseObject*>(*it);
+            this->fire(status, object);
+        }
+    }
+
+    /**
+    @brief
+        Helper method. Adds a state to the state queue, where the state will wait to become active.
+    @param state
+        The state to be added.
+    */
+    bool MultiTrigger::addState(MultiTriggerState* state)
+    {
+        assert(state);
+        
+        // If the originator is no target of this MultiTrigger.
+        if(!this->isTarget(state->originator))
+            return false;
+        
+        // Add it ot the state queue.
+        this->stateQueue_.push_back(std::pair<float, MultiTriggerState*>(this->delay_, state));
+
+        return true;
+    }
+
+    /**
+    @brief
+        Checks whether the sub-triggers amount to true for the 'and' mode for a given object.
+    @param triggerer
+        The object.
+    @return
+        Returns true if they do.
+    */
+    bool MultiTrigger::checkAnd(BaseObject* triggerer)
+    {
+        std::set<MultiTrigger*>::iterator it;
+        for(it = this->subTriggers_.begin(); it != this->subTriggers_.end(); ++it)
+        {
+            if (!(*it)->isActive(triggerer))
+                return false;
+        }
+        return true;
+    }
+
+    /**
+    @brief
+        Checks whether the sub-triggers amount to true for the 'or' mode for a given object.
+    @param triggerer
+        The object.
+    @return
+        Returns true if they do.
+    */
+    bool MultiTrigger::checkOr(BaseObject* triggerer)
+    {
+        std::set<MultiTrigger*>::iterator it;
+        for(it = this->subTriggers_.begin(); it != this->subTriggers_.end(); ++it)
+        {
+            if ((*it)->isActive(triggerer))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+    @brief
+        Checks whether the sub-triggers amount to true for the 'xor' mode for a given object.
+    @param triggerer
+        The object.
+    @return
+        Returns true if they do.
+    */
+    bool MultiTrigger::checkXor(BaseObject* triggerer)
+    {
+        std::set<MultiTrigger*>::iterator it;
+        bool test = false;
+        for(it = this->subTriggers_.begin(); it != this->subTriggers_.end(); ++it)
+        {
+            if (test && (*it)->isActive(triggerer))
+                return false;
+            if ((*it)->isActive(triggerer))
+                test = true;
+        }
+        return test;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/objects/triggers/MultiTrigger.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/MultiTrigger.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/MultiTrigger.h	(revision 6952)
@@ -0,0 +1,301 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      Benjamin Knecht
+ *
+*/
+
+/**
+    @file MultiTrigger.h
+    @brief Definition of the MultiTrigger class.
+*/
+
+#ifndef _MultiTrigger_H__
+#define _MultiTrigger_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include "core/BaseObject.h"
+#include "core/ClassTreeMask.h"
+
+#include <set>
+#include <deque>
+
+#include "tools/interfaces/Tickable.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+
+    //! The different modes the MultiTrigger can be in.
+    namespace MultiTriggerMode
+    {
+        enum Value
+        {
+            EventTriggerAND,
+            EventTriggerOR,
+            EventTriggerXOR,
+        };
+    }
+
+    //! Struct to handle MultiTrigger states internally.
+    struct MultiTriggerState
+    {
+        BaseObject* originator;
+        bool bTriggered;
+    };
+
+    /**
+    @brief
+        The MultiTrigger class implements a trigger that has a distinct state for each object triggering it.
+        In more detail: A Trigger is an object that can either be active or inactive, whith a specified behaviour how to switch between the two. A MultiTrigger generalizes that behaviour for multiple objects trigggering the trigger. A MultiTrigger can be active or inactive for any object triggering it, with the state for each object being completely independent of the state for other objects. Each time a switch occurs an Event is fired with as the originator a MultiTriggerContainer, containig a pointer to the pointer that caused the Event and a pointer to the object that caused the trigger to change it's activity.
+
+        MultiTriggers also allow for additional complexity which can be added trough the choice of the parameters explained (briefly) below:
+        But first you must understand a small implementational detail. There is a distinction between the MultiTrigger being triggered (there is the state 'triggered' for that) and the MultiTrigger being active (for that is the state 'activity'). From the outside only the activity is visible. The state 'triggered' tells us whether the trigger is actually triggered, but it could pretend (for some reason, some of which we will see shortly) to be triggered (or to the outside, active), while it in fact isn't. The standard behaviour is, that the cativity changes, when the MultiTrigger transits from being triggered to not being triggered or the other way around.
+        The parameters are:
+            'delay':                    The delay is the time that the trigger waits until it reacts (i.e. changes it's state) to the triggering condition being fulfilled.
+            'switch':                   Switch is a bool, if true the MultiTrigger is in switch-mode, meaning, that the activity changes only when the trigger is triggered , this means, that now the activity only changes, when the trigger changes from not being triggered to being triggered but not the other way around. The default is false.
+            'stayactive':               Stay active is also a bool, if true the MultiTrigger stays active after it has been activated as many times as specified by the parameter activations. The default is -1, which is infinity.
+            'activations':              The number of activations until the trigger can't be triggered anymore. The default is -1, which is infinity.
+            'invert':                   Invert is a bool, if true the trigger is in invert-mode, meaning, that if the triggering condition is fulfilled the MultiTrigger will have the state not triggered and and if the condition is not fulfilled it will have the state triggered. In short it just inverts the behaviour of the MultiTrigger. The default is false.
+            'simultaniousTriggerers':   The number of simultanious triggerers limits the number of object that are allowed to trigger the MultiTrigger at the same time. Or a little more precisely, the number of distinct objects the MultiTrigger has 'triggered' states for, at each point in time.
+            'mode':                     The mode describes how the MultiTrigger acts in relation to all the MultiTriggers, that are appended to it. There are 3 modes: 'and', meaning that the MultiTrigger can only be triggered if all the appended MultiTriggers are active. 'or', meaning that the MultiTrigger can only triggered if at least one of the appendend MultiTriggers is active. And 'xor', meaning that the MultiTrigger can only be triggered if one and only one appended MultiTrigger is active. Notice, that I wrote 'can only be active', that implies, that there is an addtitional condition to the activity of the MultiTrigger and that is the fulfillment of the triggering condition (the MultiTrigger itself doesn't have one, but all derived classes should). Also bear in mind, that the activity of a MultiTrigger is still coupled to the object that triggered it. The default is 'and'.
+            'broadcast'                 Broadcast is a bool, if true the MutliTrigger is in broadcast-mode, meaining, that all trigger events that are caused by no originator (originator is NULL) are broadcasted as having come from every possible originator, or more precisely as having come from all objects that are specified targets of this MultiTrigger.
+            'target':                   The target describes the kind of objects that are allowed to trigger this MultiTrigger. The default is 'Pawn'.
+            Also there is the possibility of appending MultiTriggers to the MultiTrigger just by adding them as subobjects in the XML description of your MultiTrigger.
+
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _ObjectsExport MultiTrigger : public StaticEntity, public Tickable
+    {
+        public:
+            MultiTrigger(BaseObject* creator); //!< Constructor. Registers the objects and initializes default values.
+            ~MultiTrigger(); //!< Destructor.
+            
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a MultiTrigger object through XML.
+            virtual void tick(float dt); //!< A method that is executed each tick.
+            
+            bool isActive(BaseObject* triggerer = NULL); //!< Get whether the MultiTrigger is active for a given object.
+
+            /**
+            @brief Set the delay of the MultiTrigger.
+            @param delay The delay to be set.
+            */
+            inline void setDelay(float delay)
+                { if(delay > 0) this->delay_= delay; }
+            /**
+            @brief Get the delay of the MultiTrigger.
+            @return The delay.
+            */
+            inline float getDelay(void) const
+                { return this->delay_; }
+
+            /**
+            @brief Set switch-mode of the MultiTrigger.
+            @param bSwitch If true the MultiTrigger is set to switched.
+            */
+            inline void setSwitch(bool bSwitch)
+                { this->bSwitch_ = bSwitch; }
+            /**
+            @brief Get the switch-mode of the MultiTrigger.
+            @return Returns true if the MultiTriger is in switch-mode.
+            */
+            inline bool getSwitch(void) const
+                { return this->bSwitch_; }
+
+            /**
+            @brief Set the stay-active-mode of the MultiTrigger.
+            @param bStayActive If true the MultiTrigger is set to stay active.
+            */
+            inline void setStayActive(bool bStayActive)
+                { this->bStayActive_ = bStayActive; }
+            /**
+            @brief Get the stay-active-mode of the MultiTrigger.
+            @return Returns true if the MultiTrigger stays active.
+            */
+            inline bool getStayActive(void) const
+                { return this->bStayActive_; }
+
+            /**
+            @brief Set the number of activations the MultiTrigger can go through.
+            @param activations The number of activations. -1 denotes infinitely many activations.
+            */
+            inline void setActivations(int activations)
+                { if(activations >= 0 || activations == INF_s) this->remainingActivations_ = activations; }
+            /**
+            @brief Get the number of remaining activations of the MultiTrigger.
+            @return The number of activations. -1 denotes infinity.
+            */
+            inline int getActivations(void) const
+                { return this->remainingActivations_; }
+
+            /**
+            @brief Set the number of objects that are allowed to simultaniously trigger this MultiTrigger.
+            @param triggerers The number of objects. -1 denotes infinitely many.
+            */
+            inline void setSimultaniousTriggerers(int triggerers)
+                { if(triggerers >= 0 || triggerers == INF_s) this->maxNumSimultaniousTriggerers_ = triggerers; }
+            /**
+            @brief Get the number of objects that are allowed to simultaniously trigger this MultiTriggger.
+            @return Returns the number of objects. -1 denotes infinity.
+            */
+            inline int getSimultaniousTriggerers(void)
+                { return this->maxNumSimultaniousTriggerers_; }
+
+            /**
+            @brief Set the invert-mode of the MultiTrigger.
+            @param bInvert If true the MultiTrigger is set to invert.
+            */
+            inline void setInvert(bool bInvert)
+                { this->bInvertMode_ = bInvert; }
+            /**
+            @brief Get the invert-mode of the MultiTrigger.
+            @return Returns true if the MultiTrigger is set to invert.
+            */
+            inline bool getInvert(void) const
+                { return this->bInvertMode_; }
+
+            void setMode(const std::string& modeName); //!< Set the mode of the MultiTrigger.
+            /**
+            @brief Set the mode of the MultiTrigger.
+            @param mode The mode of the MultiTrigger.
+            */
+            inline void setMode(MultiTriggerMode::Value mode) //!< Get the mode of the MultiTrigger.
+                { this->mode_ = mode; }
+            const std::string& getModeString(void) const;
+            /**
+            @brief Get the mode of the MultiTrigger.
+            @return Returns and Enum for the mode of the MultiTrigger.
+            */
+            inline MultiTriggerMode::Value getMode() const
+                { return mode_; }
+
+            /**
+            @brief Set the broadcast-mode of the MultiTrigger.
+            @param bBroadcast If true the MultiTrigger is set to broadcast;
+            */
+            inline void setBroadcast(bool bBroadcast)
+                { this->bBroadcast_ = bBroadcast; }
+            /**
+            @brief Get the broadcast-mode of the MultiTrigger.
+            @return Returns true if the MultiTrigger is set to broadcast.
+            */
+            inline bool getBroadcast(void)
+                { return this->bBroadcast_; }
+
+            /**
+            @brief Get whether the input object is a target of the MultiTrigger.
+            @param target A pointer to the object.
+            @return Returns true if the input object is a target, false if not.
+            */
+            inline bool isTarget(BaseObject* target)
+                { if(target == NULL) return true; else return targetMask_.isIncluded(target->getIdentifier()); }
+            void addTargets(const std::string& targets); //!< Add some target to the MultiTrigger.
+            void removeTargets(const std::string& targets); //!< Remove some target from the MultiTrigger.
+            
+            void addTrigger(MultiTrigger* trigger); //!< Adds a MultiTrigger as a sub-trigger to the trigger.
+            const MultiTrigger* getTrigger(unsigned int index) const; //!< Get the sub-trigger of this MultiTrigger at the given index.
+            
+        protected:
+            virtual std::queue<MultiTriggerState*>* letTrigger(void); //!< This method is called by the MultiTrigger to get information about new trigger events that need to be looked at.
+
+            void changeTriggered(BaseObject* originator = NULL); //!< This method can be called by any class inheriting from MultiTrigger to change it's triggered status for a specified originator.
+            
+            bool isModeTriggered(BaseObject* triggerer = NULL); //!< Checks whetherx the MultiTrigger is triggered concerning it's sub-triggers.
+            bool isTriggered(BaseObject* triggerer = NULL); //!< Get whether the MultiTrigger is triggered for a given object.
+
+            void fire(bool status, BaseObject* originator = NULL);  //!< Helper method. Creates an Event for the given status and originator and fires it.
+            void broadcast(bool status); //!< Helper method. Broadcasts an Event for every object that is a target.
+
+            /**
+            @brief Adds the parent of a MultiTrigger.
+            @param parent A pointer to the parent MultiTrigger.
+            */
+            inline void addParentTrigger(MultiTrigger* parent)
+                { this->parentTrigger_ = parent; }
+            
+            /**
+            @brief Get the target mask used to identify the targets of this MultiTrigger.
+            @return Returns the target mask.
+            */
+            inline ClassTreeMask& getTargetMask(void)
+                { return this->targetMask_; }
+            /**
+            @brief Is called, when the target mask changes.
+            */
+            //TODO: Check if something mus be done here.
+            virtual void notifyMaskUpdate(void) {}
+            
+        private:
+            static const int INF_s; //!< Magic number for infinity.
+            //! Magic strings for the mode.
+            static const std::string and_s;
+            static const std::string or_s;
+            static const std::string xor_s;
+
+            void subTrigggerActivityChanged(BaseObject* originator); //!< This method is called by any sub-trigger to advertise changes in it's state to it's parent-trigger.
+            
+            bool addState(MultiTriggerState* state); //!< Helper method. Adds a state to the state queue, where the state will wait to become active.
+            
+            bool checkAnd(BaseObject* triggerer); //!< Checks whether the sub-triggers amount to true for the 'and' mode for a given object.
+            bool checkOr(BaseObject* triggerer); //!< Checks whether the sub-triggers amount to true for the 'or' mode for a given object.
+            bool checkXor(BaseObject* triggerer); //!< Checks whether the sub-triggers amount to true for the 'xor' mode for a given object.
+
+            /**
+            @brief Get the objects for which this MultiTrigger is active.
+            @return Returns a set with all the object this MultiTrigger is active for.
+            */
+            std::set<BaseObject*>& getActive(void)
+                { return this->active_; }
+
+            bool bFirstTick_; //!< Bool to distinguish the first tick form all the following.
+
+            float delay_; //!< The delay that is imposed on all new trigger events.
+            bool bSwitch_; //!< Bool for the switch-mode, if true the MultiTrigger behaves like a switch.
+            bool bStayActive_; //!< Bool for the stay-active-mode, if true the MultiTrigger stays active after its last activation.;
+            
+            int remainingActivations_; //!< The remaining activations of this MultiTrigger.
+            int maxNumSimultaniousTriggerers_; //!< The maximum number of objects simultaniously trigggering this MultiTrigger.
+
+            bool bInvertMode_; //!< Bool for the invert-mode, if true the MultiTrigger is inverted.
+            MultiTriggerMode::Value mode_; //!< The mode of the MultiTrigger.
+
+            bool bBroadcast_; //!< Bool for the broadcast-mode, if true all triggers go to all possible targets.
+
+            MultiTrigger* parentTrigger_;
+            std::set<MultiTrigger*> subTriggers_; //!< The sub-triggers of this MultiTrigger.
+            
+            std::set<BaseObject*> active_; //!< The set of all objects the MultiTrigger is active for.
+            std::set<BaseObject*> triggered_; //!< The set of all objects the MultiTrigger is triggered for.
+
+            std::deque< std::pair<float, MultiTriggerState*> > stateQueue_; //!< The queue of states waiting to become active.
+            
+            ClassTreeMask targetMask_; //!< The target mask, masking all objects that can trigger this MultiTrigger.
+            
+    };
+
+}
+
+#endif // _MultiTrigger_H__
Index: /code/branches/rocket2/src/modules/objects/triggers/MultiTriggerContainer.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/MultiTriggerContainer.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/MultiTriggerContainer.cc	(revision 6952)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      ...
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+/**
+    @file MultiTriggerContainer.cc
+    @brief Implementation of the MultiTriggerContainer class.
+*/
+
+#include "MultiTriggerContainer.h"
+
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+
+    CreateUnloadableFactory(MultiTriggerContainer);
+    
+    /**
+    @brief
+        Default constructor. Registers the object and creates an empty container.
+    @param creator
+        The creator.
+    */
+    MultiTriggerContainer::MultiTriggerContainer(BaseObject* creator) : BaseObject(creator), originator_(NULL), data_(NULL)
+    {
+        RegisterObject(MultiTriggerContainer);
+    }
+
+    /**
+    @brief
+        Constructor. Registers the object and sets the input values.
+    @param creator
+        The creator.
+    @param originator
+        A pointer to the originator of the Event, i.e. the MultiTrigger that fired the Event. (or is about to)
+    @param data
+        A pointer to the data that should be sent with the container.
+    */
+    MultiTriggerContainer::MultiTriggerContainer(BaseObject* creator, MultiTrigger* originator, BaseObject* data) : BaseObject(creator), originator_(originator), data_(data)
+    {
+        RegisterObject(MultiTriggerContainer);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    MultiTriggerContainer::~MultiTriggerContainer()
+    {
+        
+    }
+
+
+}
Index: /code/branches/rocket2/src/modules/objects/triggers/MultiTriggerContainer.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/MultiTriggerContainer.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/MultiTriggerContainer.h	(revision 6952)
@@ -0,0 +1,78 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+/**
+    @file MultiTriggerContainer.h
+    @brief Definition of the MultiTriggerContainer class.
+*/
+
+#ifndef _MultiTriggerContainer_H__
+#define _MultiTriggerContainer_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        This class is used by the MultiTrigger class to transport additional data via Events.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _ObjectsExport MultiTriggerContainer : public BaseObject
+    {
+        
+        public:
+            MultiTriggerContainer(BaseObject* creator); //!< Default constructor. Registers the object and creates an empty container.
+            MultiTriggerContainer(BaseObject* creator, MultiTrigger* originator, BaseObject* data); //!< Constructor. Registers the object and sets the input values.
+            ~MultiTriggerContainer(); //!< Destructor.
+
+            /**
+            @brief Get the originator of the Event. (The MultiTrigger that fired the Event)
+            @return Returns a pointer to the originator.
+            */
+            inline MultiTrigger* getOriginator(void)
+                { return this->originator_; }
+            /**
+            @brief Get the data of this container.
+            @return Returns a pointer ot the data.
+            */
+            inline BaseObject* getData(void)
+                { return this->data_; }
+            
+        private:
+            MultiTrigger* originator_; //!< The originator.
+            BaseObject* data_; //!< The data.
+    };
+    
+}
+
+#endif // _MultiTriggerContainer_H__
Index: /code/branches/rocket2/src/modules/objects/triggers/Trigger.cc
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/Trigger.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/Trigger.cc	(revision 6952)
@@ -0,0 +1,328 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Trigger.h"
+
+#include "core/CoreIncludes.h"
+#include "core/ConsoleCommand.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+
+  SetConsoleCommand(Trigger, debugFlares, false).defaultValues(false);
+
+  CreateFactory(Trigger);
+
+  Trigger::Trigger(BaseObject* creator) : StaticEntity(creator)
+  {
+    RegisterObject(Trigger);
+
+    this->mode_ = TriggerMode::EventTriggerAND;
+
+    this->bFirstTick_ = true;
+    this->bActive_ = false;
+    this->bTriggered_ = false;
+    this->latestState_ = 0x0;
+
+    this->bInvertMode_ = false;
+    this->bSwitch_ = false;
+    this->bStayActive_ = false;
+    this->delay_ = 0.0f;
+    this->remainingTime_ = 0.0f;
+    this->timeSinceLastEvent_ = 0.0f;
+    this->remainingActivations_ = -1;
+
+//    this->bUpdating_ = false;
+
+    if (this->getScene() && GameMode::showsGraphics())
+    {
+      this->debugBillboard_.setBillboardSet(this->getScene()->getSceneManager(), "Examples/Flare", ColourValue(1.0, 0.0, 0.0), 1);
+      this->debugBillboard_.setVisible(false);
+
+      if (this->debugBillboard_.getBillboardSet())
+          this->attachOgreObject(this->debugBillboard_.getBillboardSet());
+    }
+
+    this->setSyncMode(0x0);
+  }
+
+  Trigger::~Trigger()
+  {
+  }
+
+  void Trigger::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+  {
+    SUPER(Trigger, XMLPort, xmlelement, mode);
+
+    XMLPortParam(Trigger, "delay",       setDelay,       getDelay,       xmlelement, mode).defaultValues(0.0f);
+    XMLPortParam(Trigger, "switch",      setSwitch,      getSwitch,      xmlelement, mode).defaultValues(false);
+    XMLPortParam(Trigger, "stayactive",  setStayActive,  getStayActive,  xmlelement, mode).defaultValues(false);
+    XMLPortParam(Trigger, "activations", setActivations, getActivations, xmlelement, mode).defaultValues(-1);
+    XMLPortParam(Trigger, "invert",      setInvert,      getInvert,      xmlelement, mode).defaultValues(false);
+    XMLPortParamTemplate(Trigger, "mode", setMode, getModeString, xmlelement, mode, const std::string&).defaultValues("or");
+
+    XMLPortObject(Trigger, Trigger, "", addTrigger, getTrigger, xmlelement, mode);
+  }
+
+  void Trigger::tick(float dt)
+  {
+    if (this->bFirstTick_)
+    {
+      this->bFirstTick_ = false;
+      this->triggered(false);
+    }
+
+    // Check if the object is active (this is NOT Trigger::isActive()!)
+    if (!this->BaseObject::isActive())
+        return;
+
+    SUPER(Trigger, tick, dt);
+
+    bool newTriggered = this->isTriggered() ^ this->bInvertMode_;
+
+    // check if new triggering event is really new
+    if ((this->latestState_ & 0x1) != newTriggered)
+    {
+      // create new state
+      if (newTriggered)
+      {
+        this->latestState_ |= 1; // set trigger bit to 1
+        this->switchState();
+      }
+      else
+      {
+        this->latestState_ &= 0xFE; // set trigger bit to 0
+        if (!this->bSwitch_)
+          this->switchState();
+      }
+    }
+
+    if (this->remainingTime_ > 0.0)
+    {
+      this->remainingTime_ -= dt;
+      // only increase when acctually waiting for a state in the queue
+      if (this->timeSinceLastEvent_ >= 0.0)
+        this->timeSinceLastEvent_ += dt;
+    }
+
+    while (this->remainingTime_ <= 0.0 && this->stateChanges_.size() > 0)
+    {
+      // time ran out, change state to new one
+      char newState = this->stateChanges_.front().second;
+      this->bTriggered_ = (newState & 0x1);
+      this->bActive_ = newState & 2;
+      this->triggered(this->bActive_);
+      this->stateChanges_.pop();
+      if (this->stateChanges_.size() != 0)
+        this->remainingTime_ = this->stateChanges_.front().first;
+      else
+        this->timeSinceLastEvent_ = this->delay_;
+    }
+
+    if (this->bTriggered_ && this->bActive_)
+      this->setBillboardColour(ColourValue(0.5, 1.0, 0.0));
+    else if (!this->bTriggered_ && this->bActive_)
+      this->setBillboardColour(ColourValue(0.0, 1.0, 0.0));
+    else if (this->bTriggered_ && !this->bActive_)
+      this->setBillboardColour(ColourValue(1.0, 0.5, 0.0));
+    else
+      this->setBillboardColour(ColourValue(1.0, 0.0, 0.0));
+  }
+
+  void Trigger::triggered(bool bIsTriggered)
+  {
+    this->fireEvent(bIsTriggered);
+  }
+
+  bool Trigger::isTriggered(TriggerMode::Value mode)
+  {
+//    if (this->bUpdating_)
+//      return this->bTriggered_;
+
+//    this->bUpdating_ = true;
+    if (this->children_.size() != 0)
+    {
+      bool returnval = false;
+
+      switch (mode)
+      {
+        case TriggerMode::EventTriggerAND:
+          returnval = checkAnd();
+          break;
+        case TriggerMode::EventTriggerOR:
+          returnval = checkOr();
+          break;
+        case TriggerMode::EventTriggerXOR:
+          returnval = checkXor();
+          break;
+        default:
+          returnval = false;
+          break;
+      }
+//      this->bUpdating_ = false;
+
+      return returnval;
+    }
+    return true;
+  }
+
+  bool Trigger::checkAnd()
+  {
+    std::set<Trigger*>::iterator it;
+    for(it = this->children_.begin(); it != this->children_.end(); ++it)
+    {
+      if (!(*it)->isActive())
+        return false;
+    }
+    return true;
+  }
+
+  bool Trigger::checkOr()
+  {
+    std::set<Trigger*>::iterator it;
+    for(it = this->children_.begin(); it != this->children_.end(); ++it)
+    {
+      if ((*it)->isActive())
+        return true;
+    }
+    return false;
+  }
+
+  bool Trigger::checkXor()
+  {
+    std::set<Trigger*>::iterator it;
+    bool test = false;
+    for(it = this->children_.begin(); it != this->children_.end(); ++it)
+    {
+      if (test && (*it)->isActive())
+        return false;
+      if ((*it)->isActive())
+        test = true;
+    }
+    return test;
+  }
+
+  bool Trigger::switchState()
+  {
+    if (( (this->latestState_ & 2) && this->bStayActive_ && (this->remainingActivations_ <= 0))
+     || (!(this->latestState_ & 2)                       && (this->remainingActivations_ == 0)))
+      return false;
+    else
+    {
+      this->latestState_ ^= 2; // toggle state bit
+
+      // increase activation count
+      if (this->latestState_ & 2 && this->remainingActivations_ > 0)
+        this->remainingActivations_--;
+
+      this->storeState();
+
+      return true;
+    }
+  }
+
+  void Trigger::storeState()
+  {
+    // put state change into queue
+    this->stateChanges_.push(std::pair<float, char>(this->timeSinceLastEvent_, this->latestState_));
+    // reset time since last event
+    this->timeSinceLastEvent_ = 0.0;
+
+    if (this->stateChanges_.size() == 1)
+      this->remainingTime_ = this->stateChanges_.front().first;
+  }
+
+  void Trigger::setDelay(float delay)
+  {
+    this->delay_ = delay;
+    this->timeSinceLastEvent_ = delay;
+  }
+
+  void Trigger::setMode(const std::string& modeName)
+  {
+    if (modeName == "and")
+      this->setMode(TriggerMode::EventTriggerAND);
+    else if (modeName == "or")
+      this->setMode(TriggerMode::EventTriggerOR);
+    else if (modeName == "xor")
+      this->setMode(TriggerMode::EventTriggerXOR);
+  }
+
+  std::string Trigger::getModeString() const
+  {
+    if (this->mode_ == TriggerMode::EventTriggerAND)
+      return "and";
+    else if (this->mode_ == TriggerMode::EventTriggerOR)
+      return "or";
+    else if (this->mode_ == TriggerMode::EventTriggerXOR)
+      return "xor";
+    else
+      return "and";
+  }
+
+  void Trigger::addTrigger(Trigger* trigger)
+  {
+    if (this != trigger)
+      this->children_.insert(trigger);
+  }
+
+  const Trigger* Trigger::getTrigger(unsigned int index) const
+  {
+    if (this->children_.size() <= index)
+      return NULL;
+
+    std::set<Trigger*>::const_iterator it;
+    it = this->children_.begin();
+
+    for (unsigned int i = 0; i != index; ++i)
+      ++it;
+
+    return (*it);
+  }
+
+  void Trigger::debugFlares(bool bVisible)
+  {
+    for (ObjectList<Trigger>::iterator it = ObjectList<Trigger>::begin(); it != ObjectList<Trigger>::end(); ++it)
+      it->setVisible(bVisible);
+  }
+
+  void Trigger::setBillboardColour(const ColourValue& colour)
+  {
+    this->debugBillboard_.setColour(colour);
+  }
+
+  void Trigger::changedVisibility()
+  {
+    SUPER(Trigger, changedVisibility);
+
+    this->debugBillboard_.setVisible(this->isVisible());
+  }
+}
Index: /code/branches/rocket2/src/modules/objects/triggers/Trigger.h
===================================================================
--- /code/branches/rocket2/src/modules/objects/triggers/Trigger.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/objects/triggers/Trigger.h	(revision 6952)
@@ -0,0 +1,143 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Trigger_H__
+#define _Trigger_H__
+
+#include "objects/ObjectsPrereqs.h"
+
+#include <set>
+#include <queue>
+
+#include "tools/BillboardSet.h"
+#include "tools/interfaces/Tickable.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+  namespace TriggerMode
+  {
+    enum Value
+    {
+      EventTriggerAND,
+      EventTriggerOR,
+      EventTriggerXOR,
+    };
+  }
+
+  class _ObjectsExport Trigger : public StaticEntity, public Tickable
+  {
+    public:
+      Trigger(BaseObject* creator);
+      virtual ~Trigger();
+
+      virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+      virtual void tick(float dt);
+
+      inline bool isActive() const
+        { return bActive_; }
+
+      void addTrigger(Trigger* trigger);
+      const Trigger* getTrigger(unsigned int index) const;
+
+      void setMode(const std::string& modeName);
+      inline void setMode(TriggerMode::Value mode)
+        { this->mode_ = mode; }
+      inline TriggerMode::Value getMode() const
+        { return mode_; }
+
+      inline void setInvert(bool bInvert)
+        { this->bInvertMode_ = bInvert; }
+      inline bool getInvert() const
+        { return this->bInvertMode_; }
+
+      inline void setSwitch(bool bSwitch)
+        { this->bSwitch_ = bSwitch; }
+      inline bool getSwitch() const
+        { return this->bSwitch_; }
+
+      inline void setStayActive(bool bStayActive)
+        { this->bStayActive_ = bStayActive; }
+      inline bool getStayActive() const
+        { return this->bStayActive_; }
+
+      inline void setActivations(int activations)
+        { this->remainingActivations_ = activations; }
+      inline int getActivations() const
+        { return this->remainingActivations_; }
+
+      inline void setVisible(bool visibility)
+        { this->debugBillboard_.setVisible(visibility); }
+
+      void setDelay(float delay);
+      inline float getDelay() const
+        { return this->delay_; }
+
+      bool switchState();
+
+      static void debugFlares(bool bVisible);
+      virtual void changedVisibility();
+
+    protected:
+      inline bool isTriggered() { return this->isTriggered(this->mode_); }
+      virtual bool isTriggered(TriggerMode::Value mode);
+      virtual void triggered(bool bIsTriggered);
+
+    private:
+      bool checkAnd();
+      bool checkOr();
+      bool checkXor();
+      void setBillboardColour(const ColourValue& colour);
+      void storeState();
+      std::string getModeString() const;
+
+      bool bActive_;
+      bool bTriggered_;
+      bool bFirstTick_;
+
+      TriggerMode::Value mode_;
+      bool bInvertMode_;
+      bool bSwitch_;
+      bool bStayActive_;
+      float delay_;
+      int remainingActivations_;
+
+      char latestState_;
+      float remainingTime_;
+      float timeSinceLastEvent_;
+
+//      bool bUpdating_;
+      BillboardSet debugBillboard_;
+
+      std::set<Trigger*> children_;
+      std::queue<std::pair<float, char> > stateChanges_;
+  };
+
+}
+
+#endif /* _Trigger_H__ */
Index: /code/branches/rocket2/src/modules/overlays/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/overlays/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,21 @@
+SET_SOURCE_FILES(OVERLAYS_SRC_FILES
+  OverlayText.cc
+  FadeoutText.cc
+  GUIOverlay.cc
+)
+
+ADD_SUBDIRECTORY(debugging)
+ADD_SUBDIRECTORY(hud)
+ADD_SUBDIRECTORY(stats)
+
+ORXONOX_ADD_LIBRARY(overlays
+  MODULE
+  FIND_HEADER_FILES
+  PCH_FILE
+    OverlaysPrecompiledHeaders.h
+  DEFINE_SYMBOL
+    "OVERLAYS_SHARED_BUILD"
+  LINK_LIBRARIES
+    orxonox
+  SOURCE_FILES ${OVERLAYS_SRC_FILES}
+)
Index: /code/branches/rocket2/src/modules/overlays/FadeoutText.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/FadeoutText.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/FadeoutText.cc	(revision 6952)
@@ -0,0 +1,116 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "FadeoutText.h"
+
+#include <OgreTextAreaOverlayElement.h>
+#include "util/Math.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(FadeoutText);
+
+    FadeoutText::FadeoutText(BaseObject* creator) : OverlayText(creator)
+    {
+        RegisterObject(FadeoutText);
+
+        this->delay_ = 3.0f;
+        this->fadeouttime_ = 1.0f;
+
+        this->bFadingOut_ = false;
+        this->fadeouttimer_.setTimer(3.0f, false, createExecutor(createFunctor(&FadeoutText::fadeout, this)));
+        this->fadeouttimer_.stopTimer();
+
+        this->initialAlpha_ = 1.0f;
+    }
+
+    void FadeoutText::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(FadeoutText, XMLPort, xmlelement, mode);
+
+        XMLPortParam(FadeoutText, "delay", setDelay, getDelay, xmlelement, mode);
+        XMLPortParam(FadeoutText, "fadeout", setFadeouttime, getFadeouttime, xmlelement, mode);
+    }
+
+    void FadeoutText::tick(float dt)
+    {
+        if (this->bFadingOut_)
+        {
+            ColourValue colour = this->getColour();
+
+            if (colour.a > 0)
+            {
+                float alpha = colour.a;
+
+                alpha -= dt / this->fadeouttime_;
+                if (alpha < 0)
+                    alpha = 0;
+                colour.a = alpha;
+
+                this->text_->setColour(colour);
+            }
+            else
+            {
+                this->text_->setCaption("");
+                this->reset();
+            }
+        }
+    }
+
+    void FadeoutText::fadeout()
+    {
+        this->bFadingOut_ = true;
+    }
+
+    void FadeoutText::reset()
+    {
+        this->bFadingOut_ = false;
+
+        ColourValue colour = this->getColour();
+        colour.a = this->initialAlpha_;
+        this->text_->setColour(colour);
+    }
+
+    void FadeoutText::changedColour()
+    {
+        OverlayText::changedColour();
+
+        this->initialAlpha_ = this->getColour().a;
+    }
+
+    void FadeoutText::changedCaption()
+    {
+        OverlayText::changedCaption();
+
+        this->reset();
+        this->fadeouttimer_.setInterval(this->delay_);
+        this->fadeouttimer_.startTimer();
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/FadeoutText.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/FadeoutText.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/FadeoutText.h	(revision 6952)
@@ -0,0 +1,75 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _FadeoutText_H__
+#define _FadeoutText_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "tools/Timer.h"
+#include "tools/interfaces/Tickable.h"
+#include "overlays/OverlayText.h"
+
+namespace orxonox
+{
+    class _OverlaysExport FadeoutText : public OverlayText, public Tickable
+    {
+        public:
+            FadeoutText(BaseObject* creator);
+            virtual ~FadeoutText() {}
+
+            virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+            virtual void tick(float dt);
+
+            inline void setDelay(float delay)
+                { this->delay_ = delay; }
+            inline float getDelay() const
+                { return this->delay_; }
+
+            inline void setFadeouttime(float fadeouttime)
+                { this->fadeouttime_ = fadeouttime; }
+            inline float getFadeouttime() const
+                { return this->fadeouttime_; }
+
+        private:
+            virtual void changedColour();
+            virtual void changedCaption();
+
+            void fadeout();
+            void reset();
+
+            float delay_;
+            float fadeouttime_;
+
+            bool bFadingOut_;
+            Timer fadeouttimer_;
+
+            float initialAlpha_;
+    };
+}
+#endif /* _FadeoutText_H__ */
Index: /code/branches/rocket2/src/modules/overlays/GUIOverlay.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/GUIOverlay.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/GUIOverlay.cc	(revision 6952)
@@ -0,0 +1,106 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "GUIOverlay.h"
+
+#include <string>
+#include <sstream>
+
+#include "core/input/InputManager.h"
+#include "core/CoreIncludes.h"
+#include "core/GUIManager.h"
+#include "core/XMLPort.h"
+#include "infos/PlayerInfo.h"
+#include "worldentities/ControllableEntity.h"
+
+namespace orxonox
+{
+    CreateFactory(GUIOverlay);
+
+    GUIOverlay::GUIOverlay(BaseObject* creator) : OrxonoxOverlay(creator)
+    {
+        RegisterObject(GUIOverlay);
+    }
+
+    GUIOverlay::~GUIOverlay()
+    {
+    }
+
+    void GUIOverlay::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        SUPER(GUIOverlay, XMLPort, xmlElement, mode);
+
+        XMLPortParam(GUIOverlay, "guiname", setGUIName, getGUIName, xmlElement, mode);
+    }
+
+    void GUIOverlay::changedVisibility()
+    {
+        SUPER(GUIOverlay, changedVisibility);
+
+        //Setting player now.
+        if (this->getOwner())
+        {
+            ControllableEntity* entity = orxonox_cast<ControllableEntity*>(this->getOwner());
+            if (entity)
+                GUIManager::getInstance().setPlayer(this->guiName_, entity->getPlayer());
+        }
+
+        if (this->isVisible())
+        {
+            std::ostringstream out;
+            out << reinterpret_cast<long>(this);
+            const std::string& str = out.str();
+            GUIManager::getInstance().showGUIExtra(this->guiName_, str);
+
+            COUT(4) << "Showing GUI " << this->guiName_ << std::endl;
+        }
+        else
+        {
+            GUIManager::hideGUI(this->guiName_);
+            COUT(4) << "Hiding GUI " << this->guiName_ << std::endl;
+        }
+    }
+
+    void GUIOverlay::setGUIName(const std::string& name)
+    {
+        this->guiName_ = name;
+        if (this->getOwner())
+        {
+            ControllableEntity* entity = orxonox_cast<ControllableEntity*>(this->getOwner());
+            if (entity)
+                GUIManager::getInstance().setPlayer(name, entity->getPlayer()); //Set Player is going to be NULL, so it needs to be set in changedVisibility() as well.
+        }
+    }
+
+    void GUIOverlay::changedOwner()
+    {
+        SUPER(GUIOverlay, changedOwner);
+        if (!this->getGUIName().empty())
+            this->setGUIName(this->getGUIName());
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/GUIOverlay.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/GUIOverlay.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/GUIOverlay.h	(revision 6952)
@@ -0,0 +1,59 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GUIOverlay_H__
+#define _GUIOverlay_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include <string>
+#include "overlays/OrxonoxOverlay.h"
+
+namespace orxonox
+{
+    class _OverlaysExport GUIOverlay : public OrxonoxOverlay
+    {
+        public:
+
+            GUIOverlay(BaseObject* creator);
+            virtual ~GUIOverlay();
+
+            virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+
+            void setGUIName(const std::string& name);
+            inline const std::string& getGUIName() const { return this->guiName_; }
+
+            virtual void changedVisibility();
+            virtual void changedOwner();
+
+        private:
+            std::string guiName_;
+    };
+}
+
+#endif
Index: /code/branches/rocket2/src/modules/overlays/OverlayText.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/OverlayText.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/OverlayText.cc	(revision 6952)
@@ -0,0 +1,170 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "OverlayText.h"
+
+#include <OgreOverlayManager.h>
+#include <OgrePanelOverlayElement.h>
+#include <OgreTextAreaOverlayElement.h>
+#include <boost/static_assert.hpp>
+
+#include "util/StringUtils.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+
+namespace orxonox
+{
+    CreateFactory(OverlayText);
+
+    BOOST_STATIC_ASSERT((int)Ogre::TextAreaOverlayElement::Left   == (int)OverlayText::Left);
+    BOOST_STATIC_ASSERT((int)Ogre::TextAreaOverlayElement::Center == (int)OverlayText::Center);
+    BOOST_STATIC_ASSERT((int)Ogre::TextAreaOverlayElement::Right  == (int)OverlayText::Right);
+
+    OverlayText::OverlayText(BaseObject* creator)
+        : OrxonoxOverlay(creator)
+    {
+        RegisterObject(OverlayText);
+
+        this->text_ = static_cast<Ogre::TextAreaOverlayElement*>(Ogre::OverlayManager::getSingleton()
+            .createOverlayElement("TextArea", "OverlayText_text_" + getUniqueNumberString()));
+        this->text_->setCharHeight(1.0);
+
+        this->setFont("Monofur");
+        this->setColour(ColourValue(1.0, 1.0, 1.0, 1.0));
+        this->setCaption("");
+        this->setTextSize(1.0f);
+        this->setAlignmentString("left");
+
+        this->background_->addChild(this->text_);
+    }
+
+    OverlayText::~OverlayText()
+    {
+        if (this->isInitialized())
+            Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->text_);
+    }
+
+    void OverlayText::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        SUPER(OverlayText, XMLPort, xmlElement, mode);
+
+        XMLPortParam(OverlayText, "font",       setFont,            getFont,            xmlElement, mode);
+        XMLPortParam(OverlayText, "colour",     setColour,          getColour,          xmlElement, mode);
+        XMLPortParam(OverlayText, "caption",    setCaption,         getCaption,         xmlElement, mode);
+        XMLPortParam(OverlayText, "textsize",   setTextSize,        getTextSize,        xmlElement, mode);
+        XMLPortParam(OverlayText, "align",      setAlignmentString, getAlignmentString, xmlElement, mode);
+        XMLPortParam(OverlayText, "spacewidth", setSpaceWidth,      getSpaceWidth,      xmlElement, mode);
+    }
+
+    void OverlayText::setAlignmentString(const std::string& alignment)
+    {
+        if (alignment == "right")
+            this->setAlignment(OverlayText::Right);
+        else if (alignment == "center")
+            this->setAlignment(OverlayText::Center);
+        else // "left" and default
+            this->setAlignment(OverlayText::Left);
+    }
+
+    std::string OverlayText::getAlignmentString() const
+    {
+        Ogre::TextAreaOverlayElement::Alignment alignment = this->text_->getAlignment();
+
+        switch (alignment)
+        {
+            case Ogre::TextAreaOverlayElement::Right:
+                return "right";
+            case Ogre::TextAreaOverlayElement::Center:
+                return "center";
+            case Ogre::TextAreaOverlayElement::Left:
+                return "left";
+            default:
+                assert(false); return "";
+        }
+    }
+
+    void OverlayText::sizeChanged()
+    {
+        if (this->rotState_ == Horizontal)
+            this->overlay_->setScale(size_.y * sizeCorrection_.y, size_.y * sizeCorrection_.y);
+        else if (this->rotState_ == Vertical)
+            this->overlay_->setScale(size_.y / (sizeCorrection_.y * sizeCorrection_.y), size_.y * sizeCorrection_.y);
+        else
+            this->overlay_->setScale(size_.y, size_.y);
+
+        positionChanged();
+    }
+
+    void OverlayText::setCaption(const std::string& caption)
+    {
+        this->text_->setCaption(caption);
+        this->changedCaption();
+    }
+    std::string OverlayText::getCaption() const
+    {
+        return this->text_->getCaption();
+    }
+
+    void OverlayText::setFont(const std::string& font)
+    {
+        if (!font.empty())
+            this->text_->setFontName(font);
+    }
+    const std::string& OverlayText::getFont() const
+    {
+        return this->text_->getFontName();
+    }
+
+    void OverlayText::setSpaceWidth(float width)
+    {
+        this->text_->setSpaceWidth(width);
+    }
+    float OverlayText::getSpaceWidth() const
+    {
+        return this->text_->getSpaceWidth();
+    }
+
+    void OverlayText::setColour(const ColourValue& colour)
+    {
+        this->text_->setColour(colour); this->changedColour();
+    }
+    const ColourValue& OverlayText::getColour() const
+    {
+        return this->text_->getColour();
+    }
+
+    void OverlayText::setAlignment(OverlayText::Alignment alignment)
+    {
+        this->text_->setAlignment(static_cast<Ogre::TextAreaOverlayElement::Alignment>(alignment));
+    }
+    OverlayText::Alignment OverlayText::getAlignment() const
+    {
+        return static_cast<OverlayText::Alignment>(this->text_->getAlignment());
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/OverlayText.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/OverlayText.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/OverlayText.h	(revision 6952)
@@ -0,0 +1,85 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _OverlayText_H__
+#define _OverlayText_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include <string>
+#include "util/Math.h"
+#include "util/OgreForwardRefs.h"
+#include "overlays/OrxonoxOverlay.h"
+
+namespace orxonox
+{
+    class _OverlaysExport OverlayText : public OrxonoxOverlay
+    {
+    public:
+        enum Alignment
+        {
+            Left,
+            Right,
+            Center
+        };
+
+        OverlayText(BaseObject* creator);
+        virtual ~OverlayText();
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+
+        void setCaption(const std::string& caption);
+        std::string getCaption() const;
+
+        void setFont(const std::string& font);
+        const std::string& getFont() const;
+
+        void setSpaceWidth(float width);
+        float getSpaceWidth() const;
+
+        void setColour(const ColourValue& colour);
+        const ColourValue& getColour() const;
+
+        void setAlignment(OverlayText::Alignment alignment);
+        OverlayText::Alignment getAlignment() const;
+
+        void setAlignmentString(const std::string& alignment);
+        std::string getAlignmentString() const;
+
+        inline void setTextSize(float size) { this->setSize(Vector2(size, size)); }
+        inline float getTextSize() const    { return this->getSize().y; }
+
+    protected:
+        virtual void sizeChanged();
+        virtual void changedColour() {}
+        virtual void changedCaption() {}
+
+        Ogre::TextAreaOverlayElement* text_;
+    };
+}
+#endif /* _OverlayText_H__ */
Index: /code/branches/rocket2/src/modules/overlays/OverlaysPrecompiledHeaders.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/OverlaysPrecompiledHeaders.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/OverlaysPrecompiledHeaders.h	(revision 6952)
@@ -0,0 +1,67 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Compilation of the most often used header files in the overlays module
+@details
+    Updated: 19. September 2009
+    Total Files: 21
+*/
+
+#include "OrxonoxConfig.h"
+
+///////////////////////////////////////////
+/////          Stable Headers         /////
+///////////////////////////////////////////
+
+#include <tinyxml/ticpp.h> // 14
+//#include <OgreOverlayelement.h> // 7, 7.2MB
+#include <bullet/LinearMath/btMotionState.h> // 6
+//#include <OgrePanelOverlayelement.h> // 5
+
+///////////////////////////////////////////
+/////       All Rebuild Headers       /////
+///////////////////////////////////////////
+
+#include "overlays/OrxonoxOverlay.h" // 21
+#include "core/CoreIncludes.h"       // 20
+
+///////////////////////////////////////////
+/////      Not so Stable Headers      /////
+///////////////////////////////////////////
+
+#include "core/Executor.h"     // 13
+//#include "network/synchronisable/Synchronisable.h" // 13
+//#include "core/XMLPort.h"    // 9
+
+
+// Just in case some header included windows.h
+#undef min
+#undef max
Index: /code/branches/rocket2/src/modules/overlays/OverlaysPrereqs.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/OverlaysPrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/OverlaysPrereqs.h	(revision 6952)
@@ -0,0 +1,97 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Shared library macros, enums, constants and forward declarations for the overlays module
+*/
+
+#ifndef _OverlaysPrereqs_H__
+#define _OverlaysPrereqs_H__
+
+#include "OrxonoxConfig.h"
+#include "OrxonoxPrereqs.h"
+
+//-----------------------------------------------------------------------
+// Shared library settings
+//-----------------------------------------------------------------------
+
+#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined(ORXONOX_STATIC_BUILD)
+#  ifdef OVERLAYS_SHARED_BUILD
+#    define _OverlaysExport __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define _OverlaysExport
+#    else
+#      define _OverlaysExport __declspec(dllimport)
+#    endif
+#  endif
+#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _OverlaysExport  __attribute__ ((visibility("default")))
+#else
+#  define _OverlaysExport
+#endif
+
+//-----------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    class FadeoutText;
+    class GUIOverlay;
+    class OverlayText;
+
+    // debugging
+    class DebugFPSText;
+    class DebugRTRText;
+
+    // hud
+    class AnnounceMessage;
+    class BarColour;
+    class ChatOverlay;
+    class DeathMessage;
+    class GametypeStatus;
+    class HUDBar;
+    class HUDHealthBar;
+    class HUDNavigation;
+    class HUDRadar;
+    class HUDSpeedBar;
+    class HUDTimer;
+    class KillMessage;
+    class TeamBaseMatchScore;
+    class UnderAttackHealthBar;
+
+    // stats
+    class CreateLines;
+    class Scoreboard;
+    class Stats;
+}
+
+#endif /* _OverlaysPrereqs_H__ */
Index: /code/branches/rocket2/src/modules/overlays/debugging/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/overlays/debugging/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/debugging/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,4 @@
+ADD_SOURCE_FILES(OVERLAYS_SRC_FILES
+  DebugFPSText.cc
+  DebugRTRText.cc
+)
Index: /code/branches/rocket2/src/modules/overlays/debugging/DebugFPSText.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/debugging/DebugFPSText.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/debugging/DebugFPSText.cc	(revision 6952)
@@ -0,0 +1,55 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "DebugFPSText.h"
+
+#include "util/Convert.h"
+#include "core/CoreIncludes.h"
+#include "core/Game.h"
+
+namespace orxonox
+{
+    CreateFactory(DebugFPSText);
+
+    DebugFPSText::DebugFPSText(BaseObject* creator) : OverlayText(creator)
+    {
+        RegisterObject(DebugFPSText);
+    }
+
+    DebugFPSText::~DebugFPSText()
+    {
+    }
+
+    void DebugFPSText::tick(float dt)
+    {
+        SUPER(DebugFPSText, tick, dt);
+
+        float fps = Game::getInstance().getAvgFPS();
+        this->setCaption(multi_cast<std::string>(fps));
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/debugging/DebugFPSText.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/debugging/DebugFPSText.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/debugging/DebugFPSText.h	(revision 6952)
@@ -0,0 +1,48 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _DebugFPSText_H__
+#define _DebugFPSText_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "tools/interfaces/Tickable.h"
+#include "overlays/OverlayText.h"
+
+namespace orxonox
+{
+    class _OverlaysExport DebugFPSText : public OverlayText, public Tickable
+    {
+    public:
+        DebugFPSText(BaseObject* creator);
+        virtual ~DebugFPSText();
+
+        virtual void tick(float dt);
+    };
+}
+#endif /* _DebugFPSText_H__ */
Index: /code/branches/rocket2/src/modules/overlays/debugging/DebugRTRText.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/debugging/DebugRTRText.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/debugging/DebugRTRText.cc	(revision 6952)
@@ -0,0 +1,55 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "DebugRTRText.h"
+
+#include "util/Convert.h"
+#include "core/CoreIncludes.h"
+#include "core/Game.h"
+
+namespace orxonox
+{
+    CreateFactory(DebugRTRText);
+
+    DebugRTRText::DebugRTRText(BaseObject* creator) : OverlayText(creator)
+    {
+        RegisterObject(DebugRTRText);
+    }
+
+    DebugRTRText::~DebugRTRText()
+    {
+    }
+
+    void DebugRTRText::tick(float dt)
+    {
+        SUPER(DebugRTRText, tick, dt);
+
+        float rtr = Game::getInstance().getAvgTickTime();
+        this->setCaption(multi_cast<std::string>(rtr));
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/debugging/DebugRTRText.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/debugging/DebugRTRText.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/debugging/DebugRTRText.h	(revision 6952)
@@ -0,0 +1,48 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _DebugRTRText_H__
+#define _DebugRTRText_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "tools/interfaces/Tickable.h"
+#include "overlays/OverlayText.h"
+
+namespace orxonox
+{
+    class _OverlaysExport DebugRTRText : public OverlayText, public Tickable
+    {
+    public:
+        DebugRTRText(BaseObject* creator);
+        virtual ~DebugRTRText();
+
+        virtual void tick(float dt);
+    };
+}
+#endif /* _DebugRTRText_H__ */
Index: /code/branches/rocket2/src/modules/overlays/hud/AnnounceMessage.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/AnnounceMessage.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/AnnounceMessage.cc	(revision 6952)
@@ -0,0 +1,60 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "AnnounceMessage.h"
+
+#include "core/CoreIncludes.h"
+#include "infos/PlayerInfo.h"
+
+namespace orxonox
+{
+    CreateFactory(AnnounceMessage);
+
+    AnnounceMessage::AnnounceMessage(BaseObject* creator) : FadeoutText(creator)
+    {
+        RegisterObject(AnnounceMessage);
+
+        this->owner_ = 0;
+
+        this->setDelay(3.0f);
+        this->setFadeouttime(1.0f);
+    }
+
+    void AnnounceMessage::announcemessage(const GametypeInfo* gtinfo, const std::string& message)
+    {
+        if (this->owner_ && this->owner_->getGametypeInfo() == gtinfo)
+            this->setCaption(message);
+    }
+
+    void AnnounceMessage::changedOwner()
+    {
+        SUPER(AnnounceMessage, changedOwner);
+
+        this->owner_ = orxonox_cast<PlayerInfo*>(this->getOwner());
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/hud/AnnounceMessage.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/AnnounceMessage.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/AnnounceMessage.h	(revision 6952)
@@ -0,0 +1,53 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _AnnounceMessage_H__
+#define _AnnounceMessage_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "interfaces/GametypeMessageListener.h"
+#include "overlays/FadeoutText.h"
+
+namespace orxonox
+{
+    class _OverlaysExport AnnounceMessage : public FadeoutText, public GametypeMessageListener
+    {
+        public:
+            AnnounceMessage(BaseObject* creator);
+            virtual ~AnnounceMessage() {}
+
+            virtual void changedOwner();
+
+            void announcemessage(const GametypeInfo* gtinfo, const std::string& message);
+
+        private:
+            PlayerInfo* owner_;
+    };
+}
+#endif /* _AnnounceMessage_H__ */
Index: /code/branches/rocket2/src/modules/overlays/hud/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,15 @@
+ADD_SOURCE_FILES(OVERLAYS_SRC_FILES
+  HUDBar.cc
+  HUDNavigation.cc
+  HUDRadar.cc
+  HUDSpeedBar.cc
+  HUDHealthBar.cc
+  HUDTimer.cc
+  ChatOverlay.cc
+  GametypeStatus.cc
+  AnnounceMessage.cc
+  KillMessage.cc
+  DeathMessage.cc
+  UnderAttackHealthBar.cc
+  TeamBaseMatchScore.cc
+)
Index: /code/branches/rocket2/src/modules/overlays/hud/ChatOverlay.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/ChatOverlay.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/ChatOverlay.cc	(revision 6952)
@@ -0,0 +1,117 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ChatOverlay.h"
+
+#include <string>
+#include <OgreTextAreaOverlayElement.h>
+
+#include "util/Convert.h"
+#include "util/DisplayStringConversions.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/Executor.h"
+
+#include "tools/Timer.h"
+#include "infos/PlayerInfo.h"
+#include "PlayerManager.h"
+
+namespace orxonox
+{
+    CreateFactory(ChatOverlay);
+
+    ChatOverlay::ChatOverlay(BaseObject* creator)
+        : OverlayText(creator)
+    {
+        RegisterObject(ChatOverlay);
+
+        this->displayTime_ = 0.0;
+
+        this->setConfigValues();
+    }
+
+    ChatOverlay::~ChatOverlay()
+    {
+        for (std::set<Timer*>::iterator it = this->timers_.begin(); it != this->timers_.end(); ++it)
+            delete (*it);
+    }
+
+    void ChatOverlay::setConfigValues()
+    {
+        SetConfigValue(displayTime_, 6.0f);
+    }
+
+    void ChatOverlay::incomingChat(const std::string& message, unsigned int senderID)
+    {
+        std::string text;
+
+        if (senderID != CLIENTID_UNKNOWN)
+        {
+            std::string name = "unknown";
+
+            PlayerInfo* player = PlayerManager::getInstance().getClient(senderID);
+            if (player)
+                name = player->getName();
+
+            text = name + ": " + message;
+        }
+        else
+        {
+            text = message;
+        }
+
+        this->messages_.push_back(multi_cast<Ogre::DisplayString>(text));
+        COUT(0) << "Chat: " << text << std::endl;
+
+        Timer* timer = new Timer();
+        this->timers_.insert(timer); // store the timer in a set to destroy it in the destructor
+        Executor* executor = createExecutor(createFunctor(&ChatOverlay::dropMessage, this));
+        executor->setDefaultValues(timer);
+        timer->setTimer(this->displayTime_, false, executor, true);
+
+        this->updateOverlayText();
+    }
+
+    void ChatOverlay::dropMessage(Timer* timer)
+    {
+        if (this->messages_.size() > 0)
+            this->messages_.pop_front();
+        this->updateOverlayText();
+        this->timers_.erase(timer); // the timer destroys itself, but we have to remove it from the set
+    }
+
+    void ChatOverlay::updateOverlayText()
+    {
+        this->text_->setCaption("");
+
+        for (std::list<Ogre::DisplayString>::reverse_iterator it = this->messages_.rbegin(); it != this->messages_.rend(); ++it)
+        {
+            this->text_->setCaption(this->text_->getCaption() + "\n" + (*it));
+        }
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/hud/ChatOverlay.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/ChatOverlay.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/ChatOverlay.h	(revision 6952)
@@ -0,0 +1,63 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ChatOverlay_H__
+#define _ChatOverlay_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include <list>
+#include <OgreOverlayElement.h>
+
+#include "network/ChatListener.h"
+#include "overlays/OverlayText.h"
+
+namespace orxonox
+{
+    class _OverlaysExport ChatOverlay : public OverlayText, public ChatListener
+    {
+        public:
+            ChatOverlay(BaseObject* creator);
+            virtual ~ChatOverlay();
+
+            void setConfigValues();
+
+        protected:
+            virtual void incomingChat(const std::string& message, unsigned int senderID);
+
+            std::list<Ogre::DisplayString> messages_;
+
+        private:
+            void updateOverlayText();
+            void dropMessage(Timer* timer);
+
+            float displayTime_;
+            std::set<Timer*> timers_;
+    };
+}
+#endif /* _DebugFPSText_H__ */
Index: /code/branches/rocket2/src/modules/overlays/hud/DeathMessage.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/DeathMessage.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/DeathMessage.cc	(revision 6952)
@@ -0,0 +1,60 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "DeathMessage.h"
+
+#include "core/CoreIncludes.h"
+#include "infos/PlayerInfo.h"
+
+namespace orxonox
+{
+    CreateFactory(DeathMessage);
+
+    DeathMessage::DeathMessage(BaseObject* creator) : FadeoutText(creator)
+    {
+        RegisterObject(DeathMessage);
+
+        this->owner_ = 0;
+
+        this->setDelay(2.0f);
+        this->setFadeouttime(0.5f);
+    }
+
+    void DeathMessage::deathmessage(const GametypeInfo* gtinfo, const std::string& message)
+    {
+        if (this->owner_ && this->owner_->getGametypeInfo() == gtinfo)
+            this->setCaption(message);
+    }
+
+    void DeathMessage::changedOwner()
+    {
+        SUPER(DeathMessage, changedOwner);
+
+        this->owner_ = orxonox_cast<PlayerInfo*>(this->getOwner());
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/hud/DeathMessage.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/DeathMessage.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/DeathMessage.h	(revision 6952)
@@ -0,0 +1,53 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _DeathMessage_H__
+#define _DeathMessage_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "interfaces/GametypeMessageListener.h"
+#include "overlays/FadeoutText.h"
+
+namespace orxonox
+{
+    class _OverlaysExport DeathMessage : public FadeoutText, public GametypeMessageListener
+    {
+        public:
+            DeathMessage(BaseObject* creator);
+            virtual ~DeathMessage() {}
+
+            virtual void changedOwner();
+
+            void deathmessage(const GametypeInfo* gtinfo, const std::string& message);
+
+        private:
+            PlayerInfo* owner_;
+    };
+}
+#endif /* _DeathMessage_H__ */
Index: /code/branches/rocket2/src/modules/overlays/hud/GametypeStatus.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/GametypeStatus.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/GametypeStatus.cc	(revision 6952)
@@ -0,0 +1,90 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "GametypeStatus.h"
+
+#include "util/Convert.h"
+#include "core/CoreIncludes.h"
+#include "infos/GametypeInfo.h"
+#include "infos/PlayerInfo.h"
+#include "worldentities/ControllableEntity.h"
+#include "worldentities/pawns/Spectator.h"
+
+namespace orxonox
+{
+    CreateFactory(GametypeStatus);
+
+    GametypeStatus::GametypeStatus(BaseObject* creator) : OverlayText(creator)
+    {
+        RegisterObject(GametypeStatus);
+
+        this->owner_ = 0;
+    }
+
+    GametypeStatus::~GametypeStatus()
+    {
+    }
+
+    void GametypeStatus::tick(float dt)
+    {
+        SUPER(GametypeStatus, tick, dt);
+
+        if (this->owner_ && this->owner_->getGametypeInfo() && this->owner_->getControllableEntity())
+        {
+            const GametypeInfo* gtinfo = this->owner_->getGametypeInfo();
+            ControllableEntity* ce = this->owner_->getControllableEntity();
+
+            if (!gtinfo->hasStarted() && !gtinfo->isStartCountdownRunning())
+            {
+                if (!this->owner_->isReadyToSpawn())
+                    this->setCaption("Press [Fire] to start the match");
+                else
+                    this->setCaption("Waiting for other players");
+            }
+            else if (!gtinfo->hasEnded())
+            {
+                if (gtinfo->isStartCountdownRunning())
+                    this->setCaption(multi_cast<std::string>(static_cast<int>(ceil(gtinfo->getStartCountdown()))));
+                else if (ce->isA(Class(Spectator)))
+                    this->setCaption("Press [Fire] to respawn");
+                else
+                    this->setCaption("");
+            }
+            else
+                this->setCaption("Game has ended");
+        }
+    }
+
+
+    void GametypeStatus::changedOwner()
+    {
+        SUPER(GametypeStatus, changedOwner);
+
+        this->owner_ = orxonox_cast<PlayerInfo*>(this->getOwner());
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/hud/GametypeStatus.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/GametypeStatus.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/GametypeStatus.h	(revision 6952)
@@ -0,0 +1,52 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GametypeStatus_H__
+#define _GametypeStatus_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "tools/interfaces/Tickable.h"
+#include "overlays/OverlayText.h"
+
+namespace orxonox
+{
+    class _OverlaysExport GametypeStatus : public OverlayText, public Tickable
+    {
+        public:
+            GametypeStatus(BaseObject* creator);
+            virtual ~GametypeStatus();
+
+            virtual void tick(float dt);
+            virtual void changedOwner();
+
+        private:
+            PlayerInfo* owner_;
+    };
+}
+#endif /* _GametypeStatus_H__ */
Index: /code/branches/rocket2/src/modules/overlays/hud/HUDBar.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/HUDBar.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/HUDBar.cc	(revision 6952)
@@ -0,0 +1,207 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      Felix Schulthess
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder
+ *
+ */
+
+#include "HUDBar.h"
+
+#include <OgreOverlayManager.h>
+#include <OgreMaterialManager.h>
+#include <OgreTechnique.h>
+#include <OgrePass.h>
+#include <OgrePanelOverlayElement.h>
+
+#include "util/Convert.h"
+#include "util/StringUtils.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(BarColour);
+
+    BarColour::BarColour(BaseObject* creator)
+        : BaseObject(creator)
+    {
+        RegisterObject(BarColour);
+
+        this->setColour(ColourValue(1.0, 1.0, 1.0, 1.0));
+        this->setPosition(0.0);
+    }
+
+    void BarColour::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        SUPER(BarColour, XMLPort, xmlElement, mode);
+
+        XMLPortParam(BarColour, "colour", setColour, getColour, xmlElement, mode);
+        XMLPortParam(BarColour, "position", setPosition, getPosition, xmlElement, mode);
+    }
+
+
+    unsigned int HUDBar::materialcount_s = 0;
+
+    HUDBar::HUDBar(BaseObject* creator)
+        : OrxonoxOverlay(creator), right2Left_(false), autoColour_(false)
+    {
+        RegisterObject(HUDBar);
+
+        // create new material
+        const std::string& materialname = "barmaterial" + multi_cast<std::string>(materialcount_s++);
+        Ogre::MaterialPtr material = static_cast<Ogre::MaterialPtr>(Ogre::MaterialManager::getSingleton().create(materialname, "General"));
+        material->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBT_TRANSPARENT_ALPHA);
+        this->textureUnitState_ = material->getTechnique(0)->getPass(0)->createTextureUnitState();
+        this->textureUnitState_->setTextureName("bar2.tga");
+        this->textureUnitState_->setNumMipmaps(0);
+        // use the default colour
+        this->textureUnitState_->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, ColourValue(0.2f, 0.7f, 0.2f));
+
+        this->bar_ = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
+            .createOverlayElement("Panel", "HUDBar_bar_" + getUniqueNumberString()));
+        this->bar_->setMaterialName(materialname);
+
+        this->value_ = 1.0f;  // initielize with 1.0f to trigger a change when calling setValue(0.0f) on the line below
+        this->setAutoColour(true);
+        this->setValue(0.0f); // <--
+        this->setRightToLeft(false);
+        this->currentColour_ = ColourValue::White;
+
+        this->background_->addChild(bar_);
+    }
+
+    HUDBar::~HUDBar()
+    {
+        if (this->isInitialized())
+        {
+            Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->bar_);
+            for (std::vector<BarColour*>::const_iterator it = this->barColours_.begin(); it != this->barColours_.end(); )
+                (*it++)->destroy();
+        }
+    }
+
+    void HUDBar::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        SUPER(HUDBar, XMLPort, xmlElement, mode);
+
+        XMLPortParam(HUDBar, "initialvalue", setValue,       getValue,       xmlElement, mode);
+        XMLPortParam(HUDBar, "righttoleft",  setRightToLeft, getRightToLeft, xmlElement, mode);
+        XMLPortParam(HUDBar, "autocolour",   setAutoColour,  getAutoColour,  xmlElement, mode);
+        XMLPortParam(HUDBar, "bartexture",   setBarTexture,  getBarTexture, xmlElement, mode);
+        XMLPortObject(HUDBar, BarColour, "", addColour, getColour, xmlElement, mode);
+    }
+
+    void HUDBar::valueChanged()
+    {
+        if (this->autoColour_ && this->textureUnitState_)
+        {
+            // set colour
+            if (this->colours_.size() > 0)
+            {
+                ColourValue colour1(0, 0, 0, 1);
+                ColourValue colour2 = this->colours_.rbegin()->second;
+                float value1(0);
+                float value2 = this->colours_.rbegin()->first;
+                for (std::map<float, ColourValue>::reverse_iterator it = this->colours_.rbegin(); it != this->colours_.rend(); ++it)
+                {
+                    colour1 = colour2;
+                    value1 = value2;
+                    colour2 = it->second;
+                    value2 = it->first;
+
+                    if (value2 < this->value_)
+                        break;
+                }
+
+                if (value2 > this->value_)
+                {
+                    this->textureUnitState_->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, colour2);
+                    this->currentColour_ = colour2;
+                }
+                else if (value1 < this->value_)
+                {
+                    this->textureUnitState_->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, colour1);
+                    this->currentColour_ = colour1;
+                }
+                else
+                {
+                    //float interpolationfactor = (this->value_ - value2) / (value1 - value2);
+                    float interpolationfactor = interpolateSmooth((this->value_ - value2) / (value1 - value2), 0.0f, 1.0f);
+                    this->currentColour_ = colour1 * interpolationfactor + colour2 * (1 - interpolationfactor);
+                    this->textureUnitState_->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, this->currentColour_);
+
+                }
+            }
+        }
+
+        // set value
+        if (this->right2Left_)
+        {
+            // backward casew
+            this->bar_->setPosition(0.06f + 0.88f * (1 - this->value_), 0.0f);
+            this->bar_->setDimensions(0.88f * this->value_, 1.0f);
+        }
+        else
+        {
+            // default case
+            this->bar_->setPosition(0.06f, 0.0f);
+            this->bar_->setDimensions(0.88f * this->value_, 1.0f);
+        }
+        if (this->value_ != 0)
+            this->bar_->setTiling(this->value_, 1.0);
+    }
+
+    void HUDBar::addColour(BarColour* colour)
+    {
+        float value = clamp<float>(colour->getPosition(), 0.0, 1.0);
+        this->colours_[value] = colour->getColour();
+
+        this->barColours_.push_back(colour);
+    }
+
+    BarColour* HUDBar::getColour(unsigned int index)
+    {
+        if (index < this->barColours_.size())
+            return barColours_[index];
+        else
+            return 0;
+    }
+
+    void HUDBar::clearColours()
+    {
+        this->colours_.clear();
+    }
+
+    void HUDBar::setBarTexture(const std::string& texture)
+    {
+        this->textureUnitState_->setTextureName(texture);
+    }
+
+    const std::string& HUDBar::getBarTexture() const
+    {
+        return this->textureUnitState_->getTextureName();
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/hud/HUDBar.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/HUDBar.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/HUDBar.h	(revision 6952)
@@ -0,0 +1,139 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      Felix Schulthess
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder
+ *
+ */
+
+#ifndef _HUDBar_H__
+#define _HUDBar_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include <map>
+#include <vector>
+
+#include "util/Math.h"
+#include "util/OgreForwardRefs.h"
+#include "core/BaseObject.h"
+#include "overlays/OrxonoxOverlay.h"
+
+namespace orxonox
+{
+    class _OverlaysExport BarColour : public BaseObject
+    {
+    public:
+        BarColour(BaseObject* creator);
+        virtual ~BarColour() { }
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+
+        void setColour(const ColourValue& colour) { this->colour_ = colour; }
+        const ColourValue& getColour() const { return this->colour_; }
+
+        void setPosition(float pos) { this->position_ = pos; }
+        float getPosition() const    { return this->position_; }
+
+    private:
+        ColourValue colour_;
+        float position_;
+    };
+
+
+    class _OverlaysExport HUDBar : public OrxonoxOverlay
+    {
+    public:
+        HUDBar(BaseObject* creator);
+        virtual ~HUDBar();
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+
+        void clearColours();
+
+        inline void setRightToLeft(bool r2l)
+        {
+            if (r2l != this->right2Left_)
+            {
+                this->right2Left_ = r2l;
+                this->valueChanged();
+            }
+        }
+        inline bool getRightToLeft() const
+            { return this->right2Left_; }
+
+        inline void setValue(float value)
+        {
+            float temp = clamp(value, 0.0f, 1.0f);
+            if (temp != this->value_)
+            {
+                this->value_ = temp;
+                this->valueChanged();
+            }
+        }
+        inline float getValue() const
+            { return this->value_; }
+
+        inline void setAutoColour(bool val)
+        {
+            if (val != this->autoColour_)
+            {
+                this->autoColour_ = val;
+                this->valueChanged();
+
+                if (!val)
+                    this->currentColour_ = ColourValue::White;
+            }
+        }
+        inline bool getAutoColour() const
+            { return this->autoColour_; }
+
+        void setBarTexture(const std::string& texture);
+        const std::string& getBarTexture() const;
+
+        inline const ColourValue& getCurrentBarColour() const
+            { return this->currentColour_; }
+
+    protected:
+        virtual void valueChanged();
+
+    private:
+        void addColour(BarColour* colour);
+        BarColour* getColour(unsigned int index);
+
+        bool right2Left_;
+        bool autoColour_;                   //!< whether bar changes colour automatically
+        float value_;                       //!< progress of bar
+        ColourValue currentColour_;
+
+        Ogre::PanelOverlayElement* bar_;
+        Ogre::TextureUnitState* textureUnitState_;
+        std::map<float, ColourValue> colours_;
+        std::vector<BarColour*> barColours_;
+
+        static unsigned int materialcount_s;
+    };
+}
+#endif /* _HUDBar_H__ */
Index: /code/branches/rocket2/src/modules/overlays/hud/HUDHealthBar.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/HUDHealthBar.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/HUDHealthBar.cc	(revision 6952)
@@ -0,0 +1,141 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "HUDHealthBar.h"
+
+#include "util/Convert.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "worldentities/pawns/Pawn.h"
+#include "overlays/OverlayGroup.h"
+
+namespace orxonox
+{
+    CreateFactory(HUDHealthBar);
+
+    HUDHealthBar::HUDHealthBar(BaseObject* creator) : HUDBar(creator)
+    {
+        RegisterObject(HUDHealthBar);
+
+        this->owner_ = 0;
+        this->bUseBarColour_ = false;
+
+        this->textoverlay_ = new OverlayText(this);
+
+        assert(this->textoverlay_.get());
+
+        this->textoverlay_->setCaption("");
+    }
+
+    HUDHealthBar::~HUDHealthBar()
+    {
+        if (this->isInitialized())
+        {
+            this->textoverlay_->destroy();
+            this->textoverlay_ = 0;
+        }
+    }
+
+    void HUDHealthBar::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(HUDHealthBar, XMLPort, xmlelement, mode);
+
+        XMLPortParam(HUDHealthBar, "showtext",          setTextVisible,          getTextVisible,          xmlelement, mode).defaultValues(true);
+        XMLPortParam(HUDHealthBar, "textfont",          setTextFont,             getTextFont,             xmlelement, mode).defaultValues("Monofur");
+        XMLPortParam(HUDHealthBar, "textusebarcolour",  setTextUseBarColour,     getTextUseBarColour,     xmlelement, mode).defaultValues(false);
+        XMLPortParam(HUDHealthBar, "textcolour",        setTextColour,           getTextColour,           xmlelement, mode).defaultValues(ColourValue(1.0, 1.0, 1.0, 1.0));
+        XMLPortParam(HUDHealthBar, "textsize",          setTextSize,             getTextSize,             xmlelement, mode).defaultValues(1.0f);
+        XMLPortParam(HUDHealthBar, "textalign",         setTextAlignmentString,  getTextAlignmentString,  xmlelement, mode).defaultValues("left");
+        XMLPortParam(HUDHealthBar, "textoffset",        setTextOffset,           getTextOffset,           xmlelement, mode).defaultValues(Vector2::ZERO);
+        XMLPortParam(HUDHealthBar, "textpickpoint",     setTextPickPoint,        getTextPickPoint,        xmlelement, mode).defaultValues(Vector2::ZERO);
+        XMLPortParam(HUDHealthBar, "textrotation",      setTextRotation,         getTextRotation,         xmlelement, mode).defaultValues(0.0f);
+        XMLPortParam(HUDHealthBar, "textcorrectaspect", setTextAspectCorrection, getTextAspectCorrection, xmlelement, mode).defaultValues(true);
+        XMLPortParam(HUDHealthBar, "textspacewidth",    setTextSpaceWidth,       getTextSpaceWidth,       xmlelement, mode).defaultValues(true);
+    }
+
+    void HUDHealthBar::tick(float dt)
+    {
+        SUPER(HUDHealthBar, tick, dt);
+
+        if (this->owner_)
+        {
+            this->setValue(this->owner_->getHealth() / this->owner_->getInitialHealth());
+            this->textoverlay_->setCaption(multi_cast<std::string>(static_cast<int>(this->owner_->getHealth())));
+        }
+        else
+        {
+            this->setValue(0);
+            this->textoverlay_->setCaption("0");
+        }
+
+        if (this->bUseBarColour_)
+            this->textoverlay_->setColour(this->getCurrentBarColour());
+    }
+
+    void HUDHealthBar::changedOwner()
+    {
+        SUPER(HUDHealthBar, changedOwner);
+
+        this->owner_ = orxonox_cast<Pawn*>(this->getOwner());
+    }
+
+    void HUDHealthBar::changedOverlayGroup()
+    {
+        SUPER(HUDHealthBar, changedOverlayGroup);
+
+        this->getOverlayGroup()->addElement(this->textoverlay_.get());
+    }
+
+    void HUDHealthBar::changedVisibility()
+    {
+        SUPER(HUDHealthBar, changedVisibility);
+
+        this->textoverlay_->setVisible(this->isVisible());
+    }
+
+    void HUDHealthBar::changedName()
+    {
+        SUPER(HUDHealthBar, changedName);
+
+        this->textoverlay_->setName(this->getName() + "text");
+    }
+
+    void HUDHealthBar::setTextColour(const ColourValue& colour)
+    {
+        this->textColour_ = colour;
+        if (!this->bUseBarColour_)
+            this->textoverlay_->setColour(colour);
+    }
+
+    void HUDHealthBar::setTextUseBarColour(bool bUseBarColour)
+    {
+        this->bUseBarColour_ = bUseBarColour;
+        if (!bUseBarColour)
+            this->textoverlay_->setColour(this->textColour_);
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/hud/HUDHealthBar.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/HUDHealthBar.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/HUDHealthBar.h	(revision 6952)
@@ -0,0 +1,119 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _HUDHealthBar_H__
+#define _HUDHealthBar_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "util/Math.h"
+#include "tools/interfaces/Tickable.h"
+#include "overlays/OverlayText.h"
+#include "HUDBar.h"
+
+namespace orxonox
+{
+    class _OverlaysExport HUDHealthBar : public HUDBar, public Tickable
+    {
+        public:
+            HUDHealthBar(BaseObject* creator);
+            virtual ~HUDHealthBar();
+
+            virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+            virtual void tick(float dt);
+            virtual void changedOwner();
+            virtual void changedOverlayGroup();
+            virtual void changedVisibility();
+            virtual void changedName();
+
+            inline void setTextFont(const std::string& font)
+                { if (!font.empty()) { this->textoverlay_->setFont(font); } }
+            inline const std::string& getTextFont() const
+                { return this->textoverlay_->getFont(); }
+
+            void setTextColour(const ColourValue& colour);
+            inline const ColourValue& getTextColour() const
+                { return this->textoverlay_->getColour(); }
+
+            void setTextUseBarColour(bool bUseBarColour);
+            inline bool getTextUseBarColour() const
+                { return this->bUseBarColour_; }
+
+            inline void setTextAlignment(OverlayText::Alignment alignment)
+                { this->textoverlay_->setAlignment(alignment); }
+            inline OverlayText::Alignment getTextAlignment() const
+                { return this->textoverlay_->getAlignment(); }
+
+            void setTextAlignmentString(const std::string& alignment)
+                { this->textoverlay_->setAlignmentString(alignment); }
+            std::string getTextAlignmentString() const
+                { return this->textoverlay_->getAlignmentString(); }
+
+            inline void setTextSize(float size)
+                { this->textoverlay_->setTextSize(size); }
+            inline float getTextSize() const
+                { return this->textoverlay_->getTextSize(); }
+
+            inline void setTextVisible(bool bVisible)
+                { this->textoverlay_->setVisible(bVisible); }
+            inline bool getTextVisible() const
+                { return this->textoverlay_->isVisible(); }
+
+            inline void setTextPickPoint(const Vector2& pickpoint)
+                { this->textoverlay_->setPickPoint(pickpoint); }
+            inline Vector2 getTextPickPoint() const
+                { return this->textoverlay_->getPickPoint(); }
+
+            inline void setTextOffset(const Vector2& position)
+                { this->textoverlay_->setPosition(this->getPosition() + (position - this->getPickPoint()) * this->getSize()); }
+            inline Vector2 getTextOffset() const
+                { return (this->textoverlay_->getPosition() - this->getPosition()) / this->getSize() + this->getPickPoint(); }
+
+            inline void setTextAspectCorrection(bool correct)
+                { this->textoverlay_->setAspectCorrection(correct); }
+            inline bool getTextAspectCorrection() const
+                { return this->textoverlay_->getAspectCorrection(); }
+
+            inline void setTextRotation(const Degree& angle)
+                { this->textoverlay_->setRotation(angle); }
+            inline const Degree& getTextRotation() const
+                { return this->textoverlay_->getRotation(); }
+
+            inline void setTextSpaceWidth(float width)
+                { this->textoverlay_->setSpaceWidth(width); }
+            inline float getTextSpaceWidth() const
+                { return this->textoverlay_->getSpaceWidth(); }
+
+        private:
+            WeakPtr<Pawn> owner_;
+            SmartPtr<OverlayText> textoverlay_;
+            bool bUseBarColour_;
+            ColourValue textColour_;
+    };
+}
+#endif /* _HUDHealthBar_H__ */
Index: /code/branches/rocket2/src/modules/overlays/hud/HUDNavigation.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/HUDNavigation.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/HUDNavigation.cc	(revision 6952)
@@ -0,0 +1,325 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Felix Schulthess
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#include "HUDNavigation.h"
+
+#include <OgreCamera.h>
+#include <OgreFontManager.h>
+#include <OgreOverlayManager.h>
+#include <OgreTextAreaOverlayElement.h>
+#include <OgrePanelOverlayElement.h>
+
+#include "util/Math.h"
+#include "util/Convert.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "CameraManager.h"
+#include "Scene.h"
+#include "Radar.h"
+#include "graphics/Camera.h"
+#include "controllers/HumanController.h"
+#include "worldentities/pawns/Pawn.h"
+#include "worldentities/WorldEntity.h"
+#include "interfaces/RadarViewable.h"
+
+namespace orxonox
+{
+    CreateFactory(HUDNavigation);
+
+    HUDNavigation::HUDNavigation(BaseObject* creator)
+        : OrxonoxOverlay(creator)
+    {
+        RegisterObject(HUDNavigation);
+
+        // Set default values
+        setFont("Monofur");
+        setTextSize(0.05f);
+        setNavMarkerSize(0.05f);
+    }
+
+    HUDNavigation::~HUDNavigation()
+    {
+        if (this->isInitialized())
+        {
+            for (ObjectMap::iterator it = activeObjectList_.begin(); it != activeObjectList_.end();)
+                removeObject((it++)->first);
+        }
+    }
+
+    void HUDNavigation::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        SUPER(HUDNavigation, XMLPort, xmlElement, mode);
+
+        XMLPortParam(HUDNavigation, "font",          setFont,          getFont,          xmlElement, mode);
+        XMLPortParam(HUDNavigation, "textSize",      setTextSize,      getTextSize,      xmlElement, mode);
+        XMLPortParam(HUDNavigation, "navMarkerSize", setNavMarkerSize, getNavMarkerSize, xmlElement, mode);
+    }
+
+    void HUDNavigation::setFont(const std::string& font)
+    {
+        const Ogre::ResourcePtr& fontPtr = Ogre::FontManager::getSingleton().getByName(font);
+        if (fontPtr.isNull())
+        {
+            COUT(2) << "Warning: HUDNavigation: Font '" << font << "' not found" << std::endl;
+            return;
+        }
+        fontName_ = font;
+        for (ObjectMap::iterator it = activeObjectList_.begin(); it != activeObjectList_.end(); ++it)
+        {
+            if (it->second.text_ != NULL)
+                it->second.text_->setFontName(fontName_);
+        }
+    }
+
+    const std::string& HUDNavigation::getFont() const
+    {
+        return fontName_;
+    }
+
+    void HUDNavigation::setTextSize(float size)
+    {
+        if (size <= 0.0f)
+        {
+            COUT(2) << "Warning: HUDNavigation: Negative font size not allowed" << std::endl;
+            return;
+        }
+        textSize_ = size;
+        for (ObjectMap::iterator it = activeObjectList_.begin(); it!=activeObjectList_.end(); ++it)
+        {
+            if (it->second.text_)
+                it->second.text_->setCharHeight(size);
+        }
+    }
+
+    float HUDNavigation::getTextSize() const
+    {
+        return textSize_;
+    }
+
+    void HUDNavigation::tick(float dt)
+    {
+        SUPER(HUDNavigation, tick, dt);
+
+        Camera* cam = CameraManager::getInstance().getActiveCamera();
+        if (cam == NULL)
+            return;
+        const Matrix4& camTransform = cam->getOgreCamera()->getProjectionMatrix() * cam->getOgreCamera()->getViewMatrix();
+
+        for (ObjectMap::iterator it = activeObjectList_.begin(); it != activeObjectList_.end(); ++it)
+        {
+            // Get Distance to HumanController and save it in the TextAreaOverlayElement.
+            int dist = (int)((it->first->getRVWorldPosition() - HumanController::getLocalControllerSingleton()->getControllableEntity()->getWorldPosition()).length() + 0.5f);
+            it->second.text_->setCaption(multi_cast<std::string>(dist));
+            float textLength = multi_cast<std::string>(dist).size() * it->second.text_->getCharHeight() * 0.3f;
+
+            // Transform to screen coordinates
+            Vector3 pos = camTransform * it->first->getRVWorldPosition();
+
+            bool outOfView = true;
+            if (pos.z > 1.0)
+            {
+                // z > 1.0 means that the object is behind the camera
+                outOfView = true;
+                // we have to switch all coordinates (if you don't know why,
+                // try linear algebra lectures, because I can't explain..)
+                pos.x = -pos.x;
+                pos.y = -pos.y;
+            }
+            else
+                outOfView = pos.x < -1.0 || pos.x > 1.0 || pos.y < -1.0 || pos.y > 1.0;
+
+            if (outOfView)
+            {
+                // Object is not in view
+
+                // Change material only if outOfView changed
+                if (!it->second.wasOutOfView_)
+                {
+                    it->second.panel_->setMaterialName("Orxonox/NavArrows");
+                    it->second.wasOutOfView_ = true;
+                }
+
+                // Switch between top, bottom, left and right position of the arrow at the screen border
+                if (pos.x < pos.y)
+                {
+                    if (pos.y > -pos.x)
+                    {
+                        // Top
+                        float position = pos.x / pos.y + 1.0f;
+                        it->second.panel_->setPosition((position - it->second.panel_->getWidth()) * 0.5f, 0.0f);
+                        it->second.panel_->setUV(0.5f, 0.0f, 1.0f, 0.5f);
+                        it->second.text_->setLeft((position - textLength) * 0.5f);
+                        it->second.text_->setTop(it->second.panel_->getHeight());
+                    }
+                    else
+                    {
+                        // Left
+                        float position = pos.y / pos.x + 1.0f;
+                        it->second.panel_->setPosition(0.0f, (position - it->second.panel_->getWidth()) * 0.5f);
+                        it->second.panel_->setUV(0.0f, 0.0f, 0.5f, 0.5f);
+                        it->second.text_->setLeft(it->second.panel_->getWidth() + 0.01f);
+                        it->second.text_->setTop((position - it->second.text_->getCharHeight()) * 0.5f);
+                    }
+                }
+                else
+                {
+
+                    if (pos.y < -pos.x)
+                    {
+                        // Bottom
+                        float position = -pos.x / pos.y + 1.0f;
+                        it->second.panel_->setPosition((position - it->second.panel_->getWidth()) * 0.5f, 1.0f - it->second.panel_->getHeight());
+                        it->second.panel_->setUV(0.0f, 0.5f, 0.5f, 1.0f);
+                        it->second.text_->setLeft((position - textLength) * 0.5f);
+                        it->second.text_->setTop(1.0f - it->second.panel_->getHeight() - it->second.text_->getCharHeight());
+                    }
+                    else
+                    {
+                        // Right
+                        float position = -pos.y / pos.x + 1.0f;
+                        it->second.panel_->setPosition(1.0f - it->second.panel_->getWidth(), (position - it->second.panel_->getHeight()) * 0.5f);
+                        it->second.panel_->setUV(0.5f, 0.5f, 1.0f, 1.0f);
+                        it->second.text_->setLeft(1.0f - it->second.panel_->getWidth() - textLength - 0.01f);
+                        it->second.text_->setTop((position - it->second.text_->getCharHeight()) * 0.5f);
+                    }
+                }
+            }
+            else
+            {
+                // Object is in view
+
+                // Change material only if outOfView changed
+                if (it->second.wasOutOfView_)
+                {
+                    it->second.panel_->setMaterialName("Orxonox/NavTDC");
+                    it->second.wasOutOfView_ = false;
+                }
+
+                // Position marker
+                it->second.panel_->setUV(0.0f, 0.0f, 1.0f, 1.0f);
+                it->second.panel_->setLeft((pos.x + 1.0f - it->second.panel_->getWidth()) * 0.5f);
+                it->second.panel_->setTop((-pos.y + 1.0f - it->second.panel_->getHeight()) * 0.5f);
+
+                // Position text
+                it->second.text_->setLeft((pos.x + 1.0f + it->second.panel_->getWidth()) * 0.5f);
+                it->second.text_->setTop((-pos.y + 1.0f + it->second.panel_->getHeight()) * 0.5f);
+            }
+
+            // Make sure the overlays are shown
+            it->second.panel_->show();
+            it->second.text_->show();
+        }
+    }
+
+
+    /** Overridden method of OrxonoxOverlay.
+    @details
+        Usually the entire overlay scales with scale().
+        Here we obviously have to adjust this.
+    */
+    void HUDNavigation::sizeChanged()
+    {
+        // Use size to compensate for aspect ratio if enabled.
+        float xScale = this->getActualSize().x;
+        float yScale = this->getActualSize().y;
+
+        for (ObjectMap::iterator it = activeObjectList_.begin(); it!=activeObjectList_.end(); ++it)
+        {
+            if (it->second.panel_ != NULL)
+                it->second.panel_->setDimensions(navMarkerSize_ * xScale, navMarkerSize_ * yScale);
+            if (it->second.text_ != NULL)
+                it->second.text_->setCharHeight(it->second.text_->getCharHeight() * yScale);
+        }
+    }
+
+    void HUDNavigation::addObject(RadarViewable* object)
+    {
+        if (object == NULL)
+            return;
+
+        // Don't display our own ship
+        if (object == dynamic_cast<RadarViewable*>(this->getOwner()))
+            return;
+
+        // Object hasn't been added yet (we know that)
+        assert(this->activeObjectList_.find(object) == this->activeObjectList_.end());
+
+        // Scales used for dimensions and text size
+        float xScale = this->getActualSize().x;
+        float yScale = this->getActualSize().y;
+
+        // Create everything needed to display the object on the radar and add it to the map
+
+        // Create arrow/marker
+        Ogre::PanelOverlayElement* panel = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
+            .createOverlayElement("Panel", "HUDNavigation_navMarker_" + getUniqueNumberString()));
+        panel->setMaterialName("Orxonox/NavTDC");
+        panel->setDimensions(navMarkerSize_ * xScale, navMarkerSize_ * yScale);
+
+        Ogre::TextAreaOverlayElement* text = static_cast<Ogre::TextAreaOverlayElement*>(Ogre::OverlayManager::getSingleton()
+            .createOverlayElement("TextArea", "HUDNavigation_navText_" + getUniqueNumberString()));
+        text->setFontName(this->fontName_);
+        text->setCharHeight(text->getCharHeight() * yScale);
+
+        ObjectInfo tempStruct = {panel, text, false};
+        activeObjectList_[object] = tempStruct;
+
+        this->background_->addChild(panel);
+        this->background_->addChild(text);
+    }
+
+    void HUDNavigation::removeObject(RadarViewable* viewable)
+    {
+        ObjectMap::iterator it = activeObjectList_.find(viewable);
+
+        if (activeObjectList_.find(viewable) != activeObjectList_.end())
+        {
+            // Detach overlays
+            this->background_->removeChild(it->second.panel_->getName());
+            this->background_->removeChild(it->second.text_->getName());
+            // Properly destroy the overlay elements (do not use delete!)
+            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.panel_);
+            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second.text_);
+            // Remove from the list
+            activeObjectList_.erase(viewable);
+        }
+        else
+            COUT(2) << "Warning, HUDNavigation: Attempting to remove non-existent object" << std::endl;
+    }
+
+    void HUDNavigation::changedOwner()
+    {
+        // TODO: Delete old objects?
+        const std::set<RadarViewable*>& respawnObjects = this->getOwner()->getScene()->getRadar()->getRadarObjects();
+        for (std::set<RadarViewable*>::const_iterator it = respawnObjects.begin(); it != respawnObjects.end(); ++it)
+        {
+            if (!(*it)->isHumanShip_)
+                this->addObject(*it);
+        }
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/hud/HUDNavigation.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/HUDNavigation.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/HUDNavigation.h	(revision 6952)
@@ -0,0 +1,96 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Felix Schulthess
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#ifndef _HUDNavigation_H__
+#define _HUDNavigation_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include <map>
+#include <string>
+
+#include "util/OgreForwardRefs.h"
+#include "tools/interfaces/Tickable.h"
+#include "interfaces/RadarListener.h"
+#include "overlays/OrxonoxOverlay.h"
+
+namespace orxonox
+{
+    class _OverlaysExport HUDNavigation : public OrxonoxOverlay, public Tickable, public RadarListener
+    {
+    public:
+        HUDNavigation(BaseObject* creator);
+        virtual ~HUDNavigation();
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+        virtual void tick(float dt);
+
+        virtual void addObject(RadarViewable* object);
+        virtual void removeObject(RadarViewable* viewable);
+        virtual void objectChanged(RadarViewable* viewable) {}
+
+        virtual void changedOwner();
+        virtual void sizeChanged();
+        virtual void angleChanged() { }
+        virtual void positionChanged() { }
+        virtual void radarTick(float dt) {}
+
+        inline float getRadarSensitivity() const
+            { return 1.0f; }
+
+    private:
+        struct ObjectInfo
+        {
+            Ogre::PanelOverlayElement* panel_;
+            Ogre::TextAreaOverlayElement* text_;
+            bool outOfView_;
+            bool wasOutOfView_;
+        };
+
+        // XMLPort accessors
+        void setNavMarkerSize(float size)
+            { navMarkerSize_ = size; this->sizeChanged(); }
+        float getNavMarkerSize() const
+            { return navMarkerSize_; }
+
+        void setTextSize(float size);
+        float getTextSize() const;
+
+        void setFont(const std::string& font);
+        const std::string& getFont() const;
+
+        typedef std::map<RadarViewable*, ObjectInfo > ObjectMap;
+        ObjectMap activeObjectList_;
+
+        float navMarkerSize_;
+        std::string fontName_;
+        float textSize_;
+    };
+}
+
+#endif /* _HUDNavigation_H__ */
Index: /code/branches/rocket2/src/modules/overlays/hud/HUDRadar.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/HUDRadar.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/HUDRadar.cc	(revision 6952)
@@ -0,0 +1,196 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *      Felix Schulthess
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#include "HUDRadar.h"
+
+#include <OgreOverlayManager.h>
+#include <OgrePanelOverlayElement.h>
+
+#include "util/Math.h"
+#include "util/StringUtils.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "tools/TextureGenerator.h"
+#include "worldentities/WorldEntity.h"
+#include "worldentities/pawns/Pawn.h"
+#include "Scene.h"
+#include "Radar.h"
+
+namespace orxonox
+{
+    CreateFactory(HUDRadar); 
+
+    HUDRadar::HUDRadar(BaseObject* creator)
+        : OrxonoxOverlay(creator)
+    {
+        RegisterObject(HUDRadar);
+
+        this->marker_ = static_cast<Ogre::PanelOverlayElement*>(Ogre::OverlayManager::getSingleton()
+            .createOverlayElement("Panel", "HUDRadar_marker_" + getUniqueNumberString()));
+        this->marker_->setMaterialName("Orxonox/RadarMarker");
+        this->overlay_->add2D(this->marker_);
+        this->marker_->hide();
+
+        this->setRadarSensitivity(1.0f);
+        this->setHalfDotSizeDistance(3000.0f);
+        this->setMaximumDotSize(0.1f);
+
+        this->shapeMaterials_[RadarViewable::Dot]      = "RadarDot.tga";
+        this->shapeMaterials_[RadarViewable::Triangle] = "RadarTriangle.tga";
+        this->shapeMaterials_[RadarViewable::Square]   = "RadarSquare.tga";
+
+        this->owner_ = 0;
+    }
+
+    HUDRadar::~HUDRadar()
+    {
+        if (this->isInitialized())
+        {
+            Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->marker_);
+            for (std::map<RadarViewable*,Ogre::PanelOverlayElement*>::iterator it = this->radarObjects_.begin();
+                it != this->radarObjects_.end(); ++it)
+            {
+                Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second);
+            }
+        }
+    }
+
+    void HUDRadar::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        SUPER(HUDRadar, XMLPort, xmlElement, mode);
+
+        XMLPortParam(HUDRadar, "sensitivity", setRadarSensitivity, getRadarSensitivity, xmlElement, mode);
+        XMLPortParam(HUDRadar, "halfDotSizeDistance", setHalfDotSizeDistance, getHalfDotSizeDistance, xmlElement, mode);
+        XMLPortParam(HUDRadar, "maximumDotSize", setMaximumDotSize, getMaximumDotSize, xmlElement, mode);
+    }
+
+    void HUDRadar::addObject(RadarViewable* object)
+    {
+        if (object == dynamic_cast<RadarViewable*>(this->owner_))
+            return;
+
+        // Make sure the object hasn't been added yet
+        assert( this->radarObjects_.find(object) == this->radarObjects_.end() );
+
+        // Create everything needed to display the object on the radar and add it to the map
+        Ogre::PanelOverlayElement* panel;
+        panel = static_cast<Ogre::PanelOverlayElement*>(
+            Ogre::OverlayManager::getSingleton().createOverlayElement("Panel", "RadarDot" + getUniqueNumberString()));
+        this->overlay_->add2D(panel);
+        // get right material
+        panel->setMaterialName(TextureGenerator::getMaterialName(
+            shapeMaterials_[object->getRadarObjectShape()], object->getRadarObjectColour()));
+        this->radarObjects_[object] = panel;
+    }
+
+    void HUDRadar::removeObject(RadarViewable* object)
+    {
+        // If object was added at all then remove it
+        std::map<RadarViewable*,Ogre::PanelOverlayElement*>::iterator it;
+        it = this->radarObjects_.find( object );
+        if( it != this->radarObjects_.end() )
+        {
+            Ogre::OverlayManager::getSingleton().destroyOverlayElement(it->second);
+            this->radarObjects_.erase(it);
+        }
+    }
+
+    void HUDRadar::objectChanged( RadarViewable* rv )
+    {
+        assert( this->radarObjects_.find(rv) != this->radarObjects_.end() );
+        Ogre::PanelOverlayElement* panel = this->radarObjects_[rv];
+        panel->setMaterialName(TextureGenerator::getMaterialName(
+            shapeMaterials_[rv->getRadarObjectShape()], rv->getRadarObjectColour()));
+    }
+
+    void HUDRadar::gatherObjects()
+    {
+        const std::set<RadarViewable*>& objectSet = this->getCreator()->getScene()->getRadar()->getRadarObjects();
+        std::set<RadarViewable*>::const_iterator it;
+        for( it=objectSet.begin(); it!=objectSet.end(); ++it )
+            this->addObject(*it);
+    }
+
+    void HUDRadar::radarTick(float dt)
+    {
+        // Make sure the owner of the radar was defined
+        if( !this->owner_ )
+        {
+            CCOUT(0) << "No owner defined" << std::endl;
+            assert(0);
+        }
+
+        this->marker_->hide();      // in case that no object is in focus
+        // get the focus object
+        Radar* radar = this->getOwner()->getScene()->getRadar();
+        const RadarViewable* focusObject = radar->getFocus();
+
+        // update the distances for all objects
+        std::map<RadarViewable*,Ogre::PanelOverlayElement*>::iterator it;
+        for( it = this->radarObjects_.begin(); it != this->radarObjects_.end(); ++it )
+        {
+            // Make sure the object really is a WorldEntity
+            const WorldEntity* wePointer = it->first->getWorldEntity();
+            if( !wePointer )
+            {
+                CCOUT(0) << "Cannot display a non-WorldEntitiy on the radar" << std::endl;
+                assert(0);
+            }
+            bool isFocus = (it->first == focusObject);
+            // set size to fit distance...
+            float distance = (wePointer->getWorldPosition() - this->owner_->getPosition()).length();
+            // calculate the size with 1/distance dependency for simplicity (instead of exp(-distance * lambda)
+            float size = maximumDotSize_ * halfDotSizeDistance_ / (halfDotSizeDistance_ + distance);
+            it->second->setDimensions(size, size);
+
+            // calc position on radar...
+            Vector2 coord = get2DViewcoordinates(this->owner_->getPosition(), this->owner_->getOrientation() * WorldEntity::FRONT, this->owner_->getOrientation() * WorldEntity::UP, wePointer->getWorldPosition());
+            coord *= Ogre::Math::PI / 3.5f; // small adjustment to make it fit the texture
+            it->second->setPosition((1.0f + coord.x - size) * 0.5f, (1.0f - coord.y - size) * 0.5f);
+            it->second->show();
+
+            // if this object is in focus, then set the focus marker
+            if (isFocus)
+            {
+                this->marker_->setDimensions(size * 1.5f, size * 1.5f);
+                this->marker_->setPosition((1.0f + coord.x - size * 1.5f) * 0.5f, (1.0f - coord.y - size * 1.5f) * 0.5f);
+                this->marker_->show();
+            }
+        }
+    }
+
+    void HUDRadar::changedOwner()
+    {
+    SUPER(HUDRadar, changedOwner);
+
+    this->owner_ = orxonox_cast<Pawn*>(this->getOwner());
+    assert(this->radarObjects_.size()==0);
+    this->gatherObjects();
+}
+}
Index: /code/branches/rocket2/src/modules/overlays/hud/HUDRadar.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/HUDRadar.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/HUDRadar.h	(revision 6952)
@@ -0,0 +1,90 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *      Felix Schulthess
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#ifndef _HUDRadar_H__
+#define _HUDRadar_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include <map>
+#include <vector>
+
+#include "util/OgreForwardRefs.h"
+#include "interfaces/RadarListener.h"
+#include "interfaces/RadarViewable.h"
+#include "overlays/OrxonoxOverlay.h"
+
+namespace orxonox
+{
+    class _OverlaysExport HUDRadar : public OrxonoxOverlay, public RadarListener
+    {
+    public:
+        HUDRadar(BaseObject* creator);
+        virtual ~HUDRadar();
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+        virtual void changedOwner();
+
+    private:
+        // XML accessors
+        float getHalfDotSizeDistance() const { return this->halfDotSizeDistance_; }
+        void setHalfDotSizeDistance(float distance) { this->halfDotSizeDistance_ = distance; }
+
+        float getMaximumDotSize() const { return this->maximumDotSize_; }
+        void setMaximumDotSize(float size) { this->maximumDotSize_ = size; }
+
+        float getRadarSensitivity() const { return this->sensitivity_; }
+        // used also by RadarListener interface!
+        void setRadarSensitivity(float sensitivity) { this->sensitivity_ = sensitivity; }
+
+        // RadarListener interface
+        virtual void addObject(RadarViewable* viewable);
+        virtual void removeObject(RadarViewable* viewable);
+        virtual void objectChanged( RadarViewable* rv );
+        void radarTick(float dt);
+        
+        void gatherObjects();
+
+        std::map<RadarViewable::Shape, std::string> shapeMaterials_;
+
+//         std::vector<Ogre::PanelOverlayElement*> radarDots_;
+//         std::vector<Ogre::PanelOverlayElement*>::iterator itRadarDots_;
+        std::map<RadarViewable*, Ogre::PanelOverlayElement*> radarObjects_;
+        Ogre::PanelOverlayElement* marker_;
+
+        float halfDotSizeDistance_;
+        float maximumDotSize_;
+
+        float sensitivity_;
+
+        Pawn* owner_;
+    };
+}
+
+#endif /* _HUDRadar_H__ */
Index: /code/branches/rocket2/src/modules/overlays/hud/HUDSpeedBar.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/HUDSpeedBar.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/HUDSpeedBar.cc	(revision 6952)
@@ -0,0 +1,69 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Felix Schulthess
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "HUDSpeedBar.h"
+
+#include "core/CoreIncludes.h"
+#include "worldentities/pawns/SpaceShip.h"
+#include "items/Engine.h"
+
+namespace orxonox
+{
+    CreateFactory(HUDSpeedBar);
+
+    HUDSpeedBar::HUDSpeedBar(BaseObject* creator)
+        : HUDBar(creator)
+    {
+        RegisterObject(HUDSpeedBar);
+
+        this->owner_ = 0;
+    }
+
+    HUDSpeedBar::~HUDSpeedBar()
+    {
+    }
+
+    void HUDSpeedBar::tick(float dt)
+    {
+        SUPER(HUDSpeedBar, tick, dt);
+
+        if (this->owner_ && this->owner_->getEngine())
+        {
+            float value = this->owner_->getVelocity().length() / (this->owner_->getEngine()->getMaxSpeedFront() * this->owner_->getEngine()->getSpeedFactor() * this->owner_->getEngine()->getBoostFactor());
+            this->setValue(value);
+        }
+    }
+
+    void HUDSpeedBar::changedOwner()
+    {
+        SUPER(HUDSpeedBar, changedOwner);
+
+        this->owner_ = orxonox_cast<SpaceShip*>(this->getOwner());
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/hud/HUDSpeedBar.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/HUDSpeedBar.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/HUDSpeedBar.h	(revision 6952)
@@ -0,0 +1,53 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Felix Schulthess
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _HUDSpeedBar_H__
+#define _HUDSpeedBar_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "tools/interfaces/Tickable.h"
+#include "HUDBar.h"
+
+namespace orxonox
+{
+    class _OverlaysExport HUDSpeedBar : public HUDBar, public Tickable
+    {
+    public:
+        HUDSpeedBar(BaseObject* creator);
+        virtual ~HUDSpeedBar();
+
+        virtual void tick(float dt);
+        virtual void changedOwner();
+
+    private:
+        SpaceShip* owner_;
+    };
+}
+#endif /* _HUDSpeedBar_H__ */
Index: /code/branches/rocket2/src/modules/overlays/hud/HUDTimer.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/HUDTimer.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/HUDTimer.cc	(revision 6952)
@@ -0,0 +1,72 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Aurelian Jaggi
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "HUDTimer.h"
+
+#include "util/Convert.h"
+#include "core/CoreIncludes.h"
+#include "worldentities/ControllableEntity.h"
+#include "gametypes/Gametype.h"
+
+namespace orxonox
+{
+    CreateFactory(HUDTimer);
+
+    HUDTimer::HUDTimer(BaseObject* creator) : OverlayText(creator)
+    {
+        RegisterObject(HUDTimer);
+
+        this->owner_ = 0;
+    }
+
+    HUDTimer::~HUDTimer()
+    {
+    }
+
+    void HUDTimer::tick(float dt)
+    {
+        SUPER(HUDTimer, tick, dt);
+
+        Gametype* gametype = this->getGametype();
+
+        if (gametype)
+        {
+            if (gametype->getTimerIsActive())
+            {
+                this->setCaption(multi_cast<std::string>(static_cast<int>(gametype->getTime()) + 1));
+            }
+        }
+    }
+
+    void HUDTimer::changedOwner()
+    {
+        SUPER(HUDTimer, changedOwner);
+
+        this->owner_ = orxonox_cast<ControllableEntity*>(this->getOwner());
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/hud/HUDTimer.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/HUDTimer.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/HUDTimer.h	(revision 6952)
@@ -0,0 +1,53 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Aurelian Jaggi
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _HUDTimer_H__
+#define _HUDTimer_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "tools/interfaces/Tickable.h"
+#include "overlays/OverlayText.h"
+
+namespace orxonox
+{
+    class _OverlaysExport HUDTimer : public OverlayText, public Tickable
+    {
+    public:
+        HUDTimer(BaseObject* creator);
+        virtual ~HUDTimer();
+
+        virtual void tick(float dt);
+
+        virtual void changedOwner();
+
+    private:
+        ControllableEntity* owner_;
+    };
+}
+#endif /* _HUDTimer_H__ */
Index: /code/branches/rocket2/src/modules/overlays/hud/KillMessage.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/KillMessage.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/KillMessage.cc	(revision 6952)
@@ -0,0 +1,60 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "KillMessage.h"
+
+#include "core/CoreIncludes.h"
+#include "infos/PlayerInfo.h"
+
+namespace orxonox
+{
+    CreateFactory(KillMessage);
+
+    KillMessage::KillMessage(BaseObject* creator) : FadeoutText(creator)
+    {
+        RegisterObject(KillMessage);
+
+        this->owner_ = 0;
+
+        this->setDelay(2.0f);
+        this->setFadeouttime(0.5f);
+    }
+
+    void KillMessage::killmessage(const GametypeInfo* gtinfo, const std::string& message)
+    {
+        if (this->owner_ && this->owner_->getGametypeInfo() == gtinfo)
+            this->setCaption(message);
+    }
+
+    void KillMessage::changedOwner()
+    {
+        SUPER(KillMessage, changedOwner);
+
+        this->owner_ = orxonox_cast<PlayerInfo*>(this->getOwner());
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/hud/KillMessage.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/KillMessage.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/KillMessage.h	(revision 6952)
@@ -0,0 +1,53 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _KillMessage_H__
+#define _KillMessage_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "interfaces/GametypeMessageListener.h"
+#include "overlays/FadeoutText.h"
+
+namespace orxonox
+{
+    class _OverlaysExport KillMessage : public FadeoutText, public GametypeMessageListener
+    {
+        public:
+            KillMessage(BaseObject* creator);
+            virtual ~KillMessage() {}
+
+            virtual void changedOwner();
+
+            void killmessage(const GametypeInfo* gtinfo, const std::string& message);
+
+        private:
+            PlayerInfo* owner_;
+    };
+}
+#endif /* _KillMessage_H__ */
Index: /code/branches/rocket2/src/modules/overlays/hud/TeamBaseMatchScore.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/TeamBaseMatchScore.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/TeamBaseMatchScore.cc	(revision 6952)
@@ -0,0 +1,124 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "TeamBaseMatchScore.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "util/Convert.h"
+#include "gametypes/TeamBaseMatch.h"
+#include "infos/PlayerInfo.h"
+
+namespace orxonox
+{
+    CreateFactory(TeamBaseMatchScore);
+
+    TeamBaseMatchScore::TeamBaseMatchScore(BaseObject* creator) : OverlayText(creator)
+    {
+        RegisterObject(TeamBaseMatchScore);
+
+        this->owner_ = 0;
+
+        this->bShowBases_ = false;
+        this->bShowScore_ = false;
+        this->bShowLeftTeam_ = false;
+        this->bShowRightTeam_ = false;
+    }
+
+    TeamBaseMatchScore::~TeamBaseMatchScore()
+    {
+    }
+
+    void TeamBaseMatchScore::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(TeamBaseMatchScore, XMLPort, xmlelement, mode);
+
+        XMLPortParam(TeamBaseMatchScore, "showbases",     setShowBases,     getShowBases,     xmlelement, mode).defaultValues(false);
+        XMLPortParam(TeamBaseMatchScore, "showscore",     setShowScore,     getShowScore,     xmlelement, mode).defaultValues(false);
+        XMLPortParam(TeamBaseMatchScore, "showleftteam",  setShowLeftTeam,  getShowLeftTeam,  xmlelement, mode).defaultValues(false);
+        XMLPortParam(TeamBaseMatchScore, "showrightteam", setShowRightTeam, getShowRightTeam, xmlelement, mode).defaultValues(false);
+    }
+
+    void TeamBaseMatchScore::tick(float dt)
+    {
+        SUPER(TeamBaseMatchScore, tick, dt);
+
+        if (this->owner_)
+        {
+            const std::string& bases1 = '(' + multi_cast<std::string>(this->owner_->getTeamBases(0)) + ')';
+            const std::string& bases2 = '(' + multi_cast<std::string>(this->owner_->getTeamBases(1)) + ')';
+
+            const std::string& score1 = multi_cast<std::string>(this->owner_->getTeamPoints(0));
+            const std::string& score2 = multi_cast<std::string>(this->owner_->getTeamPoints(1));
+
+            std::string output1;
+            if (this->bShowLeftTeam_)
+            {
+                if (this->bShowBases_ && this->bShowScore_)
+                    output1 = bases1 + " - " + score1;
+                else if (this->bShowScore_)
+                    output1 = score1;
+                else if (this->bShowBases_)
+                    output1 = bases1;
+            }
+
+            std::string output2;
+            if (this->bShowRightTeam_)
+            {
+                if (this->bShowBases_ && this->bShowScore_)
+                    output2 = score2 + " - " + bases2;
+                else if (this->bShowScore_)
+                    output2 = score2;
+                else if (this->bShowBases_)
+                    output2 = bases2;
+            }
+
+            std::string output;
+            if (this->bShowBases_ || this->bShowScore_)
+            {
+                if (this->bShowLeftTeam_ && this->bShowRightTeam_)
+                    output = output1 + ':' + output2;
+                else if (this->bShowLeftTeam_ || this->bShowRightTeam_)
+                    output = output1 + output2;
+            }
+
+            this->setCaption(output);
+        }
+    }
+
+
+    void TeamBaseMatchScore::changedOwner()
+    {
+        SUPER(TeamBaseMatchScore, changedOwner);
+
+        if (this->getOwner() && this->getOwner()->getGametype())
+            this->owner_ = orxonox_cast<TeamBaseMatch*>(this->getOwner()->getGametype().get());
+        else
+            this->owner_ = 0;
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/hud/TeamBaseMatchScore.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/TeamBaseMatchScore.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/TeamBaseMatchScore.h	(revision 6952)
@@ -0,0 +1,77 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TeamBaseMatchScore_H__
+#define _TeamBaseMatchScore_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "tools/interfaces/Tickable.h"
+#include "overlays/OverlayText.h"
+
+namespace orxonox
+{
+    class _OverlaysExport TeamBaseMatchScore : public OverlayText, public Tickable
+    {
+        public:
+            TeamBaseMatchScore(BaseObject* creator);
+            virtual ~TeamBaseMatchScore();
+
+            virtual void tick(float dt);
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void changedOwner();
+
+            inline void setShowBases(bool value)
+                { this->bShowBases_ = value; }
+            inline bool getShowBases() const
+                { return this->bShowBases_; }
+
+            inline void setShowScore(bool value)
+                { this->bShowScore_ = value; }
+            inline bool getShowScore() const
+                { return this->bShowScore_; }
+
+            inline void setShowLeftTeam(bool value)
+                { this->bShowLeftTeam_ = value; }
+            inline bool getShowLeftTeam() const
+                { return this->bShowLeftTeam_; }
+
+            inline void setShowRightTeam(bool value)
+                { this->bShowRightTeam_ = value; }
+            inline bool getShowRightTeam() const
+                { return this->bShowRightTeam_; }
+
+        private:
+            TeamBaseMatch* owner_;
+            bool bShowBases_;
+            bool bShowScore_;
+            bool bShowLeftTeam_;
+            bool bShowRightTeam_;
+    };
+}
+#endif /* _TeamBaseMatchScore_H__ */
Index: /code/branches/rocket2/src/modules/overlays/hud/UnderAttackHealthBar.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/UnderAttackHealthBar.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/UnderAttackHealthBar.cc	(revision 6952)
@@ -0,0 +1,108 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "UnderAttackHealthBar.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "infos/PlayerInfo.h"
+#include "gametypes/UnderAttack.h"
+#include "worldentities/pawns/Destroyer.h"
+#include "overlays/OverlayGroup.h"
+
+namespace orxonox
+{
+    CreateFactory(UnderAttackHealthBar);
+
+    UnderAttackHealthBar::UnderAttackHealthBar(BaseObject* creator) : HUDHealthBar(creator)
+    {
+        RegisterObject(UnderAttackHealthBar);
+
+        this->owner_ = 0;
+
+        this->text_ = new OverlayText(this);
+        this->text_->setFont("Monofur");
+        this->text_->setTextSize(0.04f);
+        this->text_->setAlignmentString("center");
+        this->text_->setColour(ColourValue::White);
+        this->text_->setPickPoint(Vector2(0.5, 0));
+
+        this->inittimer_.setTimer(0.0f, false, createExecutor(createFunctor(&UnderAttackHealthBar::init, this)));
+    }
+
+    UnderAttackHealthBar::~UnderAttackHealthBar()
+    {
+        if (this->isInitialized())
+        {
+            this->text_->destroy();
+            this->text_ = 0;
+        }
+    }
+
+    void UnderAttackHealthBar::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(UnderAttackHealthBar, XMLPort, xmlelement, mode);
+
+        XMLPortParam(UnderAttackHealthBar, "descriptionpickpoint", setDescriptionPickPoint, getDescriptionPickPoint, xmlelement, mode);
+        XMLPortParam(UnderAttackHealthBar, "descriptionoffset", setDescriptionOffset, getDescriptionOffset, xmlelement, mode);
+    }
+
+    void UnderAttackHealthBar::changedOwner()
+    {
+        SUPER(UnderAttackHealthBar, changedOwner);
+
+        PlayerInfo* player = orxonox_cast<PlayerInfo*>(this->getOwner());
+        if (player)
+        {
+            this->owner_ = player;
+
+            UnderAttack* ua = orxonox_cast<UnderAttack*>(player->getGametype().get());
+            if (ua)
+            {
+                this->setOwner(ua->getDestroyer());
+
+                if (ua->getTeam(player) == 0)
+                    this->text_->setCaption("Attack the Transporter!");
+                else
+                    this->text_->setCaption("Defend the Transporter!");
+            }
+        }
+    }
+
+    void UnderAttackHealthBar::changedOverlayGroup()
+    {
+        SUPER(UnderAttackHealthBar, changedOverlayGroup);
+
+        this->getOverlayGroup()->addElement(this->text_.get());
+    }
+
+    void UnderAttackHealthBar::init()
+    {
+        this->setOwner(this->owner_);
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/hud/UnderAttackHealthBar.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/hud/UnderAttackHealthBar.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/hud/UnderAttackHealthBar.h	(revision 6952)
@@ -0,0 +1,68 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _UnderAttackHealthBar_H__
+#define _UnderAttackHealthBar_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "util/Math.h"
+#include "tools/Timer.h"
+#include "HUDHealthBar.h"
+
+namespace orxonox
+{
+    class _OverlaysExport UnderAttackHealthBar : public HUDHealthBar
+    {
+        public:
+            UnderAttackHealthBar(BaseObject* creator);
+            ~UnderAttackHealthBar();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void changedOwner();
+            virtual void changedOverlayGroup();
+
+            inline void setDescriptionPickPoint(const Vector2& pickpoint)
+                { this->text_->setPickPoint(pickpoint); }
+            inline Vector2 getDescriptionPickPoint() const
+                { return this->text_->getPickPoint(); }
+
+            inline void setDescriptionOffset(const Vector2& position)
+                { this->text_->setPosition(this->getPosition() + (position - this->getPickPoint()) * this->getSize()); }
+            inline Vector2 getDescriptionOffset() const
+                { return (this->text_->getPosition() - this->getPosition()) / this->getSize() + this->getPickPoint(); }
+
+        private:
+            void init();
+
+            PlayerInfo* owner_;
+            SmartPtr<OverlayText> text_;
+            Timer inittimer_;
+    };
+}
+#endif /* _UnderAttackHealthBar_H__ */
Index: /code/branches/rocket2/src/modules/overlays/stats/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/overlays/stats/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/stats/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,5 @@
+ADD_SOURCE_FILES(OVERLAYS_SRC_FILES
+  CreateLines.cc
+  Scoreboard.cc
+  Stats.cc
+)
Index: /code/branches/rocket2/src/modules/overlays/stats/CreateLines.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/stats/CreateLines.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/stats/CreateLines.cc	(revision 6952)
@@ -0,0 +1,140 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Hildebrandt
+ *
+ */
+
+#include "CreateLines.h"
+
+#include "overlays/OverlayText.h"
+#include "overlays/stats/Stats.h"
+
+namespace orxonox
+{
+    /**
+        @brief Constructor: Creates a line.
+    */
+    CreateLines::CreateLines(float leftOffset, float topOffset, float width, float height)
+    {
+        playerNameText_ = new OverlayText(0);
+        playerNameText_->setTextSize(0.04f);
+        playerNameText_->setColour(ColourValue(0.0f, 0.75f, 0.2f, 1.0f));
+        playerNameText_->setPosition(Vector2(0.1f, topOffset + 0.01f));
+
+        scoreText_ = new OverlayText(0);
+        scoreText_->setTextSize(0.04f);
+        scoreText_->setColour(ColourValue(0.0f, 0.75f, 0.2f, 1.0f));
+        scoreText_->setPosition(Vector2(0.6f, topOffset + 0.01f));
+
+        deathsText_ = new OverlayText(0);
+        deathsText_->setTextSize(0.04f);
+        deathsText_->setColour(ColourValue(0, 0.75f, 0.2f, 1.0f));
+        deathsText_->setPosition(Vector2(0.8f, topOffset + 0.01f));
+
+        background_ = new Stats(0);
+        background_->setPosition(Vector2(leftOffset, topOffset));
+        background_->setSize(Vector2(width, height));
+    }
+
+    CreateLines::~CreateLines()
+    {
+        this->playerNameText_->destroy();
+        this->scoreText_->destroy();
+        this->deathsText_->destroy();
+        this->background_->destroy();
+    }
+
+    void CreateLines::setPlayerName(const std::string& str)
+    {
+        this->playerNameText_->setCaption(str);
+    }
+
+    void CreateLines::setScore(const std::string& str)
+    {
+        this->scoreText_->setCaption(str);
+    }
+
+    void CreateLines::setDeaths(const std::string& str)
+    {
+        this->deathsText_->setCaption(str);
+    }
+
+    void CreateLines::setVisibility(bool visible)
+    {
+        this->scoreText_->setVisible(visible);
+        this->deathsText_->setVisible(visible);
+        this->playerNameText_->setVisible(visible);
+        this->background_->setVisible(visible);
+    }
+    void CreateLines::changedVisibility()
+    {
+        this->scoreText_->changedVisibility();
+        this->deathsText_->changedVisibility();
+        this->playerNameText_->changedVisibility();
+        this->background_->changedVisibility();
+    }
+
+    void CreateLines::setOverlayGroup( OverlayGroup* group )
+    {
+        this->scoreText_->setOverlayGroup( group );
+        this->deathsText_->setOverlayGroup( group );
+        this->playerNameText_->setOverlayGroup( group );
+        this->background_->setOverlayGroup( group );
+    }
+
+    /**
+        @brief Ensures that the number of OverlayElements is equal to numberOfColumns.
+    */
+    //void CreateLines::setNumberOfColumns(unsigned int numberOfColumns, unsigned int lineIndex) {
+
+    //    Ogre::OverlayManager* ovMan = Ogre::OverlayManager::getSingletonPtr();
+
+    //    unsigned int colIndex = 0;
+
+    //    while (textColumns_.size() < numberOfColumns)
+    //    {
+    //        Ogre::TextAreaOverlayElement* tempTextArea = static_cast<Ogre::TextAreaOverlayElement*>(ovMan->createOverlayElement("TextArea", "StatsLineTextArea" + getName() + multi_cast<std::string>(lineIndex) + multi_cast<std::string>(colIndex)));
+    //        textColumns_.push_back(tempTextArea);
+    //        this->background_->addChild(tempTextArea);
+
+    //        colIndex++;
+    //    }
+
+    //    while (textColumns_.size() > numberOfColumns)
+    //    {
+    //        this->background_->_removeChild(textColumns_.back());
+    //        ovMan->destroyOverlayElement(textColumns_.back());
+    //        textColumns_.pop_back();
+    //    }
+    //}
+
+    //void CreateLines::alignColumn(int columnIndex, float leftOffset, float topOffset)
+    //{
+    //    this->textColumns_[columnIndex]->setPosition(leftOffset, topOffset);
+    //}
+
+    //void CreateLines::setColumnText(int columnIndex, std::string columnText)
+    //{
+    //    this->textColumns_[columnIndex]->setCaption(columnText);
+    //}
+}
Index: /code/branches/rocket2/src/modules/overlays/stats/CreateLines.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/stats/CreateLines.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/stats/CreateLines.h	(revision 6952)
@@ -0,0 +1,66 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Hildebrandt
+ *
+ */
+
+#ifndef _CreateLines_H__
+#define _CreateLines_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+namespace orxonox
+{
+    class _OverlaysExport CreateLines
+    {
+
+    public: // functions
+        CreateLines(float, float, float, float);
+        virtual ~CreateLines();
+
+        void setPlayerName(const std::string&);
+        void setScore(const std::string&);
+        void setDeaths(const std::string&);
+
+        void setVisibility(bool);
+        void changedVisibility();
+        void setOverlayGroup( OverlayGroup* group );
+
+        //void setNumberOfColumns(unsigned int numberOfColumns, unsigned int lineIndex);
+        //void alignColumn(int columnIndex, float leftOffset, float topOffset);
+        //void setColumnText(int columnIndex, std::string columnText);
+
+    private: // functions
+
+    private: // variables
+        //std::vector<OverlayText*> textColumns_;
+        OverlayText* playerNameText_;
+        OverlayText* scoreText_;
+        OverlayText* deathsText_;
+
+        Stats* background_;
+
+    };
+}
+
+#endif /* _CreateLines_H__ */
Index: /code/branches/rocket2/src/modules/overlays/stats/Scoreboard.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/stats/Scoreboard.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/stats/Scoreboard.cc	(revision 6952)
@@ -0,0 +1,140 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Hildebrandt
+ *
+ */
+
+#include "Scoreboard.h"
+
+#include "util/Convert.h"
+#include "core/CoreIncludes.h"
+#include "gametypes/Gametype.h"
+#include "infos/PlayerInfo.h"
+#include "CreateLines.h"
+
+namespace orxonox
+{
+    CreateFactory(Scoreboard);
+
+    /**
+        @brief Constructor: Creates the scoreboard.
+    */
+    Scoreboard::Scoreboard(BaseObject* creator)
+        : OrxonoxOverlay(creator)
+    {
+        RegisterObject(Scoreboard);
+    }
+
+    Scoreboard::~Scoreboard()
+    {
+        while (this->lines_.size() > 0)
+        {
+            // destroy lines
+            delete this->lines_.back();
+            this->lines_.pop_back();
+        }
+    }
+
+    /**
+        @brief Initializes the lines.
+    */
+    void Scoreboard::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        SUPER(Scoreboard, XMLPort, xmlElement, mode);
+    }
+
+    void Scoreboard::changedVisibility()
+    {
+        SUPER(Scoreboard, changedVisibility);
+
+        for (unsigned int i = 0; i < this->lines_.size(); ++i)
+            this->lines_[i]->changedVisibility();
+    }
+
+    /**
+        @brief Prints the scoreboard on the screen.
+    */
+    void Scoreboard::tick(float dt)
+    {
+        const std::map<PlayerInfo*, Player>& playerList = this->getGametype()->getPlayers();
+
+        const float topOffset  = 0.2f;
+        const float leftOffset = 0.075f;
+        const float distance   = 0.01f;
+        const float width      = 0.85f;
+        const float height     = 0.05f;
+        while (playerList.size() > this->lines_.size())
+        {
+            // create new lines
+            CreateLines* lines = new CreateLines(leftOffset, topOffset + (distance + height) * lines_.size(), width, height);
+            lines->setVisibility(this->isVisible());
+            lines->setOverlayGroup( this->getOverlayGroup() );
+            this->lines_.push_back(lines);
+        }
+        while (playerList.size() < this->lines_.size())
+        {
+            // destroy lines
+            delete this->lines_.back();
+            this->lines_.pop_back();
+        }
+
+        // update board
+
+        unsigned int index = 0;
+        for (std::map<PlayerInfo*, Player>::const_iterator it = playerList.begin(); it != playerList.end(); ++it)
+        {
+            this->lines_[index]->setPlayerName(multi_cast<std::string>(it->first->getName()));
+            this->lines_[index]->setScore(multi_cast<std::string>(it->second.frags_));
+            this->lines_[index]->setDeaths(multi_cast<std::string>(it->second.killed_));
+            index++;
+        }
+
+        //numberOfColumns = 2;
+        //numberOfLines = 3;
+        //topOffset = 0.1;
+        //lineSpacing = 0.1;
+
+        //for (unsigned int i = 0; i < this->lines_.size(); ++i)
+        //{
+        //    columnIndex = 0;
+        //    leftOffset = 0.1;
+
+        //    this->createlines_->setNumberOfColumns(numberOfColumns, i);
+
+        //    // columnText = this->getGametype()->getPlayersName();
+        //    columnText = "PlayerName";
+        //    this->createlines_->alignColumn(columnIndex, topOffset, leftOffset);
+        //    this->createlines_->setColumnText(columnIndex, columnText);
+
+        //    columnIndex++;
+        //    leftOffset = leftOffset + 0.3;
+
+        //    // columnText = this->getGametype()->getPlayersFrags();
+        //    columnText = "PlayerFrags";
+        //    this->createlines_->alignColumn(columnIndex, topOffset, leftOffset);
+        //    this->createlines_->setColumnText(columnIndex, columnText);
+
+        //    topOffset = topOffset + lineSpacing;
+        //}
+    }
+}
Index: /code/branches/rocket2/src/modules/overlays/stats/Scoreboard.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/stats/Scoreboard.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/stats/Scoreboard.h	(revision 6952)
@@ -0,0 +1,73 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Hildebrandt
+ *
+ */
+
+#ifndef _Scoreboard_H__
+#define _Scoreboard_H__
+
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include <string>
+#include <vector>
+#include "tools/interfaces/Tickable.h"
+#include "overlays/OrxonoxOverlay.h"
+
+namespace orxonox
+{
+    class _OverlaysExport Scoreboard : public OrxonoxOverlay, public Tickable
+    {
+    public: // functions
+        Scoreboard(BaseObject* creator);
+        virtual ~Scoreboard();
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+        virtual void tick(float dt);
+
+        inline void setCreateLines(CreateLines* cl)
+            { this->createlines_ = cl; }
+        inline CreateLines* getCreateLines() const
+            { return this->createlines_; }
+
+        virtual void changedVisibility();
+
+    private: // functions
+        void printLines();
+
+    private: // variables
+        std::vector<CreateLines*> lines_;
+
+        unsigned int numberOfColumns;
+        unsigned int numberOfLines;
+        unsigned int columnIndex;
+        float topOffset;
+        float leftOffset;
+        float lineSpacing;
+        std::string columnText;
+        CreateLines* createlines_;
+    };
+}
+
+#endif /* _Scoreboard_H__ */
Index: /code/branches/rocket2/src/modules/overlays/stats/Stats.cc
===================================================================
--- /code/branches/rocket2/src/modules/overlays/stats/Stats.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/stats/Stats.cc	(revision 6952)
@@ -0,0 +1,118 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Felix Schulthess
+ *   Co-authors:
+ *      Fabian 'x3n' Landau, Benjamin Hildebrandt
+ *
+ */
+
+#include "Stats.h"
+
+#include <string>
+#include <OgreOverlayManager.h>
+#include <OgreBorderPanelOverlayElement.h>
+
+#include "util/StringUtils.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+
+namespace orxonox
+{
+    CreateFactory(Stats);
+
+    /**
+        @brief Constructor: Creates and initializes the Stats panel.
+    */
+    Stats::Stats(BaseObject* creator)
+        : OrxonoxOverlay(creator)
+        , statsOverlayNoise_(0)
+        , statsOverlayBorder_(0)
+    {
+        RegisterObject(Stats);
+
+        this->setConfigValues();
+
+        // create overlay and elements
+        Ogre::OverlayManager* ovMan = Ogre::OverlayManager::getSingletonPtr();
+
+        // create BorderPanel
+        this->statsOverlayBorder_ = static_cast<Ogre::BorderPanelOverlayElement*>(ovMan->createOverlayElement("BorderPanel", "StatsBorderPanel" + getUniqueNumberString()));
+        //this->statsOverlayBorder_->setMaterialName("StatsCenter");
+        this->statsOverlayBorder_->setBorderSize(0.003f, 16.0f * 0.003f);
+        this->statsOverlayBorder_->setBorderMaterialName("StatsBorder");
+        this->statsOverlayBorder_->setTopBorderUV(0.49f, 0.0f, 0.51f, 0.5f);
+        this->statsOverlayBorder_->setTopLeftBorderUV(0.0f, 0.0f, 0.5f, 0.5f);
+        this->statsOverlayBorder_->setTopRightBorderUV(0.5f, 0.0f, 1.0f, 0.5f);
+        this->statsOverlayBorder_->setLeftBorderUV(0.0f, 0.49f, 0.5f, 0.51f);
+        this->statsOverlayBorder_->setRightBorderUV(0.5f, 0.49f, 1.0f, 0.5f);
+        this->statsOverlayBorder_->setBottomBorderUV(0.49f, 0.5f, 0.51f, 1.0f);
+        this->statsOverlayBorder_->setBottomLeftBorderUV(0.0f, 0.5f, 0.5f, 1.0f);
+        this->statsOverlayBorder_->setBottomRightBorderUV(0.5f, 0.5f, 1.0f, 1.0f);
+
+        background_->addChild(statsOverlayBorder_);
+
+        // create noise
+        //this->statsOverlayNoise_ = static_cast<Ogre::PanelOverlayElement*>(ovMan->createOverlayElement("Panel", "StatsNoise" + getUniqueNumberString()));
+        //this->statsOverlayNoise_->setPosition(0,0);
+        //this->statsOverlayNoise_->setMaterialName("StatsNoiseSmall");
+        // comment following line to disable noise
+        //background_->addChild(this->statsOverlayNoise_);
+    }
+
+    Stats::~Stats()
+    {
+        if (this->isInitialized())
+        {
+            Ogre::OverlayManager* ovMan = Ogre::OverlayManager::getSingletonPtr();
+            ovMan->destroyOverlayElement(this->statsOverlayBorder_);
+            //ovMan->destroyOverlayElement(this->statsOverlayNoise_);
+        }
+    }
+
+    /**
+        @brief Sets the config values, describing the size of the Stats panel.
+    */
+    void Stats::setConfigValues()
+    {
+        SetConfigValue(noiseSize_, 1.0f);
+    }
+
+    /**
+        @brief Initializes the Stats panel.
+    */
+    void Stats::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        OrxonoxOverlay::XMLPort(xmlElement, mode);
+    }
+
+    void Stats::tick(float dt)
+    {
+        // SUPER(Stats, tick, dt);
+
+            // this creates a flickering effect (extracts exactly 80% of the texture at a random location)
+            //float uRand = (rand() & 1023) / 1023.0f * 0.2f;
+            //float vRand = (rand() & 1023) / 1023.0f * 0.2f;
+            //this->statsOverlayNoise_->setUV(uRand, vRand, 7.5f + uRand, 7.5f + vRand);
+    }
+
+}
Index: /code/branches/rocket2/src/modules/overlays/stats/Stats.h
===================================================================
--- /code/branches/rocket2/src/modules/overlays/stats/Stats.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/overlays/stats/Stats.h	(revision 6952)
@@ -0,0 +1,59 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Felix Schulthess
+ *   Co-authors:
+ *      Fabian 'x3n' Landau, Benjamin Hildebrandt
+ *
+ */
+
+#ifndef _Stats_H__
+#define _Stats_H__
+
+#include "overlays/OverlaysPrereqs.h"
+
+#include "util/OgreForwardRefs.h"
+#include "tools/interfaces/Tickable.h"
+#include "overlays/OrxonoxOverlay.h"
+
+namespace orxonox
+{
+    class _OverlaysExport Stats : public OrxonoxOverlay, public Tickable
+    {
+    public: // functions
+        Stats(BaseObject* creator);
+        virtual ~Stats();
+
+        void setConfigValues();
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+
+        virtual void tick(float dt);
+
+    private: // variables
+        Ogre::PanelOverlayElement* statsOverlayNoise_;
+        Ogre::BorderPanelOverlayElement* statsOverlayBorder_;
+        float noiseSize_;
+    };
+}
+
+#endif /* _Stats_H__ */
Index: /code/branches/rocket2/src/modules/pickup/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/pickup/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,26 @@
+SET_SOURCE_FILES(PICKUP_SRC_FILES
+  DroppedPickup.cc
+  Pickup.cc
+  PickupCollection.cc
+  PickupCollectionIdentifier.cc
+  PickupManager.cc
+  PickupRepresentation.cc
+  PickupSpawner.cc
+)
+
+ADD_SUBDIRECTORY(items)
+
+ORXONOX_ADD_LIBRARY(pickup
+  MODULE
+  FIND_HEADER_FILES
+  TOLUA_FILES
+    PickupManager.h
+    PickupRepresentation.h
+  DEFINE_SYMBOL
+    "PICKUP_SHARED_BUILD"
+  PCH_FILE
+    PickupPrecompiledHeaders.h
+  LINK_LIBRARIES
+    orxonox
+  SOURCE_FILES ${PICKUP_SRC_FILES}
+)
Index: /code/branches/rocket2/src/modules/pickup/DroppedPickup.cc
===================================================================
--- /code/branches/rocket2/src/modules/pickup/DroppedPickup.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/DroppedPickup.cc	(revision 6952)
@@ -0,0 +1,101 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Daniel 'Huty' Haggenmueller
+ *   Co-authors:
+ *      Damian 'Mozork' Frick
+ *
+ */
+
+/**
+    @file DroppedPickup.cc
+    @brief Implementation of the DroppedPickup class.
+*/
+
+#include "DroppedPickup.h"
+
+#include "core/CoreIncludes.h"
+#include "interfaces/Pickupable.h"
+#include "interfaces/PickupCarrier.h"
+#include "graphics/Model.h"
+
+namespace orxonox
+{
+    
+    CreateFactory(DroppedPickup);
+    
+    /**
+    @brief
+        Default constructor. Registers object and sets default values.
+    */
+    DroppedPickup::DroppedPickup(BaseObject* creator) : PickupSpawner(creator)
+    {
+        RegisterObject(DroppedPickup);
+        
+    }
+
+    /**
+    @brief
+        Constructor. Registers the object and sets values.
+    @param creator
+        The creator of the DroppedPickup.
+    @param pickup
+        The Pickupable that was dropped.
+    @param position
+        The position at which the DroppedPickup should be created.
+    @param triggerDistance
+        The distance at which the PickupSpawner triggers. Default is 10.
+    */
+    DroppedPickup::DroppedPickup(BaseObject* creator, Pickupable* pickup, PickupCarrier* carrier, float triggerDistance) : PickupSpawner(creator, pickup, triggerDistance, 5, 1)
+    {   
+        RegisterObject(DroppedPickup);
+
+        this->setPosition(carrier->getCarrierPosition());
+        this->setActive(false);
+        
+        //TODO: Do more elegantly.
+        this->startRespawnTimer();
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    DroppedPickup::~DroppedPickup()
+    {
+        if(this->pickup_ != NULL && this->pickup_->isPickedUp())
+        {
+            this->pickup_ = NULL;
+        }
+    }
+
+    /**
+    @brief
+        Creates the Pickupable that is going to get picked up.
+        In the case of the DroppedItem it is the one and only Pickupable that was dropped. No additional Pickupables of the same type are created.
+    */
+    Pickupable* DroppedPickup::getPickup(void)
+    {
+        return this->pickup_;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/pickup/DroppedPickup.h
===================================================================
--- /code/branches/rocket2/src/modules/pickup/DroppedPickup.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/DroppedPickup.h	(revision 6952)
@@ -0,0 +1,64 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Daniel 'Huty' Haggenmueller
+ *   Co-authors:
+ *      Damian 'Mozork' Frick
+ *
+ */
+
+/**
+    @file DroppedPickup.h
+    @brief Definition of the DroppedPickup class.
+*/
+
+#ifndef _DroppedPickup_H__
+#define _DroppedPickup_H__
+
+#include "PickupPrereqs.h"
+
+#include "PickupSpawner.h"
+
+namespace orxonox
+{
+    
+    /**
+    @brief
+        Special PickupSpawner that is created whe a Pickupable is dropped. It just spawns one pickup, the one that was dropped.
+    @author
+        Daniel 'Huty' Haggenmueller
+        Damian 'Mozork' Frick
+    */
+    class _PickupExport DroppedPickup : public PickupSpawner
+    {
+        public:
+            DroppedPickup(BaseObject* creator); //!< Default constructor.
+            DroppedPickup(BaseObject* creator, Pickupable* pickup, PickupCarrier* carrier, float triggerDistance = 10.0); //!< Constructor.
+            virtual ~DroppedPickup(); //!< Destructor.
+
+        protected:
+            virtual Pickupable* getPickup(void); //!< Creates the Pickupable that is going to get picked up.
+
+    };
+}
+
+#endif /* _DroppedPickup_H__ */
Index: /code/branches/rocket2/src/modules/pickup/Pickup.cc
===================================================================
--- /code/branches/rocket2/src/modules/pickup/Pickup.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/Pickup.cc	(revision 6952)
@@ -0,0 +1,261 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+/**
+    @file Pickup.cc
+    @brief Implementation of the Pickup class.
+*/
+
+#include "Pickup.h"
+
+#include "core/CoreIncludes.h"
+#include "util/StringUtils.h"
+#include "pickup/PickupIdentifier.h"
+#include "DroppedPickup.h"
+
+#include "tools/Timer.h"
+
+namespace orxonox
+{
+
+    /*static*/ const std::string Pickup::activationTypeImmediate_s = "immediate";
+    /*static*/ const std::string Pickup::activationTypeOnUse_s = "onUse";
+    /*static*/ const std::string Pickup::durationTypeOnce_s = "once";
+    /*static*/ const std::string Pickup::durationTypeContinuous_s = "continuous";
+
+    Pickup::Pickup(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(Pickup);
+
+        this->initialize();
+    }
+
+    Pickup::~Pickup()
+    {
+
+    }
+
+    /**
+    @brief
+        Initializes the member variables.
+    */
+    void Pickup::initialize(void)
+    {
+        this->activationType_ = pickupActivationType::immediate;
+        this->durationType_ = pickupDurationType::once;
+    }
+
+    /**
+    @brief
+        Initializes the PickupIdentififer of this Pickup.
+    */
+    void Pickup::initializeIdentifier(void)
+    {
+        std::string val1 = this->getActivationType();
+        std::string type1 = "activationType";
+        this->pickupIdentifier_->addParameter(type1, val1);
+
+        std::string val2 = this->getDurationType();
+        std::string type2 = "durationType";
+        this->pickupIdentifier_->addParameter(type2, val2);
+    }
+
+    /**
+    @brief
+        Method for creating a Pickup object through XML.
+    */
+    void Pickup::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Pickup, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Pickup, "activationType", setActivationType, getActivationType, xmlelement, mode);
+        XMLPortParam(Pickup, "durationType", setDurationType, getDurationType, xmlelement, mode);
+
+        this->initializeIdentifier();
+    }
+
+    /**
+    @brief
+        Get the activation type of the pickup.
+    @return
+        Returns a string containing the activation type.
+    */
+    const std::string& Pickup::getActivationType(void)
+    {
+        switch(this->activationType_)
+        {
+            case pickupActivationType::immediate:
+                return activationTypeImmediate_s;
+            case pickupActivationType::onUse:
+                return activationTypeOnUse_s;
+            default:
+                return BLANKSTRING;
+        }
+    }
+
+    /**
+    @brief
+        Get the duration type of the pickup.
+    @return
+        Returns a string containing the duration type.
+    */
+    const std::string& Pickup::getDurationType(void)
+    {
+        switch(this->durationType_)
+        {
+            case pickupDurationType::once:
+                return durationTypeOnce_s;
+            case pickupDurationType::continuous:
+                return durationTypeContinuous_s;
+            default:
+                return BLANKSTRING;
+        }
+    }
+
+    /**
+    @brief
+        Set the activation type of the Pickup.
+    @param type
+        The activation type of the Pickup as a string.
+    */
+    void Pickup::setActivationType(const std::string& type)
+    {
+        if(type == activationTypeImmediate_s)
+        {
+            this->activationType_ = pickupActivationType::immediate;
+        }
+        else if(type == activationTypeOnUse_s)
+        {
+            this->activationType_ = pickupActivationType::onUse;
+        }
+        else
+        {
+            COUT(1) << "Invalid activationType in pickup." << std::endl;
+        }
+    }
+
+    /**
+    @brief
+        Set the duration type of the Pickup.
+    @param type
+        The duration type of the Pickup as a string.
+    */
+    void Pickup::setDurationType(const std::string& type)
+    {
+        if(type == durationTypeOnce_s)
+        {
+            this->durationType_ = pickupDurationType::once;
+        }
+        else if(type == durationTypeContinuous_s)
+        {
+            this->durationType_ = pickupDurationType::continuous;
+        }
+        else
+        {
+            COUT(1) << "Invalid durationType in pickup." << std::endl;
+        }
+    }
+
+    /**
+    @brief
+        Should be called when the pickup has transited from picked up to dropped or the other way around.
+        Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedPickedUp); to their changedPickedUp method.
+    */
+    void Pickup::changedPickedUp(void)
+    {
+        SUPER(Pickup, changedPickedUp);
+
+        //! Sets the Pickup to used if the Pickup has activation type 'immediate' and gets picked up.
+        if(this->getCarrier() != NULL && this->isPickedUp() && this->isImmediate())
+        {
+            this->setUsed(true);
+        }
+    }
+
+    /**
+    @brief
+        Creates a duplicate of the Pickup.
+    @return
+        Returns the clone of this pickup as a pointer to a Pickupable.
+    */
+    void Pickup::clone(OrxonoxClass*& item)
+    {
+        if(item == NULL)
+            item = new Pickup(this);
+
+        SUPER(Pickup, clone, item);
+
+        Pickup* pickup = dynamic_cast<Pickup*>(item);
+        pickup->setActivationTypeDirect(this->getActivationTypeDirect());
+        pickup->setDurationTypeDirect(this->getDurationTypeDirect());
+
+        pickup->initializeIdentifier();
+    }
+
+    /**
+    @brief
+        Facilitates the creation of a PickupSpawner upon dropping of the Pickupable.
+        This method must be implemented by any class directly inheriting from Pickupable. It is most easily done by just creating a new DroppedPickup, e.g.:
+        DroppedPickup(BaseObject* creator, Pickupable* pickup, const Vector3& position);
+    @param position
+        The position at which the PickupSpawner should be placed.
+    @return
+        Returns true if a spawner was created, false if not.
+    */
+    bool Pickup::createSpawner(void)
+    {
+        new DroppedPickup(this, this, this->getCarrier());
+        return true;
+    }
+
+    /**
+    @brief
+        Starts the pickup duration timer.
+        After the specified durationTime has expired the function pickupTimerCallback is called.
+        pickupTimerCallback can be overloaded and thus the desired functionality can be implemented.
+    @param durationTime
+        The duration after which the expires and the callback function is called.
+    @return
+        Returns true if the pickup duration timer was started successfully, false if not.
+    */
+    bool Pickup::startPickupTimer(float durationTime)
+    {
+        if (durationTime<=0)
+        {
+            COUT(1) << "Invalid durationTime in pickup." << std::endl;
+            return false;
+        }
+        if (this->durationTimer_.isActive()) //!< Check if Timer is already running
+        {
+            COUT(1) << "Pickup durationTimer already in use." << std::endl;
+            return false;
+        }
+        this->durationTimer_.setTimer(durationTime, false, createExecutor(createFunctor(&Pickup::pickupTimerCallback, this)));
+        return true;
+    }
+}
Index: /code/branches/rocket2/src/modules/pickup/Pickup.h
===================================================================
--- /code/branches/rocket2/src/modules/pickup/Pickup.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/Pickup.h	(revision 6952)
@@ -0,0 +1,184 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+/**
+    @file Pickup.h
+    @brief Declaration of the Pickup class.
+*/
+
+#ifndef _Pickup_H__
+#define _Pickup_H__
+
+#include "pickup/PickupPrereqs.h"
+
+#include "core/BaseObject.h"
+#include "core/XMLPort.h"
+
+#include "interfaces/Pickupable.h"
+
+#include "tools/Timer.h"
+
+namespace orxonox
+{
+
+    //! Enum for the activation type.
+    namespace pickupActivationType
+    {
+        enum Value
+        {
+            immediate,
+            onUse,
+        };
+    }
+
+    //! Enum for the duration tyoe.
+    namespace pickupDurationType
+    {
+        enum Value
+        {
+            once,
+            continuous,
+        };
+    }
+
+    /**
+    @brief
+        Pickup class. Offers base functionality for a wide range of pickups.
+        Pickups ingeriting from this class cann choose an activation type and a duration type.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _PickupExport Pickup : public Pickupable, public BaseObject
+    {
+
+        protected:
+            Pickup(BaseObject* creator); //!< Constructor.
+
+        public:
+            virtual ~Pickup(); //!< Destructor.
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            /**
+            @brief Get the activation type of the pickup.
+            @return Returns the activation type of the pickup.
+            */
+            inline pickupActivationType::Value getActivationTypeDirect(void)
+                { return this->activationType_; }
+            /**
+            @brief Get the duration type of the pickup.
+            @return Returns the duration type of the pickup.
+            */
+            inline pickupDurationType::Value getDurationTypeDirect(void)
+                { return this->durationType_; }
+
+            const std::string& getActivationType(void); //!< Get the activation type of the pickup.
+            const std::string& getDurationType(void); //!< Get the duration type of the pickup.
+
+            /**
+            @brief Get whether the activation type is 'immediate'.
+            @return Returns true if the activation type is 'immediate'.
+            */
+            inline bool isImmediate(void)
+                { return this->getActivationTypeDirect() == pickupActivationType::immediate; }
+            /**
+            @brief Get whether the activation type is 'onUse'.
+            @return Returns true if the activation type is 'onUse'.
+            */
+            inline bool isOnUse(void)
+                { return this->getActivationTypeDirect() == pickupActivationType::onUse; }
+            /**
+            @brief Get whether the duration type is 'once'.
+            @return Returns true if the duration type is 'once'.
+            */
+            inline bool isOnce(void)
+                { return this->getDurationTypeDirect() == pickupDurationType::once; }
+            /**
+            @brief Get whether the duration type is 'continuous'.
+            @return Returns true if the duration type is 'continuous'.
+            */
+            inline bool isContinuous(void)
+                { return this->getDurationTypeDirect() == pickupDurationType::continuous; }
+
+            virtual void changedPickedUp(void); //!< Should be called when the pickup has transited from picked up to dropped or the other way around.
+
+            virtual void clone(OrxonoxClass*& item); //!< Creates a duplicate of the Pickup.
+
+        protected:
+            void initializeIdentifier(void);
+
+            virtual bool createSpawner(void); //!< Facilitates the creation of a PickupSpawner upon dropping of the Pickupable.
+
+            bool startPickupTimer(float durationTime); //!< Starts the pickup duration timer.
+            /**
+            @brief Get your Timer.
+            @return Returns a pointer to the Timer.
+            */
+            inline Timer* getTimer(void)
+                { return &this->durationTimer_; }
+
+            /**
+            @brief The callback method for the Timer.
+                   Can be overloaded to implement desired functionality.
+            */
+            virtual void pickupTimerCallback(void) {}
+
+            /**
+            @brief Set the activation type of the pickup.
+            @param type The activation type of the pickup.
+            */
+            inline void setActivationTypeDirect(pickupActivationType::Value type)
+                { this->activationType_ = type; }
+            /**
+            @brief Set the duration type of the pickup.
+            @param type The duration type of the pickup.
+            */
+            inline void setDurationTypeDirect(pickupDurationType::Value type)
+                { this->durationType_ = type; }
+
+            void setActivationType(const std::string& type); //!< Set the activation type of the pickup.
+            void setDurationType(const std::string& type); //!< Set the duration type of the pickup
+
+        private:
+            void initialize(void); //!< Initializes the member variables.
+            
+            //TODO: Problems, when there are more Timers needed? Solutions?
+            Timer durationTimer_; //!< Timer at the disposal of each Class implementing Pickup.
+
+            pickupActivationType::Value activationType_; //!< The activation type of the Pickup.
+            pickupDurationType::Value durationType_; //!< The duration type of the pickup.
+
+            //! Strings for the activation and duration types.
+            static const std::string activationTypeImmediate_s;
+            static const std::string activationTypeOnUse_s;
+            static const std::string durationTypeOnce_s;
+            static const std::string durationTypeContinuous_s;
+    };
+
+}
+#endif // _Pickup_H__
Index: /code/branches/rocket2/src/modules/pickup/PickupCollection.cc
===================================================================
--- /code/branches/rocket2/src/modules/pickup/PickupCollection.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/PickupCollection.cc	(revision 6952)
@@ -0,0 +1,248 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file PickupCollection.cc
+    @brief Implementation of PickupCollection.
+*/
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "interfaces/PickupCarrier.h"
+#include "DroppedPickup.h"
+#include "PickupCollectionIdentifier.h"
+
+#include "PickupCollection.h"
+
+namespace orxonox
+{
+ 
+    CreateFactory(PickupCollection);
+
+    /**
+    @brief
+        Default Constructor.
+    */
+    PickupCollection::PickupCollection(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(PickupCollection);
+        
+        this->pickupCollectionIdentifier_ = new PickupCollectionIdentifier(this);
+    }
+    
+    /**
+    @brief
+        Destructor. Iterates through all Pickupables this PickupCollection consists of and destroys them if they haven't been already.
+    */
+    PickupCollection::~PickupCollection()
+    {
+        //! Destroy all Pickupables constructing this PickupCollection.
+        for(std::vector<WeakPtr<Pickupable> >::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            if((*it).get() != NULL)
+                (*it).get()->destroy();
+        }
+    }
+    
+    /**
+    @brief
+        Creates an instance of this Class through XML.
+    */
+    void PickupCollection::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(PickupCollection, XMLPort, xmlelement, mode);
+        
+        XMLPortObject(PickupCollection, Pickupable, "pickupables", addPickupable, getPickupable, xmlelement, mode);
+        
+        this->initializeIdentifier();
+    }
+    
+    /**
+    @brief
+        Initializes the PickupIdentifier for this pickup.
+    */
+    void PickupCollection::initializeIdentifier(void)
+    {
+        for(std::vector<WeakPtr<Pickupable> >::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            this->pickupCollectionIdentifier_->addPickup((*it).get()->getPickupIdentifier());
+        }
+    }
+    
+    /**
+    @brief
+        Is called when the pickup has transited from used to unused or the other way around.
+        Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedUsed); to their changdeUsed method.
+    */
+    void PickupCollection::changedUsed(void)
+    {
+        SUPER(PickupCollection, changedUsed);
+        
+        //! Change used for all Pickupables this PickupCollection consists of.
+        for(std::vector<WeakPtr<Pickupable> >::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            (*it).get()->setUsed(this->isUsed());
+        }
+    }
+    
+    /**
+    @brief
+        Is called when the pickup has changed its PickupCarrier.
+        Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedCarrier); to their changedCarrier method.
+    */
+    void PickupCollection::changedCarrier(void)
+    {
+        SUPER(PickupCollection, changedCarrier);
+        
+        //! Change the PickupCarrier for all Pickupables this PickupCollection consists of.
+        for(std::vector<WeakPtr<Pickupable> >::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            (*it).get()->setCarrier(this->getCarrier()->getTarget(*it));
+        }
+    }
+    
+    /**
+    @brief
+        Is called when the pickup has transited from picked up to dropped or the other way around.
+        Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedPickedUp); to their changedPickedUp method.
+    */
+    void PickupCollection::changedPickedUp()
+    {
+        SUPER(PickupCollection, changedPickedUp);
+        
+        //! Change the pickedUp status for all Pickupables this PickupCollection consists of.
+        for(std::vector<WeakPtr<Pickupable> >::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            (*it).get()->setPickedUp(this->isPickedUp());
+        }
+    }
+    
+    /**
+    @brief
+        Creates a duplicate of the input OrxonoxClass.
+        This method needs to be implemented by any Class inheriting from Pickupable.
+    @param item
+        A reference to a pointer to the OrxonoxClass that is to be duplicated.
+    */
+    void PickupCollection::clone(OrxonoxClass*& item)
+    {
+        if(item == NULL)
+            item = new PickupCollection(this);
+        
+        SUPER(PickupCollection, clone, item);
+        
+        PickupCollection* pickup = dynamic_cast<PickupCollection*>(item);
+        //! Clone all Pickupables this PickupCollection consist of.
+        for(std::vector<WeakPtr<Pickupable> >::iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            Pickupable* newPickup = (*it).get()->clone();
+            pickup->addPickupable(newPickup);
+        }
+
+        pickup->initializeIdentifier();
+    }
+    
+    /**
+    @brief
+        Get whether a given class, represented by the input Identifier, is a target of this PickupCollection.
+    @param identifier
+        A pointer to the PickupIdentifier of the PickupCarrier we want to know of, whether it is a target of this PickupCollection.
+    @return
+        Returns true if the PickupCarrier identified by the input PickupIdentififer it is a target of this PickupCollection, false if not.
+    */
+    bool PickupCollection::isTarget(PickupCarrier* carrier) const
+    {
+        for(std::vector<WeakPtr<Pickupable> >::const_iterator it = this->pickups_.begin(); it != this->pickups_.end(); it++)
+        {
+            if(!carrier->isTarget((*it).get()))
+                return false;
+        }
+        
+        return true;
+    }
+    
+    /**
+    @brief
+        Get the PickupIdentifier of this PickupCollection.
+        This is in fact the PickupCollectionIdentifier.
+    @return
+        Returns a pointer to the PickupIdentifier of this PickupCollection.
+    */
+    const PickupIdentifier* PickupCollection::getPickupIdentifier(void)
+    {
+        return this->pickupCollectionIdentifier_;
+    }
+    
+    /**
+    @brief
+        Add the input Pickupable to list of Pickupables combined by this PickupCollection.
+    @param pickup
+        The Pickupable to be added.
+    @return
+        Returns true if successful,
+    */
+    bool PickupCollection::addPickupable(Pickupable* pickup)
+    {
+        if(pickup == NULL)
+            return false;
+        
+        WeakPtr<Pickupable> ptr = pickup; //!< Create a weak pointer to be able to test in the constructor if the Pointer is still valid.
+        this->pickups_.push_back(ptr);
+        return true;
+    }
+    
+    /**
+    @brief
+        Get the Pickupable at the given index.
+    @param index
+        The index the Pickupable is fetched from.
+    @return
+        Returns a pointer to the Pickupable at the index given by index.
+    */
+    const Pickupable* PickupCollection::getPickupable(unsigned int index)
+    {
+        return this->pickups_[index].get();
+    }
+        
+    /**
+    @brief
+        Facilitates the creation of a PickupSpawner upon dropping of the Pickupable.
+        This method must be implemented by any class directly inheriting from Pickupable. It is most easily done by just creating a new DroppedPickup, e.g.:
+        DroppedPickup(BaseObject* creator, Pickupable* pickup, const Vector3& position);
+    @param position
+        The position at which the PickupSpawner should be placed.
+    @return
+        Returns true if a spawner was created, false if not.
+    */
+    bool PickupCollection::createSpawner(void)
+    {
+        new DroppedPickup(this, this, this->getCarrier());
+        return true;
+    }
+    
+}
Index: /code/branches/rocket2/src/modules/pickup/PickupCollection.h
===================================================================
--- /code/branches/rocket2/src/modules/pickup/PickupCollection.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/PickupCollection.h	(revision 6952)
@@ -0,0 +1,91 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file PickupCollection.h
+    @brief Declaration of PickupCollection.
+*/
+
+#ifndef _PickupCollection_H__
+#define _PickupCollection_H__
+
+#include "PickupPrereqs.h"
+
+#include "interfaces/Pickupable.h"
+#include "core/BaseObject.h"
+
+#include <list>
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        The PickupCollection combines different Pickupables to a coherent, single pickup and makes the seem (from the outside looking in) just as if they were just one Pickupable.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _PickupExport PickupCollection : public Pickupable, public BaseObject
+    {
+        
+        public:
+            
+            PickupCollection(BaseObject* creator); //!< Default Constructor.
+            virtual ~PickupCollection(); //!< Destructor.
+            
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Creates an instance of this Class through XML.
+
+            virtual void changedUsed(void); //!< Is called when the pickup has transited from used to unused or the other way around.
+            virtual void changedCarrier(void); //!< Is called when the pickup has changed its PickupCarrier.
+            virtual void changedPickedUp(void); //!< Is called when the pickup has transited from picked up to dropped or the other way around.
+            
+            virtual void clone(OrxonoxClass*& item); //!< Creates a duplicate of the input OrxonoxClass.
+            
+            virtual bool isTarget(PickupCarrier* carrier) const; //!< Get whether a given class, represented by the input Identifier, is a target of this PickupCollection.
+            
+            virtual const PickupIdentifier* getPickupIdentifier(void); //!< Get the PickupIdentifier of this PickupCollection.
+            
+            bool addPickupable(Pickupable* pickup); //!< Add the input Pickupable to list of Pickupables combined by this PickupCollection.
+            const Pickupable* getPickupable(unsigned int index); //!< Get the Pickupable at the given index.
+            
+        protected:
+            void initializeIdentifier(void); //!< Initializes the PickupIdentifier for this pickup.
+            
+            virtual bool createSpawner(void); //!< Facilitates the creation of a PickupSpawner upon dropping of the Pickupable.
+            
+            PickupCollectionIdentifier* pickupCollectionIdentifier_; //!< The PickupCollectionIdentifier of this PickupCollection. Is used to distinguish different PickupCollections amongst themselves.
+            
+        private:
+            
+            std::vector<WeakPtr<Pickupable> > pickups_; //!< The list of the pointers of all the Pickupables this PickupCollection consists of. They are weak pointers to facilitate testing, whether the pointers are still valid.
+        
+    };
+    
+}
+
+#endif /* _PickupCollection_H__ */
Index: /code/branches/rocket2/src/modules/pickup/PickupCollectionIdentifier.cc
===================================================================
--- /code/branches/rocket2/src/modules/pickup/PickupCollectionIdentifier.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/PickupCollectionIdentifier.cc	(revision 6952)
@@ -0,0 +1,110 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+/**
+    @file PickupCollectionIdentifier.cc
+    @brief Implementation of PickupCollectionIdentifier.
+*/
+
+#include "core/CoreIncludes.h"
+
+#include "PickupCollectionIdentifier.h"
+
+namespace orxonox
+{
+    
+    /**
+    @brief
+        Constructor. Registers the object.
+    */
+    PickupCollectionIdentifier::PickupCollectionIdentifier(Pickupable* pickup) : PickupIdentifier(pickup)
+    {
+        RegisterObject(PickupCollectionIdentifier);
+    }
+    
+    /**
+    @brief
+        Destructor.
+    */
+    PickupCollectionIdentifier::~PickupCollectionIdentifier()
+    {
+        
+    }
+
+    /**
+    @brief
+        Compares a PickupCollectionIdentifier with a PickupIdentifier and returns 0 if a == b, <0 if a < b and >0 if a > b for a.compare(b), where a is a PickupCollectionIdentifier and b is just some PickupIdentifier.
+    @param identifier
+        Pointer to the second PickupIdentifier, b.
+    @return
+        Returns an integer. 0 if the two compared PickupIdentifiers are the same, <0 if a < b and >0 if a > b.
+    */
+    int PickupCollectionIdentifier::compare(const PickupIdentifier* identifier) const
+    {
+        //! Slight un-niceity to cast the PickupIdentifier to a PickupCollectionIdentifier.
+        PickupIdentifier* temp = const_cast<PickupIdentifier*>(identifier);
+        const PickupCollectionIdentifier* collectionIdentifier = dynamic_cast<PickupCollectionIdentifier*>(temp);
+        
+        //! If the input PickupIdentifier 'identifier' is no PickupCollectionIdentifier then just the two PickupIdentifiers are compared.
+        if(collectionIdentifier == NULL)
+        {
+            return this->PickupIdentifier::compare(identifier);
+        }
+        
+        //! If the number of Pickupables each of the two PickupCollectionIdentifiers contain differ, the one with less is considered smaller.
+        if(this->identifiers_.size() != collectionIdentifier->identifiers_.size())
+            return this->identifiers_.size()-collectionIdentifier->identifiers_.size();
+        
+        //! Compare the Pickupables of the two PickupCollectionIdentifiers one after the other. the one with the first 'smaller' one is considered smaller.
+        std::set<const PickupIdentifier*, PickupIdentifierCompare>::const_iterator it2 = collectionIdentifier->identifiers_.begin();
+        for(std::set<const PickupIdentifier*, PickupIdentifierCompare>::const_iterator it = this->identifiers_.begin(); it != this->identifiers_.end(); it++)
+        {
+            
+            if((*it)->compare(*it2) < 0)
+                return -1;
+            if((*it2)->compare(*it) < 0)
+                return 1;
+        }
+        
+        //! Means they are equal.
+        return 0;
+    }
+    
+    /**
+    @brief
+        Add a Pickupable to the PickupCollectionIdentifier.
+    @param
+        A pointer to the PickupIdentifier of the Pickupable to be added.
+    */
+    void PickupCollectionIdentifier::addPickup(const PickupIdentifier* identifier)
+    {
+        this->identifiers_.insert(identifier);
+    }
+    
+}
+
Index: /code/branches/rocket2/src/modules/pickup/PickupCollectionIdentifier.h
===================================================================
--- /code/branches/rocket2/src/modules/pickup/PickupCollectionIdentifier.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/PickupCollectionIdentifier.h	(revision 6952)
@@ -0,0 +1,72 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+/**
+    @file PickupCollectionIdentifier.h
+    @brief Declaration of PickupCollectionIdentifier.
+*/
+
+#ifndef _PickupCollectionIdentifier_H__
+#define _PickupCollectionIdentifier_H_
+
+#include "PickupPrereqs.h"
+
+#include "pickup/PickupIdentifier.h"
+
+#include <set>
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        The PickupCollectionIdentifier is the specialization of the PickupIdentifier for the PickupCollection class.
+        It identifies PickupCollections based on the different Pickupables they consist of.
+        Pickupables can be added to the PickupCollectionIdentifier via the addPickup method.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _PickupExport PickupCollectionIdentifier : public PickupIdentifier
+    {
+        
+        public:
+            PickupCollectionIdentifier(Pickupable* pickup); //!< Constructor.
+            ~PickupCollectionIdentifier(); //!< Destructor.
+            
+            virtual int compare(const PickupIdentifier* identifier) const; //!< Compares a PickupCollectionIdentifier with a PickupIdentifier.
+            
+            void addPickup(const PickupIdentifier* identifier); //!< Add a Pickupable to the PickupCollectionIdentifier.
+            
+        private:
+            std::set<const PickupIdentifier*, PickupIdentifierCompare> identifiers_; //!< The set of PickupIdentifiers of the Pickupables the PickupCollection with this PickupCollectionIdentifier consists of, ordered by the rule set by PickupIdentifierCompare.
+            
+    };
+    
+}
+
+#endif // _PickupCollectionIdentifier_H_
Index: /code/branches/rocket2/src/modules/pickup/PickupManager.cc
===================================================================
--- /code/branches/rocket2/src/modules/pickup/PickupManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/PickupManager.cc	(revision 6952)
@@ -0,0 +1,212 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      ...
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+/**
+    @file PickupManager.cc
+    @brief Implementation of the PickupManager class.
+*/
+
+#include "PickupManager.h"
+
+#include "core/CoreIncludes.h"
+#include "core/LuaState.h"
+#include "core/GUIManager.h"
+#include "core/ScopedSingletonManager.h"
+#include "core/Identifier.h"
+#include "interfaces/PickupCarrier.h"
+#include "infos/PlayerInfo.h"
+#include "worldentities/pawns/Pawn.h"
+#include "PickupRepresentation.h"
+
+#include "ToluaBindPickup.h"
+
+namespace orxonox
+{
+    // Register tolua_open function when loading the library
+    DeclareToluaInterface(Pickup);
+    
+    ManageScopedSingleton(PickupManager, ScopeID::Graphics, false);
+    
+    /*static*/ const std::string PickupManager::guiName_s = "PickupInventory";
+    
+    /**
+    @brief
+        Constructor. Registers the PickupManager and creates the default PickupRepresentation.
+    */
+    PickupManager::PickupManager() : defaultRepresentation_(NULL)
+    {
+        RegisterRootObject(PickupManager);
+        
+        this->defaultRepresentation_ = new PickupRepresentation();
+        
+        COUT(3) << "PickupManager created." << std::endl;
+    }
+    
+    /**
+    @brief
+        Destructor.
+        Destroys the default PickupRepresentation.
+    */
+    PickupManager::~PickupManager()
+    {
+        if(this->defaultRepresentation_ != NULL)
+            this->defaultRepresentation_->destroy();
+        
+        this->representations_.clear();
+        
+        COUT(3) << "PickupManager destroyed." << std::endl;
+    }
+    
+    /**
+    @brief
+        Registers a PickupRepresentation together with the PickupIdentifier of the Pickupable the PickupRepresentation represents.
+        For every type of Pickupable (uniquely idnetified by a PickupIdentifier) there can be one (and just one) PickupRepresentation registered.
+    @param identifier
+        The PickupIdentifier identifying the Pickupable.
+    @param representation
+        A pointer to the PickupRepresentation.
+    @return
+        Returns true if successful and false if not.
+    */
+    bool PickupManager::registerRepresentation(const PickupIdentifier* identifier, PickupRepresentation* representation)
+    {       
+        if(identifier == NULL || representation == NULL || this->representations_.find(identifier) != this->representations_.end()) //!< If the Pickupable already has a Representation registered.
+            return false;
+        
+        this->representations_[identifier] = representation;
+        
+        COUT(4) << "PickupRepresentation " << representation << " registered with the PickupManager." << std::endl;
+        return true;
+    }
+    
+    /**
+    @brief
+        Unegisters a PickupRepresentation together with the PickupIdentifier of the Pickupable the PickupRepresentation represents.
+    @param identifier
+        The PickupIdentifier identifying the Pickupable.
+    @param representation
+        A pointer to the PickupRepresentation.
+    @return
+        Returns true if successful and false if not.
+    */
+    bool PickupManager::unregisterRepresentation(const PickupIdentifier* identifier, PickupRepresentation* representation)
+    {       
+        if(identifier == NULL || representation == NULL)
+            return false;
+        
+        std::map<const PickupIdentifier*, PickupRepresentation*, PickupIdentifierCompare>::iterator it = this->representations_.find(identifier);
+        if(it == this->representations_.end()) //!< If the Pickupable is not registered in the first place.
+            return false;
+        
+        this->representations_.erase(it);
+        
+        COUT(4) << "PickupRepresentation " << representation << " unregistered with the PickupManager." << std::endl;
+        return true;
+    }
+    
+    /**
+    @brief
+        Get the PickupRepresentation representing the Pickupable with the input PickupIdentifier.
+    @param identifier
+        The PickupIdentifier.
+    @return
+        Returns a pointer to the PickupRepresentation.
+    */
+    PickupRepresentation* PickupManager::getRepresentation(const PickupIdentifier* identifier)
+    {
+        std::map<const PickupIdentifier*, PickupRepresentation*, PickupIdentifierCompare>::iterator it = this->representations_.find(identifier);
+        if(it == this->representations_.end())
+        {
+            COUT(4) << "PickupManager::getRepresentation() returned default representation." << std::endl;
+            return this->defaultRepresentation_;
+        }
+        
+        return it->second;
+    }
+    
+    PickupCarrier* PickupManager::getPawn(void)
+    {
+        PlayerInfo* player = GUIManager::getInstance().getPlayer(PickupManager::guiName_s);
+        if (player != NULL)
+            return dynamic_cast<PickupCarrier*>(player->getControllableEntity());
+        else
+            return NULL;
+    }
+    
+    int PickupManager::getNumCarrierChildren(PickupCarrier* carrier)
+    {
+        if(carrier == NULL)
+            return 0;
+        return carrier->getNumCarrierChildren();
+    }
+            
+    PickupCarrier* PickupManager::getCarrierChild(int index, PickupCarrier* carrier)
+    {
+        if(carrier == NULL)
+            return NULL;
+        return carrier->getCarrierChild(index);
+    }
+    
+    const std::string& PickupManager::getCarrierName(orxonox::PickupCarrier* carrier)
+    {
+        if(carrier == NULL)
+            return BLANKSTRING;
+        return carrier->getCarrierName();
+    }
+    
+    PickupRepresentation* PickupManager::getPickupRepresentation(int index, PickupCarrier* carrier)
+    {
+        Pickupable* pickup = carrier->getPickup(index);
+        if(pickup == NULL)
+            return NULL;
+        
+        return this->getRepresentation(pickup->getPickupIdentifier());
+    }
+    
+    int PickupManager::getNumPickups(PickupCarrier* carrier)
+    {
+        if(carrier == NULL)
+            return 0;
+        return carrier->getNumPickups();
+    }
+    
+    void PickupManager::dropPickup(int index, PickupCarrier* carrier)
+    {
+        Pickupable* pickup = carrier->getPickup(index);
+        if(pickup != NULL)
+            carrier->drop(pickup);
+    }
+    
+    void PickupManager::usePickup(int index, PickupCarrier* carrier, bool use)
+    {
+        Pickupable* pickup = carrier->getPickup(index);
+        if(pickup != NULL)
+            pickup->setUsed(use);
+    }
+    
+}
Index: /code/branches/rocket2/src/modules/pickup/PickupManager.h
===================================================================
--- /code/branches/rocket2/src/modules/pickup/PickupManager.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/PickupManager.h	(revision 6952)
@@ -0,0 +1,97 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+/**
+    @file PickupManager.h
+    @brief Definition of the PickupManager class.
+*/
+
+#ifndef _PickupManager_H__
+#define _PickupManager_H__
+
+#include "PickupPrereqs.h"
+
+#include <map>
+#include "util/Singleton.h"
+#include "pickup/PickupIdentifier.h"
+#include "PickupRepresentation.h"
+
+#include "core/OrxonoxClass.h"
+
+namespace orxonox // tolua_export
+{ // tolua_export
+
+    /**
+    @brief
+        Manages Pickupables.
+        In essence has two tasks to fulfill. Firstly it must link Pickupables (through their PickupIdentifiers) and their PickupRepresentations. Secondly it manages the PickupInventory.
+        //TODO: Manage Pickup GUI.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _PickupExport PickupManager // tolua_export
+        : public Singleton<PickupManager>, public OrxonoxClass
+    { // tolua_export
+        friend class Singleton<PickupManager>;
+        
+        public:
+            PickupManager();
+            virtual ~PickupManager();
+            
+            static PickupManager& getInstance() { return Singleton<PickupManager>::getInstance(); } // tolua_export
+            
+            bool registerRepresentation(const PickupIdentifier* identifier, PickupRepresentation* representation); //!< Registers a PickupRepresentation together with the PickupIdentifier of the Pickupable the PickupRepresentation represents.
+            bool unregisterRepresentation(const PickupIdentifier* identifier, PickupRepresentation* representation); //!< Unegisters a PickupRepresentation together with the PickupIdentifier of the Pickupable the PickupRepresentation represents.
+            PickupRepresentation* getRepresentation(const PickupIdentifier* identifier); //!< Get the PickupRepresentation representing the Pickupable with the input PickupIdentifier.
+            
+            // tolua_begin
+            orxonox::PickupCarrier* getPawn(void);
+            
+            int getNumCarrierChildren(orxonox::PickupCarrier* carrier);
+            orxonox::PickupCarrier* getCarrierChild(int index, orxonox::PickupCarrier* carrier);
+            
+            const std::string& getCarrierName(orxonox::PickupCarrier* carrier);
+            
+            int getNumPickups(orxonox::PickupCarrier* carrier);
+            PickupRepresentation* getPickupRepresentation(int index, orxonox::PickupCarrier* carrier);
+            void dropPickup(int index, orxonox::PickupCarrier* carrier);
+            void usePickup(int index, orxonox::PickupCarrier* carrier, bool use);
+            // tolua_end
+            
+        private:
+            static PickupManager* singletonPtr_s;
+            static const std::string guiName_s;
+            
+            PickupRepresentation* defaultRepresentation_; //!< The default PickupRepresentation.
+            std::map<const PickupIdentifier*, PickupRepresentation*, PickupIdentifierCompare> representations_; //!< Map linking PickupIdentifiers (representing types if Pickupables) and PickupRepresentations.
+        
+    }; // tolua_export
+    
+} // tolua_export
+
+#endif // _PickupManager_H__
Index: /code/branches/rocket2/src/modules/pickup/PickupPrereqs.h
===================================================================
--- /code/branches/rocket2/src/modules/pickup/PickupPrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/PickupPrereqs.h	(revision 6952)
@@ -0,0 +1,84 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Shared library macros, enums, constants and forward declarations for the questsystem module
+*/
+
+#ifndef _PickupPrereqs_H__
+#define _PickupPrereqs_H__
+
+#include "OrxonoxConfig.h"
+#include "OrxonoxPrereqs.h"
+
+//-----------------------------------------------------------------------
+// Shared library settings
+//-----------------------------------------------------------------------
+
+#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined(ORXONOX_STATIC_BUILD)
+#  ifdef PICKUP_SHARED_BUILD
+#    define _PickupExport __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define _PickupExport
+#    else
+#      define _PickupExport __declspec(dllimport)
+#    endif
+#  endif
+#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _PickupExport  __attribute__ ((visibility("default")))
+#else
+#  define _PickupExport
+#endif
+
+//-----------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    
+    class DroppedPickup;
+    class Pickup;
+    class PickupCollection;
+    class PickupCollectionIdentifier;
+    class PickupManager;
+    class PickupRepresentation;
+    class PickupSpawner;
+
+    //items
+    class HealthPickup;
+    class InvisiblePickup;
+    class MetaPickup;
+    class SpeedPickup;
+
+}
+
+#endif /* _PickupPrereqs_H__ */
Index: /code/branches/rocket2/src/modules/pickup/PickupRepresentation.cc
===================================================================
--- /code/branches/rocket2/src/modules/pickup/PickupRepresentation.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/PickupRepresentation.cc	(revision 6952)
@@ -0,0 +1,174 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+/**
+    @file PickupRepresentation.cc
+    @brief Implementation of the PickupRepresentation class.
+*/
+
+#include "PickupRepresentation.h"
+
+#include "core/CoreIncludes.h"
+#include "graphics/Billboard.h"
+#include "util/StringUtils.h"
+#include "PickupManager.h"
+
+namespace orxonox
+{
+    
+    CreateFactory(PickupRepresentation);
+    
+    /**
+    @brief
+        Constructor. Registers the object and initializes its member variables.
+        This is primarily for use of the PickupManager in creating a default PickupRepresentation.
+    */
+    PickupRepresentation::PickupRepresentation() : BaseObject(NULL), spawnerRepresentation_(NULL), pickup_(NULL)
+    {
+        RegisterObject(PickupRepresentation);
+        
+        this->initialize();
+    }
+    
+    /**
+    @brief
+        Default Constructor. Registers the object and initializes its member variables.
+    */
+    PickupRepresentation::PickupRepresentation(BaseObject* creator) : BaseObject(creator), spawnerRepresentation_(NULL), pickup_(NULL)
+    {
+        RegisterObject(PickupRepresentation);
+        
+        this->initialize();
+    }
+    
+    /**
+    @brief
+        Destructor.
+    */
+    PickupRepresentation::~PickupRepresentation()
+    {
+        if(this->spawnerRepresentation_ != NULL)
+            this->spawnerRepresentation_->destroy();
+        
+        if(this->pickup_ != NULL)
+            PickupManager::getInstance().unregisterRepresentation(this->pickup_->getPickupIdentifier(), this);
+    }
+    
+    /**
+    @brief
+        Initializes the member variables of this PickupRepresentation.
+    */
+    void PickupRepresentation::initialize(void)
+    {
+        this->description_ = "This is a pickup.";
+        this->name_ = "Pickup";
+        this->spawnerTemplate_ = "";
+        this->inventoryRepresentation_ = "Default";
+    }
+    
+    /**
+    @brief
+        Method for creating a PickupRepresentation object through XML.
+    */
+    void PickupRepresentation::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(PickupRepresentation, XMLPort, xmlelement, mode);
+        
+        XMLPortParam(PickupRepresentation, "pickupName", setPickupName, getPickupName, xmlelement, mode);
+        XMLPortParam(PickupRepresentation, "pickupDescription", setPickupDescription, getPickupDescription, xmlelement, mode);
+        XMLPortParam(PickupRepresentation, "spawnerTemplate", setSpawnerTemplate, getSpawnerTemplate, xmlelement, mode);
+        XMLPortParam(PickupRepresentation, "inventoryRepresentation", setInventoryRepresentation, getInventoryRepresentation, xmlelement, mode);
+        XMLPortObject(PickupRepresentation, Pickupable, "pickup", setPickup, getPickup, xmlelement, mode);
+        XMLPortObject(PickupRepresentation, StaticEntity, "spawner-representation", setSpawnerRepresentation, getSpawnerRepresentationIndex, xmlelement, mode);
+        
+        PickupManager::getInstance().registerRepresentation(this->pickup_->getPickupIdentifier(), this); //!< Registers the PickupRepresentation with the PickupManager through the PickupIdentifier of the Pickupable it represents.
+        
+        if(this->spawnerRepresentation_ != NULL)
+            this->spawnerRepresentation_->setVisible(false);
+        
+        COUT(4) << "PickupRepresentation created: name: '" << this->name_ << "', description: '" << this->description_ << "', spawnerTemplate: '" << this->spawnerTemplate_ << "'." << std::endl;
+    }
+    
+    /**
+    @brief
+        Get a spawnerRepresentation for a specific PickupSpawner.
+    @param spawner
+        A pointer to the PickupSpawner.
+    @return
+        Returns a pointer to the StaticEntity.
+    */
+    StaticEntity* PickupRepresentation::getSpawnerRepresentation(PickupSpawner* spawner)
+    {
+        if(this->spawnerRepresentation_ == NULL)
+        {
+            COUT(4) << "PickupRepresentation: No spawner representation found." << std::endl;
+            if(this->spawnerTemplate_ == BLANKSTRING)
+            {
+                COUT(4) << "PickupRepresentation: Spawner template is empty." << std::endl;
+                //!< If neither spawnerRepresentation nor spawnerTemplate was specified
+                return this->getDefaultSpawnerRepresentation(spawner);
+            }
+            this->addTemplate(this->spawnerTemplate_);
+        }
+        
+        StaticEntity* representation = this->spawnerRepresentation_;
+        representation->setVisible(true);
+        
+        this->addTemplate(this->spawnerTemplate_);
+        this->spawnerRepresentation_->setVisible(false);
+        
+        return representation;
+    }
+    
+    /**
+    @brief
+        Get the default spawnerRepresentation for a specific PickupSpawner.
+        Helper method of internal use.
+    @param spawner
+        A pointer to the PickupSpawner.
+    @return
+        Returns a pointer to the StaticEntity.
+    */
+    //TODO: Possibility to define default representation through XML.
+    StaticEntity* PickupRepresentation::getDefaultSpawnerRepresentation(PickupSpawner* spawner)
+    {
+        StaticEntity* representation = new StaticEntity(spawner);
+        Billboard* sphere = new Billboard(spawner);
+        sphere->setColour(ColourValue(0.95f, 0.85f, 0.27f));
+        sphere->setMaterial("Sphere2");
+        sphere->setScale(0.1f);
+        Billboard* icon = new Billboard(spawner);
+        icon->setColour(ColourValue(0.89f, 0.79f, 0.08f));
+        icon->setMaterial("Asterix");
+        icon->setScale(0.5);
+        sphere->attach(icon);
+        representation->attach(sphere);
+        return representation;
+    }
+    
+}
Index: /code/branches/rocket2/src/modules/pickup/PickupRepresentation.h
===================================================================
--- /code/branches/rocket2/src/modules/pickup/PickupRepresentation.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/PickupRepresentation.h	(revision 6952)
@@ -0,0 +1,159 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+/**
+    @file PickupRepresentation.h
+    @brief Definition of the PickupRepresentation class.
+*/
+
+#ifndef _PickupRepresentation_H__
+#define _PickupRepresentation_H__
+
+#include "PickupPrereqs.h"
+
+#include "core/XMLPort.h"
+#include "interfaces/Pickupable.h"
+#include "pickup/PickupIdentifier.h"
+#include "worldentities/StaticEntity.h"
+#include "PickupSpawner.h"
+
+#include "core/BaseObject.h"
+
+namespace orxonox // tolua_export
+{ // tolua_export
+
+    /**
+    @brief
+        The PickupRepresentation class represents a specific pickup type (identified by its PickupIdentifier). It defines the information displayed in the GUI and how PickupSpawners that spawn the pickup type look like.
+        They are created through XML and are registered with the PickupManager.
+    */
+    class _PickupExport PickupRepresentation // tolua_export
+        : public BaseObject
+    { // tolua_export
+        
+        public:
+            PickupRepresentation(); //!< Constructor
+            PickupRepresentation(BaseObject* creator); //!< Default constructor.
+            virtual ~PickupRepresentation(); //!< Destructor.
+            
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            
+            /**
+            @brief Set the name of the Pickupable represented by this PickupRepresentation.
+            @param name The name.
+            */
+            inline void setPickupName(const std::string& name)
+                { this->name_ = name; }
+            /**
+            @brief Set the description of the Pickupable represented by this PickupRepresentation.
+            @param description The Description.
+            */
+            inline void setPickupDescription(const std::string& description)
+                { this->description_ = description; }
+            /**
+            @brief Set the spawnerTemplate of the Pickupable represented by this PickupRepresentation.
+                   The spawnerTemplate is a name of a template defined in XML that defines the StaticEntity that is the spawnerRepresentation of this PickupRepresentation.
+            @param spawnerTemplate The name of the template.
+            */
+            inline void setSpawnerTemplate(const std::string& spawnerTemplate)
+                { this->spawnerTemplate_ = spawnerTemplate; }
+            /**
+            @brief Set the StaticEntity that defines how the PickupSpawner of the Pickupable represented by this PickupRepresentation looks like.
+                   This will be set by the spawnerTemplate. Setting it when creating the PickupRepresentation without creating a template and specifying its name will be futile, because through the course of the game many PickupSpawners for one specific pickup type may have to be created, thus the StaticEntity that is the spawnerRepresentation has to be generated (with the template) for every new PickupSpawner spawning the Pickupable represented by this PickupRepresentation. The spawnerRepresentation that is set here, however can only be used once.
+            @param representation A pointer to the StaticEntity that is the spawnerRepresentation of this PickupRepresentation.
+            */
+            inline void setSpawnerRepresentation(StaticEntity* representation)
+                { this->spawnerRepresentation_ = representation; }
+            /**
+            @brief Set the image representing the pickup in the PickupInventory.
+            @param image A string with the name of the image representing the pickup.
+            */
+            inline void setInventoryRepresentation(const std::string& image)
+                { this->inventoryRepresentation_ = image; }
+            /**
+            @brief Set the Pickupable that is represented by this PickupRepresentation.
+            @param pickup A pointer to the Pickupable.
+            */
+            inline void setPickup(Pickupable* pickup)
+                { this->pickup_ = pickup; }
+                
+            /**
+            @brief Get the name of the Pickupable represented by this PickupRepresentation.
+            @return Returns the name.
+            */
+            inline const std::string& getPickupName(void) { return this->name_; } // tolua_export
+            /**
+            @brief Get the description of the Pickupable represented by this PickupRepresentation.
+            @return Returns the description.
+            */
+            inline const std::string& getPickupDescription(void) { return this->description_; } // tolua_export
+            /**
+            @brief Get the name of spawnerTemplate the Pickupable represented by this PickupRepresentation.
+            @return Returns the name of the spawnerTemplate.
+            */
+            inline const std::string& getSpawnerTemplate(void)
+                { return this->spawnerTemplate_; }
+            /**
+            @brief Get the StaticEntity that defines how the PickupSpawner of the Pickupable represented by this PickupRepresentation looks like.
+            @param index The index.
+            @return Returns (for index = 0) a pointer to the StaticEntity. For index > 0 it returns NULL.
+            */
+            inline const StaticEntity* getSpawnerRepresentationIndex(unsigned int index)
+                { if(index == 0) return this->spawnerRepresentation_; return NULL; }
+            /**
+            @brief Get the name of the image representing the pickup in the PickupInventory.
+            @return Returns the name of the image as a string.
+            */
+            inline const std::string& getInventoryRepresentation(void) { return this->inventoryRepresentation_; } // tolua_export
+            /**
+            @brief Get the Pickupable represented by this PickupRepresentation.
+            @param index The index.
+            @return Returns (for index = 0) a pointer to the Pickupable. For index > 0 it returns NULL.
+            */
+            inline const Pickupable* getPickup(unsigned int index)
+                { if(index == 0) return this->pickup_; return NULL; }
+                
+            StaticEntity* getSpawnerRepresentation(PickupSpawner* spawner); //!< Get a spawnerRepresentation for a specific PickupSpawner.
+        
+        private:
+            void initialize(void); //!< Initializes the member variables of this PickupRepresentation.
+            StaticEntity* getDefaultSpawnerRepresentation(PickupSpawner* spawner); //!< Get the default spawnerRepresentation for a specific PickupSpawner.
+            
+            std::string name_; //!< The name of the Pickupable represented by this PickupRepresentation.
+            std::string description_; //!< The description of the Pickupable represented by this PickupRepresentation.
+            std::string spawnerTemplate_; //!<  The name of the template of this PickupRepresentation.
+            StaticEntity* spawnerRepresentation_; //!< The spawnerRepresentation of this PickupRepresentation.
+            std::string inventoryRepresentation_; //!< The name of an image representing the pickup in the PickupInventory. TODO: Exact format and placement of image?
+            
+            Pickupable* pickup_; //!< The Pickupable that is represented by this PickupRepresentation.
+            
+    }; // tolua_export
+
+} // tolua_export
+    
+#endif // _PickupRepresentation_H__
Index: /code/branches/rocket2/src/modules/pickup/PickupSpawner.cc
===================================================================
--- /code/branches/rocket2/src/modules/pickup/PickupSpawner.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/PickupSpawner.cc	(revision 6952)
@@ -0,0 +1,358 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Daniel 'Huty' Haggenmueller
+ *   Co-authors:
+ *      Damian 'Mozork' Frick
+ *
+ */
+
+/**
+    @file PickupSpawner.cc
+    @brief Implementation of the PickupSpawner class.
+*/
+
+#include "PickupSpawner.h"
+
+#include "core/CoreIncludes.h"
+#include "core/Template.h"
+#include "core/XMLPort.h"
+#include "worldentities/pawns/Pawn.h"
+#include "PickupManager.h"
+#include "PickupRepresentation.h"
+
+namespace orxonox
+{
+
+    CreateFactory(PickupSpawner);
+
+    /**
+    @brief
+        Constructor. Creates a blank PickupSpawner.
+    @param creator
+        Pointer to the object which created this item.
+    */
+    PickupSpawner::PickupSpawner(BaseObject* creator) : StaticEntity(creator), pickup_(NULL)
+    {
+        RegisterObject(PickupSpawner);
+        
+        this->initialize();
+    }
+
+    /**
+    @brief
+        Constructor, Creates a fully functional PickupSpawner.
+    @param creator
+        The creator of this PickupSpawner.
+    @param pickup
+        The Pickupable to be spawned by this PickupSpawner.
+    @param triggerDistance
+        The distance at which the PickupSpawner will trigger.
+    @param respawnTime
+        The minimum time between two spawns.
+    @param maySpawnedItems
+        The maximum number of items spawned by this PickupSpawner.
+    */
+    PickupSpawner::PickupSpawner(BaseObject* creator, Pickupable* pickup, float triggerDistance, float respawnTime, int maxSpawnedItems) : StaticEntity(creator), pickup_(NULL)
+    {
+        RegisterObject(PickupSpawner);
+        
+        this->initialize();
+  
+        this->pickup_ = pickup;
+
+        this->triggerDistance_ = triggerDistance;
+        this->respawnTime_ = respawnTime;
+        this->setMaxSpawnedItems(maxSpawnedItems);
+        
+        if(this->pickup_ == NULL)
+        {
+            COUT(2) << "A PickupSpawner was created without a valid Pickupable. This won't work." << std::endl;
+            this->setActive(false);
+        }
+        else
+        {
+            PickupRepresentation* representation = PickupManager::getInstance().getRepresentation(this->pickup_->getPickupIdentifier());
+            this->attach(representation->getSpawnerRepresentation(this));
+        }
+    }
+
+    /**
+    @brief
+        Registers the object and sets some default values.
+    */
+    void PickupSpawner::initialize(void)
+    {
+        this->triggerDistance_ = 10;
+        this->respawnTime_ = 0;
+        this->maxSpawnedItems_ = INF;
+        this->spawnsRemaining_ = INF;
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    PickupSpawner::~PickupSpawner()
+    {
+        if(this->pickup_ != NULL)
+            this->pickup_->destroy();
+    }
+
+    /**
+    @brief
+        Method for creating a PickupSpawner through XML.
+    @param xmlelement
+        XML element which contains the PickupSpawner.
+    @param mode
+        XMLPort mode.
+    */
+    void PickupSpawner::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(PickupSpawner, XMLPort, xmlelement, mode);
+
+        XMLPortObject(PickupSpawner, Pickupable, "pickup", setPickupable, getPickupable, xmlelement, mode);
+        
+        XMLPortParam(PickupSpawner, "triggerDistance", setTriggerDistance, getTriggerDistance, xmlelement, mode);
+        XMLPortParam(PickupSpawner, "respawnTime", setRespawnTime, getRespawnTime, xmlelement, mode);
+        XMLPortParam(PickupSpawner, "maxSpawnedItems", setMaxSpawnedItems, getMaxSpawnedItems, xmlelement, mode);
+        
+        if(this->pickup_ == NULL)
+        {
+            COUT(2) << "A PickupSpawner was created without a valid Pickupable. This won't work." << std::endl;
+            this->setActive(false);
+        }
+        else
+        {
+            PickupRepresentation* representation = PickupManager::getInstance().getRepresentation(this->pickup_->getPickupIdentifier());
+            representation->setVisible(this->isActive());
+            this->attach(representation->getSpawnerRepresentation(this));
+            this->setActive(true);
+        }
+    }
+    
+    /**
+    @brief
+        Invoked when the activity has changed. Sets visibility of attached objects.
+    */
+    void PickupSpawner::changedActivity()
+    {
+        SUPER(PickupSpawner, changedActivity);
+
+        this->setVisible(this->isActive());
+    }
+     
+    /**
+    @brief
+        Tick, checks if any Pawn is close enough to trigger.
+    @param dt
+        Time since last tick.
+    */
+    //TODO: Replace with collisions.
+    void PickupSpawner::tick(float dt)
+    {
+        SUPER(PickupSpawner, tick, dt);
+        
+        //! If the PickupSpawner is active.
+        if (this->isActive())
+        {
+            //! Iterate trough all Pawns.
+            for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)
+            {
+                Vector3 distance = it->getWorldPosition() - this->getWorldPosition();
+                PickupCarrier* carrier = dynamic_cast<PickupCarrier*>(*it);
+                //! If a Pawn, that fits the target-range of the item spawned by this Pickup, is in trigger-distance.
+                if (distance.length() < this->triggerDistance_ && carrier != NULL && carrier->isTarget(this->pickup_))
+                {
+                    this->trigger(*it);
+                }
+            }
+        }
+    }
+    
+    /**
+    @brief
+        Sets the maximum number of spawned items.
+    @param items
+        The maximum number of spawned items to be set.
+    */
+    void PickupSpawner::setMaxSpawnedItems(int items)
+    {
+        this->maxSpawnedItems_ = items;
+        this->spawnsRemaining_ = items;
+    }
+    
+    /**
+    @brief
+        Decrements the number of remaining spawns.
+        Sets the PickupSpawner to inactive for the duration of the respawnTime.
+        Destroys the PickupSpawner if the number of remaining spawns has reached zero.
+    */
+    void PickupSpawner::decrementSpawnsRemaining(void)
+    {
+        if(this->spawnsRemaining_ != INF)
+        {
+            this->spawnsRemaining_--;
+        }
+        if(this->spawnsRemaining_ != 0 && this->respawnTime_ > 0)
+        {
+            this->startRespawnTimer();
+
+            this->setActive(false);
+            this->fireEvent();
+        }
+        else
+        {
+            COUT(3) << "PickupSpawner empty, selfdestruct initialized." << std::endl;
+            this->setActive(false);
+            this->destroy();
+        }
+    }
+    
+    /**
+    @brief
+        Starts the respawn timer.
+    */
+    void PickupSpawner::startRespawnTimer(void)
+    {
+        this->respawnTimer_.setTimer(this->respawnTime_, false, createExecutor(createFunctor(&PickupSpawner::respawnTimerCallback, this)));
+    }
+    
+    /**
+    @brief
+        Sets a Pickupable for the PickupSpawner to spawn.
+    @param pickup
+        The Pickupable to be set.
+    */
+    void PickupSpawner::setPickupable(Pickupable* pickup)
+    {
+        if(this->pickup_ != NULL)
+        {
+            COUT(1) << "In PickupSpawner: setPickupable called, with this->pickup_ already set." << std::endl;
+            return;
+        }
+        if(pickup == NULL)
+        {
+            COUT(1) << "In PickupSpawner: Argument of setPickupable is NULL." << std::endl;
+            return;
+        }
+        
+        this->pickup_ = pickup;
+    }
+    
+    /**
+    @brief
+        Get the Pickupable that is spawned by this PickupSpawner.
+    @return
+        Returns the Pickupable that is spawned by this PickupSpawner.
+    */
+    const Pickupable* PickupSpawner::getPickupable(void)
+    {
+        return this->pickup_;
+    }
+
+    /**
+    @brief
+        Trigger the PickupSpawner.
+        Adds the pickup to the Pawn that triggered, sets the timer to re-activate and deactives the PickupSpawner.
+    @param pawn
+        Pawn which triggered the PickupSpawner.
+    */
+    void PickupSpawner::trigger(Pawn* pawn)
+    {
+        if (this->isActive()) //!< Checks whether PickupSpawner is active.
+        {
+            COUT(3) << "PickupSpawner triggered and active." << std::endl;
+            
+            PickupCarrier* carrier = dynamic_cast<PickupCarrier*>(pawn);
+            if(carrier == NULL)
+            {
+                COUT(1) << "This is bad. Pawn isn't PickupCarrier." << std::endl;
+                return;
+            }
+            
+            if(!carrier->isTarget(this->pickup_))
+            {
+                COUT(4) << "PickupSpawner triggered but Pawn wasn't a target of the Pickupable." << std::endl;
+                return;
+            }
+            
+            PickupCarrier* target = carrier->getTarget(this->pickup_);
+            Pickupable* pickup = this->getPickup();
+            
+            if(target != NULL && pickup != NULL)
+            {
+                if(target->pickup(pickup))
+                {
+                    this->decrementSpawnsRemaining();
+                }
+                else
+                {
+                    pickup->destroy();
+                }
+            }
+            else
+            {
+                if(target == NULL)
+                    COUT(1) << "PickupSpawner: Pickupable has no target." << std::endl;
+                
+                if(pickup == NULL)
+                {
+                    COUT(1) << "PickupSpawner: getPickup produced an error, no Pickupable created." << std::endl;
+                }
+                else
+                {
+                    pickup->destroy();
+                }
+            }
+        }
+    }
+
+    /**
+    @brief
+        Creates a new Pickupable.
+    @return
+        The Pickupable created.
+    */    
+    Pickupable* PickupSpawner::getPickup(void)
+    {
+        if(this->spawnsRemaining_ == 0)
+        {
+            COUT(1) << "Massive Error: PickupSpawner still alive until having spawned last item." << std::endl;
+            return NULL;
+        }
+        
+        Pickupable* pickup = this->pickup_->clone();
+        return pickup;
+    }
+
+    /**
+    @brief
+        Invoked by the timer, re-activates the PickupSpawner.
+    */
+    void PickupSpawner::respawnTimerCallback()
+    {
+        COUT(3) << "PickupSpawner reactivated." << std::endl;
+
+        this->setActive(true);
+    }
+}
Index: /code/branches/rocket2/src/modules/pickup/PickupSpawner.h
===================================================================
--- /code/branches/rocket2/src/modules/pickup/PickupSpawner.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/PickupSpawner.h	(revision 6952)
@@ -0,0 +1,131 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Daniel 'Huty' Haggenmueller
+ *   Co-authors:
+ *      Damian 'Mozork' Frick
+ *
+ */
+
+/**
+    @file PickupSpawner.h
+    @brief Definition of the PickupSpawner class.
+*/
+
+#ifndef _PickupSpawner_H__
+#define _PickupSpawner_H__
+
+#include "PickupPrereqs.h"
+
+#include <string>
+#include "interfaces/Pickupable.h"
+#include "tools/Timer.h"
+
+#include "tools/interfaces/Tickable.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    /**
+        @brief
+            The PickupSpawner class is responsible for spawning pickups of a specific type.
+            Forthermore it can be specified how long the time interval between spawning two items is and how many pickups are spawned at maximum, amongst other things.
+        @author
+            Daniel 'Huty' Haggenmueller
+            Damian 'Mozork' Frick
+    */
+    class _PickupExport PickupSpawner : public StaticEntity, public Tickable
+    {
+        public:
+            PickupSpawner(BaseObject* creator); //!< Default Constructor.
+            PickupSpawner(BaseObject* creator, Pickupable* pickup, float triggerDistance, float respawnTime, int maxSpawnedItems); //!< Constructor.
+            virtual ~PickupSpawner(); //!< Destructor.
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);  //!< Method for creating a PickupSpawner through XML.
+            virtual void changedActivity(); //!< Invoked when activity has changed (set visibilty).
+            virtual void tick(float dt);
+
+            /**
+            @brief Get the distance in which to trigger.
+            @return Returns the distance in which this gets triggered.
+            */
+            inline float getTriggerDistance() const
+                { return this->triggerDistance_; }
+            /**
+            @brief Set the distance in which to trigger.
+            @param value The new distance in which to trigger.
+            */
+            inline void setTriggerDistance(float value)
+                { this->triggerDistance_ = value; }
+
+            /**
+            @brief Get the time to respawn.
+            @returns Returns the time after which this gets re-actived.
+            */
+            inline float getRespawnTime() const
+                { return this->respawnTime_; }
+            /**
+            @brief Set the time to respawn.
+            @param time New time after which this gets re-actived.
+            */
+            inline void setRespawnTime(float time)
+                { this->respawnTime_ = time; }
+
+            /**
+            @brief Get the maximum number of items that will be spawned by this PickupSpawner.
+            @return Returns the maximum number of items spawned by this PickupSpawner.
+            */
+            inline int getMaxSpawnedItems(void)
+                { return this->maxSpawnedItems_; }
+            void setMaxSpawnedItems(int items); //!< Sets the maximum number of spawned items.
+
+        protected:
+            void decrementSpawnsRemaining(void); //!< Decrements the number of remaining spawns.
+                        
+            void startRespawnTimer(void);
+            
+            virtual Pickupable* getPickup(void); //!< Creates a new Pickupable.
+            
+            void setPickupable(Pickupable* pickup); //!< Sets a Pickupable for the PickupSpawner to spawn.
+            const Pickupable* getPickupable(void); //!< Get the Pickupable that is spawned by this PickupSpawner.
+            
+            Pickupable* pickup_; //!< The pickup to be spawned.
+
+        private:
+            void initialize(void);
+            
+            void trigger(Pawn* pawn); //!< Method called when a Pawn is close enough.
+            void respawnTimerCallback(); //!< Method called when the timer runs out.
+
+            int maxSpawnedItems_; //!< Maximum number of items spawned by this PickupSpawner.
+            int spawnsRemaining_; //!< Number of items that can be spawned by this PickupSpawner until it selfdestructs.
+
+            float triggerDistance_; //!< Distance in which this gets triggered.
+
+            float respawnTime_; //!< Time after which this gets re-actived.
+            Timer respawnTimer_; //!< Timer used for re-activating.
+
+            static const int INF = -1; //!< Constant for infinity.
+    };
+}
+
+#endif /* _PickupSpawner_H__ */
Index: /code/branches/rocket2/src/modules/pickup/items/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/pickup/items/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/items/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,6 @@
+ADD_SOURCE_FILES(PICKUP_SRC_FILES
+  HealthPickup.cc
+  InvisiblePickup.cc
+  MetaPickup.cc
+  SpeedPickup.cc
+)
Index: /code/branches/rocket2/src/modules/pickup/items/HealthPickup.cc
===================================================================
--- /code/branches/rocket2/src/modules/pickup/items/HealthPickup.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/items/HealthPickup.cc	(revision 6952)
@@ -0,0 +1,388 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file HealthPickup.cc
+    @brief Implementation of the HealthPickup class.
+*/
+
+#include "HealthPickup.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "util/StringUtils.h"
+
+#include "worldentities/pawns/Pawn.h"
+#include "pickup/PickupIdentifier.h"
+
+#include <sstream>
+
+namespace orxonox
+{
+    
+    /*static*/ const std::string HealthPickup::healthTypeLimited_s = "limited";
+    /*static*/ const std::string HealthPickup::healthTypeTemporary_s = "temporary";
+    /*static*/ const std::string HealthPickup::healthTypePermanent_s = "permanent";
+    
+    CreateFactory(HealthPickup);
+    
+    /**
+    @brief
+        Constructor. Registers the object and initializes the member variables.
+    */
+    HealthPickup::HealthPickup(BaseObject* creator) : Pickup(creator)
+    {
+        RegisterObject(HealthPickup);
+        
+        this->initialize();
+    }
+    
+    /**
+    @brief
+        Destructor.
+    */
+    HealthPickup::~HealthPickup()
+    {
+        
+    }
+    
+    /**
+    @brief 
+        Initializes the member variables.
+    */
+    void HealthPickup::initialize(void)
+    {        
+        this->health_ = 0;
+        this->healthRate_ = 0;
+        this->healthType_ = pickupHealthType::limited;
+        this->maxHealthSave_ = 0;
+        this->maxHealthOverwrite_ = 0;
+        
+        this->addTarget(ClassIdentifier<Pawn>::getIdentifier());
+    }
+    
+    /**
+    @brief
+        Initializes the PickupIdentifier of this pickup.
+    */
+    void HealthPickup::initializeIdentifier(void)
+    {
+        std::stringstream stream;
+        stream << this->getHealth();
+        std::string type1 = "health";
+        std::string val1 = stream.str();
+        this->pickupIdentifier_->addParameter(type1, val1);
+        
+        std::string val2 = this->getHealthType();
+        std::string type2 = "healthType";
+        this->pickupIdentifier_->addParameter(type2, val2);
+        
+        stream.clear();
+        stream << this->getHealthRate();
+        std::string val3 = stream.str();
+        std::string type3 = "healthRate";
+        this->pickupIdentifier_->addParameter(type3, val3);
+    }
+    
+    /**
+    @brief
+        Method for creating a HealthPickup object through XML.
+    */
+    void HealthPickup::XMLPort(Element& xmlelement, orxonox::XMLPort::Mode mode)
+    {
+        SUPER(HealthPickup, XMLPort, xmlelement, mode);
+        
+        XMLPortParam(HealthPickup, "health", setHealth, getHealth, xmlelement, mode);
+        XMLPortParam(HealthPickup, "healthRate", setHealthRate, getHealthRate, xmlelement, mode);
+        XMLPortParam(HealthPickup, "healthType", setHealthType, getHealthType, xmlelement, mode);
+        
+        if(!this->isContinuous())
+            this->healthRate_ = 0.0;
+        
+        this->initializeIdentifier();
+    }
+    
+    /**
+    @brief
+        Is called every tick.
+        Does all the continuous stuff of this HealthPickup.
+    @param dt
+        The duration of the last tick.
+    */
+    void HealthPickup::tick(float dt)
+    {
+        SUPER(HealthPickup, tick, dt);
+        
+        if(this->isContinuous() && this->isUsed())
+        {
+            Pawn* pawn = this->carrierToPawnHelper();
+            if(pawn == NULL) //!< If the PickupCarrier is no Pawn, then this pickup is useless and therefore is destroyed.
+                this->destroy();
+            
+            //! Calculate the health that is added this tick.
+            float health = dt*this->getHealthRate();
+            if(health > this->getHealth())
+                health = this->getHealth();
+            //! Calculate the health the Pawn will have once the health is added.
+            float fullHealth = pawn->getHealth() + health;
+            this->setHealth(this->getHealth()-health);
+                    
+            switch(this->getHealthTypeDirect())
+            {
+                case pickupHealthType::permanent:
+                    if(pawn->getMaxHealth() < fullHealth)
+                        pawn->setMaxHealth(fullHealth);
+                case pickupHealthType::limited:
+                    pawn->addHealth(health);
+                    break;
+                case pickupHealthType::temporary:
+                    if(pawn->getMaxHealth() > fullHealth)
+                    {
+                        this->maxHealthSave_ = pawn->getMaxHealth();
+                        this->maxHealthOverwrite_ = fullHealth;
+                        pawn->setMaxHealth(fullHealth);
+                    }
+                    pawn->addHealth(health);
+                    break;
+                default:
+                    COUT(1) << "Invalid healthType in HealthPickup." << std::endl;
+            }
+            
+            //! If all health has been transfered.
+            if(this->getHealth() == 0)
+            {
+                this->setUsed(false);
+            }
+        }
+    }
+    
+    /**
+    @brief
+        Is called when the pickup has transited from used to unused or the other way around.
+    */
+    void HealthPickup::changedUsed(void)
+    {
+        SUPER(HealthPickup, changedUsed);
+        
+        //! If the pickup is not picked up nothing must be done.
+        if(!this->isPickedUp())
+            return;
+        
+        //! If the pickup has transited to used.
+        if(this->isUsed())
+        {
+            if(this->isOnce())
+            {
+                Pawn* pawn = this->carrierToPawnHelper();
+                if(pawn == NULL) //!< If the PickupCarrier is no Pawn, then this pickup is useless and therefore is destroyed.
+                    this->destroy();
+                
+                float health = 0;
+                switch(this->getHealthTypeDirect())
+                {
+                    case pickupHealthType::permanent:
+                        health = pawn->getHealth()+this->getHealth();
+                        if(pawn->getMaxHealth() < health)
+                            pawn->setMaxHealth(health);
+                    case pickupHealthType::limited:
+                        pawn->addHealth(this->getHealth());
+                        break;
+                    case pickupHealthType::temporary:
+                        health = pawn->getHealth()+this->getHealth();
+                        if(pawn->getMaxHealth() < health)
+                        {
+                            this->maxHealthSave_ = pawn->getMaxHealth();
+                            this->maxHealthOverwrite_ = health;
+                            pawn->setMaxHealth(health);
+                        }
+                        pawn->addHealth(this->getHealth());
+                        break;
+                    default:
+                        COUT(1) << "Invalid healthType in HealthPickup." << std::endl;
+                }
+                
+                //! The pickup has been used up.
+                this->setUsed(false);
+            }
+        }
+        else
+        {
+            if(this->getHealthTypeDirect() == pickupHealthType::temporary)
+            {
+                PickupCarrier* carrier = this->getCarrier();
+                Pawn* pawn = dynamic_cast<Pawn*>(carrier);
+                
+                if(pawn == NULL)
+                {
+                    COUT(1) << "Something went horribly wrong in Health Pickup. PickupCarrier is no Pawn." << std::endl;
+                    this->destroy();
+                    return;
+                }
+                
+                if(pawn->getMaxHealth() == this->maxHealthOverwrite_)
+                {
+                    pawn->setMaxHealth(this->maxHealthSave_);
+                    this->maxHealthOverwrite_ = 0;
+                    this->maxHealthSave_ = 0;
+                }
+            }
+            
+            //! If either the pickup can only be used once or it is continuous and used up, it is destroyed upon setting it to unused.
+            if(this->isOnce() || (this->isContinuous() && this->getHealth() == 0))
+            {
+                this->destroy();
+            }
+        }
+    }
+    
+    /**
+    @brief
+        Helper to transform the PickupCarrier to a Pawn, and throw an error message if the conversion fails.
+    @return
+        A pointer to the Pawn, or NULL if the conversion failed.
+    */
+    Pawn* HealthPickup::carrierToPawnHelper(void)
+    {
+        PickupCarrier* carrier = this->getCarrier();
+        Pawn* pawn = dynamic_cast<Pawn*>(carrier);
+        
+        if(pawn == NULL)
+        {
+            COUT(1) << "Invalid PickupCarrier in HealthPickup." << std::endl;
+        }
+        
+        return pawn;
+    }
+    
+    /**
+    @brief
+        Creates a duplicate of the input OrxonoxClass.
+    @param item
+        A pointer to the Orxonox class.
+    */
+    void HealthPickup::clone(OrxonoxClass*& item)
+    {
+        if(item == NULL)
+            item = new HealthPickup(this);
+        
+        SUPER(HealthPickup, clone, item);
+        
+        HealthPickup* pickup = dynamic_cast<HealthPickup*>(item);
+        pickup->setHealth(this->getHealth());
+        pickup->setHealthRate(this->getHealthRate());
+        pickup->setHealthTypeDirect(this->getHealthTypeDirect());
+        
+        pickup->initializeIdentifier();
+    }
+    
+    /**
+    @brief
+        Get the health type of this pickup.
+    @return
+        Returns the health type as a string.
+    */
+    const std::string& HealthPickup::getHealthType(void)
+    {
+        switch(this->getHealthTypeDirect())
+        {
+            case pickupHealthType::limited:
+                return HealthPickup::healthTypeLimited_s;
+            case pickupHealthType::temporary:
+                return HealthPickup::healthTypeTemporary_s;
+            case pickupHealthType::permanent:
+                return HealthPickup::healthTypePermanent_s;
+            default:
+                COUT(1) << "Invalid healthType in HealthPickup." << std::endl;
+                return BLANKSTRING;
+        }
+    }
+    
+    /**
+    @brief
+        Sets the health.
+    @param health
+        The health.
+    */
+    void HealthPickup::setHealth(float health)
+    {
+        if(health >= 0.0f)
+        {
+            this->health_ = health;
+        }
+        else
+        {
+            COUT(1) << "Invalid health in HealthPickup." << std::endl;
+            this->health_ = 0.0;
+        }
+    }
+    
+    /**
+    @brief
+        Set the rate at which health is transferred if the pickup is continuous.
+    @param rate
+        The rate.
+    */
+    void HealthPickup::setHealthRate(float rate)
+    {
+        if(rate >= 0)
+        {
+            this->healthRate_ = rate;
+        }
+        else
+        {
+            COUT(1) << "Invalid healthSpeed in HealthPickup." << std::endl; 
+        }
+    }
+    
+    /**
+    @brief
+        Set the type of the HealthPickup.
+    @param type
+        The type as a string.
+    */
+    void HealthPickup::setHealthType(std::string type)
+    {
+        if(type == HealthPickup::healthTypeLimited_s)
+        {
+            this->setHealthTypeDirect(pickupHealthType::limited);
+        }
+        else if(type == HealthPickup::healthTypeTemporary_s)
+        {
+            this->setHealthTypeDirect(pickupHealthType::temporary);
+        }
+        else if(type == HealthPickup::healthTypePermanent_s)
+        {
+            this->setHealthTypeDirect(pickupHealthType::permanent);
+        }
+        else
+        {
+            COUT(1) << "Invalid healthType in HealthPickup." << std::endl;
+        }
+    }
+
+}
Index: /code/branches/rocket2/src/modules/pickup/items/HealthPickup.h
===================================================================
--- /code/branches/rocket2/src/modules/pickup/items/HealthPickup.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/items/HealthPickup.h	(revision 6952)
@@ -0,0 +1,136 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file HealthPickup.h
+    @brief Declaration of the HealthPickup class.
+*/
+
+#ifndef _HealthPickup_H__
+#define _HealthPickup_H__
+
+#include "pickup/PickupPrereqs.h"
+
+#include <string>
+#include <worldentities/pawns/Pawn.h>
+#include "worldentities/StaticEntity.h"
+
+#include "pickup/Pickup.h"
+#include "tools/interfaces/Tickable.h"
+
+namespace orxonox {
+    
+    //! Enum for the type of the HealthPickup
+    namespace pickupHealthType
+    {
+        enum Value
+        {
+            limited,
+            temporary,
+            permanent
+        };
+    }
+    
+    /**
+    @brief
+        A pickup that can do (dependent upon the parameters) lots of different things to the health of a Pawn.
+        There are 4 parameters that can be chosen:
+        1) The health. The amount of health that (in a way dependent on the other parameters) is transfered to the Pawn.
+        2) The activation type: It can be chosen to be either 'immediate' or 'onUse'. The activation type essentially (as indicated by the name) defines when the health is transfered, either immediately after being picked up or only after the player uses it.
+        3) The duration type: It can be chosen to be either 'once' or 'continuous'. For 'once' the specified health is transfered once to the Pawn, for 'continuous' the set health is transfered over a span of time at a rate defined by the health rate parameter.
+        4) The health type: The health type can be chosen to be 'limited', 'temporary' or 'permanent'. 'limited' means that the health is increased only to the maximum health of the Pawn. 'temporary' means that the maximum health is temporarily elevated but will be set back as soon as the pickup is no longer in use. 'permanent' means that the maximum health of the Pawn is increased such that the health provided by the pickup will fit in and the maximum health stays that way.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _PickupExport HealthPickup : public Pickup, public Tickable
+    {
+        public:
+        
+            HealthPickup(BaseObject* creator); //!< Constructor.
+            virtual ~HealthPickup(); //!< Destructor.
+            
+            virtual void XMLPort(Element& xmlelement, orxonox::XMLPort::Mode mode); //!< Method for creating a HealthPickup object through XML.
+            virtual void tick(float dt); //!< Is called every tick.
+            
+            virtual void changedUsed(void); //!< Is called when the pickup has transited from used to unused or the other way around.
+            virtual void clone(OrxonoxClass*& item); //!< Creates a duplicate of the input OrxonoxClass.
+            
+            /**
+            @brief Get the health that is transfered to the Pawn upon usage of this pickup.
+            @return Returns the health.
+            */
+            inline float getHealth(void)
+                { return this->health_; }
+            /**
+            @brief Get the rate at which the health is transferred to the Pawn, if this pickup has duration type 'continuous'.
+            @return Returns the rate.
+            */
+            inline float getHealthRate(void)
+                { return this->healthRate_; }
+                
+            /**
+            @brief Get the type of HealthPickup, this pickup is.
+            @return Returns the health type as an enum. 
+            */
+            inline pickupHealthType::Value getHealthTypeDirect(void)
+                { return this->healthType_; }
+            const std::string& getHealthType(void); //!< Get the health type of this pickup.
+            
+        protected:
+            void initializeIdentifier(void); //!< Initializes the PickupIdentifier of this pickup.
+
+            void setHealth(float health); //!< Sets the health.
+            void setHealthRate(float speed); //!< Set the rate at which health is transferred if the pickup is continuous.
+            
+            /**
+            @brief Set the health type of this pickup.
+            @param type The type of this pickup as an enum.
+            */
+            inline void setHealthTypeDirect(pickupHealthType::Value type)
+                { this->healthType_ = type; }
+            void setHealthType(std::string type); //!< Set the type of the HealthPickup.
+        
+        private:
+            void initialize(void); //!< Initializes the member variables.
+            Pawn* carrierToPawnHelper(void); //!< Helper to transform the PickupCarrier to a Pawn, and throw an error message if the conversion fails.
+            
+            float health_; //!< The health that is transferred to the Pawn.
+            float healthRate_; //!< The rate at which the health is transferred.
+            float maxHealthSave_; //!< Helper to remember what the actual maxHealth of the Pawn was before we changed it.
+            float maxHealthOverwrite_; //!< Helper to remember with which value we overwrote the maxHealh, to detect if someone else changed it as well.
+            pickupHealthType::Value healthType_; //!< The type of the HealthPickup.
+            
+            //! Strings for the health types.
+            static const std::string healthTypeLimited_s;
+            static const std::string healthTypeTemporary_s;
+            static const std::string healthTypePermanent_s;
+        
+    };
+}
+
+#endif // _HealthPickup_H__
Index: /code/branches/rocket2/src/modules/pickup/items/InvisiblePickup.cc
===================================================================
--- /code/branches/rocket2/src/modules/pickup/items/InvisiblePickup.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/items/InvisiblePickup.cc	(revision 6952)
@@ -0,0 +1,217 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benedict Simlinger
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file InvisiblePickup.cc
+    @brief Implementation of the InvisiblePickup class.
+*/
+
+#include "InvisiblePickup.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "util/StringUtils.h"
+
+#include "worldentities/pawns/Pawn.h"
+#include "pickup/PickupIdentifier.h"
+
+#include <sstream>
+
+namespace orxonox
+{
+
+    CreateFactory(InvisiblePickup);
+    
+    /**
+    @brief
+        Constructor. Registers the object and initializes the member variables.
+    */
+    InvisiblePickup::InvisiblePickup(BaseObject* creator) : Pickup(creator)
+    {
+        RegisterObject(InvisiblePickup);
+        //! Defines who is allowed to pick up the pickup.
+        this->initialize(); 
+    }
+    
+    /**
+    @brief
+        Destructor.
+    */
+    InvisiblePickup::~InvisiblePickup()
+    {        
+    }
+    
+    
+    void InvisiblePickup::initializeIdentifier(void)
+    {
+        std::stringstream stream;
+        stream << this->getDuration();
+        std::string type1 = "duration";
+        std::string val1 = stream.str();
+        this->pickupIdentifier_->addParameter(type1, val1);
+    }
+    
+    /**
+    @brief
+    Initializes the member variables.
+    */
+    void InvisiblePickup::initialize(void)
+    {
+        this->duration_ = 0.0f;
+        this->addTarget(ClassIdentifier<Pawn>::getIdentifier());
+    }
+
+    /**
+    @brief
+        Method for creating a HealthPickup object through XML.
+    */
+    void InvisiblePickup::XMLPort(Element& xmlelement, orxonox::XMLPort::Mode mode)
+    {
+        SUPER(InvisiblePickup, XMLPort, xmlelement, mode);    
+        XMLPortParam(InvisiblePickup, "duration", setDuration, getDuration, xmlelement, mode);
+        
+        this->initializeIdentifier();
+    }
+    
+    /**
+    @brief
+        Is called when the pickup has transited from used to unused or the other way around.
+    */
+    void InvisiblePickup::changedUsed(void)
+    {
+        SUPER(InvisiblePickup, changedUsed);
+        
+        //! If the pickup is not picked up nothing must be done.
+        if(!this->isPickedUp())
+            return;
+        
+        if (this->isUsed())
+        {
+            if(!this->getTimer()->isActive() && this->getTimer()->getRemainingTime() > 0.0f)
+            {
+                this->getTimer()->unpauseTimer();
+            }
+            else
+            {
+                this->startPickupTimer(this->getDuration());
+            }
+            this->setInvisible(true);
+        }
+        else
+        {
+            this->setInvisible(false);
+        
+            if(!this->getTimer()->isActive() && this->getTimer()->getRemainingTime() == this->getDuration())
+            {
+                this->destroy();
+            }
+            else
+            {
+                this->getTimer()->pauseTimer();
+            }
+        }
+        
+    }
+    
+    /**
+    @brief
+        Helper to transform the PickupCarrier to a Pawn, and throw an error message if the conversion fails.
+    @return
+        A pointer to the Pawn, or NULL if the conversion failed.
+    */
+    Pawn* InvisiblePickup::carrierToPawnHelper(void)
+    {
+        PickupCarrier* carrier = this->getCarrier();
+        Pawn* pawn = dynamic_cast<Pawn*>(carrier);
+        
+        if(pawn == NULL)
+        {
+            COUT(1) << "Invalid PickupCarrier in InvisiblePickup." << std::endl;
+        }
+        return pawn;
+    }
+    
+    /**
+    @brief
+        Creates a duplicate of the input OrxonoxClass.
+    @param item
+        A pointer to the Orxonox class.
+    */
+    void InvisiblePickup::clone(OrxonoxClass*& item)
+    {
+        if(item == NULL)
+            item = new InvisiblePickup(this);
+        
+        SUPER(InvisiblePickup, clone, item);
+        
+        InvisiblePickup* pickup = dynamic_cast<InvisiblePickup*>(item);
+        pickup->setDuration(this->getDuration());
+        pickup->initializeIdentifier();
+    }
+    
+    /**
+    @brief
+        Sets the invisibility.
+    @param invisibility
+        The invisibility.
+    */
+    bool InvisiblePickup::setInvisible(bool invisibility)
+    {
+        Pawn* pawn = this->carrierToPawnHelper();
+        if(pawn == NULL)
+            return false;
+        
+        pawn->setVisible(!invisibility);
+        return true;
+    }
+    
+    /**
+    @brief
+        Sets the duration.
+    @param duration
+        The duration
+    */
+    void InvisiblePickup::setDuration(float duration)
+    {
+        if(duration >= 0.0f)
+        {
+            this->duration_ = duration;
+        }
+        else
+        {
+            COUT(1) << "Invalid duration in InvisiblePickup." << std::endl;
+            this->duration_ = 0.0f;
+        }
+    }
+    
+    void InvisiblePickup::pickupTimerCallback(void)
+    {
+        this->setUsed(false);
+    }
+
+}
Index: /code/branches/rocket2/src/modules/pickup/items/InvisiblePickup.h
===================================================================
--- /code/branches/rocket2/src/modules/pickup/items/InvisiblePickup.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/items/InvisiblePickup.h	(revision 6952)
@@ -0,0 +1,89 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benedict Simlinger
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file InvisiblePickup.h
+    @brief Declaration of the InvisiblePickup class.
+*/
+
+#ifndef _InvisiblePickup_H__
+#define _InvisiblePickup_H__
+
+#include "pickup/PickupPrereqs.h"
+
+#include <string>
+#include <worldentities/pawns/Pawn.h>
+#include "worldentities/StaticEntity.h"
+
+#include "pickup/Pickup.h"
+
+namespace orxonox {
+        
+    /**
+    @brief
+        A pickup that makes the Pawn invisible.
+        There are 2 parameters that can be chosen:
+        1) The activation type: It can be chosen to be either 'immediate' or 'onUse'. The activation type essentially (as indicated by the name) defines when the Pawn will be invisible, either immediately after being picked up or only after the player uses it.
+        2) The duration type: It can be chosen how long the Pawn will be invisibel.
+    @author
+        Benedict Simlinger
+    */
+    class _PickupExport InvisiblePickup : public Pickup
+    {
+        public:
+        
+            InvisiblePickup(BaseObject* creator); //!< Constructor.
+            virtual ~InvisiblePickup(); //!< Destructor.
+            virtual void XMLPort(Element& xmlelement, orxonox::XMLPort::Mode mode); //!< Method for creating a HealthPickup object through XML.
+            virtual void changedUsed(void); //!< Is called when the pickup has transited from used to unused or the other way around.
+            virtual void clone(OrxonoxClass*& item); //!< Creates a duplicate of the input OrxonoxClass.
+            
+            /**
+            @brief Checks whether the Pawn is invisible.
+            @return Returns if the Pawn is invisible.
+            */
+            inline bool getInvisibility(bool)
+                { return this->invisible_; }
+            inline float getDuration()
+                { return this->duration_; }
+ 
+        protected:
+            bool setInvisible(bool invisibility); //!< Set the Pawn to be invisible or visible again.
+            void setDuration(float duration);
+            void initializeIdentifier(void);
+            virtual void pickupTimerCallback(void); //!< Function that gets called when the timer ends.
+        
+        private:
+            void initialize(void); //!< Initializes the member variables.
+            Pawn* carrierToPawnHelper(void); //!< Helper to transform the PickupCarrier to a Pawn, and throw an error message if the conversion fails.
+            bool invisible_; //!< Helper to remember wether the Pawn is invisible.
+            float duration_; //! Duration of invisibility.
+    };
+}
+
+#endif // _InvisiblePickup_H__
Index: /code/branches/rocket2/src/modules/pickup/items/MetaPickup.cc
===================================================================
--- /code/branches/rocket2/src/modules/pickup/items/MetaPickup.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/items/MetaPickup.cc	(revision 6952)
@@ -0,0 +1,209 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+/**
+    @file MetaPickup.cc
+    @brief Implementation of the MetaPickup class.
+*/
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "interfaces/PickupCarrier.h"
+#include "pickup/PickupIdentifier.h"
+
+#include "MetaPickup.h"
+
+namespace orxonox {
+ 
+    CreateFactory(MetaPickup);
+    
+    //! Setting the static variables to their values.
+    /*static*/ const std::string MetaPickup::metaTypeNone_s = "none";
+    /*static*/ const std::string MetaPickup::metaTypeUse_s = "use";
+    /*static*/ const std::string MetaPickup::metaTypeDrop_s = "drop";
+    
+    /**
+    @brief
+        Constructor. Registers and initializes the object.
+    */
+    MetaPickup::MetaPickup(BaseObject* creator) : Pickup(creator)
+    {
+        RegisterObject(MetaPickup);
+        
+        this->initialize();
+    }
+    
+    /**
+    @brief
+        Destructor.
+    */
+    MetaPickup::~MetaPickup()
+    {
+        
+    }
+    
+    /**
+    @brief
+        Initializes the object.
+    */
+    void MetaPickup::initialize(void)
+    {
+        this->addTarget(ClassIdentifier<PickupCarrier>::getIdentifier());
+        
+        this->setActivationTypeDirect(pickupActivationType::immediate);
+        this->setDurationTypeDirect(pickupDurationType::once);
+        this->metaType_ = pickupMetaType::none;
+    }
+    
+    /**
+    @brief
+        Helper method to initialize the PickupIdentifier.
+    */
+    void MetaPickup::initializeIdentifier(void)
+    {
+        std::string val = this->getMetaType();
+        std::string type = "metaType";
+        this->pickupIdentifier_->addParameter(type, val);
+    }
+    
+    /**
+    @brief
+        Method for creating a MetaPickup object through XML.
+    */
+    void MetaPickup::XMLPort(Element& xmlelement, orxonox::XMLPort::Mode mode)
+    {
+        SUPER(MetaPickup, XMLPort, xmlelement, mode);
+        
+        XMLPortParam(MetaPickup, "metaType", setMetaType, getMetaType, xmlelement, mode);
+        
+        this->initializeIdentifier();
+    }
+    
+    /**
+    @brief
+        Is called when the pickup has transited from used to unused or the other way around.
+        Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedUsed); to their changdeUsed method.
+    */
+    void MetaPickup::changedUsed(void)
+    {
+        SUPER(MetaPickup, changedUsed);
+        
+        //! If the MetaPickup transited to used.
+        if(this->isUsed())
+        {
+            PickupCarrier* carrier = this->getCarrier();
+            if(this->getMetaTypeDirect() != pickupMetaType::none && carrier != NULL)
+            {
+                std::set<Pickupable*> pickups = carrier->getPickups();
+                //! Set all Pickupables carried by the PickupCarrier either to used or drop them, depending o the meta type.
+                for(std::set<Pickupable*>::iterator it = pickups.begin(); it != pickups.end(); it++)
+                {
+                    Pickup* pickup = dynamic_cast<Pickup*>(*it);
+                    if(this->getMetaTypeDirect() == pickupMetaType::use)
+                    {
+                        if(pickup != NULL && pickup != this && pickup->isOnUse() && !pickup->isUsed())
+                        {
+                            pickup->setUsed(true);
+                        }
+                    }
+                    if(this->getMetaTypeDirect() == pickupMetaType::drop)
+                    {
+                        if(pickup != NULL && pickup != this)
+                        {
+                            carrier->drop(pickup);
+                        }
+                    }
+                }
+            }
+            this->destroy();
+        }
+    }
+        
+    /**
+    @brief
+        Creates a duplicate of the input OrxonoxClass.
+    @param item
+        A pointer to the Orxonox class.
+    */
+    void MetaPickup::clone(OrxonoxClass*& item)
+    {
+        if(item == NULL)
+            item = new MetaPickup(this);
+        
+        SUPER(MetaPickup, clone, item);
+        
+        MetaPickup* pickup = dynamic_cast<MetaPickup*>(item);
+        pickup->setMetaTypeDirect(this->getMetaTypeDirect());
+        
+        pickup->initializeIdentifier();
+    }
+    
+    /**
+    @brief
+        Get the meta type of this MetaPickup.
+    @return
+        Returns a string with the meta type of the MetaPickup.
+    */
+    const std::string& MetaPickup::getMetaType(void)
+    {
+        switch(this->getMetaTypeDirect())
+        {
+            case pickupMetaType::none:
+                return MetaPickup::metaTypeNone_s;
+            case pickupMetaType::use:
+                return MetaPickup::metaTypeUse_s;
+            case pickupMetaType::drop:
+                return MetaPickup::metaTypeDrop_s;
+            default:
+                return BLANKSTRING;
+        }
+    }
+    
+    /**
+    @brief
+        Set the meta type of this MetaPickup.
+    @param type
+        A string with the type to be set.
+    */
+    void MetaPickup::setMetaType(const std::string& type)
+    {
+        if(type == MetaPickup::metaTypeNone_s)
+        {
+            this->setMetaTypeDirect(pickupMetaType::none);
+        }
+        else if(type == MetaPickup::metaTypeUse_s)
+        {
+            this->setMetaTypeDirect(pickupMetaType::use);
+        }
+        else if(type == MetaPickup::metaTypeDrop_s)
+        {
+            this->setMetaTypeDirect(pickupMetaType::drop);
+        }
+    }
+    
+}
Index: /code/branches/rocket2/src/modules/pickup/items/MetaPickup.h
===================================================================
--- /code/branches/rocket2/src/modules/pickup/items/MetaPickup.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/items/MetaPickup.h	(revision 6952)
@@ -0,0 +1,106 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+*/
+
+/**
+    @file MetaPickup.h
+    @brief Definition of the MetaPickup class.
+*/
+
+#ifndef _MetaPickup_H__
+#define _MetaPickup_H__
+
+#include "pickup/PickupPrereqs.h"
+
+#include "pickup/Pickup.h"
+
+namespace orxonox {
+
+    //! The meta type, deciding what the pickup does exactly.
+    namespace pickupMetaType
+    {
+        enum Value
+        {
+            none,
+            use,
+            drop
+        };
+    }
+    
+    /**
+    @brief
+        The MetaPickup is a pickup that can, depending on the parameters, either drop all pickups of the PickupCarrier that picks it up, or use all the unused pickups of the PickupCarrier, that picks it up. The parameter to set for this is the metaType and it can be used with the values 'none', 'drop' and 'use'.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _PickupExport MetaPickup : public Pickup
+    {
+        
+        public:
+            MetaPickup(BaseObject* creator); //!< Constructor. Registers and initializes the object.
+            virtual ~MetaPickup(); //!< Destructor.
+            
+            virtual void XMLPort(Element& xmlelement, orxonox::XMLPort::Mode mode); //!< Method for creating a MetaPickup object through XML.
+            
+            virtual void changedUsed(void); //!< Is called when the pickup has transited from used to unused or the other way around.
+            virtual void clone(OrxonoxClass*& item); //!< Creates a duplicate of the input OrxonoxClass.
+            
+            /**
+            @brief Returns the meta type of the MetaPickup.
+            @return Returns an enum with the meta type of the MetaPickup.
+            */
+            inline pickupMetaType::Value getMetaTypeDirect(void)
+                { return this->metaType_; }
+            const std::string& getMetaType(void); //!< Get the meta type of this MetaPickup.
+            
+        protected:
+            void initializeIdentifier(void); //!< Initializes the PickupIdentifier of this pickup.
+            
+            /**
+            @brief Set the meta type of the MetaPickup.
+            @param type The meta type as an enum.
+            */
+            inline void setMetaTypeDirect(pickupMetaType::Value type)
+                { this->metaType_ =  type; }
+            void setMetaType(const std::string& type); //!< Set the meta type of this MetaPickup.
+            
+        private:
+            void initialize(void); //!< Initializes the member variables.
+            
+            pickupMetaType::Value metaType_; //!< The meta type of the MetaPickup, determines which actions are taken.
+            
+            //! Static strings for the meta types.
+            static const std::string metaTypeNone_s;
+            static const std::string metaTypeUse_s;
+            static const std::string metaTypeDrop_s;
+            
+        
+    };
+
+}
+
+#endif // _TestPickup_H__
Index: /code/branches/rocket2/src/modules/pickup/items/SpeedPickup.cc
===================================================================
--- /code/branches/rocket2/src/modules/pickup/items/SpeedPickup.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/items/SpeedPickup.cc	(revision 6952)
@@ -0,0 +1,274 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Eric Beier
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file SpeedPickup.cc
+    @brief Implementation of the SpeedPickup class.
+*/
+
+#include "SpeedPickup.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "util/StringUtils.h"
+
+#include "worldentities/pawns/SpaceShip.h"
+#include "items/Engine.h"
+#include "pickup/PickupIdentifier.h"
+
+#include <sstream>
+
+
+namespace orxonox
+{
+    CreateFactory(SpeedPickup);
+
+    /**
+    @brief
+        Constructor. Registers the object and initializes the member variables.
+    */
+    SpeedPickup::SpeedPickup(BaseObject* creator) : Pickup(creator)
+    {
+        RegisterObject(SpeedPickup);
+
+        this->initialize();
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    SpeedPickup::~SpeedPickup()
+    {
+
+    }
+
+    /**
+    @brief
+        Initializes the member variables.
+    */
+    void SpeedPickup::initialize(void)
+    {
+        this->duration_ = 0.0f;
+        this->speedAdd_ = 0.0f;
+        this->speedMultiply_ = 1.0f;
+
+        this->addTarget(ClassIdentifier<Engine>::getIdentifier());
+    }
+
+    /**
+    @brief
+        Initializes the PickupIdentifier of this pickup.
+    */
+    void SpeedPickup::initializeIdentifier(void)
+    {
+        std::stringstream stream;
+        stream << this->getDuration();
+        std::string type1 = "duration";
+        std::string val1 = stream.str();
+        this->pickupIdentifier_->addParameter(type1, val1);
+
+        stream.clear();
+        stream << this->getSpeedAdd();
+        std::string type2 = "speedAdd";
+        std::string val2 = stream.str();
+        this->pickupIdentifier_->addParameter(type2, val2);
+
+        stream.clear();
+        stream << this->getSpeedMultiply();
+        std::string type3 = "speedMultiply";
+        std::string val3 = stream.str();
+        this->pickupIdentifier_->addParameter(type3, val3);
+    }
+
+    /**
+    @brief
+        Method for creating a SpeedPickup object through XML.
+    */
+    void SpeedPickup::XMLPort(Element& xmlelement, orxonox::XMLPort::Mode mode)
+    {
+        SUPER(SpeedPickup, XMLPort, xmlelement, mode);
+
+        XMLPortParam(SpeedPickup, "duration", setDuration, getDuration, xmlelement, mode);
+        XMLPortParam(SpeedPickup, "speedAdd", setSpeedAdd, getSpeedAdd, xmlelement, mode);
+        XMLPortParam(SpeedPickup, "speedMultiply", setSpeedMultiply, getSpeedMultiply, xmlelement, mode);
+
+        this->initializeIdentifier();
+    }
+
+    /**
+    @brief
+        Is called when the pickup has transited from used to unused or the other way around.
+    */
+    void SpeedPickup::changedUsed(void)
+    {
+        SUPER(SpeedPickup, changedUsed);
+
+        //! If the pickup is not picked up nothing must be done.
+        if(!this->isPickedUp())
+            return;
+
+        Engine* engine = this->carrierToEngineHelper();
+        if(engine == NULL) //!< If the PickupCarrier is no Engine, then this pickup is useless and therefore is destroyed.
+            this->destroy();
+        
+        //! If the pickup has transited to used.
+        if(this->isUsed())
+        {
+            if(!this->getTimer()->isActive() && this->getTimer()->getRemainingTime() > 0.0f)
+            {
+                this->getTimer()->unpauseTimer();
+            }
+            else
+            {
+                this->startPickupTimer(this->getDuration());
+            }
+            engine->setSpeedAdd(this->getSpeedAdd());
+            engine->setSpeedMultiply(this->getSpeedMultiply());
+        }
+        else
+        {
+            engine->setSpeedAdd(0.0f);
+            engine->setSpeedMultiply(1.0f);
+            
+            if(this->isOnce())
+            {
+                if(!this->getTimer()->isActive() && this->getTimer()->getRemainingTime() == this->getDuration())
+                {
+                    this->destroy();
+                }
+                else
+                {
+                    this->getTimer()->pauseTimer();
+                }
+            }
+        }
+    }
+
+    /**
+    @brief
+        Helper to transform the PickupCarrier to a Pawn, and throw an error message if the conversion fails.
+    @return
+        A pointer to the Pawn, or NULL if the conversion failed.
+    */
+    Engine* SpeedPickup::carrierToEngineHelper(void)
+    {
+        PickupCarrier* carrier = this->getCarrier();
+        Engine* engine = dynamic_cast<Engine*>(carrier);
+
+        if(engine == NULL)
+        {
+            COUT(1) << "Invalid PickupCarrier in SpeedPickup." << std::endl;
+        }
+        
+        return engine;
+    }
+
+    /**
+    @brief
+        Creates a duplicate of the input OrxonoxClass.
+    @param item
+        A pointer to the Orxonox class.
+    */
+    void SpeedPickup::clone(OrxonoxClass*& item)
+    {
+        if(item == NULL)
+            item = new SpeedPickup(this);
+
+        SUPER(SpeedPickup, clone, item);
+
+        SpeedPickup* pickup = dynamic_cast<SpeedPickup*>(item);
+        pickup->setDuration(this->getDuration());
+        pickup->setSpeedAdd(this->getSpeedAdd());
+        pickup->setSpeedMultiply(this->getSpeedMultiply());
+
+        pickup->initializeIdentifier();
+    }
+
+    /**
+    @brief
+        Sets the duration.
+    @param duration
+        The duration
+    */
+    void SpeedPickup::setDuration(float duration)
+    {
+        if(duration >= 0.0f)
+        {
+            this->duration_ = duration;
+        }
+        else
+        {
+            COUT(1) << "Invalid duration in SpeedPickup." << std::endl;
+            this->duration_ = 0.0f;
+        }
+    }
+
+    /**
+    @brief
+        Sets the SpeedAdd
+    @param speedAdd
+        The added Speed
+    */
+    void SpeedPickup::setSpeedAdd(float speedAdd)
+    {
+        if(speedAdd >= 0.0f)
+        {
+            this->speedAdd_ = speedAdd;
+        }
+        else
+        {
+            COUT(1) << "Invalid speedAdd in SpeedPickup." << std::endl;
+            this->speedAdd_ = 0.0f;
+        }
+    }
+
+    /**
+    @brief
+        Sets the SpeedMultiply
+    @param speedAdd
+        The multiplied Speed
+    */
+    void SpeedPickup::setSpeedMultiply(float speedMultiply)
+    {
+        if(speedMultiply != 0)
+        {
+            this->speedMultiply_ = speedMultiply;
+        }
+        else
+        {
+            COUT(1) << "Invalid speedMultiply in SpeedPickup." << std::endl;
+            this->speedMultiply_ = 1.0f;
+        }
+    }
+
+    void SpeedPickup::pickupTimerCallback(void)
+    {       
+        this->setUsed(false);
+    }
+}
Index: /code/branches/rocket2/src/modules/pickup/items/SpeedPickup.h
===================================================================
--- /code/branches/rocket2/src/modules/pickup/items/SpeedPickup.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pickup/items/SpeedPickup.h	(revision 6952)
@@ -0,0 +1,97 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Eric Beier
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file SpeedPickup.h
+    @brief Declaration of the SpeedPickup class.
+*/
+
+#ifndef _SpeedPickup_H__
+#define _SpeedPickup_H__
+
+#include "pickup/PickupPrereqs.h"
+
+#include <string>
+#include "worldentities/pawns/Pawn.h"
+#include "worldentities/StaticEntity.h"
+
+#include "pickup/Pickup.h"
+
+namespace orxonox {
+
+    /**
+    @brief
+        A Pickup which can manipulate the Speed of a Pawn.
+
+        1) The speed multiplier:
+           The additional (forward) speed:
+        2) The activation type: 'immediate' or 'onUse'. defines if the item is used when it's picked up or only after the player chooses to use it.
+        4) The duration: the activation time of the pickup.
+
+    @author
+        Eric Beier
+    */
+    class _PickupExport SpeedPickup : public Pickup
+    {
+        public:
+
+            SpeedPickup(BaseObject* creator); //!< Constructor.
+            virtual ~SpeedPickup(); //!< Destructor.
+
+            virtual void XMLPort(Element& xmlelement, orxonox::XMLPort::Mode mode); //!< Method for creating a HealthPickup object through XML.
+
+            virtual void changedUsed(void); //!< Is called when the pickup has transited from used to unused or the other way around.
+            virtual void clone(OrxonoxClass*& item); //!< Creates a duplicate of the input OrxonoxClass.
+
+            inline float getDuration(void)
+                { return this->duration_; }
+            inline float getSpeedAdd(void)
+                { return this->speedAdd_; }
+            inline float getSpeedMultiply(void)
+                { return this->speedMultiply_; }
+
+        protected:
+            void initializeIdentifier(void); //!< Initializes the PickupIdentifier of this pickup.
+            
+            virtual void pickupTimerCallback(void); //!< Function that gets called when timer ends.
+
+            void setDuration(float duration);
+            void setSpeedAdd(float speedAdd);
+            void setSpeedMultiply(float speedMultiply);
+
+        private:
+            void initialize(void); //!< Initializes the member variables.
+            Engine* carrierToEngineHelper(void); //!< Helper to transform the PickupCarrier to a Pawn, and throw an error message if the conversion fails.
+
+            float duration_; //!< The health that is transferred to the Pawn.
+            float speedAdd_;
+            float speedMultiply_;
+    };
+}
+
+#endif // _SpeedPickup_H__
Index: /code/branches/rocket2/src/modules/pong/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/pong/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,22 @@
+SET_SOURCE_FILES(PONG_SRC_FILES
+COMPILATION_BEGIN PongCompilation.cc
+  Pong.cc
+  PongAI.cc
+  PongBall.cc
+  PongBat.cc
+  PongBot.cc
+  PongCenterpoint.cc
+  PongScore.cc
+COMPILATION_END
+)
+
+ORXONOX_ADD_LIBRARY(pong
+  MODULE
+  FIND_HEADER_FILES
+  DEFINE_SYMBOL
+    "PONG_SHARED_BUILD"
+  LINK_LIBRARIES
+    orxonox
+    overlays
+  SOURCE_FILES ${PONG_SRC_FILES}
+)
Index: /code/branches/rocket2/src/modules/pong/Pong.cc
===================================================================
--- /code/branches/rocket2/src/modules/pong/Pong.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/Pong.cc	(revision 6952)
@@ -0,0 +1,209 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Pong.h"
+
+#include "core/CoreIncludes.h"
+#include "core/EventIncludes.h"
+#include "core/Executor.h"
+#include "PongCenterpoint.h"
+#include "PongBall.h"
+#include "PongBat.h"
+#include "PongBot.h"
+#include "PongAI.h"
+
+namespace orxonox
+{
+    CreateEventName(PongCenterpoint, right);
+    CreateEventName(PongCenterpoint, left);
+
+    CreateUnloadableFactory(Pong);
+
+    Pong::Pong(BaseObject* creator) : Deathmatch(creator)
+    {
+        RegisterObject(Pong);
+
+        this->center_ = 0;
+        this->ball_ = 0;
+        this->bat_[0] = 0;
+        this->bat_[1] = 0;
+
+        this->setHUDTemplate("PongHUD");
+
+        this->starttimer_.setTimer(1.0, false, createExecutor(createFunctor(&Pong::startBall, this)));
+        this->starttimer_.stopTimer();
+
+        this->botclass_ = Class(PongBot);
+    }
+
+    void Pong::start()
+    {
+        if (this->center_)
+        {
+            if (!this->ball_)
+            {
+                this->ball_ = new PongBall(this->center_);
+                this->ball_->addTemplate(this->center_->getBalltemplate());
+            }
+
+            this->center_->attach(this->ball_);
+            this->ball_->setPosition(0, 0, 0);
+            this->ball_->setFieldDimension(this->center_->getFieldDimension());
+            this->ball_->setSpeed(0);
+            this->ball_->setAccelerationFactor(this->center_->getBallAccelerationFactor());
+            this->ball_->setBatLength(this->center_->getBatLength());
+
+            if (!this->bat_[0])
+            {
+                this->bat_[0] = new PongBat(this->center_);
+                this->bat_[0]->addTemplate(this->center_->getBattemplate());
+            }
+            if (!this->bat_[1])
+            {
+                this->bat_[1] = new PongBat(this->center_);
+                this->bat_[1]->addTemplate(this->center_->getBattemplate());
+            }
+
+            this->center_->attach(this->bat_[0]);
+            this->center_->attach(this->bat_[1]);
+            this->bat_[0]->setPosition(-this->center_->getFieldDimension().x / 2, 0, 0);
+            this->bat_[1]->setPosition( this->center_->getFieldDimension().x / 2, 0, 0);
+            this->bat_[0]->yaw(Degree(-90));
+            this->bat_[1]->yaw(Degree(90));
+            this->bat_[0]->setSpeed(this->center_->getBatSpeed());
+            this->bat_[1]->setSpeed(this->center_->getBatSpeed());
+            this->bat_[0]->setFieldHeight(this->center_->getFieldDimension().y);
+            this->bat_[1]->setFieldHeight(this->center_->getFieldDimension().y);
+            this->bat_[0]->setLength(this->center_->getBatLength());
+            this->bat_[1]->setLength(this->center_->getBatLength());
+
+            this->ball_->setBats(this->bat_);
+        }
+        else
+        {
+            COUT(1) << "Error: No Centerpoint specified." << std::endl;
+        }
+
+        this->starttimer_.startTimer();
+
+
+        bool temp = this->bForceSpawn_;
+        this->bForceSpawn_ = true;
+
+        Deathmatch::start();
+
+        this->bForceSpawn_ = temp;
+    }
+
+    void Pong::end()
+    {
+        if (this->ball_)
+        {
+            this->ball_->destroy();
+            this->ball_ = 0;
+        }
+
+        Deathmatch::end();
+    }
+
+    void Pong::spawnPlayer(PlayerInfo* player)
+    {
+        if (!this->bat_[0]->getPlayer())
+        {
+            player->startControl(this->bat_[0]);
+            this->players_[player].state_ = PlayerState::Alive;
+        }
+        else if (!this->bat_[1]->getPlayer())
+        {
+            player->startControl(this->bat_[1]);
+            this->players_[player].state_ = PlayerState::Alive;
+        }
+        else
+            return;
+
+        if (player && player->getController() && player->getController()->isA(Class(PongAI)))
+        {
+            PongAI* ai = orxonox_cast<PongAI*>(player->getController());
+            ai->setPongBall(this->ball_);
+        }
+    }
+
+    void Pong::playerScored(PlayerInfo* player)
+    {
+        Deathmatch::playerScored(player);
+
+        if (this->center_)
+        {
+            if (player == this->getRightPlayer())
+                this->center_->fireEvent(FireEventName(PongCenterpoint, right));
+            else if (player == this->getLeftPlayer())
+                this->center_->fireEvent(FireEventName(PongCenterpoint, left));
+
+            if (player)
+                this->gtinfo_->sendAnnounceMessage(player->getName() + " scored");
+        }
+
+        if (this->ball_)
+        {
+            this->ball_->setPosition(Vector3::ZERO);
+            this->ball_->setVelocity(Vector3::ZERO);
+            this->ball_->setAcceleration(Vector3::ZERO);
+            this->ball_->setSpeed(0);
+        }
+
+        if (this->bat_[0] && this->bat_[1])
+        {
+            this->bat_[0]->setPosition(-this->center_->getFieldDimension().x / 2, 0, 0);
+            this->bat_[1]->setPosition( this->center_->getFieldDimension().x / 2, 0, 0);
+        }
+
+        this->starttimer_.startTimer();
+    }
+
+    void Pong::startBall()
+    {
+        if (this->ball_ && this->center_)
+            this->ball_->setSpeed(this->center_->getBallSpeed());
+    }
+
+    PlayerInfo* Pong::getLeftPlayer() const
+    {
+        if (this->bat_ && this->bat_[0])
+            return this->bat_[0]->getPlayer();
+        else
+            return 0;
+    }
+
+    PlayerInfo* Pong::getRightPlayer() const
+    {
+        if (this->bat_ && this->bat_[1])
+            return this->bat_[1]->getPlayer();
+        else
+            return 0;
+    }
+}
Index: /code/branches/rocket2/src/modules/pong/Pong.h
===================================================================
--- /code/branches/rocket2/src/modules/pong/Pong.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/Pong.h	(revision 6952)
@@ -0,0 +1,68 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Pong_H__
+#define _Pong_H__
+
+#include "pong/PongPrereqs.h"
+
+#include "tools/Timer.h"
+#include "gametypes/Deathmatch.h"
+
+namespace orxonox
+{
+    class _PongExport Pong : public Deathmatch
+    {
+        public:
+            Pong(BaseObject* creator);
+            virtual ~Pong() {}
+
+            virtual void start();
+            virtual void end();
+
+            virtual void spawnPlayer(PlayerInfo* player);
+
+            virtual void playerScored(PlayerInfo* player);
+
+            void setCenterpoint(PongCenterpoint* center)
+                { this->center_ = center; }
+
+            PlayerInfo* getLeftPlayer() const;
+            PlayerInfo* getRightPlayer() const;
+
+        protected:
+            void startBall();
+
+            PongCenterpoint* center_;
+            PongBall* ball_;
+            PongBat* bat_[2];
+            Timer starttimer_;
+    };
+}
+
+#endif /* _Pong_H__ */
Index: /code/branches/rocket2/src/modules/pong/PongAI.cc
===================================================================
--- /code/branches/rocket2/src/modules/pong/PongAI.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/PongAI.cc	(revision 6952)
@@ -0,0 +1,334 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "PongAI.h"
+
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "tools/Timer.h"
+#include "worldentities/ControllableEntity.h"
+#include "PongBall.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(PongAI);
+
+    const static float MAX_REACTION_TIME = 0.4f;
+
+    PongAI::PongAI(BaseObject* creator) : Controller(creator)
+    {
+        RegisterObject(PongAI);
+
+        this->ball_ = 0;
+        this->ballDirection_ = Vector2::ZERO;
+        this->ballEndPosition_ = 0;
+        this->randomOffset_ = 0;
+        this->bChangedRandomOffset_ = false;
+        this->relHysteresisOffset_ = 0.02f;
+        this->strength_ = 0.5f;
+        this->movement_ = 0;
+        this->oldMove_ = 0;
+        this->bOscillationAvoidanceActive_ = false;
+
+        this->setConfigValues();
+    }
+
+    PongAI::~PongAI()
+    {
+        for (std::list<std::pair<Timer*, char> >::iterator it = this->reactionTimers_.begin(); it != this->reactionTimers_.end(); ++it)
+            it->first->destroy();
+    }
+
+    void PongAI::setConfigValues()
+    {
+        SetConfigValue(strength_, 0.5).description("A value from 0 to 1 where 0 is weak and 1 is strong.");
+    }
+
+    void PongAI::tick(float dt)
+    {
+        if (!this->ball_ || !this->getControllableEntity())
+            return;
+
+        Vector3 mypos = this->getControllableEntity()->getPosition();
+        Vector3 ballpos = this->ball_->getPosition();
+        Vector3 ballvel = this->ball_->getVelocity();
+        float hysteresisOffset = this->relHysteresisOffset_ * this->ball_->getFieldDimension().y;
+
+        char move = 0;
+        bool delay = false;
+
+        // Check in which direction the ball is flying
+        if ((mypos.x > 0 && ballvel.x < 0) || (mypos.x < 0 && ballvel.x > 0))
+        {
+            // The ball is flying away
+            this->ballDirection_.x = -1;
+            this->ballDirection_.y = 0;
+            this->bOscillationAvoidanceActive_ = false;
+
+            // Move to the middle
+            if (mypos.z > hysteresisOffset)
+                move = 1;
+            else if (mypos.z < -hysteresisOffset)
+                move = -1;
+        }
+        else if (ballvel.x == 0)
+        {
+            // The ball is standing still
+            this->ballDirection_.x = 0;
+            this->ballDirection_.y = 0;
+            this->bOscillationAvoidanceActive_ = false;
+        }
+        else
+        {
+            // The ball is approaching
+            if (this->ballDirection_.x != 1)
+            {
+                // The ball just startet to approach, initialize all values
+                this->ballDirection_.x = 1;
+                this->ballDirection_.y = sgn(ballvel.z);
+                this->ballEndPosition_ = 0;
+                this->randomOffset_ = 0;
+                this->bChangedRandomOffset_ = false;
+
+                this->calculateRandomOffset();
+                this->calculateBallEndPosition();
+                delay = true;
+                this->bOscillationAvoidanceActive_ = false;
+            }
+
+            if (this->ballDirection_.y != sgn(ballvel.z))
+            {
+                // The ball just bounced from a bound, recalculate the predicted end position
+                this->ballDirection_.y = sgn(ballvel.z);
+
+                this->calculateBallEndPosition();
+                delay = true;
+                this->bOscillationAvoidanceActive_ = false;
+            }
+
+            // If the ball is close enough, calculate another random offset to accelerate the ball
+            if (!this->bChangedRandomOffset_)
+            {
+                float timetohit = (-this->ball_->getPosition().x + this->ball_->getFieldDimension().x / 2 * sgn(this->ball_->getVelocity().x)) / this->ball_->getVelocity().x;
+                if (timetohit < 0.05)
+                {
+                    this->bChangedRandomOffset_ = true;
+                    if (rnd() < this->strength_)
+                        this->calculateRandomOffset();
+                }
+            }
+
+            // Move to the predicted end position with an additional offset (to hit the ball with the side of the bat)
+            if (!this->bOscillationAvoidanceActive_)
+            {
+                float desiredZValue = this->ballEndPosition_ + this->randomOffset_;
+
+                if (mypos.z > desiredZValue + hysteresisOffset * (this->randomOffset_ < 0))
+                    move = 1;
+                else if (mypos.z < desiredZValue - hysteresisOffset * (this->randomOffset_ > 0))
+                    move = -1;
+            }
+
+            if (move != 0 && this->oldMove_ != 0 && move != this->oldMove_ && !delay)
+            {
+                // We had to correct our position because we moved too far
+                // (and delay ist false, so we're not in the wrong place because of a new end-position prediction)
+                if (fabs(mypos.z - this->ballEndPosition_) < 0.5 * this->ball_->getBatLength() * this->ball_->getFieldDimension().y)
+                {
+                    // We're not at the right position, but we still hit the ball, so just stay there to avoid oscillation
+                    move = 0;
+                    this->bOscillationAvoidanceActive_ = true;
+                }
+            }
+        }
+
+        this->oldMove_ = move;
+        this->move(move, delay);
+        this->getControllableEntity()->moveFrontBack(this->movement_);
+    }
+
+    void PongAI::calculateRandomOffset()
+    {
+        // Calculate the exponent for the position-formula
+        float exp = pow(10, 1 - 2*this->strength_); // strength: 0   -> exp = 10
+                                                    // strength: 0.5 -> exp = 1
+                                                    // strength: 1   -> exp = 0.1
+
+        // Calculate the relative position where to hit the ball with the bat
+        float position = pow(rnd(), exp); // exp > 1 -> position is more likely a small number
+                                          // exp < 1 -> position is more likely a large number
+
+        // The position shouln't be larger than 0.5 (50% of the bat-length from the middle is the end)
+        position *= 0.48f;
+
+        // Both sides are equally probable
+        position *= rndsgn();
+
+        // Calculate the offset in world units
+        this->randomOffset_ = position * this->ball_->getBatLength() * this->ball_->getFieldDimension().y;
+    }
+
+    void PongAI::calculateBallEndPosition()
+    {
+        Vector3 position = this->ball_->getPosition();
+        Vector3 velocity = this->ball_->getVelocity();
+        Vector3 acceleration = this->ball_->getAcceleration();
+        Vector2 dimension = this->ball_->getFieldDimension();
+
+        // Calculate bounces. The number of predicted bounces is limited by the AIs strength
+        for (float limit = -0.05f; limit < this->strength_ || this->strength_ > 0.99f; limit += 0.4f)
+        {
+            // calculate the time until the ball reaches the other side
+            float totaltime = (-position.x + dimension.x / 2 * sgn(velocity.x)) / velocity.x;
+
+            // calculate wall bounce position (four possible solutions of the equation: pos.z + vel.z*t + acc.z/2*t^2 = +/- dim.z/2)
+            float bouncetime = totaltime;
+            bool bUpperWall = false;
+
+            if (acceleration.z == 0)
+            {
+                if (velocity.z > 0)
+                {
+                    bUpperWall = true;
+                    bouncetime = (dimension.y/2 - position.z) / velocity.z;
+                }
+                else if (velocity.z < 0)
+                {
+                    bUpperWall = false;
+                    bouncetime = (-dimension.y/2 - position.z) / velocity.z;
+                }
+            }
+            else
+            {
+                // upper wall
+                float temp = velocity.z*velocity.z + 2*acceleration.z*(dimension.y/2 - position.z);
+                if (temp >= 0)
+                {
+                    float t1 = (sqrt(temp) - velocity.z) / acceleration.z;
+                    float t2 = (sqrt(temp) + velocity.z) / acceleration.z * (-1);
+                    if (t1 > 0 && t1 < bouncetime)
+                    {
+                        bouncetime = t1;
+                        bUpperWall = true;
+                    }
+                    if (t2 > 0 && t2 < bouncetime)
+                    {
+                        bouncetime = t2;
+                        bUpperWall = true;
+                    }
+                }
+                // lower wall
+                temp = velocity.z*velocity.z - 2*acceleration.z*(dimension.y/2 + position.z);
+                if (temp >= 0)
+                {
+                    float t1 = (sqrt(temp) - velocity.z) / acceleration.z;
+                    float t2 = (sqrt(temp) + velocity.z) / acceleration.z * (-1);
+                    if (t1 > 0 && t1 < bouncetime)
+                    {
+                        bouncetime = t1;
+                        bUpperWall = false;
+                    }
+                    if (t2 > 0 && t2 < bouncetime)
+                    {
+                        bouncetime = t2;
+                        bUpperWall = false;
+                    }
+                }
+            }
+
+            if (bouncetime < totaltime)
+            {
+                // Calculate a random prediction error, based on the vertical speed of the ball and the strength of the AI
+                float randomErrorX = rnd(-1, 1) * dimension.y * (velocity.z / velocity.x / PongBall::MAX_REL_Z_VELOCITY) * (1 - this->strength_);
+                float randomErrorZ = rnd(-1, 1) * dimension.y * (velocity.z / velocity.x / PongBall::MAX_REL_Z_VELOCITY) * (1 - this->strength_);
+
+                // ball bounces after <bouncetime> seconds, update the position and continue
+                velocity.z = velocity.z + acceleration.z * bouncetime;
+
+                if (bUpperWall)
+                {
+                    position.z = dimension.y / 2;
+                    velocity.z = -fabs(velocity.z) + fabs(randomErrorZ);
+                }
+                else
+                {
+                    position.z = -dimension.y / 2;
+                    velocity.z = fabs(velocity.z) - fabs(randomErrorZ);
+                }
+
+                position.x = position.x + velocity.x * bouncetime + randomErrorX;
+                this->ballEndPosition_ = position.z;
+            }
+            else
+            {
+                // ball doesn't bounce, calculate the end position and return
+                // calculate end-height: current height + slope * distance incl. acceleration
+                this->ballEndPosition_ = position.z + velocity.z * totaltime + acceleration.z / 2 * totaltime * totaltime;
+                return;
+            }
+        }
+    }
+
+    void PongAI::move(char direction, bool bUseDelay)
+    {
+        // The current direction is either what we're doing right now (movement_) or what is last in the queue
+        char currentDirection = this->movement_;
+        if (this->reactionTimers_.size() > 0)
+            currentDirection = this->reactionTimers_.back().second;
+
+        // Only add changes of direction
+        if (direction == currentDirection)
+            return;
+
+        if (bUseDelay)
+        {
+            // Calculate delay
+            float delay = MAX_REACTION_TIME * (1 - this->strength_);
+
+            // Add a new Timer
+            Timer* timer = new Timer(delay, false, createExecutor(createFunctor(&PongAI::delayedMove, this)));
+            this->reactionTimers_.push_back(std::pair<Timer*, char>(timer, direction));
+        }
+        else
+        {
+            this->movement_ = direction;
+        }
+    }
+
+    void PongAI::delayedMove()
+    {
+        // Get the new movement direction from the timer list
+        this->movement_ = this->reactionTimers_.front().second;
+
+        // Destroy the timer and remove it from the list
+        Timer* timer = this->reactionTimers_.front().first;
+        timer->destroy();
+
+        this->reactionTimers_.pop_front();
+    }
+}
Index: /code/branches/rocket2/src/modules/pong/PongAI.h
===================================================================
--- /code/branches/rocket2/src/modules/pong/PongAI.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/PongAI.h	(revision 6952)
@@ -0,0 +1,75 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PongAI_H__
+#define _PongAI_H__
+
+#include "pong/PongPrereqs.h"
+
+#include <list>
+#include "util/Math.h"
+#include "tools/interfaces/Tickable.h"
+#include "controllers/Controller.h"
+
+namespace orxonox
+{
+    class _PongExport PongAI : public Controller, public Tickable
+    {
+        public:
+            PongAI(BaseObject* creator);
+            virtual ~PongAI();
+
+            void setConfigValues();
+
+            virtual void tick(float dt);
+
+            void setPongBall(PongBall* ball)
+                { this->ball_ = ball; }
+
+        protected:
+            void calculateRandomOffset();
+            void calculateBallEndPosition();
+            void move(char direction, bool bUseDelay);
+            void delayedMove();
+
+            PongBall* ball_;
+            Vector2 ballDirection_;
+            float ballEndPosition_;
+            float randomOffset_;
+            bool bChangedRandomOffset_;
+            float relHysteresisOffset_;
+            float strength_;
+
+            std::list<std::pair<Timer*, char> > reactionTimers_;
+            char movement_;
+            char oldMove_;
+            bool bOscillationAvoidanceActive_;
+    };
+}
+
+#endif /* _PongAI_H__ */
Index: /code/branches/rocket2/src/modules/pong/PongBall.cc
===================================================================
--- /code/branches/rocket2/src/modules/pong/PongBall.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/PongBall.cc	(revision 6952)
@@ -0,0 +1,183 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "PongBall.h"
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "gametypes/Gametype.h"
+#include "PongBat.h"
+
+namespace orxonox
+{
+    CreateFactory(PongBall);
+
+    const float PongBall::MAX_REL_Z_VELOCITY = 1.5;
+
+    PongBall::PongBall(BaseObject* creator)
+        : MovableEntity(creator)
+    {
+        RegisterObject(PongBall);
+
+        this->speed_ = 0;
+        this->accelerationFactor_ = 1.0f;
+        this->bat_ = 0;
+        this->batID_ = new unsigned int[2];
+        this->batID_[0] = OBJECTID_UNKNOWN;
+        this->batID_[1] = OBJECTID_UNKNOWN;
+        this->relMercyOffset_ = 0.05f;
+
+        this->registerVariables();
+    }
+
+    PongBall::~PongBall()
+    {
+    }
+
+    void PongBall::registerVariables()
+    {
+        registerVariable( this->fieldWidth_ );
+        registerVariable( this->fieldHeight_ );
+        registerVariable( this->batlength_ );
+        registerVariable( this->speed_ );
+        registerVariable( this->relMercyOffset_ );
+        registerVariable( this->batID_[0] );
+        registerVariable( this->batID_[1], VariableDirection::ToClient, new NetworkCallback<PongBall>( this, &PongBall::applyBats) );
+    }
+
+    void PongBall::tick(float dt)
+    {
+        SUPER(PongBall, tick, dt);
+
+        Vector3 position = this->getPosition();
+        Vector3 velocity = this->getVelocity();
+        Vector3 acceleration = this->getAcceleration();
+
+        if (position.z > this->fieldHeight_ / 2 || position.z < -this->fieldHeight_ / 2)
+        {
+            velocity.z = -velocity.z;
+            if (position.z > this->fieldHeight_ / 2)
+                position.z = this->fieldHeight_ / 2;
+            if (position.z < -this->fieldHeight_ / 2)
+                position.z = -this->fieldHeight_ / 2;
+
+            this->fireEvent();
+        }
+
+        if (position.x > this->fieldWidth_ / 2 || position.x < -this->fieldWidth_ / 2)
+        {
+            float distance = 0;
+
+            if (this->bat_)
+            {
+                if (position.x > this->fieldWidth_ / 2 && this->bat_[1])
+                {
+                    distance = (position.z - this->bat_[1]->getPosition().z) / (this->fieldHeight_ * (this->batlength_ * 1.10f) / 2);
+                    if (fabs(distance) <= 1)
+                    {
+                        position.x = this->fieldWidth_ / 2;
+                        velocity.x = -velocity.x;
+                        velocity.z = distance * distance * sgn(distance) * PongBall::MAX_REL_Z_VELOCITY * this->speed_;
+                        acceleration = this->bat_[1]->getVelocity() * this->accelerationFactor_ * -1;
+
+                        this->fireEvent();
+                    }
+                    else if (GameMode::isMaster() && position.x > this->fieldWidth_ / 2 * (1 + this->relMercyOffset_))
+                    {
+                        if (this->getGametype() && this->bat_[0])
+                        {
+                            this->getGametype()->playerScored(this->bat_[0]->getPlayer());
+                            return;
+                        }
+                    }
+                }
+                if (position.x < -this->fieldWidth_ / 2 && this->bat_[0])
+                {
+                    distance = (position.z - this->bat_[0]->getPosition().z) / (this->fieldHeight_ * (this->batlength_ * 1.10f) / 2);
+                    if (fabs(distance) <= 1)
+                    {
+                        position.x = -this->fieldWidth_ / 2;
+                        velocity.x = -velocity.x;
+                        velocity.z = distance * distance * sgn(distance) * PongBall::MAX_REL_Z_VELOCITY * this->speed_;
+                        acceleration = this->bat_[0]->getVelocity() * this->accelerationFactor_ * -1;
+
+                        this->fireEvent();
+                    }
+                    else if (GameMode::isMaster() && position.x < -this->fieldWidth_ / 2 * (1 + this->relMercyOffset_))
+                    {
+                        if (this->getGametype() && this->bat_[1])
+                        {
+                            this->getGametype()->playerScored(this->bat_[1]->getPlayer());
+                            return;
+                        }
+                    }
+                }
+            }
+        }
+
+        if (acceleration != this->getAcceleration())
+            this->setAcceleration(acceleration);
+        if (velocity != this->getVelocity())
+            this->setVelocity(velocity);
+        if (position != this->getPosition())
+            this->setPosition(position);
+    }
+
+    void PongBall::setSpeed(float speed)
+    {
+        if (speed != this->speed_)
+        {
+            this->speed_ = speed;
+
+            Vector3 velocity = this->getVelocity();
+            if (velocity.x != 0)
+                velocity.x = sgn(velocity.x) * this->speed_;
+            else
+                velocity.x = this->speed_ * sgn(rnd(-1,1));
+
+            this->setVelocity(velocity);
+        }
+    }
+
+    void PongBall::setBats(PongBat** bats)
+    {
+        this->bat_ = bats;
+        this->batID_[0] = this->bat_[0]->getObjectID();
+        this->batID_[1] = this->bat_[1]->getObjectID();
+    }
+
+    void PongBall::applyBats()
+    {
+        if (!this->bat_)
+            this->bat_ = new PongBat*[2];
+        if (this->batID_[0] != OBJECTID_UNKNOWN)
+            this->bat_[0] = orxonox_cast<PongBat*>(Synchronisable::getSynchronisable(this->batID_[0]));
+        if (this->batID_[1] != OBJECTID_UNKNOWN)
+            this->bat_[1] = orxonox_cast<PongBat*>(Synchronisable::getSynchronisable(this->batID_[1]));
+    }
+}
Index: /code/branches/rocket2/src/modules/pong/PongBall.h
===================================================================
--- /code/branches/rocket2/src/modules/pong/PongBall.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/PongBall.h	(revision 6952)
@@ -0,0 +1,87 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PongBall_H__
+#define _PongBall_H__
+
+#include "pong/PongPrereqs.h"
+
+#include "util/Math.h"
+#include "worldentities/MovableEntity.h"
+
+namespace orxonox
+{
+    class _PongExport PongBall : public MovableEntity
+    {
+        public:
+            PongBall(BaseObject* creator);
+            virtual ~PongBall();
+
+            virtual void tick(float dt);
+
+            void registerVariables();
+
+            void setFieldDimension(float width, float height)
+                { this->fieldWidth_ = width; this->fieldHeight_ = height; }
+            void setFieldDimension(const Vector2& dimension)
+                { this->setFieldDimension(dimension.x, dimension.y); }
+            Vector2 getFieldDimension() const
+                { return Vector2(this->fieldWidth_, this->fieldHeight_); }
+
+            void setSpeed(float speed);
+            float getSpeed() const
+                { return this->speed_; }
+
+            void setAccelerationFactor(float factor)
+                { this->accelerationFactor_ = factor; }
+            float getAccelerationFactor() const
+                { return this->accelerationFactor_; }
+
+            void setBatLength(float batlength)
+                { this->batlength_ = batlength; }
+            float getBatLength() const
+                { return this->batlength_; }
+
+            void setBats(PongBat** bats);
+            void applyBats();
+
+            static const float MAX_REL_Z_VELOCITY;
+
+        private:
+            float fieldWidth_;
+            float fieldHeight_;
+            float speed_;
+            float accelerationFactor_;
+            float batlength_;
+            PongBat** bat_;
+            unsigned int* batID_;
+            float relMercyOffset_;
+    };
+}
+
+#endif /* _PongBall_H__ */
Index: /code/branches/rocket2/src/modules/pong/PongBat.cc
===================================================================
--- /code/branches/rocket2/src/modules/pong/PongBat.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/PongBat.cc	(revision 6952)
@@ -0,0 +1,114 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "PongBat.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(PongBat);
+
+    PongBat::PongBat(BaseObject* creator) : ControllableEntity(creator)
+    {
+        RegisterObject(PongBat);
+
+        this->movement_ = 0;
+        this->bMoveLocal_ = false;
+        this->speed_ = 60;
+        this->length_ = 0.25;
+        this->fieldHeight_ = 100;
+        this->bSteadiedPosition_ = false;
+
+        this->registerVariables();
+    }
+
+    void PongBat::registerVariables()
+    {
+        registerVariable(this->speed_);
+        registerVariable(this->fieldHeight_);
+        registerVariable(this->length_);
+    }
+
+    void PongBat::tick(float dt)
+    {
+        if (this->hasLocalController())
+        {
+            if (this->movement_ != 0)
+            {
+                this->movement_ = clamp(this->movement_, -1.0f, 1.0f) * this->speed_;
+
+                if (this->bMoveLocal_)
+                    this->setVelocity(this->getOrientation() * Vector3(this->movement_, 0, 0));
+                else
+                    this->setVelocity(0, 0, this->movement_);
+
+                this->movement_ = 0;
+                this->bSteadiedPosition_ = false;
+            }
+            else if (!this->bSteadiedPosition_)
+            {
+                // To ensure network synchronicity
+                this->setVelocity(0, 0, 0);
+                this->setPosition(this->getPosition());
+                this->bSteadiedPosition_ = true;
+            }
+        }
+
+        SUPER(PongBat, tick, dt);
+
+        Vector3 position = this->getPosition();
+        if (position.z > this->fieldHeight_ / 2 - this->fieldHeight_ * this->length_ / 2)
+            position.z = this->fieldHeight_ / 2 - this->fieldHeight_ * this->length_ / 2;
+        if (position.z < -this->fieldHeight_ / 2 + this->fieldHeight_ * this->length_ / 2)
+            position.z = -this->fieldHeight_ / 2 + this->fieldHeight_ * this->length_ / 2;
+        if (position != this->getPosition())
+        {
+            this->setPosition(position);
+            this->setVelocity( Vector3::ZERO );
+        }
+    }
+
+    void PongBat::moveFrontBack(const Vector2& value)
+    {
+        this->bMoveLocal_ = false;
+        this->movement_ = -value.x;
+    }
+
+    void PongBat::moveRightLeft(const Vector2& value)
+    {
+        this->bMoveLocal_ = true;
+        this->movement_ = value.x;
+    }
+
+    void PongBat::changedPlayer()
+    {
+        this->setVelocity(0, 0, 0);
+    }
+}
Index: /code/branches/rocket2/src/modules/pong/PongBat.h
===================================================================
--- /code/branches/rocket2/src/modules/pong/PongBat.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/PongBat.h	(revision 6952)
@@ -0,0 +1,76 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PongBat_H__
+#define _PongBat_H__
+
+#include "pong/PongPrereqs.h"
+#include "worldentities/ControllableEntity.h"
+
+namespace orxonox
+{
+    class _PongExport PongBat : public ControllableEntity
+    {
+        public:
+            PongBat(BaseObject* creator);
+            virtual ~PongBat() {}
+
+            void registerVariables();
+            virtual void tick(float dt);
+
+            virtual void moveFrontBack(const Vector2& value);
+            virtual void moveRightLeft(const Vector2& value);
+
+            virtual void changedPlayer();
+
+            void setSpeed(float speed)
+                { this->speed_ = speed; }
+            float getSpeed() const
+                { return this->speed_; }
+
+            void setFieldHeight(float height)
+                { this->fieldHeight_ = height; }
+            float getFieldHeight() const
+                { return this->fieldHeight_; }
+
+            void setLength(float length)
+                { this->length_ = length; }
+            float getLength() const
+                { return this->length_; }
+
+        private:
+            float movement_;
+            bool bMoveLocal_;
+            float speed_;
+            float length_;
+            float fieldHeight_;
+            bool bSteadiedPosition_;
+    };
+}
+
+#endif /* _PongBat_H__ */
Index: /code/branches/rocket2/src/modules/pong/PongBot.cc
===================================================================
--- /code/branches/rocket2/src/modules/pong/PongBot.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/PongBot.cc	(revision 6952)
@@ -0,0 +1,45 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "PongBot.h"
+
+#include "core/CoreIncludes.h"
+#include "PongAI.h"
+
+namespace orxonox
+{
+    CreateFactory(PongBot);
+
+    PongBot::PongBot(BaseObject* creator) : Bot(creator)
+    {
+        RegisterObject(PongBot);
+
+        this->defaultController_ = Class(PongAI);
+        this->createController();
+    }
+}
Index: /code/branches/rocket2/src/modules/pong/PongBot.h
===================================================================
--- /code/branches/rocket2/src/modules/pong/PongBot.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/PongBot.h	(revision 6952)
@@ -0,0 +1,45 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PongBot_H__
+#define _PongBot_H__
+
+#include "pong/PongPrereqs.h"
+#include "infos/Bot.h"
+
+namespace orxonox
+{
+    class _PongExport PongBot : public Bot
+    {
+        public:
+            PongBot(BaseObject* creator);
+            virtual ~PongBot() {}
+    };
+}
+
+#endif /* _PongBot_H__ */
Index: /code/branches/rocket2/src/modules/pong/PongCenterpoint.cc
===================================================================
--- /code/branches/rocket2/src/modules/pong/PongCenterpoint.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/PongCenterpoint.cc	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "PongCenterpoint.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "Pong.h"
+
+namespace orxonox
+{
+    CreateFactory(PongCenterpoint);
+
+    PongCenterpoint::PongCenterpoint(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(PongCenterpoint);
+
+        this->width_ = 200;
+        this->height_ = 120;
+        this->ballspeed_ = 100;
+        this->ballaccfactor_ = 1.0;
+        this->batspeed_ = 60;
+        this->batlength_ = 0.25;
+
+        this->checkGametype();
+    }
+
+    void PongCenterpoint::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(PongCenterpoint, XMLPort, xmlelement, mode);
+
+        XMLPortParam(PongCenterpoint, "dimension", setFieldDimension, getFieldDimension, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "balltemplate", setBalltemplate, getBalltemplate, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "battemplate", setBattemplate, getBattemplate, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "ballspeed", setBallSpeed, getBallSpeed, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "ballaccfactor", setBallAccelerationFactor, getBallAccelerationFactor, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "batspeed", setBatSpeed, getBatSpeed, xmlelement, mode);
+        XMLPortParam(PongCenterpoint, "batlength", setBatLength, getBatLength, xmlelement, mode);
+    }
+
+    void PongCenterpoint::changedGametype()
+    {
+        SUPER(PongCenterpoint, changedGametype);
+
+        this->checkGametype();
+    }
+
+    void PongCenterpoint::checkGametype()
+    {
+        if (this->getGametype() && this->getGametype()->isA(Class(Pong)))
+        {
+            Pong* pong_gametype = orxonox_cast<Pong*>(this->getGametype().get());
+            pong_gametype->setCenterpoint(this);
+        }
+    }
+}
Index: /code/branches/rocket2/src/modules/pong/PongCenterpoint.h
===================================================================
--- /code/branches/rocket2/src/modules/pong/PongCenterpoint.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/PongCenterpoint.h	(revision 6952)
@@ -0,0 +1,101 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PongCenterpoint_H__
+#define _PongCenterpoint_H__
+
+#include "pong/PongPrereqs.h"
+
+#include <string>
+#include <util/Math.h>
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _PongExport PongCenterpoint : public StaticEntity
+    {
+        public:
+            PongCenterpoint(BaseObject* creator);
+            virtual ~PongCenterpoint() {}
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            virtual void changedGametype();
+
+            void setBalltemplate(const std::string& balltemplate)
+                { this->balltemplate_ = balltemplate; }
+            const std::string& getBalltemplate() const
+                { return this->balltemplate_; }
+
+            void setBattemplate(const std::string& battemplate)
+                { this->battemplate_ = battemplate; }
+            const std::string& getBattemplate() const
+                { return this->battemplate_; }
+
+            void setFieldDimension(const Vector2& dimension)
+                { this->width_ = dimension.x; this->height_ = dimension.y; }
+            Vector2 getFieldDimension() const
+                { return Vector2(this->width_, this->height_); }
+
+            void setBallSpeed(float ballspeed)
+                { this->ballspeed_ = ballspeed; }
+            float getBallSpeed() const
+                { return this->ballspeed_; }
+
+            void setBallAccelerationFactor(float ballaccfactor)
+                { this->ballaccfactor_ = ballaccfactor; }
+            float getBallAccelerationFactor() const
+                { return this->ballaccfactor_; }
+
+            void setBatSpeed(float batspeed)
+                { this->batspeed_ = batspeed; }
+            float getBatSpeed() const
+                { return this->batspeed_; }
+
+            void setBatLength(float batlength)
+                { this->batlength_ = batlength; }
+            float getBatLength() const
+                { return this->batlength_; }
+
+        private:
+            void checkGametype();
+
+            std::string balltemplate_;
+            std::string battemplate_;
+
+            float ballspeed_;
+            float ballaccfactor_;
+            float batspeed_;
+            float batlength_;
+
+            float width_;
+            float height_;
+    };
+}
+
+#endif /* _PongCenterpoint_H__ */
Index: /code/branches/rocket2/src/modules/pong/PongPrereqs.h
===================================================================
--- /code/branches/rocket2/src/modules/pong/PongPrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/PongPrereqs.h	(revision 6952)
@@ -0,0 +1,76 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Shared library macros, enums, constants and forward declarations for the pong module
+*/
+
+#ifndef _PongPrereqs_H__
+#define _PongPrereqs_H__
+
+#include "OrxonoxConfig.h"
+#include "OrxonoxPrereqs.h"
+
+//-----------------------------------------------------------------------
+// Shared library settings
+//-----------------------------------------------------------------------
+
+#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined(ORXONOX_STATIC_BUILD)
+#  ifdef PONG_SHARED_BUILD
+#    define _PongExport __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define _PongExport
+#    else
+#      define _PongExport __declspec(dllimport)
+#    endif
+#  endif
+#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _PongExport  __attribute__ ((visibility("default")))
+#else
+#  define _PongExport
+#endif
+
+//-----------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    class Pong;
+    class PongAI;
+    class PongBall;
+    class PongBat;
+    class PongBot;
+    class PongCenterpoint;
+    class PongScore;
+}
+
+#endif /* _PongPrereqs_H__ */
Index: /code/branches/rocket2/src/modules/pong/PongScore.cc
===================================================================
--- /code/branches/rocket2/src/modules/pong/PongScore.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/PongScore.cc	(revision 6952)
@@ -0,0 +1,139 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "PongScore.h"
+
+#include "util/Convert.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "Pong.h"
+#include "infos/PlayerInfo.h"
+
+namespace orxonox
+{
+    CreateFactory(PongScore);
+
+    PongScore::PongScore(BaseObject* creator) : OverlayText(creator)
+    {
+        RegisterObject(PongScore);
+
+        this->owner_ = 0;
+
+        this->bShowName_ = false;
+        this->bShowScore_ = false;
+        this->bShowLeftPlayer_ = false;
+        this->bShowRightPlayer_ = false;
+    }
+
+    PongScore::~PongScore()
+    {
+    }
+
+    void PongScore::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(PongScore, XMLPort, xmlelement, mode);
+
+        XMLPortParam(PongScore, "showname",        setShowName,        getShowName,        xmlelement, mode).defaultValues(false);
+        XMLPortParam(PongScore, "showscore",       setShowScore,       getShowScore,       xmlelement, mode).defaultValues(false);
+        XMLPortParam(PongScore, "showleftplayer",  setShowLeftPlayer,  getShowLeftPlayer,  xmlelement, mode).defaultValues(false);
+        XMLPortParam(PongScore, "showrightplayer", setShowRightPlayer, getShowRightPlayer, xmlelement, mode).defaultValues(false);
+    }
+
+    void PongScore::tick(float dt)
+    {
+        SUPER(PongScore, tick, dt);
+
+        if (this->owner_)
+        {
+            PlayerInfo* player1 = this->owner_->getLeftPlayer();
+            PlayerInfo* player2 = this->owner_->getRightPlayer();
+
+            std::string name1;
+            std::string name2;
+
+            std::string score1("0");
+            std::string score2("0");
+
+            if (player1)
+            {
+                name1 = player1->getName();
+                score1 = multi_cast<std::string>(this->owner_->getScore(player1));
+            }
+
+            if (player2)
+            {
+                name2 = player2->getName();
+                score2 = multi_cast<std::string>(this->owner_->getScore(player2));
+            }
+
+            std::string output1;
+            if (this->bShowLeftPlayer_)
+            {
+                if (this->bShowName_ && this->bShowScore_ && player1)
+                    output1 = name1 + " - " + score1;
+                else if (this->bShowScore_)
+                    output1 = score1;
+                else if (this->bShowName_)
+                    output1 = name1;
+            }
+
+            std::string output2;
+            if (this->bShowRightPlayer_)
+            {
+                if (this->bShowName_ && this->bShowScore_ && player2)
+                    output2 = score2 + " - " + name2;
+                else if (this->bShowScore_)
+                    output2 = score2;
+                else if (this->bShowName_)
+                    output2 = name2;
+            }
+
+            std::string output("PONG");
+            if (this->bShowName_ || this->bShowScore_)
+            {
+                if (this->bShowLeftPlayer_ && this->bShowRightPlayer_)
+                    output = output1 + ':' + output2;
+                else if (this->bShowLeftPlayer_ || this->bShowRightPlayer_)
+                    output = output1 + output2;
+            }
+
+            this->setCaption(output);
+        }
+    }
+
+
+    void PongScore::changedOwner()
+    {
+        SUPER(PongScore, changedOwner);
+
+        if (this->getOwner() && this->getOwner()->getGametype())
+            this->owner_ = orxonox_cast<Pong*>(this->getOwner()->getGametype().get());
+        else
+            this->owner_ = 0;
+    }
+}
Index: /code/branches/rocket2/src/modules/pong/PongScore.h
===================================================================
--- /code/branches/rocket2/src/modules/pong/PongScore.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/pong/PongScore.h	(revision 6952)
@@ -0,0 +1,77 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PongScore_H__
+#define _PongScore_H__
+
+#include "pong/PongPrereqs.h"
+
+#include "tools/interfaces/Tickable.h"
+#include "overlays/OverlayText.h"
+
+namespace orxonox
+{
+    class _PongExport PongScore : public OverlayText, public Tickable
+    {
+        public:
+            PongScore(BaseObject* creator);
+            virtual ~PongScore();
+
+            virtual void tick(float dt);
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void changedOwner();
+
+            inline void setShowName(bool value)
+                { this->bShowName_ = value; }
+            inline bool getShowName() const
+                { return this->bShowName_; }
+
+            inline void setShowScore(bool value)
+                { this->bShowScore_ = value; }
+            inline bool getShowScore() const
+                { return this->bShowScore_; }
+
+            inline void setShowLeftPlayer(bool value)
+                { this->bShowLeftPlayer_ = value; }
+            inline bool getShowLeftPlayer() const
+                { return this->bShowLeftPlayer_; }
+
+            inline void setShowRightPlayer(bool value)
+                { this->bShowRightPlayer_ = value; }
+            inline bool getShowRightPlayer() const
+                { return this->bShowRightPlayer_; }
+
+        private:
+            Pong* owner_;
+            bool bShowName_;
+            bool bShowScore_;
+            bool bShowLeftPlayer_;
+            bool bShowRightPlayer_;
+    };
+}
+#endif /* _PongScore_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/AddQuest.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/AddQuest.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/AddQuest.cc	(revision 6952)
@@ -0,0 +1,110 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the AddQuest class.
+*/
+
+#include "AddQuest.h"
+
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "QuestManager.h"
+#include "Quest.h"
+
+namespace orxonox
+{
+    CreateFactory(AddQuest);
+
+    /**
+    @brief
+        Constructor. Registers the object.
+    */
+    AddQuest::AddQuest(BaseObject* creator) : ChangeQuestStatus(creator)
+    {
+        RegisterObject(AddQuest);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    AddQuest::~AddQuest()
+    {
+    }
+
+    /**
+    @brief
+        Method for creating a AddQuest object through XML.
+    */
+    void AddQuest::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(AddQuest, XMLPort, xmlelement, mode);
+
+        COUT(4) << "New AddQuest, with target Quest {" << this->getQuestId() << "}, created." << std::endl;
+    }
+
+    /**
+    @brief
+        Invokes the QuestEffect.
+    @param player
+        The player the QuestEffect is invoked on.
+    @return
+        Returns true if the QuestEffect was successfully invoked.
+    */
+    bool AddQuest::invoke(PlayerInfo* player)
+    {
+        if(player == NULL) //!< Null-pointers are badass.
+        {
+            COUT(2) << "Input player is NULL." << std::endl;
+            return false;
+        }
+
+        COUT(5) << "AddQuest on player: " << player << " ." << std::endl;
+
+        try
+        {
+            Quest* quest = QuestManager::getInstance().findQuest(this->getQuestId());
+            if(quest == NULL || !quest->start(player))
+            {
+               return false;
+            }
+        }
+        catch(const orxonox::Exception& ex)
+        {
+            COUT(2) << ex.getFullDescription() << std::endl;
+            return false;
+        }
+
+        COUT(4) << "Quest {" << this->getQuestId() << "} successfully added to player: " << player << " ." << std::endl;
+        return true;
+    }
+
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/AddQuest.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/AddQuest.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/AddQuest.h	(revision 6952)
@@ -0,0 +1,66 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the AddQuest class.
+*/
+
+#ifndef _AddQuest_H__
+#define _AddQuest_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+#include "ChangeQuestStatus.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Adds a Quest, resp. changes the quests status to active for the player invoking the Quest.
+
+        Creating a AddQuest through XML goes as follows:
+
+        <AddQuest questId="id" />  //Where id is a GUID, see http://en.wikipedia.org/wiki/Globally_Unique_Identifier#Basic_structure for more information, and identifies the Quest that should be added.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport AddQuest : public ChangeQuestStatus
+    {
+        public:
+        AddQuest(BaseObject* creator);
+        virtual ~AddQuest();
+
+        virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a AddQuest object through XML.
+
+        virtual bool invoke(PlayerInfo* player); //!< Invokes the QuestEffect.
+
+    };
+
+}
+
+#endif /* _AddQuest_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/AddQuestHint.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/AddQuestHint.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/AddQuestHint.cc	(revision 6952)
@@ -0,0 +1,133 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the AddQuestHint class.
+*/
+
+#include "AddQuestHint.h"
+
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "QuestManager.h"
+#include "QuestItem.h"
+#include "QuestHint.h"
+
+namespace orxonox
+{
+    CreateFactory(AddQuestHint);
+
+    /**
+    @brief
+        Constructor. Registers the object.
+    */
+    AddQuestHint::AddQuestHint(BaseObject* creator) : QuestEffect(creator)
+    {
+        RegisterObject(AddQuestHint);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    AddQuestHint::~AddQuestHint()
+    {
+    }
+
+    /**
+    @brief
+        Method for creating a AddQuestHint object through XML.
+    */
+    void AddQuestHint::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(AddQuestHint, XMLPort, xmlelement, mode);
+
+        XMLPortParam(AddQuestHint, "hintId", setHintId, getHintId, xmlelement, mode);
+
+        COUT(4) << "New AddQuestHint, with target QuestHint {" << this->getHintId() << "}, created." << std::endl;
+    }
+
+    /**
+    @brief
+        Sets the id of the QuestHint to be added to the player the QuestEffect is invoked on.
+    @param id
+        The QuestHint id.
+    @param
+        Returns true if successful.
+    */
+    bool AddQuestHint::setHintId(const std::string & id)
+    {
+        if(id.compare(BLANKSTRING) == 0)
+        {
+            COUT(2) << "Invalid id. QuestItem id {" << id << "} could not be set." << std::endl;
+            return false;
+        }
+
+        this->hintId_ = id;
+        return true;
+    }
+
+    /**
+    @brief
+        Invokes the QuestEffect.
+    @param player
+        The player.
+    @return
+        Returns true if the QuestEffect was successfully invoked.
+    */
+    bool AddQuestHint::invoke(PlayerInfo* player)
+    {
+        if(player == NULL) //!< NULL-pointers are evil!
+        {
+            COUT(2) << "The input player is NULL." << std::endl;
+            return false;
+        }
+
+        COUT(5) << "AddQuestHint on player: " << player << " ." << std::endl;
+
+        try
+        {
+            QuestHint* hint = QuestManager::getInstance().findHint(this->hintId_);
+            if(hint == NULL || !hint->setActive(player))
+            {
+                return false;
+            }
+        }
+        catch(const Exception& e)
+        {
+           COUT(2) << e.getFullDescription() << std::endl;
+           return false;
+        }
+
+        COUT(4) << "QuestHint {" << this->getHintId() << "} successfully added to player: " << player << " ." << std::endl;
+        return true;
+
+    }
+}
Index: /code/branches/rocket2/src/modules/questsystem/AddQuestHint.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/AddQuestHint.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/AddQuestHint.h	(revision 6952)
@@ -0,0 +1,80 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the AddQuestHint class.
+*/
+
+#ifndef _AddQuestHint_H__
+#define _AddQuestHint_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <string>
+#include "QuestEffect.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Adds a QuestHint, resp. activates the QuestHint of the given id for the player the QuestEffect is invoked on.
+
+    Creating a AddQuestHint through XML goes as follows:
+
+        <AddQuestHint hintId="id" />  //Where id is a GUID, see http://en.wikipedia.org/wiki/Globally_Unique_Identifier#Basic_structure for more information, and identifies the QuestHint that should be added.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport AddQuestHint : public QuestEffect
+    {
+        public:
+            AddQuestHint(BaseObject* creator);
+            virtual ~AddQuestHint();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a AddQuestHint object through XML.
+
+            virtual bool invoke(PlayerInfo* player); //!< Invokes the QuestEffect.
+
+        private:
+            std::string hintId_; //!< The id of the QuestHint.
+
+            /**
+            @brief Returns the id of the QuestHint.
+            @return Returns the id of the QuestHint.
+            */
+            inline const std::string & getHintId(void) const
+                { return this->hintId_; }
+
+            bool setHintId(const std::string & id); //!< Sets the id of the QuestHint.
+
+    };
+
+}
+
+#endif /* _AddQuestHint_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/AddReward.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/AddReward.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/AddReward.cc	(revision 6952)
@@ -0,0 +1,118 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the AddReward class.
+*/
+
+#include "AddReward.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "interfaces/Rewardable.h"
+
+namespace orxonox
+{
+    CreateFactory(AddReward);
+
+    /**
+    @brief
+        Constructor. Registers the object.
+    */
+    AddReward::AddReward(BaseObject* creator) : QuestEffect(creator)
+    {
+        RegisterObject(AddReward);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    AddReward::~AddReward()
+    {
+    }
+
+    /**
+        Method for creating a AddReward object through XML.
+    */
+    void AddReward::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(AddReward, XMLPort, xmlelement, mode);
+
+        XMLPortObject(AddReward, Rewardable, "", addRewardable, getRewardables, xmlelement, mode);
+
+        COUT(4) << "New AddReward, with " << this->rewards_.size() << " Rewardables created." << std::endl;
+    }
+
+    /**
+    @brief
+        Returns the Rewardable object at the given index.
+    @param index
+        The index.
+    @return
+        Returns a pointer to the Rewardable object at the given index.
+    */
+    const Rewardable* AddReward::getRewardables(unsigned int index) const
+    {
+        int i = index;
+        for (std::list<Rewardable*>::const_iterator reward = this->rewards_.begin(); reward != this->rewards_.end(); ++reward)
+        {
+            if(i == 0)
+            {
+               return *reward;
+            }
+            i--;
+        }
+        return NULL;
+    }
+
+    /**
+    @brief
+        Invokes the QuestEffect.
+    @param player
+        The player.
+    @return
+        Returns true if the QuestEffect was invoked successfully.
+    */
+    bool AddReward::invoke(PlayerInfo* player)
+    {
+        COUT(5) << "AddReward on player: " << player << " ." << std::endl;
+
+        bool check = true;
+        for ( std::list<Rewardable*>::iterator reward = this->rewards_.begin(); reward != this->rewards_.end(); ++reward )
+        {
+            check = check && (*reward)->reward(player);
+        }
+
+        COUT(4) << "Rewardable successfully added to player." << player << " ." << std::endl;
+
+        return check;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/AddReward.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/AddReward.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/AddReward.h	(revision 6952)
@@ -0,0 +1,84 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the AddReward class.
+*/
+
+#ifndef _AddReward_H__
+#define _AddReward_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <list>
+#include "QuestEffect.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Adds a list of Rewardables to a player.
+
+        Creating a AddReward through XML goes as follows:
+
+        <AddReward>
+            <Rewardable /> //A list of Rewardable objects to be rewarded the player, see the specific Rewardables for their respective XML representations.
+            ...
+            <Rewardable />
+        </AddReward>
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport AddReward : public QuestEffect
+    {
+        public:
+            AddReward(BaseObject* creator);
+            virtual ~AddReward();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a AddReward object through XML.
+
+            virtual bool invoke(PlayerInfo* player); //!< Invokes the QuestEffect.
+
+        private:
+            std::list<Rewardable*> rewards_; //!< A list of Rewardables to be added to the player invoking the QuestEffect.
+
+            /**
+            @brief Add a Rewardable object to the list of objects to be awarded to the player invoking the QuestEffect.
+            @param reward Pointer to the Rewardable to be added.
+            */
+            inline void addRewardable(Rewardable* reward)
+                { this->rewards_.push_back(reward); }
+
+            const Rewardable* getRewardables(unsigned int index) const; //!< Returns the Rewardable object at the given index.
+
+    };
+
+}
+
+#endif /* _AddReward_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,39 @@
+SET_SOURCE_FILES(QUESTSYSTEM_SRC_FILES
+  AddQuest.cc
+  AddQuestHint.cc
+  AddReward.cc
+  ChangeQuestStatus.cc
+  CompleteQuest.cc
+  FailQuest.cc
+  GlobalQuest.cc
+  LocalQuest.cc
+  Quest.cc
+  QuestDescription.cc
+  QuestEffect.cc
+  QuestEffectBeacon.cc
+  QuestGUINode.cc
+  QuestGUI.cc
+  QuestHint.cc
+  QuestItem.cc
+  QuestListener.cc
+  QuestManager.cc
+  QuestNotification.cc
+)
+
+ADD_SUBDIRECTORY(notifications)
+
+ORXONOX_ADD_LIBRARY(questsystem
+  MODULE
+  FIND_HEADER_FILES
+  TOLUA_FILES
+    QuestManager.h
+  DEFINE_SYMBOL
+    "QUESTSYSTEM_SHARED_BUILD"
+  PCH_FILE
+    QuestsystemPrecompiledHeaders.h
+  LINK_LIBRARIES
+    orxonox
+    objects
+    overlays
+  SOURCE_FILES ${QUESTSYSTEM_SRC_FILES}
+)
Index: /code/branches/rocket2/src/modules/questsystem/ChangeQuestStatus.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/ChangeQuestStatus.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/ChangeQuestStatus.cc	(revision 6952)
@@ -0,0 +1,90 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the ChangeQuestStatus class.
+*/
+
+#include "ChangeQuestStatus.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "QuestItem.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Constructor. Registers the object.
+    */
+    ChangeQuestStatus::ChangeQuestStatus(BaseObject* creator) : QuestEffect(creator)
+    {
+        RegisterObject(ChangeQuestStatus);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    ChangeQuestStatus::~ChangeQuestStatus()
+    {
+    }
+
+    /**
+    @brief
+        Method for creating a ChangeQuestStatus object through XML.
+    */
+    void ChangeQuestStatus::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(ChangeQuestStatus, XMLPort, xmlelement, mode);
+
+        XMLPortParam(ChangeQuestStatus, "questId", setQuestId, getQuestId, xmlelement, mode);
+    }
+
+    /**
+    @brief
+        Sets the id of the Quest the Questffect changes the status of.
+    @param id
+        The id of the Quest.
+    @return
+        Returns true if successful.
+    */
+    bool ChangeQuestStatus::setQuestId(const std::string & id)
+    {
+        if(id.compare(BLANKSTRING) == 0)
+        {
+            COUT(2) << "Invalid id. QuestItem id {" << id << "} could not be set." << std::endl;
+            return false;
+        }
+
+        this->questId_ = id;
+        return true;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/ChangeQuestStatus.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/ChangeQuestStatus.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/ChangeQuestStatus.h	(revision 6952)
@@ -0,0 +1,77 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the ChangeQuestStatus class.
+*/
+
+#ifndef _ChangeQuestStatus_H__
+#define _ChangeQuestStatus_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <string>
+#include "QuestEffect.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        A QuestEffect which changes the status of a specified Quest for the player invoking the QuestEffect.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport ChangeQuestStatus : public QuestEffect
+    {
+        public:
+            ChangeQuestStatus(BaseObject* creator);
+            virtual ~ChangeQuestStatus();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a ChangeQuestStatus object through XML.
+
+            virtual bool invoke(PlayerInfo* player) = 0; //!< Invokes the QuestEffect.
+
+        protected:
+            /**
+            @brief Returns the id of the Quest.
+            @return Returns the id of the Quest.
+            */
+            inline const std::string & getQuestId(void) const
+                { return this->questId_; }
+
+        private:
+            std::string questId_; //!< The id of the Quest the status should be changed of.
+
+            bool setQuestId(const std::string & id); //!< Sets the id of the Quest.
+
+    };
+
+}
+
+#endif /* _ChangeQuestStatus_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/CompleteQuest.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/CompleteQuest.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/CompleteQuest.cc	(revision 6952)
@@ -0,0 +1,112 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the CompleteQuest class.
+*/
+
+#include "CompleteQuest.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "QuestManager.h"
+#include "Quest.h"
+
+namespace orxonox
+{
+    CreateFactory(CompleteQuest);
+
+    /**
+    @brief
+        Constructor. Registers the object.
+    */
+    CompleteQuest::CompleteQuest(BaseObject* creator) : ChangeQuestStatus(creator)
+    {
+        RegisterObject(CompleteQuest);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    CompleteQuest::~CompleteQuest()
+    {
+    }
+
+    /**
+    @brief
+        Method for creating a CompleteQuest object through XML.
+    */
+    void CompleteQuest::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(CompleteQuest, XMLPort, xmlelement, mode);
+
+        COUT(4) << "New CompleteQuest, with target Quest {" << this->getQuestId() << "}, created." << std::endl;
+    }
+
+    /**
+    @brief
+        Invokes the QuestEffect.
+    @param player
+        The player the QuestEffect is invoked on.
+    @return
+        Returns true if the QuestEffect was invoked successfully.
+    */
+    bool CompleteQuest::invoke(PlayerInfo* player)
+    {
+        if(player == NULL) //!< You know, what we think of NULL-pointers...
+        {
+            COUT(2) << "Input player is NULL." << std::endl;
+            return false;
+        }
+
+        COUT(5) << "CompleteQuest on player: " << player << " ." << std::endl;
+
+        Quest* quest;
+
+        try
+        {
+            quest = QuestManager::getInstance().findQuest(this->getQuestId());
+            if(quest == NULL || !quest->complete(player))
+            {
+               return false;
+            }
+        }
+        catch(const Exception& e)
+        {
+            COUT(2) << e.getFullDescription() << std::endl;
+            return false;
+        }
+
+        COUT(4) << "Quest {" << quest->getId() << "} successfully completed by player: " << player << " ." << std::endl;
+        return true;
+    }
+
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/CompleteQuest.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/CompleteQuest.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/CompleteQuest.h	(revision 6952)
@@ -0,0 +1,66 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the CompleteQuest class.
+*/
+
+#ifndef _CompleteQuest_H__
+#define _CompleteQuest_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+#include "ChangeQuestStatus.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Completes a Quest (with a specified id) for the player invoking the QuestEffect.
+
+        Creating a CompleteQuest through XML goes as follows:
+
+        <CompleteQuest questId="id" />  //Where id is a GUID, see http://en.wikipedia.org/wiki/Globally_Unique_Identifier#Basic_structure for more information, and identifies the Quest that should be completed.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport CompleteQuest : public ChangeQuestStatus
+    {
+        public:
+            CompleteQuest(BaseObject* creator);
+            virtual ~CompleteQuest();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a CompleteQuest object through XML.
+
+            virtual bool invoke(PlayerInfo* player); //!< Invokes the QuestEffect.
+
+    };
+
+}
+
+#endif /* _CompleteQuest_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/FailQuest.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/FailQuest.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/FailQuest.cc	(revision 6952)
@@ -0,0 +1,111 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the FailQuest class.
+*/
+
+#include "FailQuest.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "QuestManager.h"
+#include "Quest.h"
+
+namespace orxonox
+{
+    CreateFactory(FailQuest);
+
+    /**
+    @brief
+        Constructor. Registers the object.
+    */
+    FailQuest::FailQuest(BaseObject* creator) : ChangeQuestStatus(creator)
+    {
+        RegisterObject(FailQuest);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    FailQuest::~FailQuest()
+    {
+    }
+
+    /**
+    @brief
+        Method for creating a FailQuest object through XML.
+    */
+    void FailQuest::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(FailQuest, XMLPort, xmlelement, mode);
+
+        COUT(4) << "New FailQUest, with target Quest {" << this->getQuestId() << "}, created." << std::endl;
+    }
+
+    /**
+    @brief
+        Invokes the QuestEffect.
+    @param player
+        The player the QuestEffect is invoked on.
+    @return
+        Returns true if the QuestEffect was invoked successfully.
+    */
+    bool FailQuest::invoke(PlayerInfo* player)
+    {
+        if(player == NULL) //!< We don't know what to do with no player.
+        {
+            COUT(2) << "Input player is NULL." << std::endl;
+            return false;
+        }
+
+        COUT(4) << "FailQuest on player: " << player << " ." << std::endl;
+
+        Quest* quest;
+        try
+        {
+            quest = QuestManager::getInstance().findQuest(this->getQuestId());
+            if(quest == NULL || !quest->fail(player))
+            {
+               return false;
+            }
+        }
+        catch(const Exception& e)
+        {
+            COUT(2) << e.getFullDescription() << std::endl;
+            return false;
+        }
+
+        COUT(4) << "Quest {" << quest->getId() << "} failed by player: " << player << " ." << std::endl;
+        return true;
+    }
+
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/FailQuest.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/FailQuest.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/FailQuest.h	(revision 6952)
@@ -0,0 +1,66 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the FailQuest class.
+*/
+
+#ifndef _FailQuest_H__
+#define _FailQuest_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+#include "ChangeQuestStatus.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Fails a quest (with a specified id) for the player invoking the QuestEffect.
+
+        Creating a FailQuest through XML goes as follows:
+
+        <FailQuest questId="id" />  //Where id is a GUID, see http://en.wikipedia.org/wiki/Globally_Unique_Identifier#Basic_structure for more information, and identifies the Quest that should be failed.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport FailQuest : public ChangeQuestStatus
+    {
+        public:
+            FailQuest(BaseObject* creator);
+            virtual ~FailQuest();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a FailQuest object through XML.
+
+            virtual bool invoke(PlayerInfo* player); //!< Invokes the QuestEffect.
+
+    };
+
+}
+
+#endif /* _FailQuest_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/GlobalQuest.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/GlobalQuest.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/GlobalQuest.cc	(revision 6952)
@@ -0,0 +1,282 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the GlobalQuest class.
+*/
+
+#include "GlobalQuest.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "QuestEffect.h"
+
+namespace orxonox
+{
+    CreateFactory(GlobalQuest);
+
+    /**
+    @brief
+        Constructor. Registers the object.
+    */
+    GlobalQuest::GlobalQuest(BaseObject* creator) : Quest(creator)
+    {
+        RegisterObject(GlobalQuest);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    GlobalQuest::~GlobalQuest()
+    {
+
+    }
+
+    /**
+    @brief
+        Method for creating a GlobalQuest object through XML.
+    */
+    void GlobalQuest::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(GlobalQuest, XMLPort, xmlelement, mode);
+
+        XMLPortObject(GlobalQuest, QuestEffect, "reward-effects", addRewardEffect, getRewardEffects, xmlelement, mode);
+
+        COUT(4) << "New GlobalQuest {" << this->getId() << "} created." << std::endl;
+    }
+
+    /**
+    @brief
+        Fails the Quest for all players.
+        Invokes the fail QuestEffects on all the players possessing this Quest.
+    @param player
+        The player failing it.
+    @return
+        Returns true if the Quest could be failed, false if not.
+    */
+    bool GlobalQuest::fail(PlayerInfo* player)
+    {
+        if(!this->isFailable(player)) //!< Check whether the Quest can be failed.
+        {
+            COUT(4) << "A non-completable quest was trying to be failed." << std::endl;
+            return false;
+        }
+
+        Quest::fail(player);
+
+    //! Iterate through all players possessing this Quest.
+    for(std::set<PlayerInfo*>::const_iterator it = players_.begin(); it != players_.end(); it++)
+    {
+        QuestEffect::invokeEffects(*it, this->getFailEffectList());
+    }
+
+    return true;
+    }
+
+    /**
+    @brief
+        Completes the Quest for all players.
+        Invokes the complete QuestEffects on all the players possessing this Quest.
+        Invokes the reward QuestEffects on the player completing the Quest.
+    @param player
+        The player completing it.
+    @return
+        Returns true if the Quest could be completed, false if not.
+    */
+    bool GlobalQuest::complete(PlayerInfo* player)
+    {
+        if(!this->isCompletable(player)) //!< Check whether the Quest can be completed.
+        {
+            COUT(4) << "A non-completable quest was trying to be completed." << std::endl;
+            return false;
+        }
+
+        //! Iterate through all players possessing the Quest.
+        for(std::set<PlayerInfo*>::const_iterator it = players_.begin(); it != players_.end(); it++)
+        {
+            QuestEffect::invokeEffects(*it, this->getCompleteEffectList());
+        }
+
+        Quest::complete(player);
+
+        QuestEffect::invokeEffects(player, this->rewards_); //!< Invoke reward QuestEffects on the player completing the Quest.
+        return true;
+    }
+
+    /**
+    @brief
+        Checks whether the Quest can be started.
+    @param player
+        The player for whom is to be checked.
+    @return
+        Returns true if the quest can be started, false if not.
+    @throws
+        Throws an exception if either isInactive() of isActive() throws one.
+    */
+    bool GlobalQuest::isStartable(const PlayerInfo* player) const
+    {
+        if(!(this->getParentQuest() == NULL || this->getParentQuest()->isActive(player)))
+        {
+            return false;
+        }
+        return (this->isInactive(player) && !(this->status_ == QuestStatus::Completed || this->status_ == QuestStatus::Failed));
+    }
+
+    /**
+    @brief
+        Checks whether the Quest can be failed.
+    @param player
+        The player for whom is to be checked.
+    @return
+        Returns true if the Quest can be failed, false if not.
+    @throws
+        Throws an Exception if isActive() throws one.
+    */
+    bool GlobalQuest::isFailable(const PlayerInfo* player) const
+    {
+        return this->isActive(player);
+
+    }
+
+    /**
+    @brief
+        Checks whether the Quest can be completed.
+    @param player
+        The player for whom is to be checked.
+    @return
+        Returns true if the Quest can be completed, false if not.
+    @throws
+        Throws an Exception if isActive() throws one.
+    */
+    bool GlobalQuest::isCompletable(const PlayerInfo* player) const
+    {
+        return this->isActive(player);
+    }
+
+    /**
+    @brief
+        Returns the status of the Quest for a specific player.
+    @param player
+        The player.
+    @throws
+        Throws an Exception if player is NULL.
+    */
+    QuestStatus::Value GlobalQuest::getStatus(const PlayerInfo* player) const
+    {
+        if(player == NULL) //!< We don't want NULL-Pointers!
+        {
+            ThrowException(Argument, "The input PlayerInfo* is NULL.");
+        }
+
+        //! Find the player.
+        std::set<PlayerInfo*>::const_iterator it = this->players_.find((PlayerInfo*)(void*)player);
+        if (it != this->players_.end()) //!< If the player was found.
+        {
+            return this->status_;
+        }
+
+        return QuestStatus::Inactive;
+    }
+
+    /**
+    @brief
+        Sets the status for a specific player.
+        But be careful wit this one, the status will just be set without checking for its validity. You have to know what you're doing.
+    @param player
+        The player.
+    @param status
+        The status to be set.
+    @return
+        Returns false if player is NULL.
+    */
+    bool GlobalQuest::setStatus(PlayerInfo* player, const QuestStatus::Value & status)
+    {
+        if(player == NULL) //!< We don't want NULL-Pointers!
+        {
+            return false;
+        }
+
+        //! Find the player.
+        std::set<PlayerInfo*>::const_iterator it = this->players_.find(player);
+        if (it == this->players_.end()) //!< Player is not yet in the list.
+        {
+            this->players_.insert(player); //!< Add the player to the set.
+        }
+
+        this->status_ = status; //!< Set the status, which is global, remember...?
+        return true;
+    }
+
+    /**
+    @brief
+        Adds a reward QuestEffect to the list of reward QuestEffects.
+    @param effect
+        The QuestEffect to be added.
+    @return
+        Returns true if successful.
+    */
+    bool GlobalQuest::addRewardEffect(QuestEffect* effect)
+    {
+        if(effect == NULL) //!< We don't want NULL-Pointers!
+        {
+            COUT(2) << "The reward effect to be added to quest {" << this->getId() << "} was NULL." << std::endl;
+            return false;
+        }
+
+        this->rewards_.push_back(effect); //!< Add the QuestEffect to the list.
+
+        COUT(4) << "Reward effect was added to Quest {" << this->getId() << "}." << std::endl;
+        return true;
+    }
+
+    /**
+    @brief
+        Returns the reward QuestEffect at the given index.
+    @param index
+        The index.
+    @return
+        Returns the QuestEffect at the given index.
+    */
+    const QuestEffect* GlobalQuest::getRewardEffects(unsigned int index) const
+    {
+        int i = index;
+        for (std::list<QuestEffect*>::const_iterator effect = this->rewards_.begin(); effect != this->rewards_.end(); ++effect)
+        {
+            if(i == 0)
+            {
+               return *effect;
+            }
+            i--;
+        }
+        return NULL;
+    }
+
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/GlobalQuest.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/GlobalQuest.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/GlobalQuest.h	(revision 6952)
@@ -0,0 +1,115 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the GlobalQuest class.
+*/
+
+#ifndef _GlobalQuest_H__
+#define _GlobalQuest_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <list>
+#include <set>
+#include "Quest.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        GlobalQuests are Quests, that have the same status for all players.
+        This means, that when a player successfully completes a GlobalQuest, it is completed for all players that have it.
+
+        Creating a GlobalQuest through XML goes as follows:
+
+        <GlobalQuest id="questId"> //Where questId is a GUID, see http://en.wikipedia.org/wiki/Globally_Unique_Identifier#Basic_structure for more information
+            <QuestDescription title="Title" description="Description." /> //The description of the quest.
+            <subquests>
+                <Quest id ="questId1" /> //A list of n subquest, be aware, each of the <Quest /> tags must have a description and so on and so forth as well.
+                ...
+                <Quest id="questIdn" />
+            </subquests>
+            <hints>
+                <QuestHint id="hintId1" /> //A list of n QuestHints, see QuestHint for the full XML representation of those.
+                ...
+                <QuestHint id="hintIdn" />
+            </hints>
+            <fail-effects>
+                <QuestEffect /> //A list of QuestEffects, invoked on all players possessing this quest, when the Quest is failed, see QuestEffect for the full XML representation.
+                ...
+                <QuestEffect />
+            </fail-effects>
+            <complete-effects>
+                <QuestEffect /> //A list of QuestEffects, invoked on all players possessing this quest, when the Quest is completed, see QuestEffect for the full XML representation.
+                ...
+                <QuestEffect />
+            </complete-effects>
+            <reward-effects>
+                <QuestEffect /> //A list of QuestEffects, invoked on the player completing this quest. See QuestEffect for the full XML representation.
+                ...
+                <QuestEffect />
+            </reward-effects>
+        </GlobalQuest>
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport GlobalQuest : public Quest
+    {
+        public:
+            GlobalQuest(BaseObject* creator);
+            virtual ~GlobalQuest();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a GlobalQuest object through XML.
+
+            virtual bool fail(PlayerInfo* player); //!< Fails the Quest.
+            virtual bool complete(PlayerInfo* player); //!< Completes the Quest.
+
+        protected:
+            virtual bool isStartable(const PlayerInfo* player) const; //!< Checks whether the Quest can be started.
+            virtual bool isFailable(const PlayerInfo* player) const; //!< Checks whether the Quest can be failed.
+            virtual bool isCompletable(const PlayerInfo* player) const; //!< Checks whether the Quest can be completed.
+
+            virtual QuestStatus::Value getStatus(const PlayerInfo* player) const; //!< Returns the status of the Quest for a specific player.
+
+            virtual bool setStatus(PlayerInfo* player, const QuestStatus::Value & status); //!< Sets the status for a specific player.
+
+        private:
+            std::set<PlayerInfo*> players_; //!< The set of players which possess this Quest.
+            QuestStatus::Value status_; //!< The status of this Quest.
+            std::list<QuestEffect*> rewards_; //!< Reward QuestEffects only invoked on the player completing the Quest.
+
+            bool addRewardEffect(QuestEffect* effect); //!< Adds a reward QuestEffect to the list of reward QuestEffects.
+            const QuestEffect* getRewardEffects(unsigned int index) const; //!< Returns the reward QuestEffect at the given index.
+
+    };
+
+}
+
+#endif /* _GlobalQuest_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/LocalQuest.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/LocalQuest.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/LocalQuest.cc	(revision 6952)
@@ -0,0 +1,216 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the LocalQuest class.
+*/
+
+#include "LocalQuest.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "QuestEffect.h"
+
+namespace orxonox
+{
+    CreateFactory(LocalQuest);
+
+    /**
+    @brief
+        Constructor. Registers and initializes the object.
+    */
+    LocalQuest::LocalQuest(BaseObject* creator) : Quest(creator)
+    {
+        RegisterObject(LocalQuest);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    LocalQuest::~LocalQuest()
+    {
+
+    }
+
+    /**
+    @brief
+        Method for creating a LocalQuest object through XML.
+    */
+    void LocalQuest::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(LocalQuest, XMLPort, xmlelement, mode);
+
+        COUT(4) << "New LocalQuest {" << this->getId() << "} created." << std::endl;
+    }
+
+    /**
+    @brief
+        Fails the Quest for a given player.
+        Invokes all the failEffects on the player.
+    @param player
+        The player.
+    @return
+        Returns true if the Quest could be failed, false if not.
+    */
+    bool LocalQuest::fail(PlayerInfo* player)
+    {
+        if(!this->isFailable(player)) //!< Checks whether the quest can be failed.
+        {
+            COUT(4) << "A non-failable quest was trying to be failed." << std::endl;
+            return false;
+        }
+
+        Quest::fail(player);
+
+        QuestEffect::invokeEffects(player, this->getFailEffectList()); //!< Invoke the failEffects.
+        return true;
+    }
+
+    /**
+    @brief
+        Completes the Quest for a given player.
+    Invokes all the complete QuestEffects on the player.
+    @param player
+        The player.
+    @return
+        Returns true if the Quest could be completed, false if not.
+    */
+    bool LocalQuest::complete(PlayerInfo* player)
+    {
+        if(!this->isCompletable(player)) //!< Checks whether the Quest can be completed.
+        {
+            COUT(4) << "A non-completable quest was trying to be completed." << std::endl;
+            return false;
+        }
+
+        Quest::complete(player);
+
+        QuestEffect::invokeEffects(player, this->getCompleteEffectList()); //!< Invoke the complete QuestEffects.
+        return true;
+    }
+
+    /**
+    @brief
+        Checks whether the Quest can be started.
+    @param player
+        The player for whom is to be checked.
+    @return
+        Returns true if the Quest can be started, false if not.
+    @throws
+        Throws an exception if isInactive(PlayerInfo*) throws one.
+    */
+    bool LocalQuest::isStartable(const PlayerInfo* player) const
+    {
+        if(!(this->getParentQuest() == NULL || this->getParentQuest()->isActive(player)))
+        {
+            return false;
+        }
+        return this->isInactive(player);
+    }
+
+    /**
+    @brief
+        Checks whether the Quest can be failed.
+    @param player
+        The player for whom is to be checked.
+    @return
+        Returns true if the Quest can be failed, false if not.
+    @throws
+        Throws an exception if isActive(PlayerInfo*) throws one.
+    */
+    bool LocalQuest::isFailable(const PlayerInfo* player) const
+    {
+        return this->isActive(player);
+    }
+
+    /**
+    @brief
+        Checks whether the Quest can be completed.
+    @param player
+        The player for whom is to be checked.
+    @return
+        Returns true if the Quest can be completed, false if not.
+    @throws
+        Throws an exception if isInactive(PlayerInfo*) throws one.
+    */
+    bool LocalQuest::isCompletable(const PlayerInfo* player) const
+    {
+        return this->isActive(player);
+    }
+
+    /**
+    @brief
+        Returns the status of the Quest for a specific player.
+    @param player
+        The player.
+    @return
+        Returns the status of the Quest for the input player.
+    @throws
+        Throws an Exception if player is NULL.
+    */
+    QuestStatus::Value LocalQuest::getStatus(const PlayerInfo* player) const
+    {
+        if(player == NULL) //!< No player has no defined status.
+        {
+            ThrowException(Argument, "The input PlayerInfo* is NULL.");
+        }
+
+        std::map<const PlayerInfo*, QuestStatus::Value>::const_iterator it = this->playerStatus_.find(player);
+        if (it != this->playerStatus_.end()) //!< If there is a player in the map.
+        {
+            return it->second;
+        }
+
+        return QuestStatus::Inactive; //!< If the player is not yet in the map, that means the status of the quest form him is 'inactive'.
+    }
+
+    /**
+    @brief
+        Sets the status for a specific player.
+        But be careful wit this one, the status will just be set without checking for its validity. You have to know what you're doing. Really!
+    @param player
+        The player the status should be set for.
+    @param status
+        The status to be set.
+    @return
+        Returns false if player is NULL.
+    */
+    bool LocalQuest::setStatus(PlayerInfo* player, const QuestStatus::Value & status)
+    {
+        if(player == NULL) //!< We can't set a status for no player.
+        {
+            return false;
+        }
+
+        this->playerStatus_[player] = status;
+        return true;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/LocalQuest.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/LocalQuest.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/LocalQuest.h	(revision 6952)
@@ -0,0 +1,103 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the LocalQuest class.
+*/
+
+#ifndef _LocalQuest_H__
+#define _LocalQuest_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <map>
+#include "Quest.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Handles Quests which have different states for different players.
+        LocalQuests have (as opposed to GlobalQuests) a different state for each player, that means if for one player the status of the Quest changes it does not for all the other players which also possess this quest.
+
+        Creating a LocalQuest through XML goes as follows:
+
+        <LocalQuest id="questId"> //Where questId is a GUID, see http://en.wikipedia.org/wiki/Globally_Unique_Identifier#Basic_structure for more information
+            <QuestDescription title="Title" description="Description." /> //The description of the quest.
+            <subquests>
+                <Quest id ="questId1" /> //A list of n subquest, be aware, each of the <Quest /> tags must have a description and so on and so forth as well.
+                ...
+                <Quest id="questIdn" />
+                </subquests>
+                <hints>
+                <QuestHint id="hintId1" /> //A list of n QuestHints, see QuestHint for the full XML representation of those.
+                ...
+                <QuestHint id="hintIdn" />
+                </hints>
+            <fail-effects>
+                <QuestEffect /> //A list of QuestEffects, invoked when the Quest is failed, see QuestEffect for the full XML representation.
+                ...
+                <QuestEffect />
+            </fail-effects>
+            <complete-effects>
+                <QuestEffect /> //A list of QuestEffects, invoked when the Quest is completed, see QuestEffect for the full XML representation.
+                ...
+                <QuestEffect />
+            </complete-effects>
+        </LocalQuest>
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport LocalQuest : public Quest
+    {
+        public:
+            LocalQuest(BaseObject* creator);
+            virtual ~LocalQuest();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a LocalQuest object through XML.
+
+            virtual bool fail(PlayerInfo* player); //!< Fails the Quest.
+            virtual bool complete(PlayerInfo* player); //!< Completes the Quest.
+
+        protected:
+            virtual bool isStartable(const PlayerInfo* player) const; //!< Checks whether the Quest can be started.
+            virtual bool isFailable(const PlayerInfo* player) const; //!< Checks whether the Quest can be failed.
+            virtual bool isCompletable(const PlayerInfo* player) const; //!< Checks whether the Quest can be completed.
+
+            virtual QuestStatus::Value getStatus(const PlayerInfo* player) const; //!< Returns the status of the Quest for a specific player.
+            virtual bool setStatus(PlayerInfo* player, const QuestStatus::Value & status); //!< Sets the status for a specific player.
+
+        private:
+            std::map<const PlayerInfo*, QuestStatus::Value> playerStatus_; //!< List of the status for each player, with the Player-pointer as key.
+
+    };
+
+}
+
+#endif /* _LocalQuest_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/Quest.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/Quest.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/Quest.cc	(revision 6952)
@@ -0,0 +1,438 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the Quest class.
+*/
+
+#include "Quest.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "QuestManager.h"
+#include "QuestDescription.h"
+#include "QuestHint.h"
+#include "QuestEffect.h"
+#include "QuestListener.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Constructor. Registers and initializes object.
+    */
+    Quest::Quest(BaseObject* creator) : QuestItem(creator)
+    {
+        RegisterObject(Quest);
+
+        this->parentQuest_ = NULL;
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    Quest::~Quest()
+    {
+        if(this->isRegistered())
+            QuestManager::getInstance().unregisterQuest(this);
+    }
+
+    /**
+    @brief
+        Method for creating a Quest object through XML.
+    */
+    void Quest::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Quest, XMLPort, xmlelement, mode);
+
+        XMLPortObject(Quest, Quest, "subquests", addSubQuest, getSubQuest, xmlelement, mode);
+        XMLPortObject(Quest, QuestHint, "hints", addHint, getHint, xmlelement, mode);
+        XMLPortObject(Quest, QuestEffect, "fail-effects", addFailEffect, getFailEffect, xmlelement, mode);
+        XMLPortObject(Quest, QuestEffect, "complete-effects", addCompleteEffect, getCompleteEffect, xmlelement, mode);
+
+        QuestManager::getInstance().registerQuest(this); //!<Registers the Quest with the QuestManager.
+    }
+
+    /**
+    @brief
+        Sets the parentquest of the Quest.
+    @param quest
+        A pointer to the Quest to be set as parentquest.
+    @return
+        Returns true if the parentquest could be set.
+    */
+    bool Quest::setParentQuest(Quest* quest)
+    {
+        if(quest == NULL) //!< We don't want to set NULL-Pointers.
+        {
+            COUT(2) << "The parentquest to be added to quest {" << this->getId() << "} was NULL." << std::endl;
+            return false;
+        }
+
+        this->parentQuest_ = quest;
+
+        COUT(4) << "Parent Quest {" << quest->getId() << "} was added to Quest {" << this->getId() << "}." << std::endl;
+        return true;
+    }
+
+    /**
+    @brief
+        Adds a subquest to the Quest.
+    @param quest
+        A pointer to the Quest to be set as subquest.
+    @return
+        Returns true if the subquest could be set.
+    */
+    bool Quest::addSubQuest(Quest* quest)
+    {
+        if(quest == NULL) //!< We don't want to set NULL-Pointers.
+        {
+            COUT(2) << "The subquest to be added to quest {" << this->getId() << "} was NULL." << std::endl;
+            return false;
+        }
+
+        quest->setParentQuest(this); //!< Sets the currentQuest (this) as parentquest for the added subquest.
+        this->subQuests_.push_back(quest); //!< Adds the Quest to the end of the list of subquests.
+
+        COUT(4) << "Sub Quest {" << quest->getId() << "} was added to Quest {" << this->getId() << "}." << std::endl;
+        return true;
+    }
+
+
+    /**
+    @brief
+        Adds a QuestHint to the list of QuestHints
+    @param hint
+        The QuestHint that should be added to the list of QuestHints.
+    @return
+        Returns true if the hint was successfully added.
+    */
+    bool Quest::addHint(QuestHint* hint)
+    {
+        if(hint == NULL) //!< We don't want to set NULL-Pointers. Seriously!
+        {
+            COUT(2) << "A NULL-QuestHint was trying to be added." << std::endl;
+            return false;
+        }
+
+        hint->setQuest(this); //!< Sets the current Quest (this) as Quest for the added QuestHint.
+        this->hints_.push_back(hint); //!< Adds the QuestHint to the end of the list of QuestHints.
+
+        COUT(4) << "QuestHint {" << hint->getId() << "} was added to Quest {" << this->getId() << "}." << std::endl;
+        return true;
+    }
+
+    /**
+    @brief
+        Adds an QuestEffect to the list of fail QuestEffects.
+    @param effect
+        The QuestEffect to be added.
+    @return
+        Returns true if successful.
+    */
+    bool Quest::addFailEffect(QuestEffect* effect)
+    {
+        if(effect == NULL) //!< We don't want to set NULL-Pointers.
+        {
+            COUT(2) << "A NULL-QuestEffect was trying to be added" << std::endl;
+            return false;
+        }
+
+        this->failEffects_.push_back(effect); //!< Adds the QuestEffect to the end of the list of fail QuestEffects.
+
+        COUT(4) << "A FailEffect was added to Quest {" << this->getId() << "}." << std::endl;
+        return true;
+    }
+
+    /**
+    @brief
+        Adds an QuestEffect to the list of complete QuestEffects.
+    @param effect
+        The QuestEffect to be added.
+    @return
+        Returns true if successful.
+    */
+    bool Quest::addCompleteEffect(QuestEffect* effect)
+    {
+        if(effect == NULL) //!< We don't want to set NULL-Pointers.
+        {
+            COUT(2) << "A NULL-QuestEffect was trying to be added" << std::endl;
+            return false;
+        }
+
+        this->completeEffects_.push_back(effect); //!< Adds the QuestEffect to the end of the list of complete QuestEffects.
+
+        COUT(4) << "A CompleteEffect was added to Quest {" << this->getId() << "}." << std::endl;
+        return true;
+    }
+
+    /**
+    @brief
+        Returns the subquest at the given index.
+    @param
+        The index.
+    @return
+        Returns a pointer to the subquest at the given index. NULL if there is no element at the given index.
+    */
+    const Quest* Quest::getSubQuest(unsigned int index) const
+    {
+        int i = index;
+
+        //! Iterate through all subquests.
+        for (std::list<Quest*>::const_iterator subQuest = this->subQuests_.begin(); subQuest != this->subQuests_.end(); ++subQuest)
+        {
+            if(i == 0) //!< We're counting down...
+            {
+               return *subQuest;
+            }
+            i--;
+        }
+
+        return NULL; //!< If the index is greater than the number of elements in the list.
+    }
+
+    /**
+    @brief
+        Returns the QuestHint at the given index.
+    @param
+        The index.
+    @return
+        Returns a pointer to the QuestHint at the given index. NULL if there is no element at the given index.
+    */
+    const QuestHint* Quest::getHint(unsigned int index) const
+    {
+        int i = index;
+
+        //! Iterate through all QuestHints.
+        for (std::list<QuestHint*>::const_iterator hint = this->hints_.begin(); hint != this->hints_.end(); ++hint)
+        {
+            if(i == 0) //!< We're counting down...
+            {
+               return *hint;
+            }
+            i--;
+        }
+        return NULL; //!< If the index is greater than the number of elements in the list.
+    }
+
+    /**
+    @brief
+        Returns the fail QuestEffect at the given index.
+    @param
+        The index.
+    @return
+        Returns a pointer to the fail QuestEffect at the given index. NULL if there is no element at the given index.
+    */
+    const QuestEffect* Quest::getFailEffect(unsigned int index) const
+    {
+        int i = index;
+
+        //! Iterate through all fail QuestEffects.
+        for (std::list<QuestEffect*>::const_iterator effect = this->failEffects_.begin(); effect != this->failEffects_.end(); ++effect)
+        {
+            if(i == 0) //!< We're counting down...
+            {
+               return *effect;
+            }
+            i--;
+        }
+        return NULL; //!< If the index is greater than the number of elements in the list.
+    }
+
+    /**
+    @brief
+        Returns the complete QuestEffect at the given index.
+    @param
+        The index.
+    @return
+        Returns a pointer to the complete QuestEffect at the given index. NULL if there is no element at the given index.
+    */
+    const QuestEffect* Quest::getCompleteEffect(unsigned int index) const
+    {
+        int i = index;
+
+        //! Iterate through all complete QuestEffects.
+        for (std::list<QuestEffect*>::const_iterator effect = this->completeEffects_.begin(); effect != this->completeEffects_.end(); ++effect)
+        {
+            if(i == 0) //!< We're counting down...
+            {
+               return *effect;
+            }
+            i--;
+        }
+        return NULL; //!< If the index is greater than the number of elements in the list.
+    }
+
+    /**
+    @brief
+        Returns true if the quest status for the specific player is 'inactive'.
+    @param player
+        The player.
+    @return
+        Returns true if the quest status for the specific player is 'inactive'.
+    @throws
+        Throws an exception if getStatus throws one.
+    */
+    bool Quest::isInactive(const PlayerInfo* player) const
+    {
+        return this->getStatus(player) == QuestStatus::Inactive;
+    }
+
+    /**
+    @brief
+        Returns true if the quest status for the specific player is 'active'.
+    @param player
+        The player.
+    @return
+        Returns true if the quest status for the specific player is 'active'.
+    @throws
+        Throws an exception if getStatus throws one.
+    */
+    bool Quest::isActive(const PlayerInfo* player) const
+    {
+
+        return this->getStatus(player) == QuestStatus::Active;
+    }
+
+    /**
+    @brief
+        Returns true if the quest status for the specific player is 'failed'.
+    @param player
+        The player.
+    @return
+        Returns true if the quest status for the specific player is 'failed'.
+    @throws
+        Throws an exception if getStatus throws one.
+    */
+    bool Quest::isFailed(const PlayerInfo* player) const
+    {
+        return this->getStatus(player) == QuestStatus::Failed;
+    }
+
+    /**
+    @brief
+        Returns true if the quest status for the specific player is 'completed'.
+    @param player
+        The player.
+    @return
+        Returns true if the quest status for the specific player is 'completed'.
+    @throws
+        Throws an exception if getStatus throws one.
+    */
+    bool Quest::isCompleted(const PlayerInfo* player) const
+    {
+        return this->getStatus(player) == QuestStatus::Completed;
+    }
+
+    /**
+    @brief
+        Fails the Quest for an input player.
+    @param player
+        The player.
+    @return
+        Returns true if the Quest could be failed, false if not.
+    */
+    bool Quest::fail(PlayerInfo* player)
+    {
+        QuestListener::advertiseStatusChange(this->listeners_, "fail"); //!< Tells the QuestListeners, that the status has changed to failed.
+        this->setStatus(player, QuestStatus::Failed);
+
+        COUT(4) << "Quest {" << this->getId() << "} is failed for player: " << player << " ." <<std::endl;
+
+        this->getDescription()->sendFailQuestNotification();
+        return true;
+    }
+
+    /**
+    @brief
+        Completes the Quest for an input player.
+    @param player
+        The player.
+    @return
+        Returns true if the Quest could be completed, false if not.
+    */
+    bool Quest::complete(PlayerInfo* player)
+    {
+        QuestListener::advertiseStatusChange(this->listeners_, "complete"); //!< Tells the QuestListeners, that the status has changed to completed.
+        this->setStatus(player, QuestStatus::Completed);
+
+        COUT(4) << "Quest {" << this->getId() << "} is completed for player: " << player << " ." <<std::endl;
+
+        this->getDescription()->sendCompleteQuestNotification();
+        return true;
+    }
+
+    /**
+    @brief
+        Starts the Quest for an input player.
+    @param player
+        The player.
+    @return
+        Returns true if the Quest could be started, false if not.
+    */
+    bool Quest::start(PlayerInfo* player)
+    {
+        if(!this->isStartable(player)) //!< Checks whether the quest can be started.
+        {
+            COUT(4) << "A non-startable quest was trying to be started." << std::endl;
+            return false;
+        }
+
+        COUT(4) << "Quest {" << this->getId() << "} is started for player: " << player << " ." <<std::endl;
+
+        QuestListener::advertiseStatusChange(this->listeners_, "start"); //!< Tells the QuestListeners, that the status has changed to active.
+
+        this->setStatus(player, QuestStatus::Active);
+
+        this->getDescription()->sendAddQuestNotification();
+        return true;
+    }
+
+    /**
+    @brief
+        Adds a QuestListener to the list of QuestListeners listening to this Quest.
+    @param listener
+        The QuestListener to be added.
+    @return
+        Returns true if successful, false if not.
+    */
+    bool Quest::addListener(QuestListener* listener)
+    {
+        if(listener == NULL)
+        {
+            COUT(2) << "A NULL-QuestListener was trying to be added to a Quests listeners." << std::endl;
+            return false;
+        }
+
+        this->listeners_.push_back(listener);
+        return true;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/Quest.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/Quest.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/Quest.h	(revision 6952)
@@ -0,0 +1,157 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the Quest class.
+        The Quest is the parent class of LocalQuest and GlobalQuest.
+*/
+
+#ifndef _Quest_H__
+#define _Quest_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <list>
+#include "QuestItem.h"
+
+namespace orxonox
+{
+    namespace QuestStatus
+    {
+        //!Different states of a Quest.
+        enum Value
+        {
+            Inactive,
+            Active,
+            Failed,
+            Completed
+        };
+    }
+
+    /**
+    @brief
+        Represents a Quest in the game.
+        A Quest has a list of subquests and a parentquest (if it is not a rootquest).
+        Each Quest exists only once but it has a different status (inactive, active, failed or completed) for each player.
+        A Quest has several hints (QuestHint) that can be unlocked through QuestEffects and then display aid in solving the Quest.
+        A Quest has a list of QuestEffects that are invoked when the quest is failed and also a list of QuestEffects that are invoked, when the Quest is completed.
+
+        Quest itself should not be instantiated, if you want to create a quest either go for LocalQuest or GlobalQuest, whichever suits you needs better.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport Quest : public QuestItem
+    {
+        public:
+            Quest(BaseObject* creator);
+            virtual ~Quest();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a Quest object through XML.
+
+            /**
+            @brief Returns the parentquest of the Quest.
+            @return Returns a pointer to the parentquest of the Quest.
+            */
+            inline Quest* getParentQuest(void) const
+                { return this->parentQuest_; }
+
+            /**
+            @brief Returns the list of subquests.
+            @return Returns a reference to the list of subquests of the quest.
+            */
+            inline const std::list<Quest*> & getSubQuestList(void) const
+                { return this->subQuests_; }
+
+            /**
+            @brief Returns the list of all QuestHints of this Quest.
+            @return Returns a reference to the list of QuestHints of the Quest.
+            */
+            inline const std::list<QuestHint*> & getHintsList(void) const
+                { return this->hints_; }
+
+            bool isInactive(const PlayerInfo* player) const; //!< Returns true if the quest status for the specific player is 'inactive'.
+            bool isActive(const PlayerInfo* player) const; //!< Returns true if the quest status for the specific player is 'active'.
+            bool isFailed(const PlayerInfo* player) const; //!< Returns true if the quest status for the specific player is 'failed'.
+            bool isCompleted(const PlayerInfo* player) const; //!< Returns true if the quest status for the specific player is 'completed'.
+
+            bool start(PlayerInfo* player); //!< Sets a Quest to active.
+            virtual bool fail(PlayerInfo* player); //!< Fails the Quest.
+            virtual bool complete(PlayerInfo* player); //!< Completes the Quest.
+            
+            bool addListener(QuestListener* listener); //!< Adds a QuestListener to the list of QuestListeners listening to this Quest.
+
+        protected:
+            virtual bool isStartable(const PlayerInfo* player) const = 0; //!< Checks whether the Quest can be started.
+            virtual bool isFailable(const PlayerInfo* player) const = 0; //!< Checks whether the Quest can be failed.
+            virtual bool isCompletable(const PlayerInfo* player) const = 0; //!< Checks whether the Quest can be completed.
+
+            const Quest* getSubQuest(unsigned int index) const; //!<Returns the subquest at the given index.
+            const QuestHint* getHint(unsigned int index) const; //!< Returns the QuestHint at the given index.
+            const QuestEffect* getFailEffect(unsigned int index) const; //!< Returns the fail QuestEffect at the given index.
+            const QuestEffect* getCompleteEffect(unsigned int index) const; //!< Returns the complete QuestEffect at the given index.
+
+            /**
+            @brief Returns the list of fail QuestEffects.
+            @return Returns a reference to the list of fail QuestEffects.
+            */
+            inline std::list<QuestEffect*> & getFailEffectList(void)
+                { return this->failEffects_; }
+
+            /**
+            @brief Returns the list of complete QuestEffects.
+            @return Returns a reference to the list of complete QuestEffects.
+            */
+            inline std::list<QuestEffect*> & getCompleteEffectList(void)
+                { return this->completeEffects_; }
+
+            virtual QuestStatus::Value getStatus(const PlayerInfo* player) const = 0; //!< Returns the status of the Quest for a specific player.
+            virtual bool setStatus(PlayerInfo* player, const QuestStatus::Value & status) = 0; //!< Changes the status for a specific player.
+
+        private:
+            Quest* parentQuest_; //!< Pointer to the parentquest.
+            std::list<Quest*> subQuests_; //!< List of all the subquests.
+
+            std::list<QuestHint*> hints_; //!< A list of all the QuestHints tied to this Quest.
+
+            std::list<QuestEffect*> failEffects_; //!< A list of all QuestEffects to be invoked, when the Quest has been failed.
+            std::list<QuestEffect*> completeEffects_; //!< A list of QuestEffects to be invoked, when the Quest has been completed.
+
+            std::list<QuestListener*> listeners_; //!< A list of QuestListeners, that listen to what exactly happens with this Quest.
+
+            bool setParentQuest(Quest* quest); //!< Sets the parentquest of the Quest.
+            bool addSubQuest(Quest* quest); //!< Adds a subquest to the Quest.
+            bool addHint(QuestHint* hint); //!< Add a QuestHint to the list of QuestHints.
+            bool addFailEffect(QuestEffect* effect); //!< Adds an QuestEffect to the list of fail QuestEffects.
+            bool addCompleteEffect(QuestEffect* effect); //!< Adds an QuestEffect to the list of complete QuestEffects.
+
+    };
+
+}
+
+#endif /* _Quest_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/QuestDescription.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestDescription.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestDescription.cc	(revision 6952)
@@ -0,0 +1,130 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the QuestDescription class.
+*/
+
+
+#include "QuestDescription.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "QuestNotification.h"
+
+namespace orxonox
+{
+    CreateFactory(QuestDescription);
+
+    /**
+    @brief
+        Constructor. Registers and initializes the object.
+    */
+    QuestDescription::QuestDescription(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(QuestDescription);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    QuestDescription::~QuestDescription()
+    {
+
+    }
+
+    /**
+    @brief
+        Method for creating a QuestDescription object through XML.
+    */
+    void QuestDescription::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(QuestDescription, XMLPort, xmlelement, mode);
+
+        XMLPortParam(QuestDescription, "title", setTitle, getTitle, xmlelement, mode);
+        XMLPortParam(QuestDescription, "description", setDescription, getDescription, xmlelement, mode);
+        XMLPortParam(QuestDescription, "failMessage", setFailMessage, getFailMessage, xmlelement, mode);
+        XMLPortParam(QuestDescription, "completeMessage", setCompleteMessage, getCompleteMessage, xmlelement, mode);
+
+        COUT(4) << "New QuestDescription with title '" << this->getTitle() << "' created." << std::endl;
+    }
+
+    /**
+    @brief
+        This method is a helper for sending QuestDescriptions as Notifications.
+    @param item
+        The item the QuestDescription is for.
+    @param status
+        The status the QuestDescription us for.
+    @return
+        Returns true if successful.
+    @todo
+        Make sure the messages meet the conditions.
+    */
+    bool QuestDescription::notificationHelper(const std::string & item, const std::string & status)
+    {
+        std::string message;
+        if(item == "hint")
+        {
+            message = "You received a hint: '" + this->title_ + '\'';
+        }
+        else if(item == "quest")
+        {
+            if(status == "start")
+            {
+                message = "You received a new quest: '" + this->title_ + '\'';
+            }
+            else if(status == "fail")
+            {
+                message = "You failed the quest: '" + this->title_ + '\'';
+            }
+            else if(status == "complete")
+            {
+                message = "You successfully completed the quest: '" + this->title_ + '\'';
+            }
+            else
+            {
+                COUT(2) << "Bad input in notificationHelper, this should not be happening!" << std::endl;
+                return false;
+            }
+        }
+        else
+        {
+            COUT(2) << "Bad input in notificationHelper, this should not be happening!" << std::endl;
+            return false;
+        }
+
+        QuestNotification* notification = new QuestNotification(this, message);
+        notification->send();
+        return true;
+    }
+
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/QuestDescription.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestDescription.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestDescription.h	(revision 6952)
@@ -0,0 +1,163 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the QuestDescription class.
+*/
+
+#ifndef _QuestDescription_H__
+#define _QuestDescription_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <string>
+#include "core/BaseObject.h"
+
+// tolua_begin
+namespace orxonox
+{
+    /**
+    @brief
+        This class is a description of a QuestItem.
+        It holds a title and a description.
+
+        Creating a QuestDescription through XML goes as follows:
+
+        <QuestDescription title="Title" description="Description Text" failMessage="You fail." completeMessage="You win!" />
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport QuestDescription : public BaseObject
+    {
+// tolua_end
+        public:
+            QuestDescription(BaseObject* creator);
+            virtual ~QuestDescription();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a QuestDescription object through XML.
+
+// tolua_begin
+            /**
+            @brief Returns the title.
+            @return Returns a string containing the title of the QuestDescription.
+            */
+            inline const std::string & getTitle(void) const
+                { return this->title_; }
+
+            /**
+            @brief Returns the description text.
+            @return Returns a string containing the description text of the QuestDescription.
+            */
+            inline const std::string & getDescription(void) const
+                { return this->description_; }
+// tolua_end
+
+            /**
+            @brief Returns the fail message.
+            @return Returns a string containing the fail message of the QuestDescription.
+            */
+            inline const std::string & getFailMessage(void)
+                { return this->failMessage_; }
+
+            /**
+            @brief Returns the complete message.
+            @return Returns a string containing the complete message of the QuestDescription.
+            */
+            inline const std::string & getCompleteMessage(void)
+                { return this->completeMessage_; }
+
+            /**
+            @brief Sends a Notification displaying that a QuestHint was added.
+            @return Returns true if successful.
+            */
+            inline bool sendAddHintNotification(void)
+                { return notificationHelper("hint", ""); }
+
+            /**
+            @brief Sends a Notification displaying that a Quest was added.
+            @return Returns true if successful.
+            */
+            inline bool sendAddQuestNotification(void)
+                { return notificationHelper("quest", "start"); }
+
+            /**
+            @brief Sends a Notification displaying that a Quest was failed.
+            @return Returns true if successful.
+            */
+            inline bool sendFailQuestNotification(void)
+                { return notificationHelper("quest", "fail"); }
+
+            /**
+            @brief Sends a Notification displaying that a Quest was completed.
+            @return Returns true if successful.
+            */
+            inline bool sendCompleteQuestNotification(void)
+                { return notificationHelper("quest", "complete"); }
+
+        private:
+            std::string title_; //!< The title.
+            std::string description_; //!< The description.
+            std::string failMessage_; //!< The message displayed when the Quest is failed.
+            std::string completeMessage_; //!< The message displayed when the Quest is completed.
+
+            bool notificationHelper(const std::string & item, const std::string & status); //!< Helper for sending QuestDescriptions as Notifications.
+
+            /**
+            @brief Sets the title.
+            @param title The title to be set.
+            */
+            inline void setTitle(const std::string & title)
+                { this->title_ = title; }
+
+            /**
+            @brief Sets the description text.
+            @param description The description text to be set.
+            */
+            inline void setDescription(const std::string & description)
+                { this->description_ = description; }
+
+            /**
+            @brief Sets the fail message.
+            @param message The fail message to be set.
+            */
+            inline void setFailMessage(const std::string & message)
+                { this->failMessage_ = message; }
+
+            /**
+            @brief Sets the complete message.
+            @param message The complete message to be set.
+            */
+            inline void setCompleteMessage(const std::string & message)
+                { this->completeMessage_ = message; }
+
+    }; // tolua_export
+
+} // tolua_export
+
+#endif /* _QuestDescription_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/QuestEffect.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestEffect.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestEffect.cc	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the QuestEffect class.
+*/
+
+#include "QuestEffect.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Constructor. Creates a new QuestEffect.
+        Is not meant to be invoked directly, since this is only an interface.
+    */
+    QuestEffect::QuestEffect(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(QuestEffect);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    QuestEffect::~QuestEffect()
+    {
+
+    }
+
+    /**
+    @brief
+        Static method. Invoke all QuestEffects in an QuestEffect-list on a given player.
+    @param player
+        The player the QuestEffects are invoked on.
+    @param effects
+        A list of all the QuestEffects to be invoked.
+    @return
+        Returns false if there was an error, view console of log for further detail.
+    */
+    /*static*/ bool QuestEffect::invokeEffects(PlayerInfo* player, std::list<QuestEffect*> & effects)
+    {
+        bool check = 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);
+        }
+        return check;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/QuestEffect.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestEffect.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestEffect.h	(revision 6952)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the QuestEffect class.
+*/
+
+#ifndef _QuestEffect_H__
+#define _QuestEffect_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <list>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Handles QuestEffects for Quests.
+        QuestEffects are the only way for Quests to have any sideeffects in the game world. They are also the only way for a player to gain, complete or fail Quests.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport QuestEffect : public BaseObject
+    {
+        public:
+            QuestEffect(BaseObject* creator);
+            virtual ~QuestEffect();
+
+            virtual bool invoke(PlayerInfo* player) = 0; //!< Invokes the QuestEffect.
+            static bool invokeEffects(PlayerInfo* player, std::list<QuestEffect*> & effects); //!< Invokes all QuestEffects in the list.
+
+
+    };
+
+}
+
+#endif /* _QuestEffect_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/QuestEffectBeacon.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestEffectBeacon.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestEffectBeacon.cc	(revision 6952)
@@ -0,0 +1,277 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the QuestEffectBeacon class.
+*/
+
+#include "QuestEffectBeacon.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "core/EventIncludes.h"
+#include "worldentities/pawns/Pawn.h"
+#include "interfaces/PlayerTrigger.h"
+#include "objects/triggers/MultiTriggerContainer.h"
+#include "QuestEffect.h"
+
+namespace orxonox
+{
+    CreateFactory(QuestEffectBeacon);
+
+    /**
+    @brief
+        Constructor. Registers the object and initializes defaults.
+    */
+    QuestEffectBeacon::QuestEffectBeacon(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(QuestEffectBeacon);
+
+        this->status_ = QuestEffectBeaconStatus::Active;
+        this->times_ = INFINITE_TIME;
+    }
+
+    /**
+        Destructor.
+    */
+    QuestEffectBeacon::~QuestEffectBeacon()
+    {
+    }
+
+    /**
+    @brief
+        Method for creating a QuestEffectBeacon object through XML.
+    */
+    void QuestEffectBeacon::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(QuestEffectBeacon, XMLPort, xmlelement, mode);
+
+        XMLPortParam(QuestEffectBeacon, "times", setTimes, getTimes, xmlelement, mode);
+        XMLPortObject(QuestEffectBeacon, QuestEffect, "effects", addEffect, getEffect, xmlelement, mode);
+
+        XMLPortEventSink(QuestEffectBeacon, BaseObject, "execute", execute, xmlelement, mode); //TODO: Change BaseObject to MultiTrigger as soon as MultiTrigger is the base of all triggers.
+
+        COUT(4) << "New QuestEffectBeacon created." << std::endl;
+    }
+
+    void QuestEffectBeacon::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(QuestEffectBeacon, XMLEventPort, xmlelement, mode);
+
+        XMLPortEventSink(QuestEffectBeacon, BaseObject, "execute", execute, xmlelement, mode);
+    }
+
+    /**
+    @brief
+        Executes the QuestEffectBeacon.
+        This means extracting the Pawn from the PlayerTrigger, provided by the Event causing the execution, and the extracting the PlayerInfo from the received Pawn and invoking the QuestEffectbeacon's QuestEffects on the received PlayerInfo.
+    @param trigger
+        A pointer to the PlayerTrigger that threw the Event.
+    @return
+        Returns true if successfully executed, false if not.
+    */
+    bool QuestEffectBeacon::execute(bool b, BaseObject* trigger)
+    {
+        if(!b)
+        {
+            return false;
+        }
+        if(!(this->isActive())) //!< If the QuestEffectBeacon is inactive it cannot be executed.
+        {
+            COUT(4) << "The QuestEffectBeacon is inactive." << std::endl;
+            return false;
+        }
+
+        PlayerTrigger* pTrigger = orxonox_cast<PlayerTrigger*>(trigger);
+        MultiTriggerContainer* mTrigger = orxonox_cast<MultiTriggerContainer*>(trigger);
+        Pawn* pawn = NULL;
+        
+        //! If the trigger is neither a Playertrigger nor a MultiTrigger (i.e. a MultitriggerContainer) we can do anything with it.
+        if(pTrigger == NULL && mTrigger == NULL)
+            return false;
+        
+        // If the trigger is a PlayerTrigger.        
+        if(pTrigger != NULL)
+        {
+            if(!pTrigger->isForPlayer())  //!< The PlayerTrigger is not exclusively for Pawns which means we cannot extract one.
+                return false;
+            else
+                pawn = pTrigger->getTriggeringPlayer();
+        }
+        
+        // If the trigger is a MultiTrigger (i.e. a MultiTriggerContainer)
+        if(mTrigger != NULL)
+        {
+            pawn = orxonox_cast<Pawn*>(mTrigger->getData());
+        }
+
+        if(pawn == NULL)
+        {
+            COUT(4) << "The QuestEffectBeacon was triggered by an entity other than a Pawn. (" << trigger->getIdentifier()->getName() << ")" << std::endl;
+            return false;
+        }
+
+        //! Extract the PlayerInfo from the Pawn.
+        PlayerInfo* player = pawn->getPlayer();
+
+        if(player == NULL)
+        {
+            COUT(3) << "The PlayerInfo* is NULL." << std::endl;
+            return false;
+        }
+
+        COUT(4) << "QuestEffectBeacon executed on player: " << player << " ." << std::endl;
+
+        bool check = QuestEffect::invokeEffects(player, this->effects_); //!< Invoke the QuestEffects on the PlayerInfo.
+        if(check)
+        {
+            this->decrementTimes(); //!< Decrement the number of times the beacon can be used.
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+    @brief
+        Set the status of the QuestEffectBeacon.
+    @param activate
+        If true the QuestEffectBeacon is activated, if false it is deactivated.
+    @return
+        Returns whether the activation/deactivation was successful.
+    */
+    bool QuestEffectBeacon::setActive(bool activate)
+    {
+        if(this->getTimes() == 0 && activate) //!< A QuestEffectBeacon that can be executed only 0 times is always inactive.
+        {
+            return false;
+        }
+
+        if(activate)
+        {
+        this->status_ = QuestEffectBeaconStatus::Active;
+        return true;
+        }
+
+        this->status_ = QuestEffectBeaconStatus::Inactive;
+        return true;
+    }
+
+    /**
+    @brief
+        Decrement the number of times the QuestEffectBeacon can be executed.
+    @return
+        Returns true if successful.
+    */
+    bool QuestEffectBeacon::decrementTimes(void)
+    {
+        if(!(this->isActive())) //!< The QuestEffectBeacon mus be active to decrement the number of times it can be executed.
+        {
+            return false;
+        }
+        if(this->getTimes() == INFINITE_TIME) //!< If times is infinity the QuestEffectBeacon can be executed an infinite number fo times.
+        {
+            return true;
+        }
+
+        this->times_ = this->times_ - 1; //!< Decrement number of times the QuestEffectBeacon can be executed.
+        if(this->getTimes() == 0) //!< Set the QuestEffectBeacon to inactive when the number of times it can be executed is reduced to 0.
+        {
+            this->status_ = QuestEffectBeaconStatus::Inactive;
+        }
+
+        return true;
+    }
+
+    /**
+    @brief
+        Set the number of times the QuestEffectBeacon can be executed.
+        The number must be eighter <= 0, or INFINITY which is '-1'.
+    @param n
+        The number of times the QuestEffectBeacon can be executed.
+        The number must be eighter <= 0, or INFINITY which is '-1'.
+    @return
+        Returns true if successful.
+    */
+    bool QuestEffectBeacon::setTimes(const int & n)
+    {
+        if(n < 0 && n != INFINITE_TIME)
+        {
+            return false;
+        }
+
+        this->times_ = n;
+        return true;
+    }
+
+    /**
+    @brief
+        Adds a QuestEffect to the QuestEffectBeacon.
+    @param effect
+        A pointer to the QuestEffect to be added.
+    @return
+        Returns true if successful.
+    */
+    bool QuestEffectBeacon::addEffect(QuestEffect* effect)
+    {
+        if(effect == NULL) //!< NULL-pointers are not well liked here...
+        {
+            COUT(2) << "A NULL-QuestEffect was trying to be added" << std::endl;
+            return false;
+        }
+
+        this->effects_.push_back(effect);
+
+        COUT(4) << "A QuestEffect was added to a QuestEffectBeacon." << std::endl;
+        return true;
+    }
+
+    /**
+    @brief
+        Returns the QuestEffect at the given index.
+    @param index
+        The index.
+    @return
+        Returns a pointer to the QuestEffect at the given index.
+    */
+    const QuestEffect* QuestEffectBeacon::getEffect(unsigned int index) const
+    {
+        int i = index;
+        for (std::list<QuestEffect*>::const_iterator effect = this->effects_.begin(); effect != this->effects_.end(); ++effect)
+        {
+            if(i == 0)
+            {
+               return *effect;
+            }
+            i--;
+        }
+        return NULL;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/QuestEffectBeacon.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestEffectBeacon.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestEffectBeacon.h	(revision 6952)
@@ -0,0 +1,127 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the QuestEffectBeacon class.
+*/
+
+#ifndef _QuestEffectBeacon_H__
+#define _QuestEffectBeacon_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <list>
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    namespace QuestEffectBeaconStatus
+    {
+        //! The status of the beacon, can be either active or inactive.
+        enum Value
+        {
+            Inactive,
+            Active
+        };
+    }
+
+    /**
+    @brief
+        A QuestEffectBeacon is a physical entity in the game which can (under some condition(s)) invoke a number QuestEffects on players meeting the condition(s).
+        The conditions under which the QuestEffects are invoked on the player are defined by Triggers.
+        A QuestEffectBeacon can be executed a defined number of times.
+        A QuestEffectBeacon can be inactive or active.
+
+        Creating a QuestEffectBeacon through XML goes as follows:
+
+        <QuestEffectBeacon times=n> //Where 'n' is eighter a number >= 0, which means the QuestEffectBeacon can be executed n times. Or n = -1, which means the QuestEffectBeacon can be executed an infinite number of times.
+            <effects>
+                <QuestEffect /> //A list of QuestEffects, invoked when the QuestEffectBeacon is executed, see QuestEffect for the full XML representation.
+                ...
+                <QuestEffect />
+            </effects>
+            <events>
+                <execute>
+                    <EventListener event=eventIdString />
+                </execute>
+            </events>
+            <attached>
+                <PlayerTrigger name=eventIdString /> //A PlayerTrigger triggering the execution of the QuestEffectBeacon.
+            </attached>
+        </QuestEffectBeacon>
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport QuestEffectBeacon : public StaticEntity
+    {
+        public:
+            QuestEffectBeacon(BaseObject* creator);
+            virtual ~QuestEffectBeacon();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a QuestEffectBeacon object through XML.
+            virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
+
+            bool execute(bool b, BaseObject* trigger); //!< Executes the QuestEffects of the QuestEffectBeacon.
+
+            /**
+            @brief Tests whether the QuestEffectBeacon is active.
+            @return Returns true if the QuestEffectBeacon is active, fals if not.
+            */
+            inline bool isActive(void)
+            { return this->status_ == QuestEffectBeaconStatus::Active; }
+
+            bool setActive(bool activate); //!< Set the status of the QuestEffectBeacon.
+
+        protected:
+            bool decrementTimes(void); //!< Decrement the number of times the QuestEffectBeacon can still be executed.
+
+            /**
+            @brief Returns the number of times the QUestEffectBeacon can still be executed.
+            @return Returns the number of times the QUestEffectBeacon can still be executed.
+            */
+            inline const int & getTimes(void) const
+                { return this->times_; }
+
+        private:
+            static const int INFINITE_TIME = -1; //!< Constant to avoid using magic numbers.
+
+            std::list<QuestEffect*> effects_; //!< The list of QuestEffects to be invoked on the executing player.
+            int times_; //!< Number of times the beacon can be exectued.
+            QuestEffectBeaconStatus::Value status_; //!< The status of the QuestEffectBeacon, Can be eighter active or inactive.
+
+            bool setTimes(const int & n); //!< Set the number of times the QuestEffectBeacon can be executed.
+            bool addEffect(QuestEffect* effect); //!< Add a QuestEffect to the QuestEffectBeacon.
+
+            const QuestEffect* getEffect(unsigned int index) const; //!< Get the QuestEffect at a given index.
+
+    };
+
+}
+
+#endif /* _QuestEffectBeacon_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/QuestGUI.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestGUI.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestGUI.cc	(revision 6952)
@@ -0,0 +1,274 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "QuestGUI.h"
+
+#include <sstream>
+#include <CEGUIWindow.h>
+#include <CEGUIWindowManager.h>
+
+#include "core/CoreIncludes.h"
+#include "Quest.h"
+#include "QuestHint.h"
+#include "QuestItem.h"
+#include "QuestGUINode.h"
+#include "QuestManager.h"
+
+namespace orxonox {
+
+    /**
+    @brief
+        Constructor. Registers and initializes the object.
+    @param
+        The player the GUI is for.
+    */
+    QuestGUI::QuestGUI(PlayerInfo* player)
+    {
+        RegisterRootObject(QuestGUI);
+
+        this->player_ = player;
+        this->windowManager_ = CEGUI::WindowManager::getSingletonPtr(); //!< Get CEGUI WindowManager.
+        this->rootWindow_ = NULL;
+        this->root_ = new QuestGUINode(); //!< Create empty root node.
+
+        COUT(3) << "New QuestGUI created." << std::endl;
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    QuestGUI::~QuestGUI()
+    {
+        COUT(3) << "Destroying QuestGUI..." << std::endl;
+
+        this->clear(); //!< Clearing the GUI and in the process destroying all QuestGUINodes.
+
+        //! Destroying the windows in the this->windows_ list.
+        for(std::list<CEGUI::Window*>::iterator it = this->windows_.begin(); it != this->windows_.end(); it++)
+        {
+            if(*it != NULL)
+                (*it)->destroy();
+        }
+        this->windows_.clear();
+
+        if(this->root_ != NULL)
+            this->root_->destroy();
+    }
+
+    /**
+    @brief
+        Get the root CEGUI Window of the GUI.
+    @return
+        Returns the root CEGUI Window of the GUI.
+    */
+    CEGUI::Window* QuestGUI::getGUI(void)
+    {
+        this->update(); //!< Update the GUI.
+
+        return this->rootWindow_;
+    }
+
+    /**
+    @brief
+        Update the GUI.
+    */
+    void QuestGUI::update(void)
+    {
+        COUT(4) << "Updating QuestGUI..." << std::endl;
+
+        this->clear(); //!< Clear the GUI.
+
+        int depth = 0;
+        int index = 0;
+
+        //! Create root window.
+        this->rootWindow_ = this->windowManager_->createWindow("MenuWidgets/ScrollablePane", "QuestGUI/Quests");
+        this->rootWindow_->setSize(CEGUI::UVector2(CEGUI::UDim(1, 0),CEGUI::UDim(1, 0)));
+
+        //! Iterate through all Quests.
+        std::map<std::string, Quest*> quests = QuestManager::getInstance().getQuests();
+        for(std::map<std::string, Quest*>::iterator it = quests.begin(); it != quests.end(); it++)
+        {
+            Quest* quest = it->second;
+            if(quest->getParentQuest() == NULL && !quest->isInactive(this->player_)) //!< If the Quest isn't inactive and a root Quest (meaning it has no parent.), create a Node.
+            {
+                index = createNode(this->root_, quest, depth, index);
+            }
+        }
+        COUT(4) << "Updating QuestGUI done." << std::endl;
+    }
+
+    /**
+    @brief
+        Clear the QuestGUI.
+    */
+    void QuestGUI::clear(void)
+    {
+        COUT(4) << "Clearing QuestGUI..." << std::endl;
+
+        //! Clear all nodes.
+        for(std::map<CEGUI::Window*, QuestGUINode*>::iterator it = this->nodes_.begin(); it != this->nodes_.end(); it++)
+        {
+            QuestGUINode* node = it->second;
+            if(node == NULL)
+            {
+                COUT(1) << "Node is NULL!";
+                continue;
+            }
+            std::string* str = new std::string();
+            node->getName(*str);
+            COUT(3) << "Clearing Node '" << *str << "' ..." << std::endl;
+            delete str;
+            node->destroy();
+        }
+        this->nodes_.clear();
+
+        //! Clear root window.
+        if(this->rootWindow_ != NULL)
+            this->rootWindow_->destroy();
+
+        COUT(3) << "Clearing QuestGUI done." << std::endl;
+    }
+
+    /**
+    @brief
+        Get a CEGUI Window to use.
+        Windows that are no longer used are collected with giveWindow, and are given out again with getWindow, so save some time recreating new windows everytime.
+        The retreived window is of type "MenuWidgets/TabButton".
+    @return
+        Returns a CEGUI Window of type "MenuWidgets/TabButton".
+    */
+    CEGUI::Window* QuestGUI::getWindow(void)
+    {
+        if(!this->windows_.empty()) //!< If there are windows in the list.
+        {
+            CEGUI::Window* window = this->windows_.back();
+            this->windows_.pop_back();
+            return window;
+        }
+
+        //!< Else create a new one.
+        std::ostringstream stream;
+        stream << "QuestGUI/Quests/EmptyWindows/" << this->windows_.size()+1;
+        return this->windowManager_->createWindow("MenuWidgets/TabButton", stream.str());
+    }
+
+    /**
+    @brief
+        Return a no longer needed CEGUI Window for reuse.
+    @param window
+        The CEGUI window ot be returned.
+    */
+    void QuestGUI::giveWindow(CEGUI::Window* window)
+    {
+        if(window == NULL)
+            return;
+        this->windows_.push_back(window);
+        this->rootWindow_->removeChildWindow(window); //!< Remove the window as child of the rootWindow.
+        std::ostringstream stream;
+        stream << "QuestGUI/Quests/EmptyWindows/" << this->windows_.size();
+        window->rename(stream.str());
+    }
+
+    /**
+    @brief
+        Finde the QuestGUINode belonging to the input CEGUI Window.
+    @param window
+        A pointer to a CEGUI Window.
+    @return
+        A pointer to the QuestGUI Node belonging to the input CEGUI Window.
+    */
+    /*static*/ QuestGUINode* QuestGUI::findNode(CEGUI::Window* window)
+    {
+        for(std::map<PlayerInfo*, QuestGUI*>::iterator it = QuestManager::getInstance().questGUIs_.begin(); it != QuestManager::getInstance().questGUIs_.end(); it++)
+        {
+            QuestGUI* gui = it->second;
+            std::map<CEGUI::Window*, QuestGUINode*>::iterator node = gui->nodes_.find(window);
+            if(node != gui->nodes_.end()) return node->second;
+        }
+        return NULL;
+    }
+
+    /**
+    @brief
+        Recursive method to create Nodes for all Quests an Hints the given Quest is a parent to.
+    @param parent
+        Pointer to the parent QuestGUINode.
+    @param item
+        The QuestItem the QuestGUINode is created for.
+    @param depth
+        Parameter to define how much the list item has to be indented.
+    @param index
+        "Counter" for Quests and Hints.
+    @return
+        Returns the index.
+    */
+    int QuestGUI::createNode(QuestGUINode* parent, QuestItem* item, int depth, int index)
+    {
+        QuestGUINode* node = new QuestGUINode(this, parent, item, depth, index); //!< Create a new QuestGUINode.
+
+        this->nodes_.insert(std::pair<CEGUI::Window*, QuestGUINode*>(node->getWindow(),node)); //!< Insert the node and its window in the nodes_ map.
+
+        index++;
+
+        //! Check if the QuestItem is a Quest, if not (it's a QuestHint) it just returns.
+        Quest* quest = dynamic_cast<Quest*>(item);
+        if(quest == NULL)
+          return index;
+
+        //! Iterate through all subQuests.
+        std::list<Quest*> quests = quest->getSubQuestList();
+        for(std::list<Quest*>::iterator it = quests.begin(); it != quests.end(); it++)
+        {
+            Quest* quest = *it;
+            if(!quest->isInactive(this->player_)) //!< Add node if the subQuest is not inactive.
+            {
+                index = createNode(node, quest, depth+1, index);
+            }
+        }
+
+        //! Iterate through all hints.
+        std::list<QuestHint*> hints = quest->getHintsList();
+        int tempIndex = index; //!< Preserve the index, since for the hints we start anew with index 0.
+        index = 0;
+        for(std::list<QuestHint*>::iterator it = hints.begin(); it != hints.end(); it++)
+        {
+            QuestHint* hint = *it;
+            if(hint->isActive(this->player_)) //!< Add node if the hint is active.
+            {
+                index = createNode(node, hint, depth+1, index);
+            }
+        }
+        index = tempIndex; //!< Reset the index to the original level.
+
+        return index;
+    }
+
+}
+
Index: /code/branches/rocket2/src/modules/questsystem/QuestGUI.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestGUI.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestGUI.h	(revision 6952)
@@ -0,0 +1,109 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the QuestGIU class.
+*/
+
+#ifndef _QuestGUI_H__
+#define _QuestGUI_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <list>
+#include <map>
+#include <string>
+#include <CEGUIForwardRefs.h>
+
+#include "core/OrxonoxClass.h"
+
+namespace orxonox {
+
+    /**
+    @brief
+        Handles the GUI for the Questsystem.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport QuestGUI : public OrxonoxClass
+    {
+
+        public:
+
+            QuestGUI(PlayerInfo* player);
+            virtual ~QuestGUI();
+
+            void update(void); //!< Update the GUI.
+            CEGUI::Window* getGUI(void); //!< Get the root CEGUI Window of the GUI.
+
+            CEGUI::Window* getWindow(void); //!< Get a CEGUI Window to use.
+            void giveWindow(CEGUI::Window* window); //!< Return a no longer needed CEGUI Window for reuse.
+
+            static QuestGUINode* findNode(CEGUI::Window* window); //!< Finde the QuestGUINode belonging to the input CEGUI Window.
+
+            /**
+            @brief Retreive the CEGUI WindowManager.
+            @return Returns the CEGUI WindoWManager.
+            */
+            inline CEGUI::WindowManager* getWindowManager(void)
+                { return this->windowManager_; }
+            /**
+            @brief Retrieve the root window.
+            @return Returns the root window.
+            */
+            inline CEGUI::Window* getRootWindow(void)
+                { return this->rootWindow_; }
+            /**
+            @brief Retreive the player.
+            @return Returns the player.
+            */
+            inline PlayerInfo* getPlayer(void)
+                { return this->player_; }
+
+        private:
+
+            int createNode(QuestGUINode* parent, QuestItem* item, int depth, int index); //!< Recursive method to create Nodes for all Quests an Hints the given Quest is a parent to.
+
+            void clear(void); //!< Clear the QuestGUI.
+
+            QuestGUINode* root_; //!< An empty QuestGUINode being the parent of all otherwise parent-less nodes.
+
+            CEGUI::WindowManager* windowManager_; //!< The CEGUI WindowManager.
+            CEGUI::Window* rootWindow_; //!< The root CEGUI Window of the GUI.
+            PlayerInfo* player_; //!< The player that owns the GUI.
+
+            std::map<CEGUI::Window*, QuestGUINode*> nodes_; //!< A list of all QuestGUINodes, ordered by their respective CEGUI Windows.
+            std::list<CEGUI::Window*> windows_; //!< A list of windows to be used.
+
+    };
+
+}
+
+#endif /* _QuestGUI_H__ */
+
Index: /code/branches/rocket2/src/modules/questsystem/QuestGUINode.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestGUINode.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestGUINode.cc	(revision 6952)
@@ -0,0 +1,399 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "QuestGUINode.h"
+
+#include <sstream>
+
+#include <CEGUIWindowManager.h>
+#include <elements/CEGUIFrameWindow.h>
+#include <elements/CEGUIPushButton.h>
+#include <falagard/CEGUIFalWidgetLookFeel.h>
+#include <falagard/CEGUIFalWidgetLookManager.h>
+
+#include "core/CoreIncludes.h"
+#include "Quest.h"
+#include "QuestHint.h"
+#include "QuestItem.h"
+#include "QuestDescription.h"
+#include "QuestGUI.h"
+
+namespace orxonox {
+
+    /**
+    @brief
+        Default Constructor. Registers and initializes the object.
+    */
+    QuestGUINode::QuestGUINode(void)
+    {
+        this->initialize();
+    }
+
+    /**
+    @brief
+        Constructor. Registers and initializes the object.
+    @param gui
+        The QuestGUi the node beongs to.
+    @param parent
+        The parent node of the newly created node.
+    @param item
+        The QuestItem the  newly created node is for.
+    @param depth
+        Parameter to define how much the list item has to be indented.
+    @param index
+        "Counter" for Quests and Hints.
+    */
+    QuestGUINode::QuestGUINode(QuestGUI* gui, QuestGUINode* parent, QuestItem* item, int depth, int index)
+    {
+        this->initialize();
+
+        this->gui_ = gui;
+        this->parent_ = parent;
+        this->item_ = item;
+        this->depth_ = depth;
+        this->index_ = index;
+
+        this->createWindow();
+
+        COUT(4) << "New QuestGUINode '" << this->window_->getName() << "' created." << std::endl;
+    }
+
+    /**
+    @brief
+        Destructor.
+    @todo
+        Destroying everything?
+    */
+    QuestGUINode::~QuestGUINode(void)
+    {
+        if(this->window_ != NULL)
+            this->window_->destroy();
+        if(this->details_ != NULL)
+        {
+            this->details_->destroy();
+        }
+    }
+
+    /**
+    @brief
+        Initialize the object.
+    */
+    void QuestGUINode::initialize(void)
+    {
+        RegisterRootObject(QuestGUINode);
+
+        this->parent_ = NULL;
+        this->item_ = NULL;
+        this->window_ = NULL;
+        this->details_ = NULL;
+        this->depth_ = 0;
+        this->index_ = 0;
+        this->visible_ = true;
+    }
+
+    void QuestGUINode::toggleVisibility(void)
+    {
+
+    }
+
+    /**
+    @brief
+        Sets the input buffer to the name of the node.
+    @param buffer
+        The buffer that is set to the name of the node.
+    @todo
+        Needed?
+    */
+    void QuestGUINode::getName(std::string & buffer)
+    {
+        if(this->window_ != NULL)
+        {
+            buffer = this->window_->getName().c_str();
+        }
+        else
+        {
+            buffer.erase();
+        }
+    }
+
+    /**
+    @brief
+        Creates the details window.
+    @return
+        Returns the details window.
+    @todo
+        Return necessary?
+    */
+    CEGUI::Window* QuestGUINode::getDetails(void)
+    {
+
+        if(this->details_ == NULL) //!< If the details window was not already created.
+        {
+            std::ostringstream stream;
+
+            //! Create the main window for the details.
+            stream << this->window_->getName() << "/Details";
+            const QuestDescription* description = this->item_->getDescription();
+            this->details_ = this->gui_->getWindowManager()->createWindow("MenuWidgets/FrameWindow", stream.str());
+            this->details_->setSize(CEGUI::UVector2(CEGUI::UDim(0.7f, 0),CEGUI::UDim(0.7f, 0)));
+            this->details_->setPosition(CEGUI::UVector2(CEGUI::UDim(0.1f, 0),CEGUI::UDim(0.1f, 0)));
+            this->details_->setText(description->getTitle());
+            this->details_->setAlpha(1.0);
+            this->details_->setInheritsAlpha(false);
+            this->details_->setProperty("CloseButtonEnabled", "True");
+            this->details_->subscribeEvent(CEGUI::FrameWindow::EventCloseClicked, CEGUI::Event::Subscriber(&QuestGUINode::closeDetails, this));
+
+            //! Create a ScrollablePane.
+            stream << "/Scrollable";
+            CEGUI::Window* window = this->gui_->getWindowManager()->createWindow("MenuWidgets/ScrollablePane", stream.str());
+            window->setSize(CEGUI::UVector2(CEGUI::UDim(1.0, -2*QuestGUINode::BORDER_WIDTH),CEGUI::UDim(1.0, -QuestGUINode::TITLE_HEIGHT)));
+            window->setPosition(CEGUI::UVector2(CEGUI::UDim(0, (float)QuestGUINode::BORDER_WIDTH),CEGUI::UDim(0, (float)QuestGUINode::TITLE_HEIGHT)));
+            this->details_->addChildWindow(window);
+
+            int height;
+            int offset = 0;
+
+            //! Display the status of the QuestItem if it is a Quest.
+            Quest* quest = dynamic_cast<Quest*>(this->item_);
+            if(quest != NULL) //!< If the QuestItem is a Quest
+            {
+                stream.str("");
+                stream << this->details_->getName() << "/Status";
+                CEGUI::Window* statusWindow = this->gui_->getWindowManager()->createWindow("MenuWidgets/StaticText", stream.str());
+                window->addChildWindow(statusWindow);
+                std::string status;
+                if(quest->isActive(this->gui_->getPlayer()))
+                {
+                    status = "This quest is active.";
+                }
+                else if(quest->isCompleted(this->gui_->getPlayer()))
+                {
+                    status = "This quest was completed.";
+                }
+                else if(quest->isFailed(this->gui_->getPlayer()))
+                {
+                    status = "This quest was failed.";
+                }
+                statusWindow->setProperty("HorzFormatting", "WordWrapLeftAligned");
+                statusWindow->setProperty("VertFormatting", "TopAligned");
+                statusWindow->setText(status);
+                statusWindow->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 0),CEGUI::UDim(0, (float)offset)));
+                statusWindow->setSize(CEGUI::UVector2(CEGUI::UDim(1.0, (float)-QuestGUINode::SCROLLBAR_WIDTH),CEGUI::UDim(1.0f, 0)));
+                height = setHeight(statusWindow);
+
+                offset += height;
+            }
+
+            //! Create title pane for the description.
+            stream.str("");
+            stream << this->details_->getName() << "/Description";
+            stream << "/Title";
+            CEGUI::Window* descriptionWindowTitle = this->gui_->getWindowManager()->createWindow("MenuWidgets/StaticText", stream.str());
+            window->addChildWindow(descriptionWindowTitle);
+            descriptionWindowTitle->setProperty("HorzFormatting", "HorzCentred");
+            descriptionWindowTitle->setProperty("VertFormatting", "TopAligned");
+            descriptionWindowTitle->setText("Description:");
+            descriptionWindowTitle->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 0),CEGUI::UDim(0, (float)offset)));
+            descriptionWindowTitle->setSize(CEGUI::UVector2(CEGUI::UDim(1.0f, -QuestGUINode::SCROLLBAR_WIDTH),CEGUI::UDim(1.0f, 0)));
+
+            offset += setHeight(descriptionWindowTitle);
+
+            //! Display the Description of the QuestItem.
+            stream.str("");
+            stream << this->details_->getName() << "/Description";
+            CEGUI::Window* descriptionWindow = this->gui_->getWindowManager()->createWindow("MenuWidgets/StaticText", stream.str());
+            window->addChildWindow(descriptionWindow);
+            descriptionWindow->setProperty("HorzFormatting", "WordWrapLeftAligned");
+            descriptionWindow->setProperty("VertFormatting", "TopAligned");
+            descriptionWindow->setText(description->getDescription());
+            descriptionWindow->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 0),CEGUI::UDim(0, (float)offset)));
+            descriptionWindow->setSize(CEGUI::UVector2(CEGUI::UDim(1.0, (float)-QuestGUINode::SCROLLBAR_WIDTH),CEGUI::UDim(1.0f, 0)));
+            height = setHeight(descriptionWindow);
+
+            offset += height;
+
+            //! Display a list of hints if the QuestItem is a Quest.
+            bool title = true;
+            if(quest != NULL)
+            {
+                for(std::list<QuestGUINode*>::iterator it = this->subNodes_.begin(); it != this->subNodes_.end(); it++)
+                {
+                    if(dynamic_cast<QuestHint*>((*it)->item_) != NULL) //!< If the subNode belongs to a QuestHint.
+                    {
+                        if(title) //!< If no title pane for the QuestHints has been created, create one.
+                        {
+                            stream.str("");
+                            stream << this->details_->getName() << "/Hints/Title";
+                            CEGUI::Window* hintsTitle = this->gui_->getWindowManager()->createWindow("MenuWidgets/StaticText", stream.str());
+                            window->addChildWindow(hintsTitle);
+                            hintsTitle->setProperty("HorzFormatting", "HorzCentred");
+                            hintsTitle->setProperty("VertFormatting", "TopAligned");
+                            hintsTitle->setText("Hints:");
+                            hintsTitle->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 0),CEGUI::UDim(0, (float)offset)));
+                            hintsTitle->setSize(CEGUI::UVector2(CEGUI::UDim(1.0, -QuestGUINode::SCROLLBAR_WIDTH),CEGUI::UDim(1.0, 0)));
+                            offset += setHeight(hintsTitle);;
+                            title = false;
+                        }
+                        QuestGUINode* node = *it;
+                        node->window_->setSize(CEGUI::UVector2(CEGUI::UDim(1.0f, (float)-QuestGUINode::SCROLLBAR_WIDTH),CEGUI::UDim(0, (float)QuestGUINode::BUTTON_HEIGHT)));
+                        node->window_->setPosition(CEGUI::UVector2(CEGUI::UDim(0, 0),CEGUI::UDim(0, (float)offset)));
+                        window->addChildWindow(node->window_);
+                        offset += QuestGUINode::BUTTON_HEIGHT;
+                    }
+                }
+            }
+
+            COUT(4) << "Show Details: " << this->details_->getName() << std::endl;
+        }
+
+        return this->details_;
+    }
+
+    /**
+    @brief
+        Opens the details window for the Quest/QuestHint clicked on.
+    */
+    bool QuestGUINode::openDetails(const CEGUI::EventArgs& e)
+    {
+        COUT(4) << "Open QuestItem..." << std::endl;
+
+        //CEGUI::Window* window = this->gui_->getRootWindow();
+        CEGUI::Window* window = this->gui_->getWindowManager()->getWindow("orxonox/QuestGUI/Background");
+
+        if(window != NULL)
+            window->addChildWindow(this->getDetails());
+
+        return true;
+    }
+
+    /**
+    @brief
+        Close the details window.
+    */
+    bool QuestGUINode::closeDetails(const CEGUI::EventArgs& e)
+    {
+        //CEGUI::Window* window = this->gui_->getRootWindow();
+        CEGUI::Window* window = this->gui_->getWindowManager()->getWindow("orxonox/QuestGUI/Background");
+        window->removeChildWindow(this->details_);
+
+        return true;
+    }
+
+    /**
+    @brief
+        Helper method for setHeight(). Gets the StaticTextArea for an input CEGUI Window.
+    @param window
+        The CEGUI window.
+    @return
+        Returns a CEGUI Rect.
+    */
+    /*static*/ CEGUI::Rect QuestGUINode::getStaticTextArea(const CEGUI::Window* window)
+    {
+        const CEGUI::WidgetLookFeel& lookAndFeel = CEGUI::WidgetLookManager::getSingleton().getWidgetLook(window->getLookNFeel());
+
+        return lookAndFeel.getNamedArea("WithFrameTextRenderArea").getArea().getPixelRect(*window);
+    }
+
+    /**
+    @brief
+        Helper method to adjust the height of an input Window (of type StaticText) to the text it holds.
+    @param window
+        The  CEGUI Window (of type StaticText) for which the height is to be adjusted to the text.
+    @return
+        Returns the set height.
+    */
+    /*static*/ int QuestGUINode::setHeight(CEGUI::Window* window)
+    {
+        //! Get the area the text is formatted and drawn into.
+        const CEGUI::Rect formattedArea = getStaticTextArea(window);
+
+        //! Calculate the pixel height of the frame by subtracting the height of the area above from the total height of the window.
+        const float frameHeight = window->getUnclippedPixelRect().getHeight() - formattedArea.getHeight();
+
+        //! Get the formatted line count - using the formatting area obtained above.
+        const float lines = (float)(window->getFont()->getFormattedLineCount(window->getText(), formattedArea, CEGUI::WordWrapLeftAligned));
+
+        //! Calculate pixel height of window, which is the number of formatted lines multiplied by the spacing of the font, plus the pixel height of the frame.
+        const float height = lines * window->getFont()->getLineSpacing() + frameHeight;
+
+        //! Set the height to the window.
+        window->setHeight(CEGUI::UDim(0, height));
+
+        //Debug
+        const CEGUI::Rect newArea = getStaticTextArea(window);
+
+        return static_cast<int>(height);
+    }
+
+    /**
+    @brief
+        Update the position list item.
+    */
+    void QuestGUINode::updatePosition(void)
+    {
+        this->window_->setPosition(CEGUI::UVector2(CEGUI::UDim(0, (float)(QuestGUINode::INDENT_WIDTH*this->depth_)),CEGUI::UDim(0, (float)(QuestGUINode::BUTTON_HEIGHT*this->index_))));
+        this->window_->setSize(CEGUI::UVector2(CEGUI::UDim(1, (float)(-QuestGUINode::INDENT_WIDTH*this->depth_-QuestGUINode::SCROLLBAR_WIDTH)),CEGUI::UDim(0, (float)QuestGUINode::BUTTON_HEIGHT)));
+    }
+
+    /**
+    @brief
+        Helper method to create the CEGUI Window the node.
+    */
+    void QuestGUINode::createWindow(void)
+    {
+        Quest* quest = dynamic_cast<Quest*>(this->item_);
+
+        this->window_ = this->gui_->getWindow();
+        std::ostringstream stream;
+        stream << "QuestGUI/Quests/";
+        if(quest == NULL)
+        {
+            stream << this->parent_->index_ << "/Hints/";
+        }
+        stream << this->index_;
+
+        this->window_->rename(stream.str());
+        this->window_->setText(this->item_->getDescription()->getTitle());
+
+        this->parent_->subNodes_.push_back(this);
+
+        if(dynamic_cast<Quest*>(this->item_) != NULL)
+        {
+            this->gui_->getRootWindow()->addChildWindow(this->window_);
+            this->updatePosition();
+        }
+        else
+        {
+            this->window_->setDestroyedByParent(false);
+        }
+
+        this->window_->subscribeEvent(CEGUI::PushButton::EventClicked, CEGUI::Event::Subscriber(&QuestGUINode::openDetails, this));
+    }
+
+}
+
Index: /code/branches/rocket2/src/modules/questsystem/QuestGUINode.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestGUINode.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestGUINode.h	(revision 6952)
@@ -0,0 +1,98 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _QuestGUINode_H__
+#define _QuestGUINode_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <list>
+#include <string>
+#include <CEGUIForwardRefs.h>
+#include "core/OrxonoxClass.h"
+
+
+namespace orxonox {
+
+    class _QuestsystemExport QuestGUINode : public OrxonoxClass
+    {
+
+        public:
+
+            QuestGUINode(void);
+            QuestGUINode(QuestGUI* gui, QuestGUINode* parent, QuestItem* item, int depth, int index);
+            virtual ~QuestGUINode(void);
+
+            void toggleVisibility(void);
+
+            void getName(std::string & buffer); //!< Sets the input buffer to the name of the node.
+            /**
+            @brief Retreive the window of this node.
+            @return The CEGUI Window of this node.
+            */
+            inline CEGUI::Window* getWindow(void)
+                { return this->window_; }
+
+            bool openDetails(const CEGUI::EventArgs& e); //!< Opens the details window for the Quest/QuestHint clicked on.
+            bool closeDetails(const CEGUI::EventArgs& e); //!< Close the details window.
+
+        private:
+            CEGUI::Window* getDetails(void); //!< Creates the details window.
+
+            void initialize(void); //!< Initialize the object.
+            void updatePosition(void); //!< Update the position list item.
+            void createWindow(void); //!< Helper method to create the CEGUI Window the node.
+            static CEGUI::Rect getStaticTextArea(const CEGUI::Window* window); //Helper method for setHeight(). Gets the StaticTextArea for an input CEGUI Window.
+            static int setHeight(CEGUI::Window* window); //Helper method to adjust the height of an input Window (of type StaticText) to the text it holds.
+
+            bool visible_; //!< Boolean determining the visibility of the node.
+
+            QuestGUI* gui_; //!< The QuestGUI this node belongs to.
+            QuestGUINode* parent_; //!< The parent node.
+            std::list<QuestGUINode*> subNodes_; //!< A list of all subnodes.
+            QuestItem* item_; //!< QuestItem belonging to this node.
+
+            int depth_; //!< The depth (resp. indentation) of this node in the list of Quests. (Irrelevant for QuestHints)
+            int index_; //!< The index of this node in the list of Quests, resp. in the list of QuestHints, if the node belongs to a QuestHint, rather than a Quest.
+
+            CEGUI::Window* window_; //!< The list window of this node.
+            CEGUI::Window* details_; //!< The details window of this node.
+
+            //! Some magic numbers
+            static const int TITLE_HEIGHT = 26;
+            static const int BORDER_WIDTH = 5;
+            static const int SCROLLBAR_WIDTH = 13;
+            static const int BUTTON_HEIGHT = 30;
+            static const int INDENT_WIDTH = 20;
+
+    };
+
+}
+
+#endif /* _QuestGUINode_H__ */
+
Index: /code/branches/rocket2/src/modules/questsystem/QuestHint.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestHint.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestHint.cc	(revision 6952)
@@ -0,0 +1,157 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the QuestHint class.
+*/
+
+#include "QuestHint.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "QuestManager.h"
+#include "QuestDescription.h"
+#include "Quest.h"
+
+namespace orxonox
+{
+    CreateFactory(QuestHint);
+
+    /**
+    @brief
+        Constructor. Registers the object.
+    */
+    QuestHint::QuestHint(BaseObject* creator) : QuestItem(creator)
+    {
+        RegisterObject(QuestHint);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    QuestHint::~QuestHint()
+    {
+        if(this->isRegistered())
+            QuestManager::getInstance().unregisterHint(this);
+    }
+
+    /**
+    @brief
+        Method for creating a QuestHint object through XML.
+    */
+    void QuestHint::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(QuestHint, XMLPort, xmlelement, mode);
+
+        QuestManager::getInstance().registerHint(this); //!< Registers the QuestHint with the QuestManager.
+
+        COUT(4) << "New QuestHint {" << this->getId() << "} created." << std::endl;
+    }
+
+
+    /**
+    @brief
+        Checks whether the QuestHint is active for a specific player.
+    @param player
+        The player.
+    @throws
+        Throws an Argument Exception if the input Player-pointer is NULL.
+    @return
+        Returns true if the QuestHint is active for the specified player.
+    */
+    bool QuestHint::isActive(const PlayerInfo* player) const
+    {
+        if(player == NULL) //!< NULL-Pointers are ugly!
+        {
+            ThrowException(Argument, "The input PlayerInfo* is NULL.");
+            return false;
+        }
+
+        //! Find the player.
+        std::map<const PlayerInfo*, QuestHintStatus::Value>::const_iterator it = this->playerStatus_.find(player);
+        if (it != this->playerStatus_.end()) //!< If the player is in the map.
+        {
+            return it->second;
+        }
+
+        return QuestStatus::Inactive;
+    }
+
+    /**
+    @brief
+        Activates a QuestHint for a given player.
+    @param player
+        The player.
+    @return
+        Returns true if the activation was successful, false if there were problems.
+    */
+    bool QuestHint::setActive(PlayerInfo* player)
+    {
+        if(this->quest_->isActive(player)) //!< For a hint to get activated the quest must be active.
+        {
+            if(!(this->isActive(player)))  //!< If the hint is already active, activation is pointless.
+            {
+                this->playerStatus_[player] = QuestHintStatus::Active;
+
+                this->getDescription()->sendAddHintNotification();
+                return true;
+            }
+            else
+            {
+                COUT(4) << "An already active questHint was trying to get activated." << std::endl;
+                return false;
+            }
+        }
+
+        COUT(4) << "A hint of a non-active quest was trying to get activated." << std::endl;
+        return false;
+    }
+
+    /**
+    @brief
+        Sets the Quest the QuestHint belongs to.
+    @param quest
+        The Quest to be set as Quest the QuestHint is attached to.
+    @return
+        Returns true if successful.
+    */
+    bool QuestHint::setQuest(Quest* quest)
+    {
+        if(quest == NULL) //!< NULL-Pointer. Again..?
+        {
+            COUT(2) << "The input Quest* is NULL." << std::endl;
+            return false;
+        }
+
+        this->quest_ = quest;
+        return true;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/QuestHint.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestHint.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestHint.h	(revision 6952)
@@ -0,0 +1,97 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the QuestHint class.
+*/
+
+#ifndef _QuestHint_H__
+#define _QuestHint_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <map>
+#include "QuestItem.h"
+
+namespace orxonox
+{
+    namespace QuestHintStatus
+    {
+        //! The state of the hint.
+        enum Value
+        {
+            Inactive,
+            Active
+        };
+    }
+
+    /**
+    @brief
+        Represents a hint in the game towards completing a Quest.
+        Consists of title and description (which is stored in a QuestDescription object) in textual form and must belong to a quest.
+        A QuestHint has a defined status (inactive or active, where inactive is default) for each player, which means each a QuestHint exists only once for all players, it doesn't belong to a player, it just has different states for each of them.
+
+        Creating a QuestHint through XML goes as follows:
+
+        <QuestHint id="hintId">  //Where hintId is a GUID, see http://en.wikipedia.org/wiki/Globally_Unique_Identifier#Basic_structure for more information
+            <QuestDesctription title="" description="" />
+        </QuestHint>
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport QuestHint : public QuestItem
+    {
+
+        public:
+            QuestHint(BaseObject* creator);
+            virtual ~QuestHint();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a QuestHint object through XML.
+
+            bool isActive(const PlayerInfo* player) const; //!< Returns true if the QuestHint is active for the input player.
+
+            bool setActive(PlayerInfo* player); //!< Activates the QuestHint for the input player.
+            bool setQuest(Quest* quest); //!< Sets the Quest the QuestHint belongs to.
+
+            /**
+            @brief Returns the Quest the QuestHint is attached to.
+            @return  Returns a pointer to the Quest the QuestHint is attached to.
+            */
+            inline Quest* getQuest(void)
+               { return this->quest_; }
+
+        private:
+            Quest* quest_; //!< The Quest the QuestHint belongs to.
+            std::map<const PlayerInfo*, QuestHintStatus::Value> playerStatus_; //!< List of the states for each player, with the Player-pointer as key.
+
+    };
+
+}
+
+#endif /* _QuestHint_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/QuestItem.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestItem.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestItem.cc	(revision 6952)
@@ -0,0 +1,95 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the QuestItem class.
+*/
+
+#include "QuestItem.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "QuestDescription.h"
+
+namespace orxonox
+{
+
+    CreateUnloadableFactory(QuestItem);
+    
+    /**
+    @brief
+        Constructor. Registers and initializes the object.
+    */
+    QuestItem::QuestItem(BaseObject* creator) : BaseObject(creator)
+    {
+        this->registered_ = false;
+        
+        RegisterObject(QuestItem);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    QuestItem::~QuestItem()
+    {
+
+    }
+
+    /**
+    @brief
+        Method for creating a QuestItem object through XML.
+    */
+    void QuestItem::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(QuestItem, XMLPort, xmlelement, mode);
+
+        XMLPortParam(QuestItem, "id", setId, getId, xmlelement, mode);
+        XMLPortObject(QuestItem, QuestDescription, "", setDescription, getDescription, xmlelement, mode);
+    }
+
+    /**
+    @brief
+        Sets the id of the QuestItem.
+    The id must be of GUID form. See 'http://en.wikipedia.org/wiki/Globally_Unique_Identifier#Basic_structure' for more information.
+    @param id
+        The id to be set.
+    */
+    void QuestItem::setId(const std::string & id)
+    {
+        if(id.compare(BLANKSTRING) == 0) //!< Checks whether the id is a valid id.
+        {
+            COUT(2) << "Invalid id. QuestItem id {" << id << "} could not be set." << std::endl;
+            return;
+        }
+
+        this->id_ = id;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/QuestItem.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestItem.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestItem.h	(revision 6952)
@@ -0,0 +1,109 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the QuestItem class.
+        The QuestItem is the parent class of Quest and QuestHint.
+*/
+
+
+#ifndef _QuestItem_H__
+#define _QuestItem_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <string>
+#include "core/BaseObject.h"
+#include "QuestManager.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Functions as a base class for quest classes such as Quest or QuestHint.
+        Has a unique identifier and a description.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport QuestItem : public BaseObject
+    {
+
+        public:
+            QuestItem(BaseObject* creator);
+            virtual ~QuestItem();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a QuestItem object through XML.
+
+            /**
+            @brief Returns the id of this QuestItem.
+            @return Returns the id of the QuestItem.
+            */
+            inline const std::string & getId(void) const
+                { return this->id_; }
+
+            /**
+            @brief Returns the QuestDescription of the QuestItem.
+            @return Returns a pointer to the QuestDescription object of the QuestItem.
+            */
+            inline QuestDescription* getDescription(void) const
+                { return this->description_; }
+
+            /**
+            @brief Check whether the QuestItem is registered with the QuestManager.
+            @return Returns true if the QuestItem is registered with the QuestManager.
+            */
+            inline bool isRegistered(void)
+                { return this->registered_; }
+            /**
+            @brief Set the QuestItem as being registered with the QuestManager.
+            */
+            inline void setRegistered(void)
+                { this->registered_ = true; }
+
+        protected:
+            void setId(const std::string & id); //!< Sets the id of the QuestItem.
+
+            /**
+            @brief Sets the description of the QuestItem.
+            @param description The QuestDescription to be set.
+            */
+            inline void setDescription(QuestDescription* description)
+                { this->description_ = description; }
+
+        private:
+            std::string id_; //!< Identifier. Should be of GUID form: http://en.wikipedia.org/wiki/Globally_Unique_Identifier#Basic_structure
+            QuestDescription* description_; //!< The QuestDescription of the QuestItem.
+
+            bool registered_;
+
+    };
+
+}
+
+#endif /* _QuestItem_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/QuestListener.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestListener.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestListener.cc	(revision 6952)
@@ -0,0 +1,213 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the QuestListener class.
+*/
+
+#include "QuestListener.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "Quest.h"
+#include "QuestManager.h"
+
+namespace orxonox
+{
+    CreateFactory(QuestListener);
+
+    /**
+    @brief
+        Constructor. Registers the object and initializes variables.
+    */
+    QuestListener::QuestListener(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(QuestListener);
+
+        this->mode_ = QuestListenerMode::All;
+        this->quest_ = NULL;
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    QuestListener::~QuestListener()
+    {
+    }
+
+    /**
+    @brief
+        Method for creating a Quest object through XML.
+    */
+    void QuestListener::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(QuestListener, XMLPort, xmlelement, mode);
+
+        XMLPortParam(QuestListener, "questId", setQuestId, getQuestId, xmlelement, mode);
+        XMLPortParam(QuestListener, "mode", setMode, getMode, xmlelement, mode);
+
+        if(this->quest_ != NULL)
+            this->quest_->addListener(this); //!< Adds the QuestListener to the Quests list of listeners.
+
+        COUT(4) << "QuestListener created for quest: {" << this->quest_->getId() << "} with mode '" << this->getMode() << "'." << std::endl;
+    }
+
+    /**
+    @brief
+        Makes all QuestListener in the list aware that a certain status change has occurred and executes them if the status change affects them.
+    @param listeners
+        The list of QuestListeners that have to be made aware of the status change.
+    @param status
+        The status that has changed. Can be 'start' (if the Quest was started), 'complete' (if the Quest was completed) or 'fail' (if the Quest was failed).
+    */
+    /* static */ void QuestListener::advertiseStatusChange(std::list<QuestListener*> & listeners, const std::string & status)
+    {
+        for (std::list<QuestListener*>::iterator it = listeners.begin(); it != listeners.end(); ++it) //!< Iterate through all QuestListeners
+        {
+            QuestListener* listener = *it;
+            if(listener->getMode() == status || listener->getMode() == "all") //!< Check whether the status change affects the give QuestListener.
+            {
+                listener->execute();
+            }
+        }
+    }
+
+    /**
+    @brief
+        Sets the questId of the Quest the QuestListener reacts to.
+    @param id
+        The questId of the Quest the QUestListener reacts to.
+    @return
+        Returns true if successful.
+    */
+    bool QuestListener::setQuestId(const std::string & id)
+    {
+        this->quest_ = QuestManager::getInstance().findQuest(id); //!< Find the Quest corresponding to the given questId.
+
+        if(this->quest_ == NULL) //!< If there is no such Quest.
+        {
+            ThrowException(Argument, "This is bad! The QuestListener has not found a Quest with a corresponding id..");
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+    @brief
+        Sets the mode of the QuestListener.
+    @param mode
+        The mode to be set. Can be eighter 'all', 'start', 'fail' or 'complete'.
+    @return
+        Returns true if successful.
+    */
+    bool QuestListener::setMode(const std::string & mode)
+    {
+        if(mode == "all")
+        {
+            this->mode_ = QuestListenerMode::All;
+        }
+        else if(mode == "start")
+        {
+            this->mode_ = QuestListenerMode::Start;
+        }
+        else if(mode == "fail")
+        {
+            this->mode_ = QuestListenerMode::Fail;
+        }
+        else if(mode == "complete")
+        {
+            this->mode_ = QuestListenerMode::Complete;
+        }
+        else
+        {
+            COUT(2) << "QuestListener with invalid mode '" << mode << "' created. Mode set to 'all'." << std::endl;
+        this->mode_ = QuestListenerMode::All;
+        return false;
+        }
+
+        return true;
+    }
+
+    /**
+    @brief
+        Get the mode of the QuestListener.
+    @return
+        Return the mode of the QuestListener. Can be eighter 'all', 'start', 'fail' or 'complete'.
+    */
+    std::string QuestListener::getMode(void)
+    {
+        if(this->mode_ == QuestListenerMode::All)
+        {
+            return "all";
+        }
+        else if(this->mode_ == QuestListenerMode::Start)
+        {
+            return "start";
+        }
+        else if(this->mode_ == QuestListenerMode::Fail)
+        {
+            return "fail";
+        }
+        else if(this->mode_ == QuestListenerMode::Complete)
+        {
+            return "complete";
+        }
+        else
+        {
+            COUT(1) << "An unforseen, never to happen, Error has occurred. This is impossible!" << std::endl;
+            return "";
+        }
+    }
+
+    /**
+    @brief
+        Get the questId of the Quest the QuestListener reacts to.
+    @return
+        Returns the questId of the Quest the QuestListener reacts to.
+    */
+    const std::string & QuestListener::getQuestId(void)
+    {
+        return this->quest_->getId();
+    }
+
+    /**
+    @brief
+        Executes the QuestListener, resp. fires an Event.
+    @return
+        Returns true if successful.
+    */
+    bool QuestListener::execute()
+    {
+        this->fireEvent(true);
+        return true;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/QuestListener.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestListener.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestListener.h	(revision 6952)
@@ -0,0 +1,100 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the QuestListener class.
+*/
+
+#ifndef _QuestListener_H__
+#define _QuestListener_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <string>
+#include <list>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    namespace QuestListenerMode
+    {
+        //! The mode of the QuestListener.
+        enum Value
+        {
+            All,
+            Start,
+            Fail,
+            Complete
+        };
+    }
+
+    /**
+    @brief
+        Provides a way to react to the starting, completing and failing of Quests.
+
+        The XML representation goes as follows:
+        You can use the QuestListener as if it were a Trigger or EventListener, that fires an Event when the status (depending on the set mode) of the given Quest changes.
+
+        <BaseObject> // The object that should react to the status change of a Quest.
+            <events>
+                <function> // Where function is the method of the object that should be executed. Normally this would be visibility or activity.
+                    <QuestListener questId="someQuestId" mode="someMode" /> // Where someQuestId is the identifier for the Quest the QuestListener is reacting to, and someMode is the kind of status change the QUestListener reacts to (all, start, complete or fail).
+                </function>
+            </events>
+        </BaseObject>
+    @author
+    Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport QuestListener : public BaseObject
+    {
+    public:
+        QuestListener(BaseObject* creator);
+        virtual ~QuestListener();
+
+        virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a QuestListener object through XML.
+
+        static void advertiseStatusChange(std::list<QuestListener*> & listeners, const std::string & status); //!< Makes all QuestListener in the list aware that a certain status change has occured.
+
+        bool setQuestId(const std::string & id); //!< Sets the questId of the Quest the QuestListener reacts to.
+        bool setMode(const std::string & mode); //!< Sets the mode of the QuestListener.
+
+        std::string getMode(void); //!< Get the mode of the QuestListener.
+
+        const std::string & getQuestId(void);
+        bool execute(void); //!< Executes the QuestListener, resp. fires an Event.
+
+    private:
+        QuestListenerMode::Value mode_; //!< The mode of the QuestListener.
+        Quest* quest_; //!< A pointer to the Quest the QuestListener is reacting to.
+
+    };
+
+}
+
+#endif /* _QuestListener_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/QuestManager.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestManager.cc	(revision 6952)
@@ -0,0 +1,287 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the QuestManager class.
+*/
+
+#include "QuestManager.h"
+
+#include <CEGUIWindow.h>
+
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "core/GUIManager.h"
+#include "core/ConsoleCommand.h"
+#include "core/LuaState.h"
+#include "core/ScopedSingletonManager.h"
+#include "infos/PlayerInfo.h"
+#include "overlays/GUIOverlay.h"
+
+#include "ToluaBindQuestsystem.h"
+#include "Quest.h"
+#include "QuestHint.h"
+#include "QuestItem.h"
+
+namespace orxonox
+{
+    // Register tolua_open function when loading the library
+    DeclareToluaInterface(Questsystem);
+
+    ManageScopedSingleton(QuestManager, ScopeID::Root, false);
+
+    /**
+    @brief
+        Constructor. Registers the object.
+    @todo
+        Is inheriting from BaseObject proper?
+    */
+    QuestManager::QuestManager()
+    {
+        RegisterRootObject(QuestManager);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    QuestManager::~QuestManager()
+    {
+        for(std::map<PlayerInfo*, QuestGUI*>::iterator it = this->questGUIs_.begin(); it != this->questGUIs_.end(); it++)
+        {
+            it->second->destroy();
+        }
+        this->questGUIs_.clear();
+    }
+
+    /**
+    @brief
+        Retreive all Quests.
+    @return
+        Returns a map with all Quests indexed by their id's.
+    */
+    std::map<std::string, Quest*> & QuestManager::getQuests(void)
+    {
+        return this->questMap_;
+    }
+
+    /**
+    @brief
+        Registers a Quest with the QuestManager to make it globally accessable.
+        Uses it's id to make sure to be able to be identify and retrieve it later.
+    @param quest
+        The Quest that is to be registered.
+    @return
+        Returns true if successful, false if not.
+    */
+    bool QuestManager::registerQuest(Quest* quest)
+    {
+        if(quest == NULL) //!< Doh! Just as if there were actual quests behind NULL-pointers.
+        {
+            COUT(2) << "Registration of Quest in QuestManager failed, because inserted Quest-pointer was NULL." << std::endl;
+            return false;
+        }
+
+        std::pair<std::map<std::string, Quest*>::iterator,bool> result;
+        result = this->questMap_.insert( std::pair<std::string,Quest*>(quest->getId(),quest) ); //!< Inserting the Quest.
+
+        if(result.second) //!< If inserting was a success.
+        {
+            quest->setRegistered();
+            COUT(4) << "Quest with questId {" << quest->getId() << "} successfully inserted." << std::endl;
+            return true;
+        }
+        else
+        {
+           COUT(2) << "Quest with the same id was already present." << std::endl;
+           return false;
+        }
+    }
+
+    /**
+    @brief
+        Unregisters a Quest in the QuestManager.
+    */
+    bool QuestManager::unregisterQuest(Quest* quest)
+    {
+        return this->questMap_.erase(quest->getId()) == 1;
+    }
+
+    /**
+    @brief
+        Registers a QuestHint with the QuestManager to make it globally accessable.
+        Uses it's id to make sure to be able to be identify and retrieve it later.
+    @param hint
+        The QuestHint to be registered.
+    @return
+        Returns true if successful, false if not.
+    */
+    bool QuestManager::registerHint(QuestHint* hint)
+    {
+        if(hint == NULL) //!< Still not liking NULL-pointers.
+        {
+            COUT(2) << "Registration of QuestHint in QuestManager failed, because inserted QuestHint-pointer was NULL." << std::endl;
+            return false;
+        }
+
+        std::pair<std::map<std::string, QuestHint*>::iterator,bool> result;
+        result = this->hintMap_.insert ( std::pair<std::string,QuestHint*>(hint->getId(),hint) ); //!< Inserting the QuestHSint.
+
+        if(result.second) //!< If inserting was a success.
+        {
+            hint->setRegistered();
+            COUT(4) << "QuestHint with hintId {" << hint->getId() << "} successfully inserted." << std::endl;
+            return true;
+        }
+        else
+        {
+           COUT(2) << "QuestHint with the same id was already present." << std::endl;
+           return false;
+        }
+    }
+
+    /**
+    @brief
+        Unregisters a QuestHint in the QuestManager.
+    */
+    bool QuestManager::unregisterHint(QuestHint* hint)
+    {
+        return this->hintMap_.erase(hint->getId()) == 1;
+    }
+
+    /**
+    @brief
+        Finds a Quest with the given id.
+    @param questId
+        The id of the Quest sought for.
+    @return
+        Returns a pointer to the Quest with the input id.
+        Returns NULL if there is no Quest with the given questId.
+    @throws
+        Throws an exception if the given questId is invalid.
+    */
+    Quest* QuestManager::findQuest(const std::string & questId)
+    {
+        if(questId.compare(BLANKSTRING) == 1) //!< Check vor validity of the given id.
+        {
+            ThrowException(Argument, "Invalid questId.");
+        }
+
+        Quest* quest;
+        std::map<std::string, Quest*>::iterator it = this->questMap_.find(questId);
+        if (it != this->questMap_.end()) //!< If the Quest is registered.
+        {
+            quest = it->second;
+        }
+        else
+        {
+           quest = NULL;
+           COUT(2) << "The quest with id {" << questId << "} is nowhere to be found." << std::endl;
+        }
+
+        return quest;
+
+    }
+
+    /**
+    @brief
+        Finds a QuestHint with the given id.
+    @param hintId
+        The id of the QuestHint sought for.
+    @return
+        Returns a pointer to the QuestHint with the input id.
+        Returns NULL if there is no QuestHint with the given hintId.
+    @throws
+        Throws an exception if the given hintId is invalid.
+    */
+    QuestHint* QuestManager::findHint(const std::string & hintId)
+    {
+        if(hintId.compare(BLANKSTRING) == 1) //!< Check vor validity of the given id.
+        {
+            ThrowException(Argument, "Invalid hintId.");
+        }
+
+        QuestHint* hint;
+        std::map<std::string, QuestHint*>::iterator it = this->hintMap_.find(hintId);
+        if (it != this->hintMap_.end()) //!< If the QuestHint is registered.
+        {
+            hint = it->second;
+        }
+        else
+        {
+           hint = NULL;
+           COUT(2) << "The hint with id {" << hintId << "} is nowhere to be found." << std::endl;
+        }
+
+        return hint;
+
+    }
+
+    /**
+    @brief
+        Retreive the main window for the GUI.
+        This is for the use in the lua script tu start the QuestGUI.
+    @param guiName
+        The name of the GUI.
+    @return
+        Returns a CEGUI Window.
+    */
+    CEGUI::Window* QuestManager::getQuestGUI(const std::string & guiName)
+    {
+        PlayerInfo* player = this->retrievePlayer(guiName);
+
+        if(this->questGUIs_.find(player) == this->questGUIs_.end()) //!< Create a new GUI, if there is none, yet.
+            this->questGUIs_[player] = new QuestGUI(player);
+
+        return this->questGUIs_[player]->getGUI();
+    }
+
+    /**
+    @brief
+        Retrieve the player for a certain GUI.
+    @param guiName
+        The name of the GUI the player is retrieved for.
+    @return
+        Returns the player.
+    @todo
+        This very well might be outdated. So: Check if still needed, and update if necessary.
+    */
+    PlayerInfo* QuestManager::retrievePlayer(const std::string & guiName)
+    {
+        PlayerInfo* player = GUIManager::getInstance().getPlayer(guiName);
+        if(player == NULL)
+        {
+            COUT(1) << "Error: GUIOverlay with name '" << guiName << "' has no player." << std::endl;
+            return NULL;
+        }
+
+        return player;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/QuestManager.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestManager.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestManager.h	(revision 6952)
@@ -0,0 +1,101 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the QuestManager class.
+*/
+
+#ifndef _QuestManager_H__
+#define _QuestManager_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+#include <CEGUIForwardRefs.h>
+
+#include <list>
+#include <map>
+#include <string>
+
+#include "util/Singleton.h"
+#include "core/OrxonoxClass.h"
+
+#include "QuestGUI.h"
+
+// tolua_begin
+namespace orxonox
+{
+    /**
+    @brief
+        Is a Singleton and manages Quests, by registering every Quest/QuestHint (through registerX()) and making them globally accessible (through findX()).
+        Quests (and QuestHints) are registered in the QuestManager with their id, and can be accessed in the same way.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport QuestManager
+// tolua_end
+        : public Singleton<QuestManager>, public orxonox::OrxonoxClass
+    { // tolua_export
+
+            friend class Singleton<QuestManager>;
+            friend class QuestGUI;
+
+        public:
+            QuestManager();
+            virtual ~QuestManager();
+
+            //! Returns a reference to the single instance of the Quest Manager.
+            static QuestManager& getInstance() { return Singleton<QuestManager>::getInstance(); } // tolua_export
+
+            //! Retrieve the main window for the GUI.
+            CEGUI::Window* getQuestGUI(const std::string & guiName); // tolua_export
+
+            bool registerQuest(Quest* quest); //!< Registers a Quest in the QuestManager.
+            bool unregisterQuest(Quest* quest); //!< Unregisters a Quest in the QuestManager.
+            bool registerHint(QuestHint* hint); //!< Registers a QuestHint in the QuestManager.
+            bool unregisterHint(QuestHint* hint); //!< Unregisters a QuestHint in the QuestManager.
+
+            Quest* findQuest(const std::string & questId); //!< Returns the Quest with the input id.
+            QuestHint* findHint(const std::string & hintId); //!< Returns the QuestHint with the input id.
+
+        protected:
+            std::map<std::string, Quest*> & getQuests(void); //!< Retrieve all Quests.
+
+        private:
+            static QuestManager* singletonPtr_s;
+            PlayerInfo* retrievePlayer(const std::string & guiName); //!< Retrieve the player for a certain GUI.
+
+            std::map<std::string, Quest*> questMap_; //!< All Quests registered by their id's.
+            std::map<std::string, QuestHint*> hintMap_; //!< All QuestHints registered by their id's.
+
+            std::map<PlayerInfo*, QuestGUI*> questGUIs_; //!< All GUI's registered by the players.
+
+    }; // tolua_export
+
+} // tolua_export
+
+#endif /* _QuestManager_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/QuestNotification.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestNotification.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestNotification.cc	(revision 6952)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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 thes
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "QuestNotification.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox {
+
+    /*static*/ const std::string QuestNotification::SENDER("questsystem");
+
+    CreateUnloadableFactory(QuestNotification);
+    
+    /**
+    @brief
+        Default Constructor. Creates a useless QuestNotification.
+    */
+    QuestNotification::QuestNotification(BaseObject* creator) : Notification(creator)
+    {
+        RegisterObject(QuestNotification);
+    }
+
+    /**
+    @brief
+        Creates a QuestNotification with the input message.
+    @param message
+        The message to be sent.
+    */
+    QuestNotification::QuestNotification(BaseObject* creator, const std::string & message) : Notification(creator, message)
+    {
+        RegisterObject(QuestNotification);
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    QuestNotification::~QuestNotification()
+    {
+
+    }
+
+    /**
+    @brief
+        Send the QuestNotification.
+    @return
+        Returns true if successful.
+    */
+    bool QuestNotification::send(void)
+    {
+        return this->Notification::send(QuestNotification::SENDER);
+    }
+
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/QuestNotification.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestNotification.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestNotification.h	(revision 6952)
@@ -0,0 +1,61 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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 thes
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _QuestNotification_H__
+#define _QuestNotification_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <string>
+#include "notifications/Notification.h"
+
+namespace orxonox {
+
+    /**
+    @brief
+        The QuestNotification is a special Notification that has the single property that it is only sent by the questsystem.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport QuestNotification : public Notification
+    {
+        public:
+            QuestNotification(BaseObject* creator); //!< Default Constructor.
+            QuestNotification(BaseObject* creator, const std::string & message); //!< Constructor.
+            virtual ~QuestNotification(); //!< Destructor.
+
+            bool send(void); //!< Send the QuestNotification.
+
+        private:
+            static const std::string SENDER; //!< A string identifying the questsystem as the sender.
+
+    };
+
+}
+
+#endif /* _QuestNotification_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/QuestsystemPrecompiledHeaders.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestsystemPrecompiledHeaders.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestsystemPrecompiledHeaders.h	(revision 6952)
@@ -0,0 +1,73 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Compilation of the most often used header files in the quest system module
+@details
+    Updated: 19. September 2009
+    Total Files: 24
+*/
+
+#include "OrxonoxConfig.h"
+
+///////////////////////////////////////////
+/////          Stable Headers         /////
+///////////////////////////////////////////
+
+#include <ctime> // 18
+
+#include <OgreMath.h>        // 16
+#include <OgreVector2.h>     // 16
+#include <OgreVector3.h>     // 16
+#include <OgreVector4.h>     // 16
+#include <OgreQuaternion.h>  // 16
+#include <OgreColourValue.h> // 16
+
+#include <tinyxml/ticpp.h>   // 14
+#include "util/Singleton.h"  // 13
+
+///////////////////////////////////////////
+/////       All Rebuild Headers       /////
+///////////////////////////////////////////
+
+#include "core/BaseObject.h"   // 24
+#include "core/CoreIncludes.h" // 23
+
+///////////////////////////////////////////
+/////      Not so Stable Headers      /////
+///////////////////////////////////////////
+
+#include "core/Executor.h"     // 15
+//#include "core/XMLPort.h"    // 14
+
+
+// Just in case some header included windows.h
+#undef min
+#undef max
Index: /code/branches/rocket2/src/modules/questsystem/QuestsystemPrereqs.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/QuestsystemPrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/QuestsystemPrereqs.h	(revision 6952)
@@ -0,0 +1,94 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Shared library macros, enums, constants and forward declarations for the questsystem module
+*/
+
+#ifndef _QuestsystemPrereqs_H__
+#define _QuestsystemPrereqs_H__
+
+#include "OrxonoxConfig.h"
+#include "OrxonoxPrereqs.h"
+
+//-----------------------------------------------------------------------
+// Shared library settings
+//-----------------------------------------------------------------------
+
+#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined(ORXONOX_STATIC_BUILD)
+#  ifdef QUESTSYSTEM_SHARED_BUILD
+#    define _QuestsystemExport __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define _QuestsystemExport
+#    else
+#      define _QuestsystemExport __declspec(dllimport)
+#    endif
+#  endif
+#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _QuestsystemExport  __attribute__ ((visibility("default")))
+#else
+#  define _QuestsystemExport
+#endif
+
+//-----------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    class AddQuest;
+    class AddQuestHint;
+    class AddReward;
+    class ChangeQuestStatus;
+    class CompleteQuest;
+    class FailQuest;
+    class GlobalQuest;
+    class LocalQuest;
+    class Quest;
+    class QuestDescription;
+    class QuestEffect;
+    class QuestEffectBeacon;
+    class QuestGUI;
+    class QuestGUINode;
+    class QuestHint;
+    class QuestItem;
+    class QuestListener;
+    class QuestManager;
+    class QuestNotification;
+
+    // notifications
+    class Notification;
+    class NotificationManager;
+    class NotificationOverlay;
+    class NotificationQueue;
+}
+
+#endif /* _QuestsystemPrereqs_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/notifications/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/notifications/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/notifications/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,6 @@
+ADD_SOURCE_FILES(QUESTSYSTEM_SRC_FILES
+  Notification.cc
+  NotificationManager.cc
+  NotificationOverlay.cc
+  NotificationQueue.cc
+)
Index: /code/branches/rocket2/src/modules/questsystem/notifications/Notification.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/notifications/Notification.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/notifications/Notification.cc	(revision 6952)
@@ -0,0 +1,133 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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 thes
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the Notification class.
+*/
+
+#include "Notification.h"
+
+#include "core/CoreIncludes.h"
+#include "NotificationManager.h"
+
+namespace orxonox
+{
+
+    CreateUnloadableFactory(Notification);
+    
+    /**
+    @brief
+        Default constructor. Initializes the object.
+    */
+    Notification::Notification(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(Notification);
+        this->initialize();
+    }
+
+    /**
+    @brief
+        Constructor. Creates a Notification with the input message.
+    @param message
+        The message of the Notification.
+    */
+    Notification::Notification(BaseObject* creator, const std::string & message) : BaseObject(creator)
+    {
+        this->message_ = message;
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    Notification::~Notification()
+    {
+        
+    }
+
+    /**
+    @brief
+        Registers the object and sets some default values.
+    */
+    void Notification::initialize(void)
+    {
+        this->message_.clear();
+        this->sender_ = NotificationManager::NONE;
+        this->sent_ = false;
+    }
+
+    /**
+    @brief
+        Sends the Notification to the Notificationmanager, with sender NetificationManager::NONE.
+    @return
+        Returns true if successful.
+    */
+    bool Notification::send(void)
+    {
+        return this->send(NotificationManager::NONE);
+    }
+
+    /**
+    @brief
+        Sends the Notification to the Notificationmanager, which then in turn distributes it to the different NotificationQueues.
+    @param sender
+        The sender the Notification was sent by. Used by the NotificationManager to distributes the notification to the correct NotificationQueues.
+    @return
+        Returns true if successful.
+    */
+    bool Notification::send(const std::string & sender)
+    {
+        this->sender_ = sender;
+        bool successful = NotificationManager::getInstance().registerNotification(this);
+        if(!successful)
+            return false;
+        this->sent_ = true;
+
+        COUT(3) << "Notification \"" << this->getMessage() << "\" sent." << std::endl;
+
+        return true;
+    }
+
+    /**
+    @brief
+        Sets the message of the notification.
+    @param message
+        The message to be set.
+    @return
+        Returns true if successful.
+    */
+    bool Notification::setMessage(const std::string & message)
+    {
+        if(this->isSent()) //!< The message cannot be changed if the message has already been sent.
+            return false;
+        this->message_ = message;
+        return true;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/notifications/Notification.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/notifications/Notification.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/notifications/Notification.h	(revision 6952)
@@ -0,0 +1,90 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the Notification class.
+*/
+
+#ifndef _Notification_H__
+#define _Notification_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <string>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        A Notification is a short message used to inform the player about something that just happened. A Notification can be sent from any part of orxonox and is then displayed in the proper NotificationQueue (depending on which senders the specific NotificationQueue accepts).
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport Notification : public BaseObject
+    {
+        public:
+            Notification(BaseObject* creator);
+            Notification(BaseObject* creator, const std::string & message);
+            virtual ~Notification();
+
+            bool send(void); //!< Sends the Notification to the Notificationmanager, with sender NotificationManager::NONE;
+            bool send(const std::string & sender); //!< Sends the Notification to the Notificationmanager.
+
+            /**
+            @brief Checks whether the Notification was sent.
+            @return Returns true if the Notification was sent already.
+            */
+            inline bool isSent(void) const
+                { return this->sent_; }
+            /**
+            @brief Returns the message of the Notification.
+            @return Returns the message of the Notification.
+            */
+            inline const std::string & getMessage(void) const
+                { return this->message_; }
+
+            inline const std::string & getSender(void) const
+                { return this->sender_; }
+
+            bool setMessage(const std::string & message); //!< Sets the message of the notification.
+
+        private:
+            std::string message_; //!< The Notification message.
+            std::string sender_; //!< The sender of the notification.
+            bool sent_; //!< Whether Notification has been sent, if so it cannot be changed.
+
+            void initialize(void);
+
+    };
+
+}
+
+#endif /* _Notification_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/notifications/NotificationManager.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/notifications/NotificationManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/notifications/NotificationManager.cc	(revision 6952)
@@ -0,0 +1,284 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the NotificationManager class.
+*/
+
+#include "NotificationManager.h"
+
+#include <set>
+
+#include "core/CoreIncludes.h"
+#include "core/ScopedSingletonManager.h"
+#include "Notification.h"
+#include "interfaces/NotificationListener.h"
+
+namespace orxonox
+{
+
+    const std::string NotificationManager::ALL("all");
+    const std::string NotificationManager::NONE("none");
+
+    ManageScopedSingleton(NotificationManager, ScopeID::Root, false);
+
+    /**
+    @brief
+        Constructor. Registers the Object.
+    */
+    NotificationManager::NotificationManager()
+    {
+        RegisterRootObject(NotificationManager);
+
+        this->highestIndex_ = 0;
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    NotificationManager::~NotificationManager()
+    {
+        
+    }
+
+    /**
+    @brief
+        Registers a Notification within the NotificationManager and makes sure that the Notification is sent to all the NotificationListeners associated with its sender.
+    @param notification
+        The Notification to be registered.
+    @return
+        Returns true if successful.
+    */
+    bool NotificationManager::registerNotification(Notification* notification)
+    {
+
+        if(notification == NULL) //!< A NULL-Notification cannot be registered.
+            return false;
+
+        std::time_t time = std::time(0); //TODO: Doesn't this expire? //!< Get current time.
+
+        this->allNotificationsList_.insert(std::pair<std::time_t,Notification*>(time,notification));
+
+        if(notification->getSender() == NONE) //!< If the sender has no specific name, then the Notification is only added to the list of all Notifications.
+            return true;
+
+        bool all = false;
+        if(notification->getSender() == ALL) //!< If all are the sender, then the Notifications is added to every NotificationListener.
+            all = true;
+
+        //!< Insert the notification in all listeners that have its sender as target.
+        for(std::map<NotificationListener*,int>::iterator it = this->listenerList_.begin(); it != this->listenerList_.end(); it++) //!< Iterate through all listeners.
+        {
+            std::set<std::string> set = it->first->getTargetsSet();
+            if(all || set.find(notification->getSender()) != set.end() || set.find(ALL) != set.end()) //TODO: Make sure this works.
+            {
+                this->notificationLists_[it->second]->insert(std::pair<std::time_t,Notification*>(time,notification)); //!< Insert the Notification in the Notifications list of the current NotificationListener.
+                it->first->update(notification, time); //!< Update the listener.
+                std::map<Notification*, unsigned int>::iterator counterIt = this->listenerCounter_.find(notification);
+                if(counterIt == this->listenerCounter_.end())
+                    this->listenerCounter_[notification] = 1;
+                else
+                    this->listenerCounter_[notification] = counterIt->second + 1;
+            }
+        }
+
+        COUT(4) << "Notification registered with the NotificationManager." << std::endl;
+
+        return true;
+    }
+
+    /**
+    @brief
+        Unregisters a Notification within the NotificationManager.
+    @param notification
+        A pointer to the Notification to be unregistered.
+    @param listener
+        A pointer to the NotificationListener the Notification is unregistered for.
+    */
+    void NotificationManager::unregisterNotification(Notification* notification, NotificationListener* listener)
+    {
+        assert(notification);
+        assert(listener);
+
+        // If the Notification was removed from the list of Notifications of the input NotificationListener, the counter for the Notification of the number of NotificationListeners it is present in is decremented.
+        if(this->removeNotification(notification, *(this->notificationLists_.find(this->listenerList_.find(listener)->second)->second)))
+            this->listenerCounter_[notification] = this->listenerCounter_[notification] - 1;
+
+        // If the Notification is no longer present in any of the NotificationListeners it can be removed from the map of all Notifications and be destroyed.
+        if(this->listenerCounter_[notification] == (unsigned int) 0)
+        {
+            this->removeNotification(notification, this->allNotificationsList_);
+            this->listenerCounter_.erase(notification);
+            notification->destroy();
+        }
+
+        COUT(4) << "Notification unregistered with the NotificationManager." << std::endl;
+    }
+
+    /**
+    @brief
+        Helper method that removes an input notification form an input map.
+    @param notification
+        A pointer to the notification to be removed.
+    @param map
+        The map the notification should be removed from.
+    @return
+        Returns true if successful.
+    */
+    bool NotificationManager::removeNotification(Notification* notification, std::multimap<std::time_t, Notification*>& map)
+    {
+        // Iterates through all items in the map until the Notification is found.
+        //TODO: Do more efficiently?
+        for(std::multimap<std::time_t, Notification*>::iterator it = map.begin(); it != map.end(); it++)
+        {
+            if(it->second == notification)
+            {
+                map.erase(it);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+    @brief
+        Registers a NotificationListener within the NotificationManager.
+    @param listener
+        The NotificationListener to be registered.
+    @return
+        Returns true if successful.
+    */
+    bool NotificationManager::registerListener(NotificationListener* listener)
+    {
+        this->highestIndex_ += 1;
+        int index = this->highestIndex_;
+
+        this->listenerList_[listener] = index; //!< Add the NotificationListener to the list of listeners.
+
+        std::set<std::string> set = listener->getTargetsSet(); //TODO: Does this work?
+
+        //! If all senders are the target of the listener, then the list of notification for that specific listener is te same as the list of all Notifications.
+        if(set.find(ALL) != set.end())
+        {
+            this->notificationLists_[index] = &this->allNotificationsList_;
+            COUT(4) << "NotificationListener registered with the NotificationManager." << std::endl;
+            return true;
+        }
+
+        this->notificationLists_[index] = new std::multimap<std::time_t,Notification*>;
+        std::multimap<std::time_t,Notification*> map = *this->notificationLists_[index];
+
+        //! Iterate through all Notifications to determine whether any of them should belong to the newly registered NotificationListener.
+        for(std::multimap<std::time_t,Notification*>::iterator it = this->allNotificationsList_.begin(); it != this->allNotificationsList_.end(); it++)
+        {
+            if(set.find(it->second->getSender()) != set.end()) //!< Checks whether the overlay has the sender of the current notification as target.
+            {
+                map.insert(std::pair<std::time_t, Notification*>(it->first, it->second));
+                std::map<Notification*, unsigned int>::iterator counterIt = this->listenerCounter_.find(it->second);
+                if(counterIt == this->listenerCounter_.end())
+                    this->listenerCounter_[it->second] = 1;
+                else
+                    this->listenerCounter_[it->second] = counterIt->second + 1;
+            }
+        }
+
+        listener->update(); //!< Update the listener.
+
+        COUT(4) << "NotificationListener registered with the NotificationManager." << std::endl;
+
+        return true;
+    }
+
+    /**
+    @brief
+        Unregisters a NotificationListener withing the NotificationManager.
+    */
+    void NotificationManager::unregisterListener(NotificationListener* listener)
+    {
+        assert(listener);
+
+        int identifier = this->listenerList_.find(listener)->second;
+        std::multimap<std::time_t, Notification*>* map = this->notificationLists_.find(identifier)->second;
+        
+        // Make sure all Notifications are removed.
+        std::multimap<std::time_t, Notification*>::iterator it = map->begin();
+        while(it != map->end())
+        {
+            this->unregisterNotification(it->second, listener);
+            it = map->begin();
+        }
+
+        this->listenerList_.erase(listener);
+        this->notificationLists_.erase(identifier);
+
+        // If the map is not the map of all notifications, delete it.
+        if(map != &this->allNotificationsList_)
+            delete map;
+
+        COUT(4) << "NotificationListener unregistered with the NotificationManager." << std::endl;
+    }
+
+    /**
+    @brief
+        Fetches the Notifications for a specific NotificationListener in a specified timeframe.
+    @param listener
+        The NotificationListener the Notifications are fetched for.
+    @param map
+        A multimap, in which the notifications are stored.
+    @param timeFrameStart
+        The start time of the timeframe.
+    @param timeFrameEnd
+        The end time of the timeframe.
+    @return
+        Returns true if successful.
+    */
+    bool NotificationManager::getNotifications(NotificationListener* listener, std::multimap<std::time_t,Notification*>* map, const std::time_t & timeFrameStart, const std::time_t & timeFrameEnd)
+    {
+        if(listener == NULL || map == NULL)
+            return false;
+
+        std::multimap<std::time_t,Notification*>* notifications = this->notificationLists_[this->listenerList_[listener]]; //!< The Notifications for the input NotificationListener.
+
+        if(notifications == NULL) //!< Returns NULL, if there are no Notifications.
+            return true;
+
+        std::multimap<std::time_t,Notification*>::iterator it, itLowest, itHighest;
+        itLowest = notifications->lower_bound(timeFrameStart);
+        itHighest = notifications->upper_bound(timeFrameStart);
+
+        for(it = itLowest; it != itHighest; it++) //!< Iterate through the Notifications from the start of the time Frame to the end of it.
+        {
+            map->insert(std::pair<std::time_t,Notification*>(it->first,it->second)); //!< Add the found Notifications to the map.
+        }
+
+        return true;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/notifications/NotificationManager.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/notifications/NotificationManager.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/notifications/NotificationManager.h	(revision 6952)
@@ -0,0 +1,107 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the NotificationManager class.
+*/
+
+#ifndef _NotificationManager_H__
+#define _NotificationManager_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <ctime>
+#include <map>
+#include <string>
+
+#include "util/Singleton.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        The Singleton NotificationManager functions as a gateway between Notifications and NotificationListeners.
+        It receives, organizes Notifications and the redistributes them to the specific NotificationListeners.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport NotificationManager : public Singleton<NotificationManager>, public OrxonoxClass
+    {
+            friend class Singleton<NotificationManager>;
+        public:
+            NotificationManager();
+            virtual ~NotificationManager();
+
+            static const std::string ALL; //!< Static string to indicate a sender that sends to all NotificationListeners.
+            static const std::string NONE; //!< Static string to indicare a sender that sends to no specific NotificationListener.
+
+            bool registerNotification(Notification* notification); //!< Registers a Notification within the NotificationManager.
+            void unregisterNotification(Notification* notification, NotificationListener* listener); //!< Unregisters a Notification within the NotificationManager.
+            bool registerListener(NotificationListener* listener); //!< Registers a NotificationListener within the NotificationManager.
+            void unregisterListener(NotificationListener* listener); //!< Unregisters a NotificationListener withing the NotificationManager.
+
+            bool getNotifications(NotificationListener* listener, std::multimap<std::time_t,Notification*>* map, const std::time_t & timeFrameStart, const std::time_t & timeFrameEnd); //!< Returns the Notifications for a specific NotificationListener in a specified timeframe.
+
+            /**
+            @brief Fetches the Notifications for a specific NotificationListener starting at a specified time.
+            @param listener The NotificationListener the Notifications are fetched for.
+            @param map A multimap, in which the notifications are stored.
+            @param timeFrameStart The start time the Notifications are fetched from.
+            @return Returns true if successful.
+            */
+            bool getNotifications(NotificationListener* listener, std::multimap<std::time_t,Notification*>* map, const std::time_t & timeFrameStart)
+                { return this->getNotifications(listener, map, timeFrameStart, std::time(0)); }
+            /**
+            @brief Fetches the Notifications for a specific NotificationListener starting at a specified timespan before now.
+            @param listener The NotificationListener the Notifications are fetched for.
+            @param map A multimap, in which the notifications are stored.
+            @param timeDelay The timespan.
+            @return Returns true if successful.
+            */
+            bool getNotifications(NotificationListener* listener, std::multimap<std::time_t,Notification*>* map, int timeDelay)
+                { return this->getNotifications(listener, map, std::time(0)-timeDelay, std::time(0)); }
+
+        private:
+            static NotificationManager* singletonPtr_s;
+
+            int highestIndex_; //!< This variable holds the highest index (resp. key) in notificationLists_s, to secure that no key appears twice.
+
+            std::multimap<std::time_t,Notification*> allNotificationsList_; //!< Container where all notifications are stored.
+            std::map<NotificationListener*,int> listenerList_; //!< Container where all NotificationListeners are stored with a number as identifier.
+            std::map<int,std::multimap<std::time_t,Notification*>*> notificationLists_; //!< Container where all Notifications, for each identifier (associated with a NotificationListener), are stored.
+            std::map<Notification*, unsigned int> listenerCounter_; //!< A container to store the number of NotificationListeners a Notification is registered with.
+
+            bool removeNotification(Notification* notification, std::multimap<std::time_t, Notification*>& map); //!< Helper method that removes an input notification form an input map.
+
+    };
+
+}
+
+#endif /* _NotificationManager_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/notifications/NotificationOverlay.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/notifications/NotificationOverlay.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/notifications/NotificationOverlay.cc	(revision 6952)
@@ -0,0 +1,136 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the NotificationOverlay class.
+*/
+
+#include "NotificationOverlay.h"
+
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "Notification.h"
+#include "NotificationQueue.h"
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        Constructor. Intializes the class.
+    */
+    NotificationOverlay::NotificationOverlay(BaseObject* creator) : OverlayText(creator)
+    {
+        RegisterObject(NotificationOverlay);
+        this->initialize();
+    }
+
+    /**
+    @brief
+        Constructor. Initializes the class creates a graphical representation of the input Notification for the input Queue.
+    @param queue
+        A pointer to the queue the NotificatonOverlay belongs to.
+    @param notification
+        A pointer to the Notification represented by this overlay.
+    @throws Argument
+        Throws an Argument-Exception if either no Notification or no NotificationQueue were input.
+    */
+    NotificationOverlay::NotificationOverlay(NotificationQueue* queue, Notification* notification) : OverlayText(NULL)
+    {
+        this->initialize();
+
+        if(notification == NULL || queue == NULL) //!> If either notification or queue are not given an Exception is thrown.
+        {
+            ThrowException(Argument, "There were NULL-Pointer arguments in NotificationOverlay creation.");
+        }
+
+        this->queue_ = queue;
+        this->defineOverlay();
+
+        this->processNotification(notification);
+    }
+
+    /**
+    @brief
+        Initializes and Registers the object.
+    */
+    void NotificationOverlay::initialize(void)
+    {
+        this->queue_ = NULL;
+    }
+
+    /**
+    @brief
+        Set some Overlay-specific values.
+    */
+    void NotificationOverlay::defineOverlay(void)
+    {
+        this->setFont(this->queue_->getFont());
+        this->setTextSize(this->queue_->getFontSize());
+
+        this->setPosition(this->queue_->getPosition());
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    NotificationOverlay::~NotificationOverlay()
+    {
+    }
+
+    /**
+    @brief
+        Processes the input notification, resp. sees to it. that the NotificationOverlay displays the Notification message.
+    @param notification
+        A pointer to the notification that should be processed.
+    @return
+        Returns true if successful.
+    */
+    bool NotificationOverlay::processNotification(Notification* notification)
+    {
+        if(notification == NULL)
+            return false;
+        this->setCaption(clipMessage(notification->getMessage()));
+        this->notification_ = notification;
+        return true;
+    }
+
+    /**
+    @brief
+        Clips the input message so that it meets the requirements for the maximal length of Notifications given by the NotificationQueue.
+    */
+    std::string NotificationOverlay::clipMessage(const std::string & message)
+    {
+        if(message.length() <= static_cast<unsigned int>(this->queue_->getNotificationLength())) //!< If the message is not too long.
+            return message;
+        return message.substr(0, this->queue_->getNotificationLength());
+    }
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/notifications/NotificationOverlay.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/notifications/NotificationOverlay.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/notifications/NotificationOverlay.h	(revision 6952)
@@ -0,0 +1,83 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the NotificationOverlay class.
+*/
+
+
+#ifndef _NotificationOverlay_H__
+#define _NotificationOverlay_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <string>
+#include "overlays/OverlayText.h"
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        The NotificationOverlay is used to display single Notifications, then bundled in a NotificationQUeue.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _QuestsystemExport NotificationOverlay : public OverlayText
+    {
+
+        public:
+            NotificationOverlay(BaseObject* creator);
+            NotificationOverlay(NotificationQueue* queue, Notification* notification);
+            virtual ~NotificationOverlay();
+
+            bool processNotification(Notification* notification); //!< Processes the input Notification.
+
+            /**
+            @brief Sets the font size of this overlay's text.
+            @param size The font size.
+            */
+            inline void setFontSize(float size)
+                { this->setTextSize(size); }
+
+        protected:
+            std::string clipMessage(const std::string & message); //!< Clips the input message if too long.
+
+        private:
+            NotificationQueue* queue_; //!< The NotificationQeue this overlay belongs to.
+            Notification* notification_; //!< The Notification this overlay displays.
+
+            void initialize(void); //!< Initializes the object.
+            void defineOverlay(void); //!< Sets some overlay-specific values.
+
+    };
+
+}
+
+#endif /* _NotificationOverlay_H__ */
Index: /code/branches/rocket2/src/modules/questsystem/notifications/NotificationQueue.cc
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/notifications/NotificationQueue.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/notifications/NotificationQueue.cc	(revision 6952)
@@ -0,0 +1,458 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Implementation of the NotificationQueue class.
+*/
+
+#include "NotificationQueue.h"
+
+#include <sstream>
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "NotificationOverlay.h"
+#include "NotificationManager.h"
+
+namespace orxonox
+{
+
+    CreateFactory(NotificationQueue);
+
+    const std::string NotificationQueue::DEFAULT_FONT("VeraMono");
+    const Vector2 NotificationQueue::DEFAULT_POSITION(0.0,0.0);
+    const float NotificationQueue::DEFAULT_FONT_SIZE = 0.025f;
+
+    /**
+    @brief
+        Constructor. Creates and initializes the object.
+    */
+    NotificationQueue::NotificationQueue(BaseObject* creator) : OverlayGroup(creator)
+    {
+        this->registered_ = false;
+        
+        RegisterObject(NotificationQueue);
+        this->initialize();
+    }
+
+    /**
+    @brief
+        Destructor.
+    */
+    NotificationQueue::~NotificationQueue()
+    {
+        this->targets_.clear();
+        this->clear();
+
+        if(this->registered_)
+            NotificationManager::getInstance().unregisterListener(this);
+    }
+
+    /**
+    @brief
+        Initializes the object.
+        Registers the object, initializes variables, sets default values and registers the queue with the NotificationManager.
+    */
+    void NotificationQueue::initialize(void)
+    {
+        this->size_ = 0;
+        this->tickTime_ = 0.0;
+
+        NotificationManager::getInstance().registerListener(this);
+        this->registered_ = true;
+    }
+
+    /**
+    @brief
+        Sets the defaults.
+    */
+    void NotificationQueue::setDefaults(void)
+    {
+        this->setMaxSize(DEFAULT_SIZE);
+        this->setNotificationLength(DEFAULT_LENGTH);
+        this->setDisplayTime(DEFAULT_DISPLAY_TIME);
+        this->setPosition(DEFAULT_POSITION);
+
+        this->setTargets(NotificationManager::ALL);
+
+        this->setFontSize(DEFAULT_FONT_SIZE);
+        this->setFont(DEFAULT_FONT);
+    }
+
+    /**
+    @brief
+        Method for creating a NotificationQueue object through XML.
+    */
+    void NotificationQueue::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        SUPER(NotificationQueue, XMLPort, xmlElement, mode);
+
+        this->setDefaults();
+
+        XMLPortParam(NotificationQueue, "maxSize", setMaxSize, getMaxSize, xmlElement, mode);
+        XMLPortParam(NotificationQueue, "notificationLength", setNotificationLength, getNotificationLength, xmlElement, mode);
+        XMLPortParam(NotificationQueue, "displayTime", setDisplayTime, getDisplayTime, xmlElement, mode);
+        XMLPortParam(NotificationQueue, "targets", setTargets, getTargets, xmlElement, mode);
+        XMLPortParam(NotificationQueue, "font", setFont, getFont, xmlElement, mode);
+        XMLPortParam(NotificationQueue, "fontSize", setFontSize, getFontSize, xmlElement, mode);
+        XMLPortParam(NotificationQueue, "position", setPosition, getPosition, xmlElement, mode);
+
+        COUT(3) << "NotificationQueue '" << this->getName() << "' created." << std::endl;
+    }
+
+    /**
+    @brief
+        Updates the queue from time to time.
+    @param dt
+        The time interval that has passed since the last tick.
+    */
+    void NotificationQueue::tick(float dt)
+    {
+        this->tickTime_ += dt; //!< Add the time interval that has passed to the time counter.
+        if(this->tickTime_ >= 1.0) //!< If the time counter is greater than 1s all Notifications that have expired are removed, if it is smaller we wait to the next tick.
+        {
+            this->timeLimit_.time = std::time(0)-this->displayTime_; //!< Container containig the current time.
+
+            std::multiset<NotificationOverlayContainer*, NotificationOverlayContainerCompare>::iterator it;
+            it = this->containers_.begin();
+            while(it != this->containers_.upper_bound(&this->timeLimit_)) //!< Iterate through all elements whose creation time is smaller than the current time minus the display time.
+            {
+                this->removeContainer(*it);
+                this->scroll(Vector2(0.0f,-(1.1f*this->getFontSize())));
+                it = this->containers_.begin(); //TODO: Needed?
+            }
+
+            this->tickTime_ = 0.0f; //!< Reset time counter.
+        }
+    }
+
+    /**
+    @brief
+        Updates the NotificationQueue.
+        Updates by clearing the queue and requesting all relevant Notifications from the NotificationManager and inserting the in the queue.
+    */
+    void NotificationQueue::update(void)
+    {
+        this->clear();
+
+        std::multimap<std::time_t,Notification*>* notifications = new std::multimap<std::time_t,Notification*>;
+        if(!NotificationManager::getInstance().getNotifications(this, notifications, this->displayTime_)) //!< Get the Notifications sent in the interval form now to minus the display time.
+        {
+            COUT(1) << "NotificationQueue update failed due to undetermined cause." << std::endl;
+            return;
+        }
+
+        if(notifications->empty())
+            return;
+
+        for(std::multimap<std::time_t,Notification*>::iterator it = notifications->begin(); it != notifications->end(); it++) //!> Add all Notifications.
+        {
+            this->addNotification(it->second, it->first);
+        }
+
+        delete notifications;
+
+        COUT(4) << "NotificationQueue '" << this->getName() << "' updated." << std::endl;
+    }
+
+    /**
+    @brief
+        Updates the NotificationQueue by adding an new Notification.
+    @param notification
+        Pointer to the Notification.
+    @param time
+        The time the Notification was sent.
+    */
+    void NotificationQueue::update(Notification* notification, const std::time_t & time)
+    {
+        this->addNotification(notification, time);
+
+        std::multiset<NotificationOverlayContainer*, NotificationOverlayContainerCompare>::iterator it;
+        while(this->getSize() > this->getMaxSize())
+        {
+            it = this->containers_.begin();
+            this->removeContainer(*it);
+            this->scroll(Vector2(0.0f,-(1.1f*this->getFontSize())));
+        }
+
+        COUT(4) << "NotificationQueue '" << this->getName() << "' updated. A new Notifications has been added." << std::endl;
+    }
+
+    /**
+    @brief
+        Sets the maximum number of displayed Notifications.
+    @param size
+        The size to be set.
+    @return
+        Returns true if successful.
+    */
+    bool NotificationQueue::setMaxSize(int size)
+    {
+        if(size < 0)
+            return false;
+        this->maxSize_ = size;
+        this->update();
+        return true;
+    }
+
+    /**
+    @brief
+        Sets the maximum number of characters a Notification message displayed by this queue is allowed to have.
+    @param length
+        The length to be set.
+    @return
+        Returns true if successful.
+    */
+    bool NotificationQueue::setNotificationLength(int length)
+    {
+        if(length < 0)
+            return false;
+        this->notificationLength_ = length;
+        this->update();
+        return true;
+    }
+
+    /**
+    @brief
+        Sets the maximum number of seconds a Notification is displayed.
+    @param time
+        The number of seconds the Notifications is displayed.
+    @return
+        Returns true if successful.
+    */
+    bool NotificationQueue::setDisplayTime(int time)
+    {
+        if(time < 0)
+            return false;
+        this->displayTime_ = time;
+        this->update();
+        return true;
+    }
+
+    /**
+    @brief
+        Produces all targets concatinated as string, with kommas (',') as seperators.
+    @param string
+        Pointer to a string which will be used by the method to fill with the concatination of the targets.
+    @return
+        Returns true if successful.
+    */
+    bool NotificationQueue::getTargets(std::string* string) const
+    {
+        if(string == NULL)
+        {
+            COUT(4) << "Input string must have memory allocated." << std::endl;
+            return false;
+        }
+        string->clear();
+        bool first = true;
+        for(std::set<std::string>::const_iterator it = this->targets_.begin(); it != this->targets_.end(); it++) //!< Iterate through the set of targets.
+        {
+            if(!first)
+            {
+                *string += ',';
+            }
+            else
+            {
+                first = false;
+            }
+            *string += *it;
+        }
+
+        return true;
+    }
+
+    /**
+    @brief
+        Sets the targets of the queue.
+        The targets are the senders whose Notifications are displayed in this queue.
+    @param targets
+        Accepts a string of targets, each seperated by commas (','), spaces are ignored.
+    @return
+        Returns true if successful.
+    */
+    bool NotificationQueue::setTargets(const std::string & targets)
+    {
+        this->targets_.clear();
+
+        std::string* pTemp;
+        unsigned int index = 0;
+        while( index < targets.size() ) //!< Go through the string, character by character until the end is reached.
+        {
+            pTemp = new std::string();
+            while(index < targets.size() && targets[index] != ',' && targets[index] != ' ')
+            {
+                *pTemp += targets[index];
+                index++;
+            }
+            index++;
+            this->targets_.insert(*pTemp);
+        }
+
+        return true;
+    }
+
+    /**
+    @brief
+        Sets the font size.
+    @param size
+        The font size.
+    @return
+        Returns true if successful.
+    */
+    bool NotificationQueue::setFontSize(float size)
+    {
+        if(size <= 0)
+            return false;
+        this->fontSize_ = size;
+        for (std::map<Notification*, NotificationOverlayContainer*>::iterator it = this->overlays_.begin(); it != this->overlays_.end(); it++) //!< Set the font size for each overlay.
+        {
+            it->second->overlay->setFontSize(size);
+        }
+        return true;
+    }
+
+    /**
+    @brief
+        Sets the font.
+    @param font
+        The font.
+    @return
+        Returns true if successful.
+    */
+    bool NotificationQueue::setFont(const std::string & font)
+    {
+        this->font_ = font;
+        for (std::map<Notification*, NotificationOverlayContainer*>::iterator it = this->overlays_.begin(); it != this->overlays_.end(); it++) //!< Set the font for each overlay.
+        {
+            it->second->overlay->setFont(font);
+        }
+        return true;
+    }
+
+    /**
+    @brief
+        Scrolls the NotificationQueue, meaning all NotificationOverlays are moved the input vector.
+    @param pos
+        The vector the NotificationQueue is scrolled.
+    */
+    void NotificationQueue::scroll(const Vector2 pos)
+    {
+        for (std::map<Notification*, NotificationOverlayContainer*>::iterator it = this->overlays_.begin(); it != this->overlays_.end(); ++it) //!< Scroll each overlay.
+        {
+            it->second->overlay->scroll(pos);
+        }
+    }
+
+    /**
+    @brief
+        Aligns all the Notifications to the position of the NotificationQueue.
+    */
+    void NotificationQueue::positionChanged(void)
+    {
+        int counter = 0;
+        for (std::multiset<NotificationOverlayContainer*, NotificationOverlayContainerCompare>::iterator it = this->containers_.begin(); it != this->containers_.end(); it++) //!< Set the position for each overlay.
+        {
+            (*it)->overlay->setPosition(this->getPosition());
+            (*it)->overlay->scroll(Vector2(0.0f,(1.1f*this->getFontSize())*counter));
+            counter++;
+        }
+    }
+
+    /**
+    @brief
+        Adds a Notification, to the queue.
+        It inserts it into the storage containers, creates an corresponding overlay and a container.
+    @param notification
+        The Notification.
+    @param time
+        The time.
+    */
+    void NotificationQueue::addNotification(Notification* notification, const std::time_t & time)
+    {
+        NotificationOverlayContainer* container = new NotificationOverlayContainer;
+        container->overlay = new NotificationOverlay(this, notification);
+        container->notification = notification;
+        container->time = time;
+        std::string timeString = std::ctime(&time);
+        timeString.erase(timeString.length()-1);
+        std::ostringstream stream;
+        stream << reinterpret_cast<unsigned long>(notification);
+        const std::string& addressString = stream.str();
+        container->name = "NotificationOverlay(" + timeString + ")&" + addressString;
+
+        this->containers_.insert(container);
+        this->overlays_[notification] = container;
+        this->addElement(container->overlay);
+        this->size_= this->size_+1;
+
+        container->overlay->scroll(Vector2(0.0f,(1.1f*this->getFontSize())*(this->getSize()-1)));
+    }
+
+    /**
+    @brief
+        Removes a container from the queue.
+    @param container
+        A pointer to the container.
+    @return
+        Returns true if successful.
+    */
+    bool NotificationQueue::removeContainer(NotificationOverlayContainer* container)
+    {
+        if(this->size_ == 0) //!< You cannot remove anything if the queue is empty.
+            return false;
+
+        // Unregister the NotificationQueue with the NotificationManager.
+        NotificationManager::getInstance().unregisterNotification(container->notification, this);
+        
+        this->removeElement(container->overlay);
+        this->containers_.erase(container);
+        this->overlays_.erase(container->notification);
+        container->overlay->destroy();
+        delete container;
+        this->size_= this->size_-1;
+
+        return true;
+    }
+
+    /**
+    @brief
+        Clears the queue by removing all containers.
+    */
+    void NotificationQueue::clear(void)
+    {
+        std::multiset<NotificationOverlayContainer*, NotificationOverlayContainerCompare>::iterator it = this->containers_.begin();
+        while(it != this->containers_.end())
+        {
+            this->removeContainer(*it);
+            it = this->containers_.begin();
+        }
+    }
+
+}
Index: /code/branches/rocket2/src/modules/questsystem/notifications/NotificationQueue.h
===================================================================
--- /code/branches/rocket2/src/modules/questsystem/notifications/NotificationQueue.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/questsystem/notifications/NotificationQueue.h	(revision 6952)
@@ -0,0 +1,213 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the NotificationQueue class.
+*/
+
+#ifndef _NotificationOueue_H__
+#define _NotificationOueue_H__
+
+#include "questsystem/QuestsystemPrereqs.h"
+
+#include <ctime>
+#include <map>
+#include <set>
+#include <string>
+
+#include "util/Math.h"
+#include "tools/interfaces/Tickable.h"
+#include "overlays/OverlayGroup.h"
+#include "interfaces/NotificationListener.h"
+
+namespace orxonox
+{
+
+    //! Container to allow easy handling.
+    struct NotificationOverlayContainer
+    {
+        NotificationOverlay* overlay; //!< Pointer to the NotificationOverlay, everything is about.
+        Notification* notification; //!< The Notification displayed by the overlay.
+        time_t time; //!< The time the Notification was sent and thus first displayed.
+        std::string name; //!< The name of the overlay.
+    };
+
+    //! Struct to allow ordering of NotificationOverlayContainers.
+    struct NotificationOverlayContainerCompare {
+        bool operator() (const NotificationOverlayContainer* const & a, const NotificationOverlayContainer* const & b) const
+            { return a->time < b->time; } //!< Ordered by time.
+    };
+
+    /**
+    @brief
+        Displays Notifications from specific senders.
+        Beware! The NotificationQueue is an OverlayGruop and thus cannot be be a sub-element of an OverlayGroup (at least no for now.)
+
+        Creating a NotificationQueue through XML goes as follows:
+        Be aware that the NotificationQueue must be inside the <Level></Level> tags or bad things will happen.
+        <NotificationQueue
+            name = "SuperQueue" //Name of your OverlayQueue.
+            maxSize = "5" //The maximum size of Notifications displayed.
+            notificationLength = "64" //The maximum number of characters of a Notification, that are displayed. (Default is 5)
+            displayTime = "30" //The time a Notification is displayed in seconds. (Default is 30)
+            targets = "target1, target2" //The senders this NotificationQueue displays Notifications from. (all, if all Notifications should be displayed.)
+            font = "VeraMono" //The font (Default is VeraMono)
+            fontSize = '0.4' //The font size. (Default is 0.025)
+            position = "0.0, .0.0" //The position of the NotificationQueue. (Default is 0.0,0.0)
+        />
+    @author
+        Damian 'Mozork' Frick
+    */
+
+    class _QuestsystemExport NotificationQueue : public OverlayGroup, public Tickable, public NotificationListener
+    {
+
+        public:
+            NotificationQueue(BaseObject* creator);
+            virtual ~NotificationQueue();
+
+            virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode); //!< Method for creating a NotificationQueue object through XML.
+
+            virtual void tick(float dt); //!< To update from time to time.
+
+            void update(void); //!< Updates the queue.
+            void update(Notification* notification, const std::time_t & time); //!< Adds a Notification to the queue.
+
+            /**
+            @brief Returns the maximum number of Notifications displayed.
+            @return Returns maximum size.
+            */
+            inline int getMaxSize() const
+                { return this->maxSize_; }
+            /**
+            @brief Returns the current number of Notifications displayed.
+            @return Returns the size of the queue.
+            */
+            inline int getSize() const
+                { return this->size_; }
+            /**
+            @brief Returns the maximum length in characters a Notification message is allowed to have.
+            @return Returns the maximum Notification length.
+            */
+            inline int getNotificationLength() const
+                { return this->notificationLength_; }
+            /**
+            @brief Returns the time interval the Notification is displayed.
+            @return Returns the display time.
+            */
+            inline int getDisplayTime() const
+                { return this->displayTime_; }
+            /**
+            @brief Returns the position of the NotificationQueue.
+            @return Returns the position.
+            */
+            inline const Vector2 & getPosition() const
+                { return this->position_; }
+            /**
+            @brief Returns the font size used to display the Notifications.
+            @return  Returns the font size.
+            */
+            inline float getFontSize() const
+                { return this->fontSize_; }
+            /**
+            @brief Returns the font used to display the Notifications.
+            @return Returns the font.
+            */
+            inline const std::string & getFont() const
+                { return this->font_; }
+
+            /**
+            @brief Returns the targets of this queue, reps. the senders which Notifications are displayed in this queue.
+            @return Retuns a set of string holding the different targets.
+            */
+            inline const std::set<std::string> & getTargetsSet()
+                { return this->targets_; }
+            bool getTargets(std::string* string) const; //!< Returns a string consisting of the concatination of the targets.
+
+            /**
+            @brief Sets the position of the NotificationQueue.
+            @param pos The position.
+            */
+            inline void setPosition(Vector2 pos)
+                { this->position_ = pos; this->positionChanged(); }
+
+            void scroll(const Vector2 pos); //!< Scrolls the NotificationQueue, meaning all NotificationOverlays are moved the input vector.
+
+        private:
+            static const int DEFAULT_SIZE = 5; //!< The default maximum number of Notifications displayed.
+            static const int DEFAULT_LENGTH = 64; //!< The default maximum number of Notifications displayed.
+            static const int DEFAULT_DISPLAY_TIME = 30; //!< The default display time.
+            static const float DEFAULT_FONT_SIZE; //!< The default font size.
+
+            static const std::string DEFAULT_FONT; //!< The default font.
+            static const Vector2 DEFAULT_POSITION; //!< the default position.
+
+            int maxSize_; //!< The maximal number of Notifications displayed.
+            int size_; //!< The number of Notifications displayed.
+            int notificationLength_; //!< The maximal number of characters a Notification-message is allowed to have.
+            int displayTime_; //!< The time a Notification is displayed.
+            Vector2 position_; //!< The position of the NotificationQueue.
+
+            std::set<std::string> targets_; //!< The targets the Queue displays Notifications of.
+
+            float fontSize_; //!< The font size.
+            std::string font_; //!< The font.
+
+            std::multiset<NotificationOverlayContainer*, NotificationOverlayContainerCompare> containers_; //!< Multiset, because the ordering is based on, not necessarily unique, timestamps.
+            std::map<Notification*, NotificationOverlayContainer*> overlays_; //!< Mapping notifications to their corresponding overlay containers, for easier association and finding.
+
+            float tickTime_; //!< Helper variable, to not have to check for overlays that have been displayed too long, every tick.
+            NotificationOverlayContainer timeLimit_; //!< Helper object to check against to determine whether Notifications have expired.
+
+            bool registered_; //!< Helper variable to remember whether the NotificationQueue is registered already.
+
+            void initialize(void); //!< Initializes the object.
+            void setDefaults(void); //!< Helper method to set the default values.
+
+            bool setMaxSize(int size); //!< Sets the maximum number of displayed Notifications.
+            bool setNotificationLength(int length); //!< Sets the maximum number of characters a Notification message displayed by this queue is allowed to have.
+            bool setDisplayTime(int time); //!< Sets the maximum number of seconds a Notification is displayed.
+
+            bool setTargets(const std::string & targets); //!< Set the targets of this queue.
+
+            bool setFontSize(float size); //!< Set the font size.
+            bool setFont(const std::string & font); //!< Set the font.
+
+            void positionChanged(void); //!< Aligns all the Notifications to the position of the NotificationQueue.
+
+            void addNotification(Notification* notification, const std::time_t & time); //!< Add a notification to the queue.
+            bool removeContainer(NotificationOverlayContainer* container); //!< Remove a container from the queue.
+
+            void clear(void); //!< Clear the queue.
+
+    };
+
+}
+
+#endif /* _NotificationOverlay_H__ */
Index: /code/branches/rocket2/src/modules/weapons/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/weapons/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,22 @@
+SET_SOURCE_FILES(WEAPONS_SRC_FILES
+  MuzzleFlash.cc
+  RocketController.cc
+)
+
+ADD_SUBDIRECTORY(munitions)
+ADD_SUBDIRECTORY(projectiles)
+ADD_SUBDIRECTORY(weaponmodes)
+
+ORXONOX_ADD_LIBRARY(weapons
+  MODULE
+  FIND_HEADER_FILES
+  PCH_FILE
+    WeaponsPrecompiledHeaders.h
+  DEFINE_SYMBOL
+    "WEAPONS_SHARED_BUILD"
+  LINK_LIBRARIES
+    orxonox
+    # TODO: Remove this as soon as projectiles aren't hardcoded anymore buth rather defined in XML
+    objects
+  SOURCE_FILES ${WEAPONS_SRC_FILES}
+)
Index: /code/branches/rocket2/src/modules/weapons/MuzzleFlash.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/MuzzleFlash.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/MuzzleFlash.cc	(revision 6952)
@@ -0,0 +1,46 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Hagen Seifert
+ *   Co-authors:
+ *      Ich
+ *      Dini Mueter
+ *
+ */
+
+#include "MuzzleFlash.h"
+
+#include "core/CoreIncludes.h"
+#include "core/Executor.h"
+
+namespace orxonox
+{
+    CreateFactory(MuzzleFlash);
+
+    MuzzleFlash::MuzzleFlash(BaseObject* creator) : Billboard(creator)
+    {
+        RegisterObject(MuzzleFlash);
+        this->setScale(0.1f);
+
+        this->delayTimer_.setTimer(0.1f, false, createExecutor(createFunctor(&MuzzleFlash::destroy, this)));
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/MuzzleFlash.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/MuzzleFlash.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/MuzzleFlash.h	(revision 6952)
@@ -0,0 +1,50 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Hagen Seifert
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _MuzzleFlash_H__
+#define _MuzzleFlash_H__
+
+#include "weapons/WeaponsPrereqs.h"
+
+#include "tools/Timer.h"
+#include "graphics/Billboard.h"
+
+namespace orxonox
+{
+    class _WeaponsExport MuzzleFlash : public Billboard
+    {
+        public:
+            MuzzleFlash(BaseObject* creator);
+            virtual ~MuzzleFlash() {}
+
+        private:
+            Timer delayTimer_;
+    };
+}
+
+#endif /* _MuzzleFlash_H__ */
Index: /code/branches/rocket2/src/modules/weapons/RocketController.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/RocketController.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/RocketController.cc	(revision 6952)
@@ -0,0 +1,140 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *     Gabriel Nadler, Originalfile: Oli Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "RocketController.h"
+#include "projectiles/SimpleRocket.h" 
+#include "util/Math.h"
+#include "weapons/projectiles/SimpleRocket.h"
+#include "util/Debug.h"
+#include "weapons/weaponmodes/SimpleRocketFire.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Constructor.
+    */
+    RocketController::RocketController(BaseObject* creator) : Controller(creator)
+    {
+        RegisterObject(RocketController);
+        COUT(5)<< "RocketController constructed\n";
+
+        
+        this->rocket = new SimpleRocket(this);
+        this->rocket->setController(this);
+        this->setControllableEntity(dynamic_cast<ControllableEntity*> (rocket));
+        this->haha=0;
+    }
+
+
+    /**
+    @brief
+        The controlling happens here. This method defines what the controller has to do each tick.
+    @param dt
+        The duration of the tick.
+    */
+    void RocketController::tick(float dt)
+    {
+        haha++;
+
+        //if (haha<30)this->rocket->setVelocity(rocket->getVelocity()*1.03);
+        if (this->target_) {
+            this->setTargetPosition();
+            this->moveToTargetPosition();
+        }
+        if (haha>500) rocket->setDestroy();;
+
+    }
+
+
+    RocketController::~RocketController()
+    {
+        COUT(5)<< "RocketController destroyed\n";
+    }
+
+    void RocketController::setTargetPosition()
+    {
+        //this->targetPosition_=this->target_->getWorldPosition();
+        this->targetPosition_ = getPredictedPosition(this->getControllableEntity()->getWorldPosition(),this->getControllableEntity()->getVelocity().length() , this->target_->getWorldPosition(), this->target_->getVelocity());
+    }
+    void RocketController::moveToTargetPosition()
+    {
+        this->moveToPosition(this->targetPosition_);
+    }
+
+
+
+    void RocketController::setTarget(WorldEntity* target)
+    {
+        this->target_ = target;
+        COUT(0)<<"got target\n";
+    }
+
+    void RocketController::moveToPosition(const Vector3& target)
+    {
+        if (!this->getControllableEntity())
+            return;
+        float dx = target.x-this->getControllableEntity()->getPosition().x;
+        float dy = target.y-this->getControllableEntity()->getPosition().y;
+        COUT(4)<<"\n diff: ";
+        COUT(4)<<target-this->getControllableEntity()->getPosition() << endl;
+        //COUT(0)<<"\n 2D view: ";
+        /* COUT(0)<<this->getControllableEntity()->getPosition().x;
+        COUT(0)<<" ";
+        COUT(0)<<this->getControllableEntity()->getPosition().y;
+        COUT(0)<<" ";
+        COUT(0)<<this->getControllableEntity()->getPosition().z;
+        COUT(0)<<"\n";*/
+        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
+        float distance = (target - this->getControllableEntity()->getPosition()).length();
+        //Vector3D diff =target-this->rocket->getPosition();
+        COUT(4) << "viewdirection: "<< coord << endl;
+        //COUT(0)<<"  ";
+        //COUT(0)<<coord.y;
+        this->getControllableEntity()->rotateYaw(-0.8f*sgn(coord.x)*coord.x*coord.x);
+        this->getControllableEntity()->rotatePitch(0.8f*sgn(coord.y)*coord.y*coord.y);
+//         this->getControllableEntity()->rotateYaw(10);
+//         this->getControllableEntity()->rotatePitch(0);
+        //this->getControllableEntity()->rotatePitch(rotation.getPitch().valueRadians());
+        //this->getControllableEntity()->rotateYaw(rotation.getYaw().valueRadians());
+        //this->getControllableEntity()->moveUpDown(coord.y);
+        //this->getControllableEntity()->moveRightLeft(coord.x);
+        //this->getControllableEntity()->rotatePitch(coord);
+   //     if (this->target_ || distance > 10)
+   //     {
+   //         // Multiply with 0.8 to make them a bit slower
+            //this->getControllableEntity()->rotateYaw(coord.x );
+   //         this->getControllableEntity()->rotatePitch(coord.y);
+   //     }
+    }
+
+
+
+
+}
Index: /code/branches/rocket2/src/modules/weapons/RocketController.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/RocketController.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/RocketController.h	(revision 6952)
@@ -0,0 +1,72 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Gabriel Nadler, Originalfile: Oli Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _RocketController_H__
+#define _RocketController_H__
+
+#include "weapons/WeaponsPrereqs.h"
+
+#include "controllers/Controller.h"
+#include "tools/interfaces/Tickable.h"
+#include "weapons/projectiles/SimpleRocket.h"
+#include "weapons/weaponmodes/SimpleRocketFire.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Controller for the Drone of the PPS tutorial.
+    @author
+        Gabriel Nadler, Originalfile: Oli Scheuss
+    */
+    class _WeaponsExport RocketController : public Controller, public Tickable
+    {
+        public:
+            RocketController(BaseObject* creator);
+			virtual ~RocketController();
+            
+            virtual void tick(float dt);
+			SimpleRocket* getRocket(){return this->rocket;};
+			void setTarget(WorldEntity* target);
+        protected:
+			void moveToPosition(const Vector3& target);
+			void setTargetPosition();
+			void moveToTargetPosition();
+
+        private:
+			SimpleRocket* rocket;
+			Vector3 targetPosition_;
+			WeakPtr<PlayerInfo> player_;
+						int haha;
+			WeakPtr<WorldEntity> target_;
+
+
+    };
+}
+
+#endif /* _RocketController_H__ */
Index: /code/branches/rocket2/src/modules/weapons/WeaponsPrecompiledHeaders.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/WeaponsPrecompiledHeaders.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/WeaponsPrecompiledHeaders.h	(revision 6952)
@@ -0,0 +1,66 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Compilation of the most often used header files in the weapons module
+@details
+    Updated: 13. September 2009
+    Total Files: 13
+*/
+
+#include "OrxonoxConfig.h"
+
+///////////////////////////////////////////
+/////          Stable Headers         /////
+///////////////////////////////////////////
+
+#include <LinearMath/btMotionState.h> // 10
+#include "util/OgreForwardRefs.h"     // 10
+
+///////////////////////////////////////////
+/////       All Rebuild Headers       /////
+///////////////////////////////////////////
+
+#include "core/CoreIncludes.h" // 13
+#include "core/BaseObject.h" // 13
+#include "tools/Timer.h" // 13
+
+///////////////////////////////////////////
+/////      Not so Stable Headers      /////
+///////////////////////////////////////////
+
+#include "network/synchronisable/Synchronisable.h" // 10
+//#include "worldentities/WorldEntity.h"      // 10
+//#include "weapons/projectiles/Projectile.h" // 9
+
+
+// Just in case some header included windows.h
+#undef min
+#undef max
Index: /code/branches/rocket2/src/modules/weapons/WeaponsPrereqs.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/WeaponsPrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/WeaponsPrereqs.h	(revision 6952)
@@ -0,0 +1,88 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Shared library macros, enums, constants and forward declarations for the weapons module
+*/
+
+#ifndef _WeaponsPrereqs_H__
+#define _WeaponsPrereqs_H__
+
+#include "OrxonoxConfig.h"
+#include "OrxonoxPrereqs.h"
+
+//-----------------------------------------------------------------------
+// Shared library settings
+//-----------------------------------------------------------------------
+
+#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined(ORXONOX_STATIC_BUILD)
+#  ifdef WEAPONS_SHARED_BUILD
+#    define _WeaponsExport __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define _WeaponsExport
+#    else
+#      define _WeaponsExport __declspec(dllimport)
+#    endif
+#  endif
+#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _WeaponsExport  __attribute__ ((visibility("default")))
+#else
+#  define _WeaponsExport
+#endif
+
+//-----------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    class MuzzleFlash;
+
+    // munitions
+    class FusionMunition;
+    class LaserMunition;
+    class ReplenishingMunition;
+
+    // projectiles
+    class BillboardProjectile;
+    class LightningGunProjectile;
+    class ParticleProjectile;
+    class Projectile;
+
+    // weaponmodes
+    class EnergyDrink;
+    class FusionFire;
+    class HsW01;
+    class LaserFire;
+    class LightningGun;
+}
+
+#endif /* _WeaponsPrereqs_H__ */
Index: /code/branches/rocket2/src/modules/weapons/munitions/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/weapons/munitions/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/munitions/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,5 @@
+ADD_SOURCE_FILES(WEAPONS_SRC_FILES
+  ReplenishingMunition.cc
+  LaserMunition.cc
+  FusionMunition.cc
+)
Index: /code/branches/rocket2/src/modules/weapons/munitions/FusionMunition.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/munitions/FusionMunition.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/munitions/FusionMunition.cc	(revision 6952)
@@ -0,0 +1,51 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "FusionMunition.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    CreateFactory(FusionMunition);
+
+    FusionMunition::FusionMunition(BaseObject* creator) : Munition(creator)
+    {
+        RegisterObject(FusionMunition);
+
+        this->maxMunitionPerMagazine_ = 10;
+        this->maxMagazines_ = 10;
+        this->magazines_ = 10;
+
+        this->bUseSeparateMagazines_ = true;
+        this->bStackMunition_ = false;
+        this->reloadTime_ = 1.0f;
+
+        this->bAllowMunitionRefilling_ = true;
+        this->bAllowMultiMunitionRemovementUnderflow_ = true;
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/munitions/FusionMunition.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/munitions/FusionMunition.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/munitions/FusionMunition.h	(revision 6952)
@@ -0,0 +1,45 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _FusionMunition_H__
+#define _FusionMunition_H__
+
+#include "weapons/WeaponsPrereqs.h"
+#include "weaponsystem/Munition.h"
+
+namespace orxonox
+{
+    class _WeaponsExport FusionMunition : public Munition
+    {
+        public:
+            FusionMunition(BaseObject* creator);
+            virtual ~FusionMunition() {}
+    };
+}
+
+#endif /* _FusionMunition_H__ */
Index: /code/branches/rocket2/src/modules/weapons/munitions/LaserMunition.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/munitions/LaserMunition.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/munitions/LaserMunition.cc	(revision 6952)
@@ -0,0 +1,53 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "LaserMunition.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    CreateFactory(LaserMunition);
+
+    LaserMunition::LaserMunition(BaseObject* creator) : ReplenishingMunition(creator)
+    {
+        RegisterObject(LaserMunition);
+
+        this->maxMunitionPerMagazine_ = 20;
+        this->maxMagazines_ = 1;
+        this->magazines_ = 1;
+
+        this->bUseSeparateMagazines_ = false;
+        this->bStackMunition_ = true;
+
+        this->bAllowMunitionRefilling_ = true;
+        this->bAllowMultiMunitionRemovementUnderflow_ = true;
+
+        this->replenishIntervall_ = 0.5f;
+        this->replenishMunitionAmount_ = 1;
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/munitions/LaserMunition.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/munitions/LaserMunition.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/munitions/LaserMunition.h	(revision 6952)
@@ -0,0 +1,45 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _LaserMunition_H__
+#define _LaserMunition_H__
+
+#include "weapons/WeaponsPrereqs.h"
+#include "ReplenishingMunition.h"
+
+namespace orxonox
+{
+    class _WeaponsExport LaserMunition : public ReplenishingMunition
+    {
+        public:
+            LaserMunition(BaseObject* creator);
+            virtual ~LaserMunition() {}
+    };
+}
+
+#endif /* _LaserMunition_H__ */
Index: /code/branches/rocket2/src/modules/weapons/munitions/ReplenishingMunition.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/munitions/ReplenishingMunition.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/munitions/ReplenishingMunition.cc	(revision 6952)
@@ -0,0 +1,68 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ReplenishingMunition.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    CreateFactory(ReplenishingMunition);
+
+    ReplenishingMunition::ReplenishingMunition(BaseObject* creator) : Munition(creator)
+    {
+        RegisterObject(ReplenishingMunition);
+
+        this->replenishIntervall_ = 1.0f;
+        this->replenishMunitionAmount_ = 1;
+
+        // Use the timer to initialize itself after the first tick (because the real values for
+        // replenishIntervall_ and replenishMunitionAmount_ will be set in the constructor of the
+        // inheriting class, which comes after this constructor)
+        this->replenishingTimer_.setTimer(0.0f, false, createExecutor(createFunctor(&ReplenishingMunition::initializeTimer, this)));
+    }
+
+    void ReplenishingMunition::initializeTimer()
+    {
+        // Initialize the timer
+        this->replenishingTimer_.setTimer(this->replenishIntervall_, true, createExecutor(createFunctor(&ReplenishingMunition::replenish, this)));
+    }
+
+    void ReplenishingMunition::replenish()
+    {
+        // Make a temporary copy of bAllowMunitionRefilling_, because this might be disallowed in every
+        // case except the internal munition replenishing
+        bool temp = this->bAllowMunitionRefilling_;
+        this->bAllowMunitionRefilling_ = true;
+
+        // Replenish munition
+        this->addMunition(this->replenishMunitionAmount_);
+
+        // Write back the temporary value
+        this->bAllowMunitionRefilling_ = temp;
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/munitions/ReplenishingMunition.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/munitions/ReplenishingMunition.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/munitions/ReplenishingMunition.h	(revision 6952)
@@ -0,0 +1,57 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ReplenishingMunition_H__
+#define _ReplenishingMunition_H__
+
+#include "weapons/WeaponsPrereqs.h"
+
+#include "tools/Timer.h"
+#include "weaponsystem/Munition.h"
+
+namespace orxonox
+{
+    class _WeaponsExport ReplenishingMunition : public Munition
+    {
+        public:
+            ReplenishingMunition(BaseObject* creator);
+            virtual ~ReplenishingMunition() {}
+
+        protected:
+            float replenishIntervall_;
+            unsigned int replenishMunitionAmount_;
+
+        private:
+            void replenish();
+            void initializeTimer();
+
+            Timer replenishingTimer_;
+    };
+}
+
+#endif /* _ReplenishingMunition_H__ */
Index: /code/branches/rocket2/src/modules/weapons/projectiles/BillboardProjectile.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/projectiles/BillboardProjectile.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/projectiles/BillboardProjectile.cc	(revision 6952)
@@ -0,0 +1,75 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "BillboardProjectile.h"
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    CreateFactory(BillboardProjectile);
+
+    BillboardProjectile::BillboardProjectile(BaseObject* creator) : Projectile(creator)
+    {
+        RegisterObject(BillboardProjectile);
+
+        if (GameMode::showsGraphics())
+        {
+            assert(this->getScene()->getSceneManager()); // getScene() was already checked by WorldEntity
+            this->billboard_.setBillboardSet(this->getScene()->getSceneManager(), "Examples/Flare", ColourValue(0.5f, 0.5f, 0.7f, 0.8f), 1);
+            this->attachOgreObject(this->billboard_.getBillboardSet());
+        }
+
+        this->setScale(0.2f);
+    }
+
+    BillboardProjectile::~BillboardProjectile()
+    {
+        if (this->isInitialized() && GameMode::showsGraphics() && this->billboard_.getBillboardSet())
+            this->detachOgreObject(this->billboard_.getBillboardSet());
+    }
+
+    void BillboardProjectile::setColour(const ColourValue& colour)
+    {
+        this->billboard_.setColour(colour);
+    }
+
+    void BillboardProjectile::setMaterial(const std::string& material)
+    {
+        this->billboard_.setMaterial(material);
+    }
+
+    void BillboardProjectile::changedVisibility()
+    {
+        SUPER(BillboardProjectile, changedVisibility);
+
+        this->billboard_.setVisible(this->isVisible());
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/projectiles/BillboardProjectile.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/projectiles/BillboardProjectile.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/projectiles/BillboardProjectile.h	(revision 6952)
@@ -0,0 +1,55 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _BillboardProjectile_H__
+#define _BillboardProjectile_H__
+
+#include "weapons/WeaponsPrereqs.h"
+
+#include "util/Math.h"
+#include "tools/BillboardSet.h"
+#include "Projectile.h"
+
+namespace orxonox
+{
+    class _WeaponsExport BillboardProjectile : public Projectile
+    {
+        public:
+            BillboardProjectile(BaseObject* creator);
+            virtual ~BillboardProjectile();
+
+            virtual void setColour(const ColourValue& colour);
+            virtual void setMaterial(const std::string& material);
+            virtual void changedVisibility();
+
+        private:
+            BillboardSet billboard_;
+    };
+}
+
+#endif /* _BillboardProjectile_H__ */
Index: /code/branches/rocket2/src/modules/weapons/projectiles/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/weapons/projectiles/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/projectiles/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,8 @@
+ADD_SOURCE_FILES(WEAPONS_SRC_FILES
+  BillboardProjectile.cc
+  ParticleProjectile.cc
+  Projectile.cc
+  LightningGunProjectile.cc
+  Rocket.cc
+  SimpleRocket.cc
+)
Index: /code/branches/rocket2/src/modules/weapons/projectiles/LightningGunProjectile.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/projectiles/LightningGunProjectile.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/projectiles/LightningGunProjectile.cc	(revision 6952)
@@ -0,0 +1,69 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Joel Smely
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "LightningGunProjectile.h"
+
+#include "util/Convert.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    CreateFactory(LightningGunProjectile);
+
+    LightningGunProjectile::LightningGunProjectile(BaseObject* creator) : BillboardProjectile(creator)
+    {
+        RegisterObject(LightningGunProjectile);
+
+        this->textureIndex_ = 1;
+        this->maxTextureIndex_ = 8;
+        this->textureTimer_.setTimer(0.01f, true, createExecutor(createFunctor(&LightningGunProjectile::changeTexture, this)));
+
+        registerVariables();
+    }
+
+    void LightningGunProjectile::registerVariables()
+    {
+        registerVariable(this->materialBase_);
+    }
+
+    void LightningGunProjectile::setMaterial(const std::string& material)
+    {
+        this->materialBase_ = material;
+
+        BillboardProjectile::setMaterial(material + multi_cast<std::string>(this->textureIndex_));
+    }
+
+    void LightningGunProjectile::changeTexture()
+    {
+        this->textureIndex_++;
+        if (this->textureIndex_ > this->maxTextureIndex_)
+            this->textureIndex_ = 1;
+
+        this->setMaterial(this->materialBase_);
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/projectiles/LightningGunProjectile.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/projectiles/LightningGunProjectile.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/projectiles/LightningGunProjectile.h	(revision 6952)
@@ -0,0 +1,59 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Joel Smely
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _LightningGunProjectile_H__
+#define _LightningGunProjectile_H__
+
+#include "weapons/WeaponsPrereqs.h"
+
+#include <string>
+#include "tools/Timer.h"
+#include "BillboardProjectile.h"
+
+namespace orxonox
+{
+    class _WeaponsExport LightningGunProjectile : public BillboardProjectile
+    {
+        public:
+            LightningGunProjectile(BaseObject* creator);
+            virtual ~LightningGunProjectile() {}
+
+            virtual void setMaterial(const std::string& material);
+
+        protected:
+            void changeTexture();
+            unsigned int textureIndex_;
+            unsigned int maxTextureIndex_;
+            Timer textureTimer_;
+            std::string materialBase_;
+      private:
+            void registerVariables();
+    };
+}
+
+#endif /* _LightningGunProjectile_H__ */
Index: /code/branches/rocket2/src/modules/weapons/projectiles/ParticleProjectile.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/projectiles/ParticleProjectile.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/projectiles/ParticleProjectile.cc	(revision 6952)
@@ -0,0 +1,72 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ParticleProjectile.h"
+
+#include <OgreParticleEmitter.h>
+#include "tools/ParticleInterface.h"
+#include "core/CoreIncludes.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    CreateFactory(ParticleProjectile);
+
+    ParticleProjectile::ParticleProjectile(BaseObject* creator) : BillboardProjectile(creator)
+    {
+        RegisterObject(ParticleProjectile);
+
+        if (GameMode::showsGraphics())
+        {
+            this->particles_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/shot3_small", LODParticle::Normal);
+            this->attachOgreObject(this->particles_->getParticleSystem());
+            this->particles_->setKeepParticlesInLocalSpace(0);
+
+            this->particles_->getAllEmitters()->setDirection(-WorldEntity::FRONT);
+        }
+        else
+            this->particles_ = 0;
+    }
+
+    ParticleProjectile::~ParticleProjectile()
+    {
+        if (this->isInitialized() && this->particles_)
+        {
+            this->detachOgreObject(this->particles_->getParticleSystem());
+            this->particles_->destroy();
+        }
+    }
+
+    void ParticleProjectile::changedVisibility()
+    {
+        SUPER(ParticleProjectile, changedVisibility);
+
+        if (this->particles_)
+            this->particles_->setEnabled(this->isVisible());
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/projectiles/ParticleProjectile.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/projectiles/ParticleProjectile.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/projectiles/ParticleProjectile.h	(revision 6952)
@@ -0,0 +1,49 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ParticleProjectile_H__
+#define _ParticleProjectile_H__
+
+#include "weapons/WeaponsPrereqs.h"
+#include "BillboardProjectile.h"
+
+namespace orxonox
+{
+    class _WeaponsExport ParticleProjectile : public BillboardProjectile
+    {
+        public:
+            ParticleProjectile(BaseObject* creator);
+            virtual ~ParticleProjectile();
+            virtual void changedVisibility();
+
+        private:
+            ParticleInterface* particles_;
+    };
+}
+
+#endif /* _ParticleProjectile_H__ */
Index: /code/branches/rocket2/src/modules/weapons/projectiles/Projectile.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/projectiles/Projectile.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/projectiles/Projectile.cc	(revision 6952)
@@ -0,0 +1,136 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Projectile.h"
+
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/Executor.h"
+#include "core/GameMode.h"
+#include "objects/collisionshapes/SphereCollisionShape.h"
+#include "worldentities/pawns/Pawn.h"
+#include "graphics/ParticleSpawner.h"
+
+namespace orxonox
+{
+    CreateFactory(Projectile);
+
+    Projectile::Projectile(BaseObject* creator) : MovableEntity(creator)
+    {
+        RegisterObject(Projectile);
+
+        this->setConfigValues();
+        this->bDestroy_ = false;
+        this->owner_ = 0;
+        this->damage_ = 15;
+
+        // Get notification about collisions
+
+        if (GameMode::isMaster())
+        {
+            this->setMass(1.0);
+            this->enableCollisionCallback();
+            this->setCollisionResponse(false);
+            this->setCollisionType(Kinematic);
+
+            SphereCollisionShape* shape = new SphereCollisionShape(this);
+            shape->setRadius(20);
+            this->attachCollisionShape(shape);
+
+            this->destroyTimer_.setTimer(this->lifetime_, false, createExecutor(createFunctor(&Projectile::destroyObject, this)));
+        }
+    }
+
+    Projectile::~Projectile()
+    {
+    }
+
+    void Projectile::setConfigValues()
+    {
+        SetConfigValue(lifetime_, 4.0).description("The time in seconds a projectile stays alive");
+    }
+
+
+    void Projectile::tick(float dt)
+    {
+        SUPER(Projectile, tick, dt);
+
+        if (!this->isActive())
+            return;
+
+        if (this->bDestroy_)
+            this->destroy(); // TODO: use a scheduler instead of deleting the object right here in tick()
+    }
+
+    void Projectile::destroyObject()
+    {
+        if (GameMode::isMaster())
+            this->destroy();
+    }
+
+    bool Projectile::collidesAgainst(WorldEntity* otherObject, btManifoldPoint& contactPoint)
+    {
+        if (!this->bDestroy_ && GameMode::isMaster())
+        {
+            if (otherObject == this->owner_)
+                return false;
+
+            this->bDestroy_ = true;
+
+            if (this->owner_)
+            {
+                {
+                    ParticleSpawner* effect = new ParticleSpawner(this->owner_->getCreator());
+                    effect->setPosition(this->getPosition());
+                    effect->setOrientation(this->getOrientation());
+                    effect->setDestroyAfterLife(true);
+                    effect->setSource("Orxonox/explosion3");
+                    effect->setLifetime(2.0f);
+                }
+                {
+                    ParticleSpawner* effect = new ParticleSpawner(this->owner_->getCreator());
+                    effect->setPosition(this->getPosition());
+                    effect->setOrientation(this->getOrientation());
+                    effect->setDestroyAfterLife(true);
+                    effect->setSource("Orxonox/smoke4");
+                    effect->setLifetime(3.0f);
+                }
+            }
+
+            Pawn* victim = orxonox_cast<Pawn*>(otherObject);
+            if (victim)
+                victim->hit(this->owner_, contactPoint, this->damage_);
+        }
+        return false;
+    }
+
+    void Projectile::setOwner(Pawn* owner)
+    {
+        this->owner_ = owner;
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/projectiles/Projectile.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/projectiles/Projectile.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/projectiles/Projectile.h	(revision 6952)
@@ -0,0 +1,69 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Projectile_H__
+#define _Projectile_H__
+
+#include "weapons/WeaponsPrereqs.h"
+
+#include "tools/Timer.h"
+#include "worldentities/MovableEntity.h"
+
+namespace orxonox
+{
+    class _WeaponsExport Projectile : public MovableEntity
+    {
+        public:
+            Projectile(BaseObject* creator);
+            virtual ~Projectile();
+
+            void setConfigValues();
+            void destroyObject();
+
+            virtual void tick(float dt);
+            virtual bool collidesAgainst(WorldEntity* otherObject, btManifoldPoint& contactPoint);
+
+            inline void setDamage(float damage)
+                { this->damage_ = damage; }
+            inline float getDamage() const
+                { return this->damage_; }
+
+            void setOwner(Pawn* owner);
+            inline Pawn* getOwner() const
+                { return this->owner_; }
+
+        private:
+            WeakPtr<Pawn> owner_;
+            float lifetime_;
+            float damage_;
+            bool bDestroy_;
+            Timer destroyTimer_;
+    };
+}
+
+#endif /* _Projectile_H__ */
Index: /code/branches/rocket2/src/modules/weapons/projectiles/Rocket.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/projectiles/Rocket.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/projectiles/Rocket.cc	(revision 6952)
@@ -0,0 +1,289 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Rocket.h"
+
+#include <BulletDynamics/Dynamics/btRigidBody.h>
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "worldentities/CameraPosition.h"
+#include "worldentities/pawns/Pawn.h"
+#include "graphics/ParticleSpawner.h"
+#include "graphics/Model.h"
+#include "objects/collisionshapes/ConeCollisionShape.h"
+#include "infos/PlayerInfo.h"
+#include "controllers/Controller.h"
+#include "sound/WorldSound.h"
+
+namespace orxonox
+{
+    CreateFactory(Rocket);
+    // create the factory for the Rocket
+
+    /**
+    @brief
+        Constructor. Registers the object and initializes some default values.
+    */
+    Rocket::Rocket(BaseObject* creator) : ControllableEntity(creator)
+    {
+        RegisterObject(Rocket);// - register the Rocket class to the core
+
+        this->localAngularVelocity_ = 0;
+        this->bDestroy_ = false;
+        this->lifetime_ = 100;
+
+        if (GameMode::isMaster())
+        {
+            this->setCollisionType(WorldEntity::Kinematic);
+            this->setVelocity(0,0,-100);
+
+            Model* model = new Model(this);
+            model->setMeshSource("rocket.mesh");
+            model->scale(0.7f);
+            this->attach(model);
+            ParticleEmitter* fire = new ParticleEmitter(this);
+            this->attach(fire);
+            fire->setOrientation(this->getOrientation());
+            fire->setSource("Orxonox/rocketfire");
+
+            this->enableCollisionCallback();
+            this->setCollisionResponse(false);
+            this->setCollisionType(Kinematic);
+
+            ConeCollisionShape* collisionShape = new ConeCollisionShape(this);
+            collisionShape->setRadius(3);
+            collisionShape->setHeight(500);
+            this->attachCollisionShape(collisionShape);
+
+            this->destroyTimer_.setTimer(this->lifetime_, false, createExecutor(createFunctor(&Rocket::destroyObject, this)));
+
+            this->defSndWpnEngine_ = new WorldSound(this);
+            this->defSndWpnEngine_->setLooping(true);
+            this->defSndWpnEngine_->setSource("sounds/Rocket_engine.ogg");
+            this->attach(defSndWpnEngine_);
+
+            this->defSndWpnLaunch_ = new WorldSound(this);
+            this->defSndWpnLaunch_->setLooping(false);
+            this->defSndWpnLaunch_->setSource("sounds/Rocket_launch.ogg");
+            this->attach(defSndWpnLaunch_);
+        }
+        else
+        {
+            this->defSndWpnEngine_ = 0;
+            this->defSndWpnLaunch_ = 0;
+        }
+
+        CameraPosition* camPosition = new CameraPosition(this);
+        camPosition->setPosition(0,4,15);
+        camPosition->setAllowMouseLook(true);
+        this->addCameraPosition(camPosition);
+    }
+
+    /**
+    @brief
+        Destructor. Destroys controller, if present and kills sounds, if playing.
+    */
+    Rocket::~Rocket()
+    {
+        if(this->isInitialized())
+        {
+            if (GameMode::isMaster() && this->player_)
+                this->player_->stopTemporaryControl();
+
+            if ( this->defSndWpnEngine_ )
+                this->defSndWpnEngine_->destroy();
+
+            if ( this->defSndWpnLaunch_ )
+                this->defSndWpnLaunch_->destroy();
+        }
+    }
+
+    /**
+    @brief
+        Method for creating a Rocket through XML.
+    */
+    void Rocket::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        // this calls the XMLPort function of the parent class
+        SUPER(Rocket, XMLPort, xmlelement, mode);
+    }
+
+    void Rocket::setOwner(Pawn* owner)
+    {
+        this->owner_ = owner;
+        this->originalControllableEntity_ = this->owner_->getPlayer()->getControllableEntity();
+        this->player_ = this->owner_->getPlayer();
+        this->owner_->getPlayer()->startTemporaryControl(this);
+
+        if( GameMode::isMaster() )
+        {
+            this->defSndWpnEngine_->play();
+            this->defSndWpnLaunch_->play();
+        }
+    }
+
+    /**
+    @brief
+        Defines which actions the Rocket has to take in each tick.
+    @param dt
+        The length of the tick.
+    */
+    void Rocket::tick(float dt)
+    {
+        SUPER(Rocket, tick, dt);
+
+        if( this->hasLocalController() )
+        {
+            this->setAngularVelocity(this->getOrientation() * this->localAngularVelocity_);
+            this->setVelocity( this->getOrientation()*WorldEntity::FRONT*this->getVelocity().length() );
+            this->localAngularVelocity_ = 0;
+
+            if( this->bDestroy_ )
+                this->destroy();
+        }
+    }
+
+    bool Rocket::collidesAgainst(WorldEntity* otherObject, btManifoldPoint& contactPoint)
+    {
+        if (!this->bDestroy_ && GameMode::isMaster())
+        {
+            if (otherObject == this->owner_)
+                return false;
+
+            this->bDestroy_ = true;
+
+            if (this->owner_)
+            {
+                {
+                    ParticleSpawner* effect = new ParticleSpawner(this->owner_->getCreator());
+                    effect->setPosition(this->getPosition());
+                    effect->setOrientation(this->getOrientation());
+                    effect->setDestroyAfterLife(true);
+                    effect->setSource("Orxonox/explosion4");
+                    effect->setLifetime(2.0f);
+                }
+
+                {
+                    ParticleSpawner* effect = new ParticleSpawner(this->owner_->getCreator());
+                    effect->setPosition(this->getPosition());
+                    effect->setOrientation(this->getOrientation());
+                    effect->setDestroyAfterLife(true);
+                    effect->setSource("Orxonox/smoke4");
+                    effect->setLifetime(3.0f);
+                }
+            }
+
+            Pawn* victim = orxonox_cast<Pawn*>(otherObject);
+            if (victim)
+                victim->hit(this->owner_, contactPoint, this->damage_);
+//             this->destroy();
+        }
+        return false;
+    }
+
+    void Rocket::destroyObject()
+    {
+        if (GameMode::isMaster())
+        {
+            if(this->defSndWpnEngine_->isPlaying())
+            {
+                this->defSndWpnEngine_->stop();
+            }
+            this->destroy();
+        }
+    }
+
+    void Rocket::fired(unsigned int firemode)
+    {
+        if (this->owner_)
+        {
+            {
+                ParticleSpawner* effect = new ParticleSpawner(this->owner_->getCreator());
+                effect->setPosition(this->getPosition());
+                effect->setOrientation(this->getOrientation());
+                effect->setDestroyAfterLife(true);
+                effect->setSource("Orxonox/explosion4");
+                effect->setLifetime(2.0f);
+            }
+
+            {
+                ParticleSpawner* effect = new ParticleSpawner(this->owner_->getCreator());
+                effect->setPosition(this->getPosition());
+                effect->setOrientation(this->getOrientation());
+                effect->setDestroyAfterLife(true);
+                effect->setSource("Orxonox/smoke4");
+                effect->setLifetime(3.0f);
+            }
+            this->destroy();
+        }
+    }
+
+    /**
+    @brief
+        Rotates the Rocket around the y-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void Rocket::rotateYaw(const Vector2& value)
+    {
+        ControllableEntity::rotateYaw(value);
+
+        if( !this->isInMouseLook() )
+            this->localAngularVelocity_.y += value.x;
+    }
+
+    /**
+    @brief
+        Rotates the Rocket around the x-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void Rocket::rotatePitch(const Vector2& value)
+    {
+        ControllableEntity::rotatePitch(value);
+
+        if( !this->isInMouseLook() )
+            this->localAngularVelocity_.x += value.x;
+    }
+
+    /**
+    @brief
+        Rotates the Rocket around the z-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void Rocket::rotateRoll(const Vector2& value)
+    {
+        ControllableEntity::rotateRoll(value);
+
+        if( !this->isInMouseLook() )
+            this->localAngularVelocity_.z += value.x;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/weapons/projectiles/Rocket.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/projectiles/Rocket.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/projectiles/Rocket.h	(revision 6952)
@@ -0,0 +1,133 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Rocket_H__
+#define _Rocket_H__
+
+#include "weapons/WeaponsPrereqs.h"
+
+#include "tools/Timer.h"
+#include "worldentities/ControllableEntity.h"
+
+namespace orxonox
+{
+    class ConeCollisionShape;
+
+    /**
+    @brief
+        Rocket, that is made to move upon a specified pattern.
+        This class was constructed for the PPS tutorial.
+    @author
+        Oli Scheuss
+    */
+    class _WeaponsExport Rocket : public ControllableEntity
+    {
+        public:
+            Rocket(BaseObject* creator);
+            virtual ~Rocket();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a Rocket through XML.
+            virtual void tick(float dt); //!< Defines which actions the Rocket has to take in each tick.
+
+            virtual bool collidesAgainst(WorldEntity* otherObject, btManifoldPoint& contactPoint);
+            void destroyObject();
+
+            virtual void moveFrontBack(const Vector2& value){}
+            virtual void moveRightLeft(const Vector2& value){}
+            virtual void moveUpDown(const Vector2& value){}
+
+            virtual void rotateYaw(const Vector2& value);
+            virtual void rotatePitch(const Vector2& value);
+            virtual void rotateRoll(const Vector2& value);
+
+            /**
+            @brief Moves the Rocket in the Front/Back-direction by the specifed amount.
+            @param value  The amount by which the Rocket is to be moved.
+            */
+            inline void moveFrontBack(float value)
+            { this->moveFrontBack(Vector2(value, 0)); }
+            /**
+            @brief Moves the Rocket in the Right/Left-direction by the specifed amount.
+            @param value  The amount by which the Rocket is to be moved.
+            */
+            inline void moveRightLeft(float value)
+            { this->moveRightLeft(Vector2(value, 0)); }
+            /**
+            @brief Moves the Rocket in the Up/Down-direction by the specifed amount.
+            @param value  The amount by which the Rocket is to be moved.
+            */
+            inline void moveUpDown(float value)
+            { this->moveUpDown(Vector2(value, 0)); }
+
+            /**
+            @brief Rotates the Rocket around the y-axis by the specifed amount.
+            @param value  The amount by which the Rocket is to be rotated.
+            */
+            inline void rotateYaw(float value)
+            { this->rotateYaw(Vector2(value, 0)); }
+            /**
+            @brief Rotates the Rocket around the x-axis by the specifed amount.
+            @param value  The amount by which the Rocket is to be rotated.
+            */
+            inline void rotatePitch(float value)
+            { this->rotatePitch(Vector2(value, 0)); }
+            /**
+            @brief Rotates the Rocket around the z-axis by the specifed amount.
+            @param value  The amount by which the Rocket is to be rotated.
+            */
+            inline void rotateRoll(float value)
+            { this->rotateRoll(Vector2(value, 0)); }
+
+            void setOwner(Pawn* owner);
+            inline Pawn* getOwner() const
+                { return this->owner_; }
+
+            inline void setDamage(float damage)
+                { this->damage_ = damage; }
+            inline float getDamage() const
+                { return this->damage_; }
+            virtual void fired(unsigned int firemode);
+
+        private:
+            WeakPtr<Pawn> owner_;
+            Vector3 localAngularVelocity_;
+            float damage_;
+            bool bDestroy_;
+            ControllableEntity* originalControllableEntity_;
+
+            WeakPtr<PlayerInfo> player_;
+            Timer destroyTimer_;
+            float lifetime_;
+
+            WorldSound* defSndWpnEngine_;
+            WorldSound* defSndWpnLaunch_;
+    };
+
+}
+
+#endif /* _Rocket_H__ */
Index: /code/branches/rocket2/src/modules/weapons/projectiles/SimpleRocket.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/projectiles/SimpleRocket.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/projectiles/SimpleRocket.cc	(revision 6952)
@@ -0,0 +1,260 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "SimpleRocket.h"
+
+#include <BulletDynamics/Dynamics/btRigidBody.h>
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "worldentities/pawns/Pawn.h"
+#include "graphics/ParticleSpawner.h"
+#include "graphics/Model.h"
+#include "objects/collisionshapes/ConeCollisionShape.h"
+#include "infos/PlayerInfo.h"
+#include "controllers/Controller.h"
+#include "weapons/RocketController.h"
+#include "sound/WorldSound.h"
+#include "util/Debug.h"
+
+namespace orxonox
+{
+    CreateFactory(SimpleRocket);
+    // create the factory for the SimpleRocket
+
+    /**
+    @brief
+        Constructor. Registers the object and initializes some default values.
+    */
+    SimpleRocket::SimpleRocket(BaseObject* creator) : ControllableEntity(creator)
+    {
+        RegisterObject(SimpleRocket);// - register the SimpleRocket class to the core
+
+        this->localAngularVelocity_ = 0;
+        this->bDestroy_ = false;
+        this->lifetime_ = 100;
+        COUT(4) << "simplerocket constructed\n";
+
+
+        if (GameMode::isMaster())
+       {
+           this->setCollisionType(WorldEntity::Kinematic);
+            this->setVelocity(0,0,100);
+
+            Model* model = new Model(this);
+            model->setMeshSource("rocket.mesh");
+            model->scale(0.7f);
+            this->attach(model);
+
+            ParticleEmitter* fire = new ParticleEmitter(this);
+            this->attach(fire);
+            fire->setOrientation(this->getOrientation());
+            fire->setSource("Orxonox/rocketfire2");
+
+            this->enableCollisionCallback();
+            this->setCollisionResponse(false);
+            this->setCollisionType(Kinematic);
+
+            // TODO: fix the orientation and size of this collision shape to match the rocket
+            ConeCollisionShape* collisionShape = new ConeCollisionShape(this);
+            collisionShape->setRadius(3);
+            collisionShape->setHeight(5);
+            this->attachCollisionShape(collisionShape);
+
+            this->destroyTimer_.setTimer(this->lifetime_, false, createExecutor(createFunctor(&SimpleRocket::destroyObject, this)));
+        }
+
+    }
+    
+    void SimpleRocket::tick(float dt)
+    {
+        SUPER(SimpleRocket, tick, dt);
+
+            this->setAngularVelocity(this->getOrientation() * this->localAngularVelocity_);
+            this->setVelocity( this->getOrientation()*WorldEntity::FRONT*this->getVelocity().length() );
+            this->localAngularVelocity_ = 0;
+
+            if( this->bDestroy_ )
+                this->destroy();
+        
+    }
+
+    /**s
+    @brief
+        Destructor. Destroys controller, if present and kills sounds, if playing.
+    */
+    SimpleRocket::~SimpleRocket()
+    {
+        if (this->isInitialized()) 
+        {
+            this->getController()->destroy();
+            COUT(4)<< "simplerocket destroyed\n";
+        }
+    }
+
+    /**
+    @brief
+        Method for creating a SimpleRocket through XML.
+    */
+    void SimpleRocket::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        // this calls the XMLPort function of the parent class
+        SUPER(SimpleRocket, XMLPort, xmlelement, mode);
+    }
+
+    void SimpleRocket::setOwner(Pawn* owner)
+    {
+        this->owner_ = owner;
+        //this->originalControllableEntity_ = this->owner_->getPlayer()->getControllableEntity();
+        this->player_ = this->owner_->getPlayer();
+    }
+
+
+    bool SimpleRocket::collidesAgainst(WorldEntity* otherObject, btManifoldPoint& contactPoint)
+    {
+        if (!this->bDestroy_ && GameMode::isMaster())
+        {
+            if (otherObject == this->owner_)
+                return false;
+
+            this->bDestroy_ = true;
+
+            if (this->owner_)
+            {
+                {
+                    ParticleSpawner* effect = new ParticleSpawner(this->owner_->getCreator());
+                    effect->setPosition(this->getPosition());
+                    effect->setOrientation(this->getOrientation());
+                    effect->setDestroyAfterLife(true);
+                    effect->setSource("Orxonox/explosion4");
+                    effect->setLifetime(2.0f);
+                }
+
+                {
+                    ParticleSpawner* effect = new ParticleSpawner(this->owner_->getCreator());
+                    effect->setPosition(this->getPosition());
+                    effect->setOrientation(this->getOrientation());
+                    effect->setDestroyAfterLife(true);
+                    effect->setSource("Orxonox/smoke4");
+                    effect->setLifetime(3.0f);
+                }
+            }
+
+            float dmg = this->damage_;
+//             if (this->owner_)
+//                 dmg = this->owner_->getPickups().processModifiers(ModifierType::Damage, dmg, false);
+
+            Pawn* victim = orxonox_cast<Pawn*>(otherObject);
+            if (victim)
+                victim->hit(this->owner_, contactPoint, dmg);
+        }
+        return false;
+    }
+
+    void SimpleRocket::destroyObject()
+    {
+        if (GameMode::isMaster())
+        {
+            this->destroy();
+        }
+    }
+    
+    void SimpleRocket::setDestroy()
+    {
+        this->bDestroy_=true;
+        CCOUT(4)<<"trying to destroy";
+    }
+
+    void SimpleRocket::fired(unsigned int firemode)
+    {
+        if (this->owner_)
+        {
+            {
+                ParticleSpawner* effect = new ParticleSpawner(this->owner_->getCreator());
+                effect->setPosition(this->getPosition());
+                effect->setOrientation(this->getOrientation());
+                effect->setDestroyAfterLife(true);
+                effect->setSource("Orxonox/explosion4");
+                effect->setLifetime(2.0f);
+            }
+
+            {
+                ParticleSpawner* effect = new ParticleSpawner(this->owner_->getCreator());
+                effect->setPosition(this->getPosition());
+                effect->setOrientation(this->getOrientation());
+                effect->setDestroyAfterLife(true);
+                effect->setSource("Orxonox/smoke4");
+                effect->setLifetime(3.0f);
+            }
+            this->destroy();
+        }
+    }
+
+    /**
+    @brief
+        Rotates the SimpleRocket around the y-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void SimpleRocket::rotateYaw(const Vector2& value)
+    {
+        ControllableEntity::rotateYaw(value);
+
+        if( !this->isInMouseLook() )
+            this->localAngularVelocity_.y += value.x;
+    }
+
+    /**
+    @brief
+        Rotates the SimpleRocket around the x-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void SimpleRocket::rotatePitch(const Vector2& value)
+    {
+        ControllableEntity::rotatePitch(value);
+
+        if( !this->isInMouseLook() )
+            this->localAngularVelocity_.x += value.x;
+    }
+
+    /**
+    @brief
+        Rotates the SimpleRocket around the z-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void SimpleRocket::rotateRoll(const Vector2& value)
+    {
+        ControllableEntity::rotateRoll(value);
+
+        if( !this->isInMouseLook() )
+            this->localAngularVelocity_.z += value.x;
+    }
+
+}
Index: /code/branches/rocket2/src/modules/weapons/projectiles/SimpleRocket.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/projectiles/SimpleRocket.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/projectiles/SimpleRocket.h	(revision 6952)
@@ -0,0 +1,135 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _SimpleRocket_H__
+#define _SimpleRocket_H__
+
+#include "weapons/WeaponsPrereqs.h"
+
+#include "tools/Timer.h"
+#include "worldentities/ControllableEntity.h"
+
+namespace orxonox
+{
+    class ConeCollisionShape;
+
+    /**
+    @brief
+        SimpleRocket, that is made to move upon a specified pattern.
+        This class was constructed for the PPS tutorial.
+    @author
+        Oli Scheuss
+    */
+    class _WeaponsExport SimpleRocket : public ControllableEntity
+    {
+        public:
+            SimpleRocket(BaseObject* creator);
+            virtual ~SimpleRocket();
+			virtual void tick(float dt);
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a SimpleRocket through XML.
+
+            virtual bool collidesAgainst(WorldEntity* otherObject, btManifoldPoint& contactPoint);
+            void destroyObject();
+
+            virtual void moveFrontBack(const Vector2& value){}
+            virtual void moveRightLeft(const Vector2& value){}
+            virtual void moveUpDown(const Vector2& value){}
+
+            virtual void rotateYaw(const Vector2& value);
+            virtual void rotatePitch(const Vector2& value);
+            virtual void rotateRoll(const Vector2& value);
+			void setDestroy();
+
+            /**
+            @brief Moves the SimpleRocket in the Front/Back-direction by the specifed amount.
+            @param value  The amount by which the SimpleRocket is to be moved.
+            */
+            inline void moveFrontBack(float value)
+            { this->moveFrontBack(Vector2(value, 0)); }
+            /**
+            @brief Moves the SimpleRocket in the Right/Left-direction by the specifed amount.
+            @param value  The amount by which the SimpleRocket is to be moved.
+            */
+            inline void moveRightLeft(float value)
+            { this->moveRightLeft(Vector2(value, 0)); }
+            /**
+            @brief Moves the SimpleRocket in the Up/Down-direction by the specifed amount.
+            @param value  The amount by which the SimpleRocket is to be moved.
+            */
+            inline void moveUpDown(float value)
+            { this->moveUpDown(Vector2(value, 0)); }
+
+            /**
+            @brief Rotates the SimpleRocket around the y-axis by the specifed amount.
+            @param value  The amount by which the SimpleRocket is to be rotated.
+            */
+            inline void rotateYaw(float value)
+            { this->rotateYaw(Vector2(value, 0)); }
+            /**
+            @brief Rotates the SimpleRocket around the x-axis by the specifed amount.
+            @param value  The amount by which the SimpleRocket is to be rotated.
+            */
+            inline void rotatePitch(float value)
+            {   COUT(0)<<"rotated rocket yaw";
+				this->rotatePitch(Vector2(value, 0)); }
+            /**
+            @brief Rotates the SimpleRocket around the z-axis by the specifed amount.
+            @param value  The amount by which the SimpleRocket is to be rotated.
+            */
+            inline void rotateRoll(float value)
+            { 
+				COUT(0)<<"rotated rocket roll";
+				this->rotateRoll(Vector2(value, 0)); }
+
+            void setOwner(Pawn* owner);
+            inline Pawn* getOwner() const
+                { return this->owner_; }
+
+            inline void setDamage(float damage)
+                { this->damage_ = damage; }
+            inline float getDamage() const
+                { return this->damage_; }
+            virtual void fired(unsigned int firemode);
+			
+
+        private:
+            WeakPtr<Pawn> owner_;
+            Vector3 localAngularVelocity_;
+            float damage_;
+            bool bDestroy_;
+
+
+            WeakPtr<PlayerInfo> player_;
+            Timer destroyTimer_;
+            float lifetime_;
+
+    };
+
+}
+
+#endif /* _SimpleRocket_H__ */
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,9 @@
+ADD_SOURCE_FILES(WEAPONS_SRC_FILES
+  EnergyDrink.cc
+  FusionFire.cc
+  LaserFire.cc
+  HsW01.cc
+  LightningGun.cc
+  RocketFire.cc
+  SimpleRocketFire.cc
+)
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/DroneFire.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/DroneFire.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/DroneFire.cc	(revision 6952)
@@ -0,0 +1,74 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "DroneFire.h"
+
+#include "util/Math.h"
+#include "core/CoreIncludes.h"
+#include "worldentities/RocketDrone.h"
+
+#include "weaponsystem/Weapon.h"
+#include "weaponsystem/WeaponPack.h"
+#include "weaponsystem/WeaponSystem.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateFactory(DroneFire);
+
+    DroneFire::DroneFire(BaseObject* creator) : WeaponMode(creator)
+    {
+        RegisterObject(DroneFire);
+
+       // this->reloadTime_ = 2f;
+        //this->bParallelReload_ = false;
+        //this->damage_ = 100;
+        //this->speed_ = 100;
+
+        this->setMunitionName("LaserMunition");
+        // The firing sound of the Rocket is played in Rocket.cc (because of OpenAl sound positioning)
+    }
+
+    DroneFire::~DroneFire()
+    {
+    }
+
+    void DroneFire::fire()
+    {
+        RocketDrone* rocket = new RocketDrone(this);
+
+        //this->computeMuzzleParameters(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn()->getAimPosition());
+        //rocket->setOrientation(this->getMuzzleOrientation());
+        //rocket->setPosition(this->getMuzzlePosition());
+        //rocket->setVelocity(this->getMuzzleDirection() * this->speed_);
+        //rocket->scale(2);
+
+        //rocket->setOwner(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn());
+        //rocket->setDamage(this->getDamage());
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/DroneFire.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/DroneFire.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/DroneFire.h	(revision 6952)
@@ -0,0 +1,50 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _DroneFire_H__
+#define _DroneFire_H__
+
+#include "weapons/WeaponsPrereqs.h"
+#include "weaponsystem/WeaponMode.h"
+
+namespace orxonox
+{
+    class _WeaponsExport DroneFire : public WeaponMode
+    {
+        public:
+            DroneFire(BaseObject* creator);
+            virtual ~DroneFire();
+
+            virtual void fire();
+
+        private:
+            float speed_;
+    };
+}
+
+#endif /* _DroneFire_H__ */
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/EnergyDrink.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/EnergyDrink.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/EnergyDrink.cc	(revision 6952)
@@ -0,0 +1,117 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Hagen Seifert
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "EnergyDrink.h"
+
+#include "core/CoreIncludes.h"
+#include "core/Executor.h"
+#include "core/XMLPort.h"
+#include "graphics/Model.h"
+
+#include "weapons/projectiles/Projectile.h"
+#include "weapons/MuzzleFlash.h"
+#include "weaponsystem/Weapon.h"
+#include "weaponsystem/WeaponPack.h"
+#include "weaponsystem/WeaponSystem.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateFactory(EnergyDrink);
+
+    EnergyDrink::EnergyDrink(BaseObject* creator) : WeaponMode(creator)
+    {
+        RegisterObject(EnergyDrink);
+
+        this->reloadTime_ = 0.25;
+        this->damage_ = 15;
+        this->speed_ = 2500;
+        this->delay_ = 0;
+        this->setMunitionName("FusionMunition");
+
+        this->delayTimer_.setTimer(1.0f, false, createExecutor(createFunctor(&EnergyDrink::shot, this)));
+        this->delayTimer_.stopTimer();
+    }
+
+    void EnergyDrink::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(EnergyDrink, XMLPort, xmlelement, mode);
+
+        XMLPortParam(EnergyDrink, "delay", setDelay, getDelay, xmlelement, mode);
+        XMLPortParam(EnergyDrink, "material", setMaterial, getMaterial, xmlelement, mode);
+
+    }
+
+    void EnergyDrink::setMaterial(const std::string& material)
+    {
+        this->material_ = material;
+    }
+
+    void EnergyDrink::setDelay(float d)
+    {
+        this->delay_ = d;
+        this->delayTimer_.setInterval(this->delay_);
+    }
+
+    float EnergyDrink::getDelay() const
+    {
+        return this->delay_;
+    }
+
+    void EnergyDrink::fire()
+    {
+        this->delayTimer_.startTimer();
+    }
+
+    void EnergyDrink::muendungsfeuer()
+    {
+        MuzzleFlash *muzzleFlash = new MuzzleFlash(this);
+        this->getWeapon()->attach(muzzleFlash);
+        muzzleFlash->setPosition(this->getMuzzleOffset());
+        muzzleFlash->setMaterial(this->material_);
+    }
+
+    void EnergyDrink::shot()
+    {
+        Projectile* projectile = new Projectile(this);
+        Model* model = new Model(projectile);
+        model->setMeshSource("can.mesh");
+        model->setCastShadows(false);
+        projectile->attach(model);
+        model->setScale(5);
+
+        projectile->setOrientation(this->getMuzzleOrientation());
+        projectile->setPosition(this->getMuzzlePosition());
+        projectile->setVelocity(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn()->getVelocity() + this->getMuzzleDirection() * this->speed_);
+
+        projectile->setOwner(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn());
+        projectile->setDamage(this->getDamage());
+
+        EnergyDrink::muendungsfeuer();
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/EnergyDrink.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/EnergyDrink.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/EnergyDrink.h	(revision 6952)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Hagen Seifert
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _EnergyDrink_H__
+#define _EnergyDrink_H__
+
+#include "weapons/WeaponsPrereqs.h"
+
+#include <string>
+#include "tools/Timer.h"
+#include "weaponsystem/WeaponMode.h"
+
+namespace orxonox
+{
+    class _WeaponsExport EnergyDrink : public WeaponMode
+    {
+        public:
+            EnergyDrink(BaseObject* creator);
+            virtual ~EnergyDrink() {}
+
+            virtual void fire();
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+        private:
+            void setMaterial(const std::string& material);
+            inline const std::string& getMaterial()
+                { return this->material_; }
+            void setDelay(float d);
+            float getDelay() const;
+            void shot();
+            void muendungsfeuer();
+
+            std::string material_;
+            float speed_;
+            float delay_;
+            Timer delayTimer_;
+    };
+}
+
+#endif /* _EnergyDrink_H__ */
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/FusionFire.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/FusionFire.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/FusionFire.cc	(revision 6952)
@@ -0,0 +1,69 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "FusionFire.h"
+
+#include "util/Math.h"
+#include "core/CoreIncludes.h"
+#include "weapons/projectiles/BillboardProjectile.h"
+
+#include "weaponsystem/Weapon.h"
+#include "weaponsystem/WeaponPack.h"
+#include "weaponsystem/WeaponSystem.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateFactory(FusionFire);
+
+    FusionFire::FusionFire(BaseObject* creator) : WeaponMode(creator)
+    {
+        RegisterObject(FusionFire);
+
+        this->reloadTime_ = 1.0;
+        this->bParallelReload_ = false;
+        this->damage_ = 40;
+        this->speed_ = 1250;
+
+        this->setMunitionName("FusionMunition");
+    }
+
+    void FusionFire::fire()
+    {
+        BillboardProjectile* projectile = new BillboardProjectile(this);
+
+        projectile->setOrientation(this->getMuzzleOrientation());
+        projectile->setPosition(this->getMuzzlePosition());
+        projectile->setVelocity(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn()->getVelocity() + this->getMuzzleDirection() * this->speed_);
+        projectile->scale(5);
+
+        projectile->setOwner(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn());
+        projectile->setDamage(this->getDamage());
+        projectile->setColour(ColourValue(1.0f, 0.7f, 0.3f, 1.0f));
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/FusionFire.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/FusionFire.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/FusionFire.h	(revision 6952)
@@ -0,0 +1,50 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _FusionFire_H__
+#define _FusionFire_H__
+
+#include "weapons/WeaponsPrereqs.h"
+#include "weaponsystem/WeaponMode.h"
+
+namespace orxonox
+{
+    class _WeaponsExport FusionFire : public WeaponMode
+    {
+        public:
+            FusionFire(BaseObject* creator);
+            virtual ~FusionFire() {}
+
+            virtual void fire();
+
+        private:
+            float speed_;
+    };
+}
+
+#endif /* _FusionFire_H__ */
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/HsW01.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/HsW01.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/HsW01.cc	(revision 6952)
@@ -0,0 +1,131 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Hagen Seifert
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "HsW01.h"
+
+#include "core/CoreIncludes.h"
+#include "core/Executor.h"
+#include "core/XMLPort.h"
+#include "graphics/Model.h"
+
+#include "weapons/projectiles/Projectile.h"
+#include "weapons/MuzzleFlash.h"
+#include "weaponsystem/Weapon.h"
+#include "weaponsystem/WeaponPack.h"
+#include "weaponsystem/WeaponSystem.h"
+#include "worldentities/WorldEntity.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateFactory(HsW01);
+
+    HsW01::HsW01(BaseObject* creator) : WeaponMode(creator)
+    {
+        RegisterObject(HsW01);
+
+        this->reloadTime_ = 0.25;
+        this->damage_ = 15;
+        this->speed_ = 2500;
+        this->delay_ = 0;
+        this->setMunitionName("LaserMunition");
+
+        this->delayTimer_.setTimer(1.0f, false, createExecutor(createFunctor(&HsW01::shot, this)));
+        this->delayTimer_.stopTimer();
+
+        this->setDefaultSound("sounds/Weapon_HsW01.ogg");
+    }
+
+    HsW01::~HsW01()
+    {
+    }
+
+    void HsW01::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(HsW01, XMLPort, xmlelement, mode);
+
+        XMLPortParam(HsW01, "delay", setDelay, getDelay, xmlelement, mode);
+        XMLPortParam(HsW01, "material", setMaterial, getMaterial, xmlelement, mode);
+
+    }
+
+    void HsW01::setMaterial(const std::string& material)
+    {
+        this->material_ = material;
+    }
+
+    std::string& HsW01::getMaterial()
+    {
+        return this->material_;
+    }
+
+    void HsW01::setDelay(float d)
+    {
+        this->delay_ = d;
+        this->delayTimer_.setInterval(this->delay_);
+    }
+
+    float HsW01::getDelay() const
+    {
+        return this->delay_;
+    }
+
+    void HsW01::fire()
+    {
+        this->delayTimer_.startTimer();
+    }
+
+    void HsW01::muendungsfeuer()
+    {
+        MuzzleFlash *muzzleFlash = new MuzzleFlash(this);
+        this->getWeapon()->attach(muzzleFlash);
+        muzzleFlash->setPosition(this->getMuzzleOffset());
+        muzzleFlash->setMaterial(this->material_);
+    }
+
+    void HsW01::shot()
+    {
+        assert( this->getWeapon() && this->getWeapon()->getWeaponPack() && this->getWeapon()->getWeaponPack()->getWeaponSystem() && this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn() );
+        Projectile* projectile = new Projectile(this);
+        Model* model = new Model(projectile);
+        model->setMeshSource("laserbeam.mesh");
+        model->setCastShadows(false);
+        projectile->attach(model);
+        model->setScale(5);
+
+        this->computeMuzzleParameters(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn()->getAimPosition());
+        projectile->setOrientation(this->getMuzzleOrientation());
+        projectile->setPosition(this->getMuzzlePosition());
+        projectile->setVelocity(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn()->getVelocity() + this->getMuzzleDirection() * this->speed_);
+
+        projectile->setOwner(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn());
+        projectile->setDamage(this->getDamage());
+
+        HsW01::muendungsfeuer();
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/HsW01.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/HsW01.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/HsW01.h	(revision 6952)
@@ -0,0 +1,63 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Hagen Seifert
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _HsW01_H__
+#define _HsW01_H__
+
+#include "weapons/WeaponsPrereqs.h"
+
+#include "tools/Timer.h"
+#include "weaponsystem/WeaponMode.h"
+
+namespace orxonox
+{
+    class _WeaponsExport HsW01 : public WeaponMode
+    {
+        public:
+            HsW01(BaseObject* creator);
+            virtual ~HsW01();
+
+            virtual void fire();
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+        private:
+            void setMaterial(const std::string& material);
+            std::string& getMaterial();
+            void setDelay(float d);
+            float getDelay() const;
+            void shot();
+            void muendungsfeuer();
+
+            std::string material_;
+            float speed_;
+            float delay_;
+            Timer delayTimer_;
+    };
+}
+
+#endif /* _HsW01_H__ */
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/LaserFire.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/LaserFire.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/LaserFire.cc	(revision 6952)
@@ -0,0 +1,64 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "LaserFire.h"
+
+#include "core/CoreIncludes.h"
+#include "weapons/projectiles/ParticleProjectile.h"
+#include "weaponsystem/Weapon.h"
+#include "weaponsystem/WeaponPack.h"
+#include "weaponsystem/WeaponSystem.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateFactory(LaserFire);
+
+    LaserFire::LaserFire(BaseObject* creator) : WeaponMode(creator)
+    {
+        RegisterObject(LaserFire);
+
+        this->reloadTime_ = 0.25;
+        this->damage_ = 15;
+        this->speed_ = 1250;
+
+        this->setMunitionName("LaserMunition");
+    }
+
+    void LaserFire::fire()
+    {
+        ParticleProjectile* projectile = new ParticleProjectile(this);
+
+        projectile->setOrientation(this->getMuzzleOrientation());
+        projectile->setPosition(this->getMuzzlePosition());
+        projectile->setVelocity(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn()->getVelocity() + this->getMuzzleDirection() * this->speed_);
+
+        projectile->setOwner(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn());
+        projectile->setDamage(this->getDamage());
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/LaserFire.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/LaserFire.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/LaserFire.h	(revision 6952)
@@ -0,0 +1,50 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _LaserFire_H__
+#define _LaserFire_H__
+
+#include "weapons/WeaponsPrereqs.h"
+#include "weaponsystem/WeaponMode.h"
+
+namespace orxonox
+{
+    class _WeaponsExport LaserFire : public WeaponMode
+    {
+        public:
+            LaserFire(BaseObject* creator);
+            virtual ~LaserFire() {}
+
+            virtual void fire();
+
+        private:
+            float speed_;
+    };
+}
+
+#endif /* _LaserFire_H__ */
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/LightningGun.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/LightningGun.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/LightningGun.cc	(revision 6952)
@@ -0,0 +1,72 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Joel Smely
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "LightningGun.h"
+
+#include "core/CoreIncludes.h"
+#include "weapons/projectiles/LightningGunProjectile.h"
+#include "weaponsystem/Weapon.h"
+#include "weaponsystem/WeaponPack.h"
+#include "weaponsystem/WeaponSystem.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateFactory(LightningGun);
+
+    LightningGun::LightningGun(BaseObject* creator) : WeaponMode(creator)
+    {
+        RegisterObject(LightningGun);
+
+        this->reloadTime_ = 1;
+        this->damage_ = 100;
+        this->speed_ = 150;
+
+        this->setMunitionName("LaserMunition");
+        this->setDefaultSound("sounds/Weapon_LightningGun.ogg");
+    }
+
+    LightningGun::~LightningGun()
+    {
+    }
+
+    void LightningGun::fire()
+    {
+        LightningGunProjectile* projectile = new LightningGunProjectile(this);
+        projectile->setMaterial("Flares/LightningBall_");
+
+        this->computeMuzzleParameters(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn()->getAimPosition());
+        projectile->setOrientation(this->getMuzzleOrientation());
+        projectile->setPosition(this->getMuzzlePosition());
+        projectile->setVelocity(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn()->getVelocity() + this->getMuzzleDirection() * this->speed_);
+        projectile->setAcceleration(this->getMuzzleDirection() * 1000);
+
+        projectile->setOwner(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn());
+        projectile->setDamage(this->getDamage());
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/LightningGun.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/LightningGun.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/LightningGun.h	(revision 6952)
@@ -0,0 +1,50 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Joel Smely
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _LightningGun_H__
+#define _LightningGun_H__
+
+#include "weapons/WeaponsPrereqs.h"
+#include "weaponsystem/WeaponMode.h"
+
+namespace orxonox
+{
+    class _WeaponsExport LightningGun : public WeaponMode
+    {
+        public:
+            LightningGun(BaseObject* creator);
+            virtual ~LightningGun();
+
+            virtual void fire();
+
+       private:
+            float speed_;
+    };
+}
+
+#endif /* _LightningGun_H__ */
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/RocketFire.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/RocketFire.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/RocketFire.cc	(revision 6952)
@@ -0,0 +1,74 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "RocketFire.h"
+
+#include "util/Math.h"
+#include "core/CoreIncludes.h"
+#include "weapons/projectiles/Rocket.h"
+
+#include "weaponsystem/Weapon.h"
+#include "weaponsystem/WeaponPack.h"
+#include "weaponsystem/WeaponSystem.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateFactory(RocketFire);
+
+    RocketFire::RocketFire(BaseObject* creator) : WeaponMode(creator)
+    {
+        RegisterObject(RocketFire);
+
+        this->reloadTime_ = 0.20f;
+        this->bParallelReload_ = false;
+        this->damage_ = 100;
+        this->speed_ = 500;
+
+        this->setMunitionName("LaserMunition");
+        // The firing sound of the Rocket is played in Rocket.cc (because of OpenAl sound positioning)
+    }
+
+    RocketFire::~RocketFire()
+    {
+    }
+
+    void RocketFire::fire()
+    {
+        Rocket* rocket = new Rocket(this);
+
+        this->computeMuzzleParameters(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn()->getAimPosition());
+        rocket->setOrientation(this->getMuzzleOrientation());
+        rocket->setPosition(this->getMuzzlePosition());
+        rocket->setVelocity(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn()->getVelocity() + this->getMuzzleDirection() * this->speed_);
+        rocket->scale(2);
+
+        rocket->setOwner(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn());
+        rocket->setDamage(this->getDamage());
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/RocketFire.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/RocketFire.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/RocketFire.h	(revision 6952)
@@ -0,0 +1,50 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _RocketFire_H__
+#define _RocketFire_H__
+
+#include "weapons/WeaponsPrereqs.h"
+#include "weaponsystem/WeaponMode.h"
+
+namespace orxonox
+{
+    class _WeaponsExport RocketFire : public WeaponMode
+    {
+        public:
+            RocketFire(BaseObject* creator);
+            virtual ~RocketFire();
+
+            virtual void fire();
+
+        private:
+            float speed_;
+    };
+}
+
+#endif /* _RocketFire_H__ */
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/SimpleRocketFire.cc
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/SimpleRocketFire.cc	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/SimpleRocketFire.cc	(revision 6952)
@@ -0,0 +1,80 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "SimpleRocketFire.h"
+
+#include "util/Math.h"
+#include "core/CoreIncludes.h"
+#include "weapons/RocketController.h"
+
+#include "weaponsystem/Weapon.h"
+#include "weaponsystem/WeaponPack.h"
+#include "weaponsystem/WeaponSystem.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateFactory(SimpleRocketFire);
+
+    SimpleRocketFire::SimpleRocketFire(BaseObject* creator) : WeaponMode(creator)
+    {
+        RegisterObject(SimpleRocketFire);
+
+        this->reloadTime_ = 0.20f;
+        this->bParallelReload_ = false;
+        this->damage_ = 100;
+        this->speed_ = 100;
+
+        this->setMunitionName("LaserMunition");
+        // The firing sound of the Rocket is played in Rocket.cc (because of OpenAl sound positioning)
+    }
+
+    SimpleRocketFire::~SimpleRocketFire()
+    {
+    }
+
+    void SimpleRocketFire::fire()
+    {
+        RocketController* con = new RocketController(this);
+        SimpleRocket* rocket = con->getRocket();
+        this->computeMuzzleParameters(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn()->getAimPosition());
+//      rocket->setOrientation(this->getMuzzleOrientation());
+        rocket->setOrientation(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn()->getWorldOrientation());
+        Vector3 pos = this->getMuzzlePosition();
+        rocket->setPosition(pos);
+//      rocket->setAcceleration(20*rocket->getOrientation() * WorldEntity::FRONT);
+        rocket->setVelocity(this->getMuzzleDirection()*this->speed_);
+        rocket->setOwner(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn());
+        rocket->setDamage(this->damage_);
+        WorldEntity* pawnn=static_cast<ControllableEntity*>(this->getWeapon()->getWeaponPack()->getWeaponSystem()->getPawn())->getTarget();
+        if (pawnn)
+        {
+            con->setTarget(pawnn);
+        }
+    }
+}
Index: /code/branches/rocket2/src/modules/weapons/weaponmodes/SimpleRocketFire.h
===================================================================
--- /code/branches/rocket2/src/modules/weapons/weaponmodes/SimpleRocketFire.h	(revision 6952)
+++ /code/branches/rocket2/src/modules/weapons/weaponmodes/SimpleRocketFire.h	(revision 6952)
@@ -0,0 +1,50 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oliver Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _SimpleRocketFire_H__
+#define _SimpleRocketFire_H__
+
+#include "weapons/WeaponsPrereqs.h"
+#include "weaponsystem/WeaponMode.h"
+
+namespace orxonox
+{
+    class _WeaponsExport SimpleRocketFire : public WeaponMode
+    {
+        public:
+            SimpleRocketFire(BaseObject* creator);
+            virtual ~SimpleRocketFire();
+
+            virtual void fire();
+
+        private:
+            float speed_;
+    };
+}
+
+#endif /* _SimpleRocketFire_H__ */
Index: /code/branches/rocket2/src/orxonox-main.vcproj.user.in
===================================================================
--- /code/branches/rocket2/src/orxonox-main.vcproj.user.in	(revision 6952)
+++ /code/branches/rocket2/src/orxonox-main.vcproj.user.in	(revision 6952)
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioUserFile
+	ProjectType="Visual C++"
+	Version="${VISUAL_STUDIO_VERSION_SIMPLE}.00"
+	ShowAllFiles="false"
+	>
+	<Configurations>
+		<Configuration
+			Name="Debug|${MSVC_PLATFORM}"
+			>
+			<DebugSettings
+				WorkingDirectory="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$(OutDir)"
+				Environment="Path=${RUNTIME_LIBRARY_DIRECTORY}"
+				EnvironmentMerge="true"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|${MSVC_PLATFORM}"
+			>
+			<DebugSettings
+				WorkingDirectory="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$(OutDir)"
+				Environment="Path=${RUNTIME_LIBRARY_DIRECTORY}"
+				EnvironmentMerge="true"
+			/>
+		</Configuration>
+		<Configuration
+			Name="MinSizeRel|${MSVC_PLATFORM}"
+			>
+			<DebugSettings
+				WorkingDirectory="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$(OutDir)"
+				Environment="Path=${RUNTIME_LIBRARY_DIRECTORY}"
+				EnvironmentMerge="true"
+			/>
+		</Configuration>
+		<Configuration
+			Name="RelWithDebInfo|${MSVC_PLATFORM}"
+			>
+			<DebugSettings
+				WorkingDirectory="${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$(OutDir)"
+				Environment="Path=${RUNTIME_LIBRARY_DIRECTORY}"
+				EnvironmentMerge="true"
+			/>
+		</Configuration>
+	</Configurations>
+</VisualStudioUserFile>
Index: /code/branches/rocket2/src/orxonox/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,87 @@
+ #
+ #             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.
+ #
+
+INCLUDE_DIRECTORIES(
+  ${CMAKE_SOURCE_DIR}/src/external
+  ${CMAKE_SOURCE_DIR}/src/libraries
+  ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+SET_SOURCE_FILES(ORXONOX_SRC_FILES
+  Level.cc
+  LevelManager.cc
+  Main.cc
+  MoodManager.cc
+  PawnManager.cc
+  PlayerManager.cc
+  Radar.cc
+  ChatHistory.cc
+  ChatInputHandler.cc
+COMPILATION_BEGIN SceneCompilation.cc
+  CameraManager.cc
+  Scene.cc
+COMPILATION_END
+)
+
+ADD_SUBDIRECTORY(collisionshapes)
+ADD_SUBDIRECTORY(controllers)
+ADD_SUBDIRECTORY(gamestates)
+ADD_SUBDIRECTORY(gametypes)
+ADD_SUBDIRECTORY(graphics)
+ADD_SUBDIRECTORY(infos)
+ADD_SUBDIRECTORY(interfaces)
+ADD_SUBDIRECTORY(items)
+ADD_SUBDIRECTORY(overlays)
+ADD_SUBDIRECTORY(pickup)
+ADD_SUBDIRECTORY(sound)
+ADD_SUBDIRECTORY(weaponsystem)
+ADD_SUBDIRECTORY(worldentities)
+
+ORXONOX_ADD_LIBRARY(orxonox
+  FIND_HEADER_FILES
+  TOLUA_FILES
+    LevelManager.h
+    MoodManager.h
+    controllers/HumanController.h
+    interfaces/PickupCarrier.h
+    sound/SoundManager.h
+  DEFINE_SYMBOL
+    "ORXONOX_SHARED_BUILD"
+  PCH_FILE
+    OrxonoxPrecompiledHeaders.h
+  LINK_LIBRARIES
+    ${Boost_FILESYSTEM_LIBRARY}
+    ${Boost_SYSTEM_LIBRARY} # Filesystem dependency
+    ${Boost_THREAD_LIBRARY}
+    ${Boost_DATE_TIME_LIBRARY} # Thread dependency
+    ${OGRE_LIBRARY}
+    ${OPENAL_LIBRARY}
+    ${ALUT_LIBRARY}
+    ${VORBISFILE_LIBRARY}
+    ${VORBIS_LIBRARY}
+    ${OGG_LIBRARY}
+    tinyxml++_orxonox
+    tolua++_orxonox
+    bullet_orxonox
+    util
+    core
+    network
+    tools
+  SOURCE_FILES ${ORXONOX_SRC_FILES}
+)
Index: /code/branches/rocket2/src/orxonox/CameraManager.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/CameraManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/CameraManager.cc	(revision 6952)
@@ -0,0 +1,126 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      Fabian 'x3n' Landau
+ *
+ */
+
+#include "CameraManager.h"
+
+#include <OgreSceneManager.h>
+#include <OgreViewport.h>
+#include <OgreCompositorManager.h>
+
+#include "util/StringUtils.h"
+#include "core/GameMode.h"
+#include "core/GraphicsManager.h"
+#include "core/GUIManager.h"
+#include "core/ObjectList.h"
+#include "core/ScopedSingletonManager.h"
+#include "tools/Shader.h"
+#include "graphics/Camera.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    ManageScopedSingleton(CameraManager, ScopeID::Graphics, false);
+
+    CameraManager::CameraManager()
+        : viewport_(GraphicsManager::getInstance().getViewport())
+    {
+        assert(GameMode::showsGraphics());
+    }
+
+    CameraManager::~CameraManager()
+    {
+        GUIManager::getInstance().setCamera(0);
+    }
+
+    Camera* CameraManager::getActiveCamera() const
+    {
+        if (!this->cameraList_.empty())
+            return this->cameraList_.front();
+        else
+            return 0;
+    }
+
+    void CameraManager::requestFocus(Camera* camera)
+    {
+        // notify old camera (if it exists)
+        if (!this->cameraList_.empty())
+            this->cameraList_.front()->removeFocus();
+
+        camera->setFocus();
+
+        // make sure we don't add it twice
+        for (std::list<Camera*>::iterator it = this->cameraList_.begin(); it != this->cameraList_.end();)
+            if ((*it) == camera)
+                this->cameraList_.erase(it++);
+            else
+                ++it;
+        // add to list
+        this->cameraList_.push_front(camera);
+    }
+
+    void CameraManager::releaseFocus(Camera* camera)
+    {
+        // notify the cam of releasing the focus
+        if (!this->cameraList_.empty() && this->cameraList_.front() == camera)
+        {
+            camera->removeFocus();
+            this->cameraList_.pop_front();
+
+            // set new focus if possible
+            if (!this->cameraList_.empty())
+                this->cameraList_.front()->setFocus();
+        }
+        else
+            this->cameraList_.remove(camera);
+    }
+
+    void CameraManager::useCamera(Ogre::Camera* camera)
+    {
+        // This workaround is needed to avoid weird behaviour with active compositors while
+        // switching the camera (like freezing the image)
+        //
+        // Last known Ogre version needing this workaround:
+        // 1.4.8
+
+        // deactivate all compositors
+        {
+            Ogre::ResourceManager::ResourceMapIterator iterator = Ogre::CompositorManager::getSingleton().getResourceIterator();
+            while (iterator.hasMoreElements())
+                Ogre::CompositorManager::getSingleton().setCompositorEnabled(this->viewport_, iterator.getNext()->getName(), false);
+        }
+
+        this->viewport_->setCamera(camera);
+        GUIManager::getInstance().setCamera(camera);
+
+        // reactivate all visible compositors
+        {
+            for (ObjectList<Shader>::iterator it = ObjectList<Shader>::begin(); it != ObjectList<Shader>::end(); ++it)
+                it->updateVisibility();
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/CameraManager.h
===================================================================
--- /code/branches/rocket2/src/orxonox/CameraManager.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/CameraManager.h	(revision 6952)
@@ -0,0 +1,73 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht
+ *   Co-authors:
+ *      Fabian 'x3n' Landau
+ *
+ */
+
+ /**
+ @file
+ @brief Handles the instances of Camera class
+ @author Benjamin Knecht <beni_at_orxonox.net>
+  */
+
+#ifndef _CameraManager_H__
+#define _CameraManager_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <cassert>
+#include <list>
+#include "util/OgreForwardRefs.h"
+#include "util/Singleton.h"
+#include "core/OrxonoxClass.h"
+#include "core/SmartPtr.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport CameraManager : public Singleton<CameraManager>, public OrxonoxClass
+    {
+            friend class Singleton<CameraManager>;
+        public:
+            CameraManager();
+            ~CameraManager();
+
+            Camera* getActiveCamera() const;
+
+            void requestFocus(Camera* camera);
+            void releaseFocus(Camera* camera);
+
+            void useCamera(Ogre::Camera* camera);
+
+        private:
+            CameraManager(const CameraManager&); // don't use
+
+            std::list<Camera*>    cameraList_;
+            Ogre::Viewport*       viewport_;
+
+            static CameraManager* singletonPtr_s;
+    };
+}
+
+#endif /* _CameraManager_H__ */
Index: /code/branches/rocket2/src/orxonox/ChatHistory.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/ChatHistory.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/ChatHistory.cc	(revision 6952)
@@ -0,0 +1,195 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Sandro 'smerkli' Merkli
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ChatHistory.h"
+#include <core/ScopedSingletonManager.h>
+
+#ifndef CHATTEST
+namespace orxonox
+{
+  /* singleton */
+  ManageScopedSingleton( ChatHistory, ScopeID::Root, false );
+#endif
+
+  /* constructor */
+#ifndef CHATTEST
+  //ChatHistory::ChatHistory( BaseObject* creator ) : BaseObject(creator) 
+  ChatHistory::ChatHistory() 
+#else
+  ChatHistory::ChatHistory()
+#endif
+  {
+    /* register the object */
+#ifndef CHATTEST
+    RegisterObject(ChatHistory);
+#endif
+
+    this->hist_log_enabled = true;
+
+    /* Read setting for logfiles */
+    if( hist_log_enabled ) /* NOTE Make this a check for the logfile setting */
+    { this->chat_hist_openlog();
+
+      /* push starting line */
+      this->chat_hist_logline( "--- Logfile opened ---" );
+    }
+
+    /* Read setting for maximum number of lines and set limit */
+    this->hist_maxlines = 200; /* NOTE to be changed, 200 is just for testing */
+  }
+
+  /* destructor */
+  ChatHistory::~ChatHistory()
+  {
+    chat_hist_closelog();
+    
+    /* clear list */
+    this->hist_buffer.clear();
+  }
+
+  /* react to incoming chat */
+  void ChatHistory::incomingChat(const std::string& message, 
+    unsigned int senderID)
+  {
+    /* --> a) look up the actual name of the sender */
+    std::string text;
+
+#ifndef CHATTEST
+    /* get sender ID and prepend it to the message */
+    if (senderID != CLIENTID_UNKNOWN)
+    {
+      /* if we can't find anything, use "unknown" as default */
+      std::string name = "unknown";
+
+      PlayerInfo* player = PlayerManager::getInstance().getClient(senderID);
+      if (player)
+        name = player->getName();
+
+      text = name + ": " + message;
+    }
+    else
+      text = message;
+#else
+    text = message;
+#endif
+
+    /* add the line to the history */
+    this->chat_hist_addline( text );
+
+    /* add the line to the log */
+    this->chat_hist_logline( text );
+  } 
+
+  /* Synchronize logfile onto the hard drive */ /* MARK MARK */
+  int ChatHistory::syncLog()
+  {
+    //if( this->hist_logfile )
+      //this->hist_logfile.sync();
+    return 0;
+  }
+
+  /* add a line to this history */
+  int ChatHistory::chat_hist_addline( const std::string& toadd )
+  {
+    /* crop history at the end if it's too large */
+    while( this->hist_buffer.size() > this->hist_maxlines+1 )
+      this->hist_buffer.pop_front();
+
+    /* push to the front of the history */
+    this->hist_buffer.push_back( toadd );
+    return 0;
+  }
+
+  /* log a line to a logfile */
+  int ChatHistory::chat_hist_logline( const std::string& toadd )
+  { 
+    /* output the line to the file if logging is enabled */
+    if( this->hist_log_enabled )
+      this->hist_logfile << toadd << std::endl;
+    return 0;
+  }
+
+  /* open logfile */
+  int ChatHistory::chat_hist_openlog()
+  {
+    /* TODO: find out the name of the file to log to via settings 
+     *       and set the this->hist_logfile_path variable to it
+     */
+#ifndef CHATTEST
+    this->hist_logfile.open( (PathConfig::getInstance().getLogPathString() +
+      "chatlog.log").c_str(),
+      std::fstream::out | std::fstream::app );
+#else
+    this->hist_logfile.open( "/tmp/chatlog.log",
+      std::fstream::out | std::fstream::app );
+#endif
+
+    /* TODO check whether this works (not sure how you'd like it?) */
+    if( !this->hist_logfile )
+    { this->hist_log_enabled = false;
+#ifndef CHATTEST
+      COUT(2) << "Warning: Could not open logfile." << std::endl;
+#endif
+    }
+
+    /* if it worked */
+    return 0;
+  }
+
+  /* close logfile */
+  void ChatHistory::chat_hist_closelog()
+  {
+    /* see if we've actually got a logfile */
+    if( this->hist_logfile )
+    { 
+      /* yes, we've got one, add a line that shows we're closing it */
+      this->chat_hist_logline( "--- Logfile closed ---" );
+
+      /* actually close down the file */
+      this->hist_logfile.close();
+    }
+  }
+
+  /* output history for debugging */
+  void ChatHistory::debug_printhist()
+  {
+    /* create deque iterator */
+    std::deque<std::string>::iterator it;
+
+    /* output all the strings */
+    for( it = this->hist_buffer.begin(); it != this->hist_buffer.end();
+      ++it )
+      std::cout << *it << std::endl;
+
+    /* output size */
+    std::cout << "Size: " << hist_buffer.size() << std::endl;
+  }
+
+#ifndef CHATTEST
+}
+#endif
Index: /code/branches/rocket2/src/orxonox/ChatHistory.h
===================================================================
--- /code/branches/rocket2/src/orxonox/ChatHistory.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/ChatHistory.h	(revision 6952)
@@ -0,0 +1,149 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Sandro 'smerkli' Merkli
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include <deque>
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <cassert>
+
+/* define this if you're unit testing */
+//#define CHATTEST 
+
+#ifndef CHATTEST
+#include <OrxonoxPrereqs.h>
+#include <PlayerManager.h>
+#include <infos/PlayerInfo.h>
+#include <core/BaseObject.h>
+#include <network/ChatListener.h>
+#include <core/PathConfig.h>
+#include <util/Singleton.h>
+#endif
+
+#ifndef _ChatHistory_H__
+#define _ChatHistory_H__
+
+
+/* Class to implement chat history */
+#ifndef CHATTEST
+namespace orxonox
+{
+#endif
+
+  /* constructor */
+#ifndef CHATTEST
+  class _OrxonoxExport ChatHistory : public ChatListener,
+    public Singleton<ChatHistory>
+
+#else
+  class ChatHistory 
+#endif
+  {
+    public:
+      /* constructors, destructors */
+#ifndef CHATTEST
+      ChatHistory();
+      friend class Singleton<ChatHistory>;
+#else
+      ChatHistory();
+#endif
+      virtual ~ChatHistory();
+
+  
+    //protected:
+      /** what to do with incoming chat 
+       * 
+       * \param message The incoming message 
+       * \param senderID Identification number of the sender
+       */
+      virtual void incomingChat(const std::string& message, 
+        unsigned int senderID);
+      
+      /** Synchronize logfile onto the hard drive 
+       *
+       * \return 0 for success, other for error
+       */
+      int syncLog();
+
+      /** debug-print: output the whole history to stdout */
+      void debug_printhist();
+      
+    private:
+      /* FIELDS */
+      /** Vector to store the history in */
+      std::deque<std::string> hist_buffer;
+
+      /** Maximum number of lines stored in this history */
+      unsigned int hist_maxlines;
+
+      /** is logging enabled? */
+      bool hist_log_enabled;
+
+      /** path of logfile on the file system */
+      std::string hist_logfile_path;
+
+      /** Output file stream for logfile */
+      std::ofstream hist_logfile;
+
+#ifndef CHATTEST
+      static ChatHistory* singletonPtr_s;
+#endif
+
+
+
+      /* METHODS */
+      /** Append line to chat history
+       *
+       * \param toadd The line to add to the history
+       * \return 0 for success, other for error TODO: Throw exception
+       */
+      int chat_hist_addline( const std::string& toadd );
+
+      /** Append line to logfile
+       *
+       * \param toadd The line to add to the logfile
+       * \return 0 for success, other for error TODO: Throw exception
+       */
+      int chat_hist_logline( const std::string& toadd );
+
+      /** open logfile to log to
+       *
+       * \return 0 for success,s other for error
+       */
+      int chat_hist_openlog();
+
+
+      /** close logfile */
+      void chat_hist_closelog();
+  };
+
+#ifndef CHATTEST
+}
+#endif
+
+#endif /* _ChatHistory_H__ */
Index: /code/branches/rocket2/src/orxonox/ChatInputHandler.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/ChatInputHandler.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/ChatInputHandler.cc	(revision 6952)
@@ -0,0 +1,287 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Sandro 'smerkli' Merkli
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ChatInputHandler.h"
+#include <core/ScopedSingletonManager.h>
+#include "core/ConsoleCommand.h"
+#include "core/CoreIncludes.h"
+#include "core/GUIManager.h"
+#include "core/CorePrereqs.h"
+#include <CEGUIWindow.h>
+#include <elements/CEGUIListbox.h>
+#include <elements/CEGUIListboxItem.h>
+#include <elements/CEGUIListboxTextItem.h>
+#include <CEGUIWindowManager.h>
+#include <string>
+
+namespace orxonox 
+{
+  /* singleton */
+  ManageScopedSingleton( ChatInputHandler, ScopeID::Graphics, false );
+
+  /* add commands to console */
+  SetConsoleCommandAlias( ChatInputHandler, activate_static, "startchat",
+    true );
+  SetConsoleCommandAlias( ChatInputHandler, activate_small_static, 
+    "startchat_small", true );
+
+  /* constructor */
+  ChatInputHandler::ChatInputHandler()
+  {
+    /* register the object  */
+    RegisterObject(ChatInputHandler);
+
+    /* create necessary objects */
+    this->inpbuf = new InputBuffer();
+    this->disp_offset = 0;
+    assert( this->inpbuf != NULL );
+
+    /* generate chatbox ui and chatbox-inputonly ui */
+    GUIManager::getInstance().loadGUI( "ChatBox" );
+    GUIManager::getInstance().loadGUI( "ChatBox-inputonly" );
+
+    /* configure the input buffer */
+    configureInputBuffer();
+
+    this->inputState = InputManager::getInstance().createInputState( "chatinput", false, false, InputStatePriority::Dynamic );
+    this->inputState->setKeyHandler(this->inpbuf);
+  }
+
+  void ChatInputHandler::configureInputBuffer()
+  {
+    /* INSTALL CALLBACKS */
+    /* input has changed */
+    this->inpbuf->registerListener(this, &ChatInputHandler::inputChanged, true);
+
+    /* add a line */
+    this->inpbuf->registerListener(this, &ChatInputHandler::addline,         '\r',   false);
+    this->inpbuf->registerListener(this, &ChatInputHandler::addline,         '\n',   false);
+
+    /* backspace */
+    this->inpbuf->registerListener(this, &ChatInputHandler::backspace,       '\b',   true);
+    //this->inpbuf->registerListener(this, &ChatInputHandler::backspace,       '\177', true);
+
+    /* exit the chatinputhandler thingy (tbd) */
+    this->inpbuf->registerListener(this, &ChatInputHandler::exit,            '\033', true); // escape
+
+    /* delete character */
+    this->inpbuf->registerListener(this, &ChatInputHandler::deleteChar,      KeyCode::Delete);
+
+    /* cursor movement */
+    this->inpbuf->registerListener(this, &ChatInputHandler::cursorRight,     KeyCode::Right);
+    this->inpbuf->registerListener(this, &ChatInputHandler::cursorLeft,      KeyCode::Left);
+    this->inpbuf->registerListener(this, &ChatInputHandler::cursorEnd,       KeyCode::End);
+    this->inpbuf->registerListener(this, &ChatInputHandler::cursorHome,      KeyCode::Home);
+
+    /* GET WINDOW POINTERS */
+    input = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox/input" );
+    inputonly = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox-inputonly/input" );
+
+    /* get pointer to the history window */
+    CEGUI::Window *history = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox/history" );
+
+    /* cast it to a listbox */
+    lb_history = dynamic_cast<CEGUI::Listbox*>(history); 
+
+    /* assert wee */
+    assert( lb_history );
+  }
+
+
+  /* activate, deactivate */
+  void ChatInputHandler::activate_static()
+  { ChatInputHandler::getInstance().activate( true ); }
+
+  void ChatInputHandler::activate_small_static()
+  { ChatInputHandler::getInstance().activate( false ); }
+
+
+
+
+  void ChatInputHandler::activate( bool full )
+  {
+    /* start listening */
+    //COUT(0) << "chatinput activated." << std::endl;
+    InputManager::getInstance().enterState("chatinput");
+
+    /* MARK add spawning of chat widget stuff here.*/
+    if( full )
+      GUIManager::getInstance().showGUI( "ChatBox" );
+    else
+      GUIManager::getInstance().showGUI( "ChatBox-inputonly" );
+
+    this->fullchat = full;
+  }
+
+  void ChatInputHandler::deactivate() 
+  {
+    /* stop listening */
+    InputManager::getInstance().leaveState("chatinput");
+
+    /* un-spawning of chat widget stuff */
+    GUIManager::getInstance().hideGUI( "ChatBox" );
+    GUIManager::getInstance().hideGUI( "ChatBox-inputonly" );
+  }
+
+
+  void ChatInputHandler::incomingChat(const std::string& message, 
+    unsigned int senderID)
+  {
+    /* --> a) look up the actual name of the sender */
+    std::string text;
+
+    if (senderID != CLIENTID_UNKNOWN)
+    {
+       std::string name = "unknown";
+       PlayerInfo* player = PlayerManager::getInstance().getClient(senderID);
+       if (player)
+         name = player->getName();
+
+         text = name + ": " + message;
+    }
+    else
+      text = message;
+
+    /* e) create item and add to history */
+    CEGUI::ListboxTextItem *toadd = new CEGUI::ListboxTextItem( text );
+    this->lb_history->addItem( dynamic_cast<CEGUI::ListboxItem*>(toadd) );
+    this->lb_history->ensureItemIsVisible( dynamic_cast<CEGUI::ListboxItem*>(toadd) );
+
+    /* f) make sure the history handles it */
+    this->lb_history->handleUpdatedItemData();
+  } 
+
+
+  void ChatInputHandler::sub_adjust_dispoffset( int maxlen, 
+    int cursorpos, 
+    int inplen )
+  {
+    /* already start offsetting 5 characters before end */
+    if( cursorpos+5 > maxlen )
+    { 
+      /* always stay 5 characters ahead of end, looks better */
+      ((disp_offset = cursorpos-maxlen+5) >= 0) ? 1 : disp_offset = 0;
+
+      /* enforce visibility of cursor */
+      (disp_offset > cursorpos ) ? disp_offset = 0 : 1;
+    }
+     
+    /* make sure we don't die at substr */
+    if( inplen <= disp_offset ) disp_offset = 0;
+  }
+
+  /* callbacks for InputBuffer */
+  void ChatInputHandler::inputChanged()
+  {
+    /* update the cursor and the window */
+    std::string raw = this->inpbuf->get();
+    int cursorpos = this->inpbuf->getCursorPosition();
+    
+    /* get string before cursor */
+    std::string left = raw.substr( 0, cursorpos );
+
+    /* see if there's a string after the cursor */
+    std::string right = "";
+    if( raw.length() >= left.length()+1 )
+      right = raw.substr( cursorpos );
+      
+    /* set the text */
+    std::string assembled = "$ " + left + "|" + right;
+
+    if( this->fullchat )
+    { 
+      /* adjust curser position - magic number 5 for font width */
+      sub_adjust_dispoffset( (this->input->getUnclippedInnerRect().getWidth()/6), 
+        cursorpos, assembled.length() );
+      this->input->setProperty( "Text", assembled.substr( disp_offset ) );
+    }
+    else
+    {
+      /* adjust curser position - magic number 5 for font width */
+      sub_adjust_dispoffset( (this->inputonly->getUnclippedInnerRect().getWidth()/6), 
+        cursorpos, assembled.length() );
+      this->inputonly->setProperty( "Text", assembled.substr( disp_offset) );
+    }
+
+    /* reset display offset */
+    disp_offset = 0;
+  }
+
+  void ChatInputHandler::addline()
+  {
+    /* actually do send what was input */
+    /* a) get the string out of the inputbuffer */
+    std::string msgtosend = this->inpbuf->get();
+
+    if( msgtosend.length() == 0 )
+    { this->deactivate();
+      return;
+    }
+
+    /* b) clear the input buffer */
+    if (this->inpbuf->getSize() > 0)
+      this->inpbuf->clear();
+
+    /* c) send the chat via some call */
+    Host::Chat( msgtosend );
+
+    /* d) stop listening to input - only if this is not fullchat */
+    if( !this->fullchat )
+      this->deactivate();
+
+  }
+
+  void ChatInputHandler::backspace()
+  { this->inpbuf->removeBehindCursor(); }
+
+  void ChatInputHandler::deleteChar()
+  { this->inpbuf->removeAtCursor(); }
+
+  void ChatInputHandler::cursorRight()
+  { this->inpbuf->increaseCursor(); }
+  
+  void ChatInputHandler::cursorLeft()
+  { this->inpbuf->decreaseCursor(); }
+  
+  void ChatInputHandler::cursorEnd()
+  { this->inpbuf->setCursorToEnd(); }
+
+  void ChatInputHandler::cursorHome()
+  { this->inpbuf->setCursorToBegin(); }
+
+  void ChatInputHandler::exit()
+  {
+    /* b) clear the input buffer */
+    if (this->inpbuf->getSize() > 0)
+      this->inpbuf->clear();
+
+    /* d) stop listening to input  */
+    this->deactivate();
+  }
+
+}
Index: /code/branches/rocket2/src/orxonox/ChatInputHandler.h
===================================================================
--- /code/branches/rocket2/src/orxonox/ChatInputHandler.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/ChatInputHandler.h	(revision 6952)
@@ -0,0 +1,137 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Sandro 'smerkli' Merkli
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ChatInputHandler_H__
+#define _ChatInputHandler_H__
+
+/* std includes */
+#include <deque>
+#include <string>
+#include <fstream>
+#include <iostream>
+#include <cassert>
+#include <CEGUIForwardRefs.h>
+
+/* project includes */
+#include <OrxonoxPrereqs.h>
+#include <core/BaseObject.h>
+#include <core/PathConfig.h>
+
+#include "core/input/InputBuffer.h"
+#include "core/input/InputManager.h"
+#include "core/input/InputState.h"
+
+#include <network/ChatListener.h>
+#include <PlayerManager.h>
+#include <infos/PlayerInfo.h>
+
+#include "../libraries/network/Host.h"
+#include <util/Singleton.h>
+
+
+namespace orxonox
+{
+  /* class to handle chat using an InputBuffer */
+  class _OrxonoxExport ChatInputHandler : public Singleton<ChatInputHandler>,
+    public ChatListener
+  {
+    private:
+      /** Input buffer, to be used to catch input from the
+       * keyboard 
+       */
+      InputBuffer *inpbuf;
+      int disp_offset, width;
+      bool fullchat;
+
+      /** input state */
+      InputState *inputState;
+
+      /** setup input buffer, the constructor calls this */
+      void configureInputBuffer();
+
+      /** adjust display offset depending on cursor position */
+      void sub_adjust_dispoffset( int maxlen, int cursorpos, int inplen );
+
+      /** singleton pointer */
+      static ChatInputHandler* singletonPtr_s;
+
+      /** cegui window handles */
+      CEGUI::Window *input, *inputonly;
+
+      /** cegui handle for the history window */
+      CEGUI::Listbox *lb_history;
+
+      /* callbacks for input handler */
+      void inputChanged();
+      void addline();
+      void backspace();
+      void deleteChar();
+      void cursorRight();
+      void cursorLeft();
+      void cursorEnd();
+      void cursorHome();
+      void exit();
+
+    public:
+      /** constructor */
+      ChatInputHandler();
+      friend class Singleton<ChatInputHandler>;
+
+      /** start listening */
+      static void activate_static();
+
+      /** stop listening */
+      static void activate_small_static();
+
+      /** \param message the message text
+       * \param senderID ID of the player who sent the message
+       *
+       * Deal with incoming chat (which means in our case: Add it to the
+       * history window of the full chat window)
+       */
+      void incomingChat( const std::string& message, 
+        unsigned int senderID );
+
+      /** \param full true means show full chat window with history,
+            false means show only an input line
+       * 
+       * Show the chat window and redirect the game's keyboard input 
+       * into it.
+       */
+      void activate( bool full );
+
+      /** Deactivate the chat window, meaning: hide it. */
+      void deactivate();
+
+  };
+
+
+}
+
+
+#endif /*_ChatInputHandler_H__*/
Index: /code/branches/rocket2/src/orxonox/Level.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/Level.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/Level.cc	(revision 6952)
@@ -0,0 +1,169 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Level.h"
+
+#include "util/Math.h"
+#include "core/CoreIncludes.h"
+#include "core/Loader.h"
+#include "core/Template.h"
+#include "core/XMLFile.h"
+#include "core/XMLPort.h"
+
+#include "infos/PlayerInfo.h"
+#include "gametypes/Gametype.h"
+#include "overlays/OverlayGroup.h"
+#include "LevelManager.h"
+
+namespace orxonox
+{
+    CreateFactory(Level);
+
+    Level::Level(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
+    {
+        RegisterObject(Level);
+
+        
+        this->registerVariables();
+        this->xmlfilename_ = this->getFilename();
+        this->xmlfile_ = 0;
+    }
+
+    Level::~Level()
+    {
+        if (this->isInitialized())
+        {
+            if (LevelManager::exists())
+                LevelManager::getInstance().releaseActivity(this);
+
+            if (this->xmlfile_)
+                Loader::unload(this->xmlfile_);
+        }
+    }
+
+    void Level::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Level, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Level, "description", setDescription, getDescription, xmlelement, mode);
+        XMLPortParam(Level, "gametype", setGametypeString, getGametypeString, xmlelement, mode).defaultValues("Gametype");
+            
+        XMLPortObject(Level, MeshLodInformation, "lodinformation", addLodInfo, getLodInfo, xmlelement, mode);
+        XMLPortObjectExtended(Level, BaseObject, "", addObject, getObject, xmlelement, mode, true, false);
+}
+
+    void Level::registerVariables()
+    {
+        registerVariable(this->xmlfilename_, VariableDirection::ToClient, new NetworkCallback<Level>(this, &Level::networkcallback_applyXMLFile));
+        registerVariable(this->name_,        VariableDirection::ToClient, new NetworkCallback<Level>(this, &Level::changedName));
+        registerVariable(this->description_, VariableDirection::ToClient);
+    }
+
+    void Level::networkcallback_applyXMLFile()
+    {
+        COUT(0) << "Loading level \"" << this->xmlfilename_ << "\"..." << std::endl;
+
+        ClassTreeMask mask;
+        mask.exclude(Class(BaseObject));
+        mask.include(Class(Template));
+        mask.include(Class(OverlayGroup)); // HACK to include the ChatOverlay
+
+        this->xmlfile_ = new XMLFile(mask, this->xmlfilename_);
+
+        Loader::open(this->xmlfile_);
+    }
+
+    void Level::setGametypeString(const std::string& gametype)
+    {
+        Identifier* identifier = ClassByString(gametype);
+
+        if (!identifier || !identifier->isA(Class(Gametype)))
+        {
+            COUT(0) << "Error: \"" << gametype << "\" is not a valid gametype." << std::endl;
+            identifier = Class(Gametype);
+            this->gametype_ = "Gametype";
+        }
+        else
+            this->gametype_ = gametype;
+
+        Gametype* rootgametype = orxonox_cast<Gametype*>(identifier->fabricate(this));
+        this->setGametype(rootgametype);
+
+        for (std::list<BaseObject*>::iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
+            (*it)->setGametype(rootgametype);
+
+        if (LevelManager::exists())
+            LevelManager::getInstance().requestActivity(this);
+    }
+
+
+    void Level::addObject(BaseObject* object)
+    {
+        this->objects_.push_back(object);
+        object->setGametype(this->getGametype());
+    object->setLevel(this);
+    }
+
+    BaseObject* Level::getObject(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::list<BaseObject*>::const_iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+            ++i;
+        }
+        return 0;
+    }
+    
+    void Level::addLodInfo(MeshLodInformation* lodInformation)
+    {
+        std::string meshName = lodInformation->getMeshName();
+        this->lodInformation_.insert(std::make_pair(meshName,lodInformation));
+    }
+
+    MeshLodInformation* Level::getLodInfo(std::string meshName) const
+    {
+        if(this->lodInformation_.find(meshName)!=this->lodInformation_.end())
+            return this->lodInformation_.find(meshName)->second;
+        
+        return 0;
+    }
+
+    void Level::playerEntered(PlayerInfo* player)
+    {
+        COUT(3) << "player entered level (id: " << player->getClientID() << ", name: " << player->getName() << ')' << std::endl;
+        player->setGametype(this->getGametype());
+    }
+
+    void Level::playerLeft(PlayerInfo* player)
+    {
+        COUT(3) << "player left level (id: " << player->getClientID() << ", name: " << player->getName() << ')' << std::endl;
+        player->setGametype(0);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/Level.h
===================================================================
--- /code/branches/rocket2/src/orxonox/Level.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/Level.h	(revision 6952)
@@ -0,0 +1,86 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Level_H__
+#define _Level_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <list>
+#include <string>
+#include <map>
+#include "core/BaseObject.h"
+#include "network/synchronisable/Synchronisable.h"
+#include "graphics/MeshLodInformation.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Level : public BaseObject, public Synchronisable
+    {
+        public:
+            Level(BaseObject* creator);
+            virtual ~Level();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            inline void setDescription(const std::string& description)
+                { this->description_ = description; }
+            inline const std::string& getDescription() const
+                { return this->description_; }
+
+            void playerEntered(PlayerInfo* player);
+            void playerLeft(PlayerInfo* player);
+			
+            MeshLodInformation* getLodInfo(std::string meshName) const;
+
+
+        private:
+            void addObject(BaseObject* object);
+            BaseObject* getObject(unsigned int index) const;
+
+            void addLodInfo(MeshLodInformation* object);
+//            const MeshLodInformation* getLodInfo(std::string meshName) const;
+//            MeshLodInformation* getLodInfo(unsigned int index) const;
+
+            void setGametypeString(const std::string& gametype);
+            inline const std::string& getGametypeString() const
+                { return this->gametype_; }
+
+            void networkcallback_applyXMLFile();
+
+            std::string                    description_;
+            std::string                    gametype_;
+            std::string                    xmlfilename_;
+            XMLFile*                       xmlfile_;
+            std::list<BaseObject*>         objects_;
+            std::map<std::string,MeshLodInformation*>  lodInformation_;
+    };
+}
+
+#endif /* _Level_H__ */
Index: /code/branches/rocket2/src/orxonox/LevelManager.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/LevelManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/LevelManager.cc	(revision 6952)
@@ -0,0 +1,148 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "LevelManager.h"
+
+#include <map>
+
+#include "core/CommandLineParser.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
+#include "core/Loader.h"
+#include "core/Resource.h"
+#include "core/ScopedSingletonManager.h"
+#include "PlayerManager.h"
+#include "Level.h"
+
+namespace orxonox
+{
+    SetCommandLineArgument(level, "").shortcut("l").information("Default level file (overrides LevelManager::defaultLevelName_ configValue)");
+
+    ManageScopedSingleton(LevelManager, ScopeID::Root, false);
+
+    LevelManager::LevelManager()
+    {
+        RegisterRootObject(LevelManager);
+        this->setConfigValues();
+
+        // check override
+        if (!CommandLineParser::getArgument("level")->hasDefaultValue())
+        {
+            ModifyConfigValue(defaultLevelName_, tset, CommandLineParser::getValue("level").getString());
+        }
+    }
+
+    LevelManager::~LevelManager()
+    {
+    }
+
+    void LevelManager::setConfigValues()
+    {
+        SetConfigValue(defaultLevelName_, "presentation_dm.oxw")
+            .description("Sets the pre selection of the level in the main menu.");
+    }
+
+    void LevelManager::requestActivity(Level* level)
+    {
+        assert( std::find(this->levels_s.begin(), this->levels_s.end(), level)==this->levels_s.end() );
+        if( std::find(this->levels_s.begin(), this->levels_s.end(), level)!=this->levels_s.end() )
+            return; // level is already in list
+        this->levels_s.push_back(level);
+        if (this->levels_s.size() == 1)
+            this->activateNextLevel();
+    }
+
+    void LevelManager::releaseActivity(Level* level)
+    {
+        if (this->levels_s.size() > 0)
+        {
+            if (this->levels_s.front() == level)
+            {
+                level->setActive(false);
+                this->levels_s.pop_front();
+                this->activateNextLevel();
+            }
+            else
+            {
+                for (std::list<Level*>::iterator it = this->levels_s.begin(); it != this->levels_s.end(); ++it)
+                    if ((*it) == level)
+                        this->levels_s.erase(it);
+            }
+        }
+    }
+
+    Level* LevelManager::getActiveLevel()
+    {
+        if (this->levels_s.size() > 0)
+            return this->levels_s.front();
+        else
+            return 0;
+    }
+
+    void LevelManager::activateNextLevel()
+    {
+        if (this->levels_s.size() > 0)
+        {
+            this->levels_s.front()->setActive(true);
+            for (std::map<unsigned int, PlayerInfo*>::const_iterator it = PlayerManager::getInstance().getClients().begin(); it != PlayerManager::getInstance().getClients().end(); ++it)
+                this->levels_s.front()->playerEntered(it->second);
+        }
+    }
+
+    void LevelManager::setDefaultLevel(const std::string& levelName)
+    {
+        ModifyConfigValue(defaultLevelName_, set, levelName);
+    }
+
+    const std::string& LevelManager::getDefaultLevel() const
+    {
+        return defaultLevelName_;
+    }
+
+    const std::string& LevelManager::getAvailableLevelListItem(unsigned int index) const
+    {
+        if (index >= availableLevels_.size())
+            return BLANKSTRING;
+        else
+            return availableLevels_[index];
+    }
+
+    void LevelManager::compileAvailableLevelList()
+    {
+        this->availableLevels_.clear();
+        Ogre::StringVectorPtr levels = Resource::findResourceNames("*.oxw");
+        for (Ogre::StringVector::const_iterator it = levels->begin(); it != levels->end(); ++it)
+        {
+            if (it->find("old/") != 0)
+            {
+                size_t pos = it->find(".oxw");
+                this->availableLevels_.push_back(it->substr(0, pos));
+            }
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/LevelManager.h
===================================================================
--- /code/branches/rocket2/src/orxonox/LevelManager.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/LevelManager.h	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _LevelManager_H__
+#define _LevelManager_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <cassert>
+#include <list>
+#include <string>
+
+#include "util/Singleton.h"
+#include "core/OrxonoxClass.h"
+
+// tolua_begin
+namespace orxonox
+{
+    class _OrxonoxExport LevelManager
+    // tolua_end
+        : public Singleton<LevelManager>, public OrxonoxClass
+    { // tolua_export
+            friend class Singleton<LevelManager>;
+        public:
+            LevelManager();
+            virtual ~LevelManager();
+
+            void setConfigValues();
+
+            void requestActivity(Level* level);
+            void releaseActivity(Level* level);
+            Level* getActiveLevel();
+
+            void setDefaultLevel(const std::string& levelName); //tolua_export
+            const std::string& getDefaultLevel() const; //tolua_export
+            void compileAvailableLevelList(); //tolua_export
+            const std::string& getAvailableLevelListItem(unsigned int index) const; //tolua_export
+
+            static LevelManager& getInstance()    { return Singleton<LevelManager>::getInstance(); } // tolua_export
+
+        private:
+            LevelManager(const LevelManager&);
+
+            void activateNextLevel();
+
+            std::list<Level*> levels_s;
+            std::vector<std::string> availableLevels_;
+
+            // config values
+            std::string defaultLevelName_;
+
+            static LevelManager* singletonPtr_s;
+    }; // tolua_export
+} // tolua_export
+
+#endif /* _LevelManager_H__ */
Index: /code/branches/rocket2/src/orxonox/Main.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/Main.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/Main.cc	(revision 6952)
@@ -0,0 +1,98 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    The main function of Orxonox (but not the entry point of the program!)
+*/
+
+#include "OrxonoxPrereqs.h"
+
+#include "core/CommandLineParser.h"
+#include "core/Game.h"
+#include "core/LuaState.h"
+#include "ToluaBindOrxonox.h"
+#include "Main.h"
+
+SetCommandLineSwitch(console).information("Start in console mode (text IO only)");
+// Shortcuts for easy direct loading
+SetCommandLineSwitch(server).information("Start in server mode");
+SetCommandLineSwitch(client).information("Start in client mode");
+SetCommandLineSwitch(dedicated).information("Start in dedicated server mode");
+SetCommandLineSwitch(standalone).information("Start in standalone mode");
+SetCommandLineSwitch(dedicatedClient).information("Start in dedicated client mode");
+
+DeclareToluaInterface(Orxonox);
+
+namespace orxonox
+{
+    /**
+    @brief
+        Starting point of orxonox (however not the entry point of the program!)
+    */
+    int main(const std::string& strCmdLine)
+    {
+        Game* game = new Game(strCmdLine);
+
+        game->setStateHierarchy(
+        "root"
+        " graphics"
+        "  mainMenu"
+        "  standalone,server,client"
+        "   level"
+        " server,client"
+        "  level"
+        );
+
+        game->requestState("root");
+
+        // Some development hacks (not really, but in the future, this calls won't make sense anymore)
+        if (CommandLineParser::getValue("standalone").getBool())
+            Game::getInstance().requestStates("graphics, standalone, level");
+        else if (CommandLineParser::getValue("server").getBool())
+            Game::getInstance().requestStates("graphics, server, level");
+        else if (CommandLineParser::getValue("client").getBool())
+            Game::getInstance().requestStates("graphics, client, level");
+        else if (CommandLineParser::getValue("dedicated").getBool())
+            Game::getInstance().requestStates("server, level");
+        else if (CommandLineParser::getValue("dedicatedClient").getBool())
+            Game::getInstance().requestStates("client, level");
+        else
+        {
+            if (!CommandLineParser::getValue("console").getBool())
+                Game::getInstance().requestStates("graphics, mainMenu");
+        }
+
+        game->run();
+        delete game;
+
+        return 0;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/Main.h
===================================================================
--- /code/branches/rocket2/src/orxonox/Main.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/Main.h	(revision 6952)
@@ -0,0 +1,40 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin Knecht <beni_at_orxonox.net>, (C) 2007
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Main_H__
+#define _Main_H__
+
+#include "OrxonoxPrereqs.h"
+
+namespace orxonox
+{
+    _OrxonoxExport int main(const std::string& strCmdLine);
+}
+
+#endif /* _Main_H__ */
Index: /code/branches/rocket2/src/orxonox/MoodManager.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/MoodManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/MoodManager.cc	(revision 6952)
@@ -0,0 +1,89 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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 'youngk' Young
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "MoodManager.h"
+
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
+#include "core/ScopedSingletonManager.h"
+
+namespace orxonox
+{
+    ManageScopedSingleton(MoodManager, ScopeID::Root, false);
+
+    MoodManager::MoodManager()
+    {
+        RegisterRootObject(MoodManager);
+        this->setConfigValues();
+    }
+
+    void MoodManager::setConfigValues()
+    {
+        SetConfigValue(mood_, "default")
+            .description("Sets the mood for the current level.")
+            .callback(this, &MoodManager::checkMoodValidity);
+    }
+
+    /** Sets the mood
+    @note
+        TODO: Inform dependent classes of mood change
+    */
+    void MoodManager::setMood(const std::string& mood)
+    {
+        ModifyConfigValue(mood_, set, mood);
+    }
+
+    void MoodManager::checkMoodValidity()
+    {
+        // TODO: Insert new moods here & make this generic
+        if (mood_ != "default" && mood_ != "dnb")
+        {
+            ResetConfigValue(mood_);
+        }
+        else
+        {
+            COUT(3) << "Mood changed to " << mood_ << std::endl;
+            MoodListener::changedMood(mood_);
+        }
+    }
+
+
+    std::string MoodListener::mood_s;
+
+    MoodListener::MoodListener()
+    {
+        RegisterRootObject(MoodListener);
+    }
+
+    /*static*/ void MoodListener::changedMood(const std::string& mood)
+    {
+        mood_s = mood;
+        for (ObjectList<MoodListener>::iterator it = ObjectList<MoodListener>::begin(); it; ++it)
+            it->moodChanged(mood_s);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/MoodManager.h
===================================================================
--- /code/branches/rocket2/src/orxonox/MoodManager.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/MoodManager.h	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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 'youngk' Young
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _MoodManager_H__
+#define _MoodManager_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "util/Singleton.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport MoodListener : virtual public OrxonoxClass
+    {
+        friend class MoodManager;
+
+        protected:
+            MoodListener();
+            virtual ~MoodListener() {}
+
+            const std::string& getMood() const { return mood_s; }
+
+        private:
+            virtual void moodChanged(const std::string& mood) = 0;
+
+            static void changedMood(const std::string& mood);
+            static std::string mood_s;
+    };
+
+    class _OrxonoxExport MoodManager : public Singleton<MoodManager>, public OrxonoxClass
+    {
+            friend class Singleton<MoodManager>;
+        public:
+            MoodManager();
+
+            void setConfigValues();
+
+            void setMood(const std::string& mood);
+            inline const std::string& getMood() const { return this->mood_; }
+
+            static MoodManager& getInstance() { return Singleton<MoodManager>::getInstance(); }
+
+        private:
+            ~MoodManager() {}
+            void checkMoodValidity();
+
+            // config values
+            std::string mood_;
+
+            static MoodManager* singletonPtr_s;
+    };
+}
+
+#endif /* _MoodManager_H__ */
Index: /code/branches/rocket2/src/orxonox/OrxonoxPrecompiledHeaders.h
===================================================================
--- /code/branches/rocket2/src/orxonox/OrxonoxPrecompiledHeaders.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/OrxonoxPrecompiledHeaders.h	(revision 6952)
@@ -0,0 +1,97 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Compilation of the most often used header files in the orxonox library
+@details
+    Updated: 13. September 2009
+    Total Files: 88
+*/
+
+#include "OrxonoxConfig.h"
+
+///////////////////////////////////////////
+/////          Stable Headers         /////
+///////////////////////////////////////////
+
+#include <cassert>  // 87
+#include <cstring>  // 87
+#include <fstream>  // 87
+#include <iostream> // 87
+#include <map>      // 87
+#include <set>      // 87
+#include <sstream>  // 87
+#include <string>   // 87
+#include <vector>   // 87
+#include <list>     // 86
+#include <ctime>    // 82
+#include <cmath>    // 81
+#include <deque>    // 81
+#include <queue>    // 81
+
+#include <OgreMath.h>        // 81
+#include <OgreVector2.h>     // 81
+#include <OgreVector3.h>     // 81
+#include <OgreVector4.h>     // 81
+#include <OgreQuaternion.h>  // 81
+#include <OgreColourValue.h> // 81
+
+#include "util/OgreForwardRefs.h"     // 67
+#include <LinearMath/btMotionState.h> // 60
+#include "util/SubString.h" // 55
+#include <tinyxml/ticpp.h>  // 41
+
+//#include <OgreRenderable.h> // 14, 5.1MB
+//#include <OgreSceneNode.h>  // 13, 1MB
+//#include <OgreResourceGroupManager.h> // 12, 1.5MB
+//#include <OgreTexture.h>       // 11, 0.6MB
+//#include <OgreMovableObject.h> // 10, 1.6MB
+//#include <OgreSceneManager.h>  // 9, 8.7MB
+
+///////////////////////////////////////////
+/////       All Rebuild Headers       /////
+///////////////////////////////////////////
+
+#include "core/BaseObject.h"   // 82
+#include "core/CoreIncludes.h" // 80
+
+///////////////////////////////////////////
+/////      Not so Stable Headers      /////
+///////////////////////////////////////////
+
+#include "network/synchronisable/Synchronisable.h" // 70
+#include "util/MultiType.h"    // 65
+#include "core/Executor.h"     // 55
+//#include "core/XMLPort.h"     // 41
+
+
+// Just in case some header included windows.h
+#undef min
+#undef max
Index: /code/branches/rocket2/src/orxonox/OrxonoxPrereqs.h
===================================================================
--- /code/branches/rocket2/src/orxonox/OrxonoxPrereqs.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/OrxonoxPrereqs.h	(revision 6952)
@@ -0,0 +1,207 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Shared library macros, enums, constants and forward declarations for the orxonox library
+*/
+
+#ifndef _OrxonoxPrereqs_H__
+#define _OrxonoxPrereqs_H__
+
+#include "OrxonoxConfig.h"
+#include "tools/ToolsPrereqs.h"
+
+//-----------------------------------------------------------------------
+// Shared library settings
+//-----------------------------------------------------------------------
+
+#if defined(ORXONOX_PLATFORM_WINDOWS) && !defined(ORXONOX_STATIC_BUILD)
+#  ifdef ORXONOX_SHARED_BUILD
+#    define _OrxonoxExport __declspec(dllexport)
+#  else
+#    if defined( __MINGW32__ )
+#      define _OrxonoxExport
+#    else
+#      define _OrxonoxExport __declspec(dllimport)
+#    endif
+#  endif
+#elif defined ( ORXONOX_GCC_VISIBILITY )
+#  define _OrxonoxExport  __attribute__ ((visibility("default")))
+#else
+#  define _OrxonoxExport
+#endif
+
+//-----------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------
+
+namespace orxonox
+{
+    class CameraManager;
+    class Level;
+    class LevelManager;
+    class PawnManager;
+    class PlayerManager;
+    class Radar;
+    class Scene;
+
+    // collisionshapes
+    class CollisionShape;
+    class CompoundCollisionShape;
+    class WorldEntityCollisionShape;
+
+    // controllers
+    class AIController;
+    class ArtificialController;
+    class Controller;
+    class HumanController;
+    class ScriptController;
+    class WaypointController;
+    class WaypointPatrolController;
+
+    // gametypes
+    class Asteroids;
+    class Deathmatch;
+    class Gametype;
+    class TeamBaseMatch;
+    class TeamDeathmatch;
+    class UnderAttack;
+
+    // graphics
+    class Backlight;
+    class Billboard;
+    class BlinkingBillboard;
+    class Camera;
+    class FadingBillboard;
+    class GlobalShader;
+    class Light;
+    class Model;
+    class ParticleEmitter;
+    class ParticleSpawner;
+
+    // infos
+    class Bot;
+    class GametypeInfo;
+    class HumanPlayer;
+    class Info;
+    class PlayerInfo;
+
+    // interfaces
+    class GametypeMessageListener;
+    class NotificationListener;
+    class Pickupable;
+    class PickupCarrier;
+    class PlayerTrigger;
+    class RadarListener;
+    class RadarViewable;
+    class Rewardable;
+    class TeamColourable;
+
+    // items
+    class Engine;
+    class Item;
+    class MultiStateEngine;
+
+    // overlays
+    class InGameConsole;
+    class Map;
+    class OrxonoxOverlay;
+    class OverlayGroup;
+    
+    // pickup
+    class PickupIdentifier;
+
+    //sound
+    class AmbientSound;
+    class BaseSound;
+    class SoundBuffer;
+    class SoundManager;
+    class SoundStreamer;
+    class WorldSound;
+
+    // weaponsystem
+    class DefaultWeaponmodeLink;
+    class Munition;
+    class Weapon;
+    class WeaponMode;
+    class WeaponPack;
+    class WeaponSet;
+    class WeaponSlot;
+    class WeaponSystem;
+
+    // worldentities
+    class BigExplosion;
+    class CameraPosition;
+    class ControllableEntity;
+    class EffectContainer;
+    class ExplosionChunk;
+    class MobileEntity;
+    class MovableEntity;
+    class SpawnPoint;
+    class StaticEntity;
+    class TeamSpawnPoint;
+    class WorldEntity;
+    class Rocket;
+    // worldentities, pawns
+    class Destroyer;
+    class Pawn;
+    class SpaceShip;
+    class Spectator;
+    class TeamBaseMatchBase;
+}
+
+// Bullet Physics Engine
+class btTransform;
+class btVector3;
+
+class btRigidBody;
+class btCollisionObject;
+class btGhostObject;
+class btManifoldPoint;
+
+class btCollisionShape;
+class btSphereShape;
+class btCompoundShape;
+class btStaticPlaneShape;
+
+class btDiscreteDynamicsWorld;
+class bt32BitAxisSweep3;
+class btDefaultCollisionConfiguration;
+class btCollisionDispatcher;
+class btSequentialImpulseConstraintSolver;
+
+// ALUT
+typedef struct ALCcontext_struct ALCcontext;
+typedef struct ALCdevice_struct ALCdevice;
+typedef unsigned int ALuint;
+typedef int ALint;
+typedef int ALenum;
+
+#endif /* _OrxonoxPrereqs_H__ */
Index: /code/branches/rocket2/src/orxonox/PawnManager.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/PawnManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/PawnManager.cc	(revision 6952)
@@ -0,0 +1,67 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "PawnManager.h"
+
+#include "core/CoreIncludes.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    PawnManager* PawnManager::singletonPtr_s = 0;
+
+    PawnManager::PawnManager()
+    {
+        RegisterRootObject(PawnManager);
+    }
+
+    PawnManager::~PawnManager()
+    {
+    }
+
+    void PawnManager::touch()
+    {
+        if (!PawnManager::singletonPtr_s)
+            new PawnManager();
+    }
+
+    void PawnManager::tick(float dt)
+    {
+        unsigned int count = 0;
+        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++count)
+        {
+            if (!it->isAlive())
+                (it++)->destroy();
+            else
+                ++it;
+        }
+
+        if (count == 0)
+            this->destroy();
+    }
+}
Index: /code/branches/rocket2/src/orxonox/PawnManager.h
===================================================================
--- /code/branches/rocket2/src/orxonox/PawnManager.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/PawnManager.h	(revision 6952)
@@ -0,0 +1,55 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PawnManager_H__
+#define _PawnManager_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/Singleton.h"
+#include "tools/interfaces/Tickable.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport PawnManager : protected Singleton<PawnManager>, public Tickable
+    {
+            friend class Singleton<PawnManager>;
+        public:
+            static void touch();
+
+            virtual void tick(float dt);
+
+        private:
+            PawnManager();
+            virtual ~PawnManager();
+
+            static PawnManager* singletonPtr_s;
+    };
+}
+
+#endif /* _PawnManager_H__ */
Index: /code/branches/rocket2/src/orxonox/PlayerManager.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/PlayerManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/PlayerManager.cc	(revision 6952)
@@ -0,0 +1,116 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "PlayerManager.h"
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/ScopedSingletonManager.h"
+#include "Level.h"
+#include "infos/HumanPlayer.h"
+#include "LevelManager.h"
+
+namespace orxonox
+{
+    ManageScopedSingleton(PlayerManager, ScopeID::Root, false);
+
+    PlayerManager::PlayerManager()
+    {
+        RegisterRootObject(PlayerManager);
+
+        this->getConnectedClients();
+    }
+
+    PlayerManager::~PlayerManager()
+    {
+    }
+
+    void PlayerManager::clientConnected(unsigned int clientID)
+    {
+        if (GameMode::isMaster())
+        {
+            if (clientID != 0)
+                COUT(3) << "client connected" << std::endl;
+
+            // create new HumanPlayer instance
+            HumanPlayer* player = new HumanPlayer(0);
+            player->setClientID(clientID);
+
+            // add to clients-map
+            assert(!this->clients_[clientID]);
+            this->clients_[clientID] = player;
+
+            if (LevelManager::exists() && LevelManager::getInstance().getActiveLevel())
+                LevelManager::getInstance().getActiveLevel()->playerEntered(player);
+        }
+    }
+
+    void PlayerManager::clientDisconnected(unsigned int clientID)
+    {
+        if (GameMode::isMaster())
+        {
+            if (clientID != 0)
+                COUT(3) << "client disconnected" << std::endl;
+
+            // remove from clients-map
+            PlayerInfo* player = this->clients_[clientID];
+            this->clients_.erase(clientID);
+
+            if (LevelManager::exists() && LevelManager::getInstance().getActiveLevel())
+                LevelManager::getInstance().getActiveLevel()->playerLeft(player);
+
+            // delete PlayerInfo instance
+            if (player)
+                player->destroy();
+        }
+    }
+
+    void PlayerManager::disconnectAllClients()
+    {
+        for( std::map<unsigned int, PlayerInfo*>::iterator it = this->clients_.begin(); it != this->clients_.end(); )
+            this->clientDisconnected( (it++)->first );
+    }
+
+
+    PlayerInfo* PlayerManager::getClient(unsigned int clientID) const
+    {
+        if (GameMode::isMaster())
+        {
+            std::map<unsigned int, PlayerInfo*>::const_iterator it = this->clients_.find(clientID);
+            if (it != this->clients_.end())
+                return it->second;
+        }
+        else
+        {
+            for (ObjectList<PlayerInfo>::iterator it = ObjectList<PlayerInfo>::begin(); it != ObjectList<PlayerInfo>::end(); ++it)
+                if (it->getClientID() == clientID)
+                    return (*it);
+        }
+        return 0;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/PlayerManager.h
===================================================================
--- /code/branches/rocket2/src/orxonox/PlayerManager.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/PlayerManager.h	(revision 6952)
@@ -0,0 +1,63 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PlayerManager_H__
+#define _PlayerManager_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <cassert>
+#include <map>
+#include "util/Singleton.h"
+#include "network/ClientConnectionListener.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport PlayerManager : public Singleton<PlayerManager>, public ClientConnectionListener
+    {
+            friend class Singleton<PlayerManager>;
+        public:
+            PlayerManager();
+            virtual ~PlayerManager();
+
+            PlayerInfo* getClient(unsigned int clientID) const;
+            inline const std::map<unsigned int, PlayerInfo*>& getClients() const
+                { return this->clients_; }
+
+            void clientConnected(unsigned int clientID);
+            void clientDisconnected(unsigned int clientID);
+            void disconnectAllClients();
+
+        private:
+            std::map<unsigned int, PlayerInfo*> clients_;
+
+            static PlayerManager* singletonPtr_s;
+    };
+}
+
+#endif /* _PlayerManager_H__ */
Index: /code/branches/rocket2/src/orxonox/Radar.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/Radar.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/Radar.cc	(revision 6952)
@@ -0,0 +1,213 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      Felix Schulthess
+ *
+ */
+
+/**
+@file
+@brief
+*/
+
+#include "Radar.h"
+
+#include <cassert>
+
+//#include "util/Math.h"
+#include "core/ConsoleCommand.h"
+#include "core/ObjectList.h"
+#include "interfaces/RadarListener.h"
+#include "controllers/HumanController.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+
+    Radar::Radar()
+        : itFocus_(0)
+        , focus_(0)
+        , objectTypeCounter_(0)
+    {
+        // TODO: make this mapping configurable. Maybe there's a possibility with self configured
+        //       configValues..
+        this->objectTypes_["Asteroid"] = RadarViewable::Dot;
+        this->objectTypes_["SpaceShip"] = RadarViewable::Square;
+        this->objectTypes_["AsdfQwerty"] = RadarViewable::Triangle;
+
+        /*WorldEntity* object;
+        object = new WorldEntity();
+        object->setPosition(2000.0, 0.0, 0.0);
+        addRadarObject(object, ColourValue(0.5, 0, 0, 1));
+        object = new WorldEntity();
+        object->setPosition(0.0, 2000.0, 0.0);
+        addRadarObject(object, ColourValue(0.5, 0, 0, 1));
+        object = new WorldEntity();
+        object->setPosition(0.0, 0.0, 2000.0);
+        addRadarObject(object, ColourValue(0.5, 0, 0, 1));
+        object = new WorldEntity();
+        object->setPosition(10000.0,16000.0,0.0);
+        addRadarObject(object);*/
+
+    }
+
+    Radar::~Radar()
+    {
+    }
+
+    void Radar::addRadarObject(RadarViewable* rv)
+    {
+        assert( this->radarObjects_.find(rv) == this->radarObjects_.end() );
+        this->radarObjects_.insert(rv);
+        // iterate through all radarlisteners and notify them
+        for (ObjectList<RadarListener>::iterator itListener = ObjectList<RadarListener>::begin(); itListener; ++itListener)
+        {
+            (*itListener)->addObject(rv);
+        }
+    }
+    
+    void Radar::removeRadarObject(RadarViewable* rv)
+    {
+        assert( this->radarObjects_.find(rv) != this->radarObjects_.end() );
+        this->radarObjects_.erase(rv);
+        // iterate through all radarlisteners and notify them
+        for (ObjectList<RadarListener>::iterator itListener = ObjectList<RadarListener>::begin(); itListener; ++itListener)
+        {
+            (*itListener)->removeObject(rv);
+        }
+    }
+
+    const RadarViewable* Radar::getFocus()
+    {
+        if (this->itFocus_)
+            return *(this->itFocus_);
+        else
+            return 0;
+    }
+
+    RadarViewable::Shape Radar::addObjectDescription(const std::string& name)
+    {
+        std::map<std::string, RadarViewable::Shape>::iterator it = this->objectTypes_.find(name);
+        if (it == this->objectTypes_.end())
+            return this->objectTypes_[name] = RadarViewable::Square; // default, configure!!
+        else
+            return this->objectTypes_[name];
+    }
+
+
+    void Radar::tick(float dt)
+    {
+        SUPER(Radar, tick, dt);
+
+        if (this->itFocus_ && (this->focus_ != *(this->itFocus_)))
+        {
+            // focus object was deleted, release focus
+            this->focus_ = 0;
+            this->itFocus_ = 0;
+        }
+
+        for (ObjectList<RadarListener>::iterator itListener = ObjectList<RadarListener>::begin(); itListener; ++itListener)
+        {
+            (*itListener)->radarTick(dt);
+        }
+    }
+
+    void Radar::cycleFocus()
+    {
+        if (ObjectList<RadarViewable>::begin() == ObjectList<RadarViewable>::end())
+        {
+            // list is empty
+            this->itFocus_ = 0;
+            this->focus_ = 0;
+        }
+
+        else if (HumanController::getLocalControllerEntityAsPawn())
+        {
+            Vector3 localPosition = HumanController::getLocalControllerEntityAsPawn()->getWorldPosition();
+            Vector3 targetPosition = localPosition;
+            if (this->itFocus_ && *(this->itFocus_))
+                targetPosition = this->itFocus_->getRVWorldPosition();
+
+            // find the closest object further away than targetPosition
+            float currentDistance = localPosition.squaredDistance(targetPosition);
+            float nextDistance = FLT_MAX;
+            float minimumDistance = FLT_MAX;
+            ObjectList<RadarViewable>::iterator itFallback = 0;
+
+            for (ObjectList<RadarViewable>::iterator it = ObjectList<RadarViewable>::begin(); it; ++it)
+            {
+                if (*it == static_cast<RadarViewable*>(HumanController::getLocalControllerEntityAsPawn()))
+                    continue;
+
+                float targetDistance = localPosition.squaredDistance((*it)->getRVWorldPosition());
+                if (targetDistance > currentDistance && targetDistance < nextDistance)
+                {
+                    this->itFocus_ = it;
+                    nextDistance = targetDistance;
+                }
+                if (targetDistance < minimumDistance)
+                {
+                    itFallback = it;
+                    minimumDistance = targetDistance;
+                }
+            }
+
+            if (nextDistance == FLT_MAX)
+            {
+                // we already had the furthest object
+                this->itFocus_ = itFallback;
+                this->focus_ = *itFallback;
+            }
+            else
+            {
+                this->focus_ = *(this->itFocus_);
+            }
+        }
+    }
+
+    void Radar::releaseFocus()
+    {
+        this->itFocus_ = 0;
+        this->focus_ = 0;
+    }
+
+    void Radar::listObjects() const
+    {
+        COUT(3) << "List of RadarObjects:\n";
+        // iterate through all Radar Objects
+        unsigned int i = 0;
+        for (ObjectList<RadarViewable>::iterator it = ObjectList<RadarViewable>::begin(); it; ++it, ++i)
+        {
+            COUT(3) << i++ << ": " << (*it)->getRVWorldPosition() << std::endl;
+        }
+    }
+    
+    void Radar::radarObjectChanged(RadarViewable* rv)
+    {
+        for (ObjectList<RadarListener>::iterator itListener = ObjectList<RadarListener>::begin(); itListener; ++itListener)
+        {
+          (*itListener)->objectChanged(rv);
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/Radar.h
===================================================================
--- /code/branches/rocket2/src/orxonox/Radar.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/Radar.h	(revision 6952)
@@ -0,0 +1,83 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      Felix Schulthess
+ *
+ */
+
+/**
+@file
+@brief
+*/
+
+#ifndef _Radar_H__
+#define _Radar_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "core/ObjectListIterator.h"
+#include "interfaces/RadarViewable.h"
+#include "tools/interfaces/Tickable.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Radar : public Tickable
+    {
+        friend class RadarViewable;
+    public:
+        Radar();
+        virtual ~Radar();
+
+        virtual void tick(float dt);
+
+        const RadarViewable* getFocus();
+        RadarViewable::Shape addObjectDescription(const std::string& name);
+
+        void listObjects() const;
+        const std::set<RadarViewable*>& getRadarObjects() const
+            { return this->radarObjects_; }
+
+        void releaseFocus();
+        void cycleFocus();
+
+    private:
+        Radar(Radar& instance);
+
+        void updateFocus();
+        void addRadarObject(RadarViewable* rv);
+        void removeRadarObject(RadarViewable* rv);
+        void radarObjectChanged(RadarViewable* rv);
+
+        ObjectListIterator<RadarViewable> itFocus_;
+        RadarViewable* focus_;
+        std::map<std::string, RadarViewable::Shape> objectTypes_;
+        std::set<RadarViewable*> radarObjects_;
+        int objectTypeCounter_;
+    };
+}
+#endif /* _Radar_H__ */
Index: /code/branches/rocket2/src/orxonox/Scene.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/Scene.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/Scene.cc	(revision 6952)
@@ -0,0 +1,350 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder (physics)
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Scene.h"
+
+#include <OgreRoot.h>
+#include <OgreSceneManager.h>
+#include <OgreSceneManagerEnumerator.h>
+#include <OgreSceneNode.h>
+
+#include <BulletCollision/BroadphaseCollision/btAxisSweep3.h>
+#include <BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h>
+#include <BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h>
+#include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/GUIManager.h"
+#include "core/XMLPort.h"
+#include "tools/BulletConversions.h"
+#include "Radar.h"
+#include "worldentities/WorldEntity.h"
+
+namespace orxonox
+{
+    CreateFactory(Scene);
+
+    Scene::Scene(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
+    {
+        RegisterObject(Scene);
+
+        this->setScene(SmartPtr<Scene>(this, false), OBJECTID_UNKNOWN);
+        this->bShadows_ = true;
+        this->soundReferenceDistance_ = 20.0;
+
+        if (GameMode::showsGraphics())
+        {
+            assert(Ogre::Root::getSingletonPtr());
+            this->sceneManager_ = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC);
+            this->rootSceneNode_ = this->sceneManager_->getRootSceneNode();
+
+            this->radar_ = new Radar();
+        }
+        else
+        {
+            // create a dummy SceneManager of our own since we don't have Ogre::Root.
+            this->sceneManager_ = new Ogre::DefaultSceneManager("");
+            this->rootSceneNode_ = this->sceneManager_->getRootSceneNode();
+
+            this->radar_ = 0;
+        }
+
+        // No physics yet, XMLPort will do that.
+        const int defaultMaxWorldSize = 100000;
+        this->negativeWorldRange_ = Vector3::UNIT_SCALE * -defaultMaxWorldSize;
+        this->positiveWorldRange_ = Vector3::UNIT_SCALE *  defaultMaxWorldSize;
+        this->gravity_ = Vector3::ZERO;
+        this->physicalWorld_   = 0;
+        this->solver_          = 0;
+        this->dispatcher_      = 0;
+        this->collisionConfig_ = 0;
+        this->broadphase_      = 0;
+
+        this->registerVariables();
+    }
+
+    Scene::~Scene()
+    {
+        if (this->isInitialized())
+        {
+            if (GameMode::showsGraphics())
+                Ogre::Root::getSingleton().destroySceneManager(this->sceneManager_);
+            else
+                delete this->sceneManager_;
+
+            if (this->radar_)
+                this->radar_->destroy();
+
+            this->setPhysicalWorld(false);
+        }
+    }
+
+    void Scene::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Scene, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Scene, "skybox", setSkybox, getSkybox, xmlelement, mode);
+        XMLPortParam(Scene, "ambientlight", setAmbientLight, getAmbientLight, xmlelement, mode).defaultValues(ColourValue(0.2f, 0.2f, 0.2f, 1.0f));
+        XMLPortParam(Scene, "shadow", setShadow, getShadow, xmlelement, mode).defaultValues(true);
+        XMLPortParam(Scene, "soundReferenceDistance", setSoundReferenceDistance, getSoundReferenceDistance, xmlelement, mode);
+
+        XMLPortParam(Scene, "gravity", setGravity, getGravity, xmlelement, mode);
+        XMLPortParam(Scene, "negativeWorldRange", setNegativeWorldRange, getNegativeWorldRange, xmlelement, mode);
+        XMLPortParam(Scene, "positiveWorldRange", setPositiveWorldRange, getPositiveWorldRange, xmlelement, mode);
+        XMLPortParam(Scene, "hasPhysics", setPhysicalWorld, hasPhysics, xmlelement, mode).defaultValues(true);
+
+        XMLPortObjectExtended(Scene, BaseObject, "", addObject, getObject, xmlelement, mode, true, false);
+    }
+
+    void Scene::registerVariables()
+    {
+        registerVariable(this->skybox_,             VariableDirection::ToClient, new NetworkCallback<Scene>(this, &Scene::networkcallback_applySkybox));
+        registerVariable(this->ambientLight_,       VariableDirection::ToClient, new NetworkCallback<Scene>(this, &Scene::networkcallback_applyAmbientLight));
+        registerVariable(this->negativeWorldRange_, VariableDirection::ToClient, new NetworkCallback<Scene>(this, &Scene::networkcallback_negativeWorldRange));
+        registerVariable(this->positiveWorldRange_, VariableDirection::ToClient, new NetworkCallback<Scene>(this, &Scene::networkcallback_positiveWorldRange));
+        registerVariable(this->gravity_,            VariableDirection::ToClient, new NetworkCallback<Scene>(this, &Scene::networkcallback_gravity));
+        registerVariable(this->bHasPhysics_,        VariableDirection::ToClient, new NetworkCallback<Scene>(this, &Scene::networkcallback_hasPhysics));
+        registerVariable(this->bShadows_,           VariableDirection::ToClient, new NetworkCallback<Scene>(this, &Scene::networkcallback_applyShadows));
+    }
+
+    void Scene::setNegativeWorldRange(const Vector3& range)
+    {
+        if (range.length() < 10.0f)
+        {
+            CCOUT(2) << "Warning: Setting the negative world range to a very small value: "
+                     << multi_cast<std::string>(range) << std::endl;
+        }
+        if (this->hasPhysics())
+        {
+            CCOUT(2) << "Warning: Attempting to set the physical world range at run time. "
+                     << "This causes a complete physical reload which might take some time." << std::endl;
+            this->setPhysicalWorld(false);
+            this->negativeWorldRange_ = range;
+            this->setPhysicalWorld(true);
+        }
+        else
+            this->negativeWorldRange_ = range;
+    }
+
+    void Scene::setPositiveWorldRange(const Vector3& range)
+    {
+        if (range.length() < 10.0f)
+        {
+            CCOUT(2) << "Warning: Setting the positive world range to a very small value: "
+                     << multi_cast<std::string>(range) << std::endl;
+        }
+        if (this->hasPhysics())
+        {
+            CCOUT(2) << "Warning: Attempting to set the physical world range at run time. "
+                     << "This causes a complete physical reload which might take some time." << std::endl;
+            this->setPhysicalWorld(false);
+            this->positiveWorldRange_ = range;
+            this->setPhysicalWorld(true);
+        }
+        else
+            this->positiveWorldRange_ = range;
+    }
+
+    void Scene::setGravity(const Vector3& gravity)
+    {
+        this->gravity_ = gravity;
+        if (this->hasPhysics())
+            this->physicalWorld_->setGravity(multi_cast<btVector3>(this->gravity_));
+    }
+
+    void Scene::setPhysicalWorld(bool wantPhysics)
+    {
+        this->bHasPhysics_ = wantPhysics;
+        if (wantPhysics && !hasPhysics())
+        {
+            // Note: These are all little known default classes and values.
+            //       It would require further investigation to properly dertermine the right choices.
+            this->broadphase_      = new bt32BitAxisSweep3(
+                multi_cast<btVector3>(this->negativeWorldRange_), multi_cast<btVector3>(this->positiveWorldRange_));
+            this->collisionConfig_ = new btDefaultCollisionConfiguration();
+            this->dispatcher_      = new btCollisionDispatcher(this->collisionConfig_);
+            this->solver_          = new btSequentialImpulseConstraintSolver();
+
+            this->physicalWorld_   = new btDiscreteDynamicsWorld(this->dispatcher_, this->broadphase_, this->solver_, this->collisionConfig_);
+            this->physicalWorld_->setGravity(multi_cast<btVector3>(this->gravity_));
+
+            // also set the collision callback variable.
+            // Note: This is a global variable which we assign a static function.
+            // TODO: Check whether this (or anything about Bullet) works with multiple physics engine instances.
+            gContactAddedCallback = &Scene::collisionCallback;
+        }
+        else if (!wantPhysics && hasPhysics())
+        {
+            // Remove all WorldEntities and shove them to the queue since they would still like to be in a physical world.
+            for (std::set<WorldEntity*>::const_iterator it = this->physicalObjects_.begin();
+                it != this->physicalObjects_.end(); ++it)
+            {
+                this->physicalWorld_->removeRigidBody((*it)->physicalBody_);
+                this->physicalObjectQueue_.insert(*it);
+            }
+            this->physicalObjects_.clear();
+
+            delete this->physicalWorld_;
+            delete this->solver_;
+            delete this->dispatcher_;
+            delete this->collisionConfig_;
+            delete this->broadphase_;
+            this->physicalWorld_   = 0;
+            this->solver_          = 0;
+            this->dispatcher_      = 0;
+            this->collisionConfig_ = 0;
+            this->broadphase_      = 0;
+        }
+    }
+
+    void Scene::tick(float dt)
+    {
+        if (!GameMode::showsGraphics())
+        {
+            // We need to update the scene nodes if we don't render
+            this->rootSceneNode_->_update(true, false);
+        }
+        if (this->hasPhysics())
+        {
+            // TODO: This here is bad practice! It will slow down the first tick() by ages.
+            //       Rather have an initialise() method as well, called by the Level after everything has been loaded.
+            if (this->physicalObjectQueue_.size() > 0)
+            {
+                // Add all scheduled WorldEntities
+                for (std::set<WorldEntity*>::const_iterator it = this->physicalObjectQueue_.begin();
+                    it != this->physicalObjectQueue_.end(); ++it)
+                {
+                    this->physicalWorld_->addRigidBody((*it)->physicalBody_);
+                    this->physicalObjects_.insert(*it);
+                }
+                this->physicalObjectQueue_.clear();
+            }
+
+            // Note: 60 means that Bullet will do physics correctly down to 1 frames per seconds.
+            //       Under that mark, the simulation will "loose time" and get unusable.
+            physicalWorld_->stepSimulation(dt, 60);
+        }
+    }
+
+    void Scene::setSkybox(const std::string& skybox)
+    {
+        if (GameMode::showsGraphics() && this->sceneManager_)
+            this->sceneManager_->setSkyBox(true, skybox);
+
+        this->skybox_ = skybox;
+    }
+
+    void Scene::setAmbientLight(const ColourValue& colour)
+    {
+        if (GameMode::showsGraphics() && this->sceneManager_)
+            this->sceneManager_->setAmbientLight(colour);
+
+        this->ambientLight_ = colour;
+    }
+
+    void Scene::setShadow(bool bShadow)
+    {
+        if (GameMode::showsGraphics() && this->sceneManager_)
+        {
+            if (bShadow)
+                this->sceneManager_->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
+            else
+                this->sceneManager_->setShadowTechnique(Ogre::SHADOWTYPE_NONE);
+        }
+
+        this->bShadows_ = bShadow;
+    }
+
+    void Scene::addObject(BaseObject* object)
+    {
+        this->objects_.push_back(object);
+        object->setScene(this, this->getObjectID());
+    }
+
+    BaseObject* Scene::getObject(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::list<BaseObject*>::const_iterator it = this->objects_.begin(); it != this->objects_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+            ++i;
+        }
+        return 0;
+    }
+
+    void Scene::addPhysicalObject(WorldEntity* object)
+    {
+        if (object)
+        {
+            std::set<WorldEntity*>::iterator it = this->physicalObjects_.find(object);
+            if (it != this->physicalObjects_.end())
+                return;
+
+            this->physicalObjectQueue_.insert(object);
+        }
+    }
+
+    void Scene::removePhysicalObject(WorldEntity* object)
+    {
+        // check queue first
+        std::set<WorldEntity*>::iterator it = this->physicalObjectQueue_.find(object);
+        if (it != this->physicalObjectQueue_.end())
+        {
+            this->physicalObjectQueue_.erase(it);
+            return;
+        }
+
+        it = this->physicalObjects_.find(object);
+        if (it == this->physicalObjects_.end())
+            return;
+        this->physicalObjects_.erase(it);
+
+        if (this->hasPhysics())
+            this->physicalWorld_->removeRigidBody(object->physicalBody_);
+    }
+
+    /*static*/ bool Scene::collisionCallback(btManifoldPoint& cp, const btCollisionObject* colObj0, int partId0,
+                                             int index0, const btCollisionObject* colObj1, int partId1, int index1)
+    {
+        // get the WorldEntity pointers
+        SmartPtr<WorldEntity> object0 = static_cast<WorldEntity*>(colObj0->getUserPointer());
+        SmartPtr<WorldEntity> object1 = static_cast<WorldEntity*>(colObj1->getUserPointer());
+
+        // false means that bullet will assume we didn't modify the contact
+        bool modified = false;
+        if (object0->isCollisionCallbackActive())
+            modified |= object0->collidesAgainst(object1, cp);
+        if (object1->isCollisionCallbackActive())
+            modified |= object1->collidesAgainst(object0, cp);
+
+        return modified;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/Scene.h
===================================================================
--- /code/branches/rocket2/src/orxonox/Scene.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/Scene.h	(revision 6952)
@@ -0,0 +1,161 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder (physics)
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Scene_H__
+#define _Scene_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <list>
+#include <set>
+#include <string>
+
+#include "util/Math.h"
+#include "util/OgreForwardRefs.h"
+#include "core/BaseObject.h"
+#include "network/synchronisable/Synchronisable.h"
+#include "tools/interfaces/Tickable.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Scene : public BaseObject, public Synchronisable, public Tickable
+    {
+        public:
+            Scene(BaseObject* creator);
+            virtual ~Scene();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            inline Ogre::SceneManager* getSceneManager() const
+                { return this->sceneManager_; }
+            inline Ogre::SceneNode* getRootSceneNode() const
+                { return this->rootSceneNode_; }
+
+            void setSkybox(const std::string& skybox);
+            inline const std::string& getSkybox() const
+                { return this->skybox_; }
+
+            void setAmbientLight(const ColourValue& colour);
+            inline const ColourValue& getAmbientLight() const
+                { return this->ambientLight_; }
+
+            void setShadow(bool bShadow);
+            inline bool getShadow() const
+                { return this->bShadows_; }
+
+            inline void setSoundReferenceDistance(float distance)
+                { this->soundReferenceDistance_ = distance; }
+            inline float getSoundReferenceDistance() const
+                { return this->soundReferenceDistance_; }
+
+            inline Radar* getRadar()
+                { return this->radar_; }
+
+            inline virtual uint32_t getSceneID() const { return this->getObjectID(); }
+
+            virtual void tick(float dt);
+
+        private:
+            void addObject(BaseObject* object);
+            BaseObject* getObject(unsigned int index) const;
+
+            void networkcallback_applySkybox()
+                { this->setSkybox(this->skybox_); }
+            void networkcallback_applyAmbientLight()
+                { this->setAmbientLight(this->ambientLight_); }
+            void networkcallback_applyShadows()
+                { this->setShadow(this->bShadows_); }
+
+            Ogre::SceneManager*      sceneManager_;
+            Ogre::SceneNode*         rootSceneNode_;
+
+            std::string              skybox_;
+            ColourValue              ambientLight_;
+            std::list<BaseObject*>   objects_;
+            bool                     bShadows_;
+            float                    soundReferenceDistance_;
+            Radar*                   radar_;
+
+
+        /////////////
+        // Physics //
+        /////////////
+
+        public:
+            inline bool hasPhysics()
+                { return this->physicalWorld_ != 0; }
+            void setPhysicalWorld(bool wantsPhysics);
+
+            void setNegativeWorldRange(const Vector3& range);
+            inline const Vector3& getNegativeWorldRange() const
+                { return this->negativeWorldRange_; }
+
+            void setPositiveWorldRange(const Vector3& range);
+            inline const Vector3& getPositiveWorldRange() const
+                { return this->positiveWorldRange_; }
+
+            void setGravity(const Vector3& gravity);
+            inline const Vector3& getGravity() const
+                { return this->gravity_; }
+
+            void addPhysicalObject(WorldEntity* object);
+            void removePhysicalObject(WorldEntity* object);
+
+        private:
+            inline void networkcallback_hasPhysics()
+                { this->setPhysicalWorld(this->bHasPhysics_); }
+            inline void networkcallback_negativeWorldRange()
+                { this->setNegativeWorldRange(this->negativeWorldRange_); }
+            inline void networkcallback_positiveWorldRange()
+                { this->setPositiveWorldRange(this->positiveWorldRange_); }
+            inline void networkcallback_gravity()
+                { this->setGravity(this->gravity_); }
+
+            // collision callback from bullet
+            static bool collisionCallback(btManifoldPoint& cp, const btCollisionObject* colObj0, int partId0,
+                                          int index0, const btCollisionObject* colObj1, int partId1, int index1);
+
+            // Bullet objects
+            btDiscreteDynamicsWorld*             physicalWorld_;
+            bt32BitAxisSweep3*                   broadphase_;
+            btDefaultCollisionConfiguration*     collisionConfig_;
+            btCollisionDispatcher*               dispatcher_;
+            btSequentialImpulseConstraintSolver* solver_;
+
+            std::set<WorldEntity*>               physicalObjectQueue_;
+            std::set<WorldEntity*>               physicalObjects_;
+            bool                                 bHasPhysics_;
+            Vector3                              negativeWorldRange_;
+            Vector3                              positiveWorldRange_;
+            Vector3                              gravity_;
+    };
+}
+
+#endif /* _Scene_H__ */
Index: /code/branches/rocket2/src/orxonox/Test.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/Test.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/Test.cc	(revision 6952)
@@ -0,0 +1,150 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oli Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/ConsoleCommand.h"
+#include "network/NetworkFunction.h"
+#include "Test.h"
+#include "util/MultiType.h"
+
+namespace orxonox
+{
+    CreateFactory ( Test );
+  
+    SetConsoleCommand(Test, printV1, true).accessLevel(AccessLevel::User);
+    SetConsoleCommand(Test, printV2, true).accessLevel(AccessLevel::User);
+    SetConsoleCommand(Test, printV3, true).accessLevel(AccessLevel::User);
+    SetConsoleCommand(Test, printV4, true).accessLevel(AccessLevel::User);
+    SetConsoleCommand(Test, call, true).accessLevel(AccessLevel::User);
+    SetConsoleCommand(Test, call2, true).accessLevel(AccessLevel::User);
+  
+  
+  //void=* aaaaa = copyPtr<sizeof(&Test::printV1)>( &NETWORK_FUNCTION_POINTER, &Test::printV1 );
+  //void* NETWORK_FUNCTION_TEST_B = memcpy(&NETWORK_FUNCTION_POINTER, &a, sizeof(a));
+//   NetworkFunctionBase* NETWORK_FUNCTION_TEST_C = new NetworkFunctionStatic( createFunctor(&Test::printV1), "bla", NETWORK_FUNCTION_POINTER );
+  
+    registerStaticNetworkFunction( &Test::printV1 );
+    registerMemberNetworkFunction( Test, checkU1 );
+    registerMemberNetworkFunction( Test, printBlaBla );
+  
+    Test* Test::instance_ = 0;
+
+    Test::Test(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
+    {
+        assert(instance_==0);
+        instance_=this;
+        RegisterObject ( Test );
+        setConfigValues();
+        registerVariables();
+        setSyncMode(0x3);
+        this->pointer_ = 0;
+    }
+
+    Test::~Test()
+    {
+        instance_=0;
+    }
+
+    void Test::setConfigValues()
+    {
+        SetConfigValue ( u1, 1 )/*.callback ( this, &Test::checkV1 )*/;
+        SetConfigValue ( u2, 2 )/*.callback ( this, &Test::checkV2 )*/;
+        SetConfigValue ( u3, 3 )/*.callback ( this, &Test::checkV3 )*/;
+        SetConfigValue ( u4, 4 )/*.callback ( this, &Test::checkV4 )*/;
+    
+        SetConfigValue ( s1, 1 )/*.callback ( this, &Test::checkV1 )*/;
+        SetConfigValue ( s2, 2 )/*.callback ( this, &Test::checkV2 )*/;
+        SetConfigValue ( s3, 3 )/*.callback ( this, &Test::checkV3 )*/;
+        SetConfigValue ( s4, 4 )/*.callback ( this, &Test::checkV4 )*/;
+    }
+
+
+    void Test::registerVariables()
+    {
+        registerVariable ( u1, VariableDirection::ToClient, new NetworkCallback<Test> ( this, &Test::checkU1 ));
+        registerVariable ( u2, VariableDirection::ToServer, new NetworkCallback<Test> ( this, &Test::checkU2 ));
+        registerVariable ( u3, Bidirectionality::ServerMaster, new NetworkCallback<Test> ( this, &Test::checkU3 ), true );
+        registerVariable ( u4, Bidirectionality::ClientMaster, new NetworkCallback<Test> ( this, &Test::checkU4 ), true );
+    
+        registerVariable ( s1, VariableDirection::ToClient, new NetworkCallback<Test> ( this, &Test::checkS1 ));
+        registerVariable ( s2, VariableDirection::ToServer, new NetworkCallback<Test> ( this, &Test::checkS2 ));
+        registerVariable ( s3, Bidirectionality::ServerMaster, new NetworkCallback<Test> ( this, &Test::checkS3 ), true );
+        registerVariable ( s4, Bidirectionality::ClientMaster, new NetworkCallback<Test> ( this, &Test::checkS4 ), true );
+    
+        registerVariable ( pointer_, VariableDirection::ToClient, new NetworkCallback<Test> ( this, &Test::printPointer ) );
+    }
+  
+  void Test::call(unsigned int clientID)
+    {
+        callStaticNetworkFunction( &Test::printV1, clientID );
+        callStaticNetworkFunction( &Test::printV1, clientID );
+    }
+  
+    void Test::call2(unsigned int clientID, std::string s1, std::string s2, std::string s3, std::string s4)
+    {
+        callMemberNetworkFunction( Test, printBlaBla, this->getObjectID(), clientID, s1, s2, s3, s4, s4 );
+    }
+  
+    void Test::tick(float dt)
+    {
+    //     std::string str1 = "blub";
+    //     //MultiType mt1(std::string("blub"));
+    //     MultiType mt1(str1);
+    //     uint8_t* mem = new uint8_t[mt1.getNetworkSize()];
+    //     uint8_t* temp = mem;
+    //     mt1.exportData( temp );
+    //     assert( temp-mem == mt1.getNetworkSize() );
+    //     MultiType mt2;
+    //     temp = mem;
+    //     mt2.importData( temp );
+    //     assert( temp-mem == mt1.getNetworkSize() );
+    //     COUT(0) << mt2 << endl;
+    //     if(!Core::isMaster())
+    //       call2(0, "bal", "a", "n", "ce");
+    //       callMemberNetworkFunction( Test, checkU1, this->getObjectID(), 0 );
+    }
+    
+    void Test::printBlaBla(std::string s1, std::string s2, std::string s3, std::string s4, std::string s5)
+    {
+        COUT(0) << s1 << s2 << s3 << s4 << s5 << endl;
+    }
+    
+    void Test::checkU1(){ COUT(1) << "U1 changed: " << u1 << std::endl; }
+    void Test::checkU2(){ COUT(1) << "U2 changed: " << u2 << std::endl; }
+    void Test::checkU3(){ COUT(1) << "U3 changed: " << u3 << std::endl; }
+    void Test::checkU4(){ COUT(1) << "U4 changed: " << u4 << std::endl; }
+
+    void Test::checkS1(){ COUT(1) << "S1 changed: " << s1 << std::endl; }
+    void Test::checkS2(){ COUT(1) << "S2 changed: " << s2 << std::endl; }
+    void Test::checkS3(){ COUT(1) << "S3 changed: " << s3 << std::endl; }
+    void Test::checkS4(){ COUT(1) << "S4 changed: " << s4 << std::endl; }
+    
+    void Test::printPointer(){ CCOUT(1) << "pointer: " << this->pointer_ << endl; }
+
+}
Index: /code/branches/rocket2/src/orxonox/Test.h
===================================================================
--- /code/branches/rocket2/src/orxonox/Test.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/Test.h	(revision 6952)
@@ -0,0 +1,104 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oli Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Test_H__
+#define _Test_H__
+
+#include "OrxonoxPrereqs.h"
+#include "core/BaseObject.h"
+#include "network/synchronisable/Synchronisable.h"
+#include "tools/interfaces/Tickable.h"
+
+
+typedef int TYPE;
+typedef unsigned int UTYPE;
+
+
+namespace orxonox
+{
+  class _OrxonoxExport Test: public BaseObject, public Synchronisable, public Tickable
+  {
+    public:
+      Test(BaseObject* creator);
+      virtual ~Test();
+
+      void setConfigValues();
+      void registerVariables();
+
+      static void call(unsigned int clientID);
+      void call2(unsigned int clientID, std::string s1, std::string s2, std::string s3, std::string s4);
+      virtual void tick(float dt);
+
+
+      //unsigned functions
+      void setU1(UTYPE value){ u1 = value; }
+      void setU2(UTYPE value){ u2 = value; }
+      void setU3(UTYPE value){ u3 = value; }
+      void setU4(UTYPE value){ u4 = value; }
+      void checkU1();
+      void checkU2();
+      void checkU3();
+      void checkU4();
+
+      //signed functions
+      void setS1(TYPE value){ s1 = value; }
+      void setS2(TYPE value){ s2 = value; }
+      void setS3(TYPE value){ s3 = value; }
+      void setS4(TYPE value){ s4 = value; }
+      void checkS1();
+      void checkS2();
+      void checkS3();
+      void checkS4();
+
+      void printPointer();
+
+      static void printV1(){ instance_->checkU1(); }
+      static void printV2(){ instance_->checkU2(); }
+      static void printV3(){ instance_->checkU3(); }
+      static void printV4(){ instance_->checkU4(); }
+
+      void printBlaBla(std::string s1, std::string s2, std::string s3, std::string s4, std::string s5);
+
+    private:
+      UTYPE u1;
+      UTYPE u2;
+      UTYPE u3;
+      UTYPE u4;
+
+      TYPE s1;
+      TYPE s2;
+      TYPE s3;
+      TYPE s4;
+
+      Test* pointer_;
+
+      static Test* instance_;
+  };
+}
+
+#endif /* _Test_H__ */
Index: /code/branches/rocket2/src/orxonox/collisionshapes/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/collisionshapes/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/collisionshapes/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,5 @@
+ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+  CollisionShape.cc
+  CompoundCollisionShape.cc
+  WorldEntityCollisionShape.cc
+)
Index: /code/branches/rocket2/src/orxonox/collisionshapes/CollisionShape.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/collisionshapes/CollisionShape.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/collisionshapes/CollisionShape.cc	(revision 6952)
@@ -0,0 +1,159 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "CollisionShape.h"
+
+#include <BulletCollision/CollisionShapes/btCollisionShape.h>
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "worldentities/WorldEntity.h"
+#include "CompoundCollisionShape.h"
+#include "WorldEntityCollisionShape.h"
+
+namespace orxonox
+{
+    CollisionShape::CollisionShape(BaseObject* creator)
+        : BaseObject(creator)
+        , Synchronisable(creator)
+    {
+        RegisterObject(CollisionShape);
+
+        this->parent_ = 0;
+        this->parentID_ = OBJECTID_UNKNOWN;
+        this->collisionShape_ = 0;
+        this->position_ = Vector3::ZERO;
+        this->orientation_ = Quaternion::IDENTITY;
+        this->scale_ = Vector3::UNIT_SCALE;
+
+        this->registerVariables();
+    }
+
+    CollisionShape::~CollisionShape()
+    {
+        // Detach from parent
+        if (this->isInitialized() && this->parent_)
+            this->parent_->detach(this);
+    }
+
+    void CollisionShape::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(CollisionShape, XMLPort, xmlelement, mode);
+
+        XMLPortParamTemplate(CollisionShape, "position", setPosition, getPosition, xmlelement, mode, const Vector3&);
+        XMLPortParamTemplate(CollisionShape, "orientation", setOrientation, getOrientation, xmlelement, mode, const Quaternion&);
+        XMLPortParamTemplate(CollisionShape, "scale3D", setScale3D, getScale3D, xmlelement, mode, const Vector3&);
+        XMLPortParamLoadOnly(CollisionShape, "scale", setScale, xmlelement, mode);
+        XMLPortParamLoadOnly(CollisionShape, "yaw",   yaw,   xmlelement, mode);
+        XMLPortParamLoadOnly(CollisionShape, "pitch", pitch, xmlelement, mode);
+        XMLPortParamLoadOnly(CollisionShape, "roll",  roll,  xmlelement, mode);
+    }
+
+    void CollisionShape::registerVariables()
+    {
+        registerVariable(this->parentID_, VariableDirection::ToClient, new NetworkCallback<CollisionShape>(this, &CollisionShape::parentChanged));
+    }
+
+    void CollisionShape::parentChanged()
+    {
+        Synchronisable* parent = Synchronisable::getSynchronisable(this->parentID_);
+        // Parent can either be a WorldEntity or a CompoundCollisionShape. The reason is that the
+        // internal collision shape (which is compound) of a WE doesn't get synchronised.
+        CompoundCollisionShape* parentCCS = orxonox_cast<CompoundCollisionShape*>(parent);
+        if (parentCCS)
+            parentCCS->attach(this);
+        else
+        {
+            WorldEntity* parentWE = orxonox_cast<WorldEntity*>(parent);
+            if (parentWE)
+                parentWE->attachCollisionShape(this);
+        }
+    }
+
+    bool CollisionShape::notifyBeingAttached(CompoundCollisionShape* newParent)
+    {
+        if (this->parent_)
+            this->parent_->detach(this);
+
+        this->parent_ = newParent;
+
+        WorldEntityCollisionShape* parentWECCS = orxonox_cast<WorldEntityCollisionShape*>(newParent);
+        if (parentWECCS)
+            this->parentID_ = parentWECCS->getWorldEntityOwner()->getObjectID();
+        else
+            this->parentID_ = newParent->getObjectID();
+
+        return true;
+    }
+
+    void CollisionShape::notifyDetached()
+    {
+        this->parent_ = 0;
+        this->parentID_ = OBJECTID_UNKNOWN;
+    }
+
+    void CollisionShape::updateParent()
+    {
+        if (this->parent_)
+            this->parent_->updateAttachedShape(this);
+    }
+
+    bool CollisionShape::hasTransform() const
+    {
+        return (!this->position_.positionEquals(Vector3(0, 0, 0), 0.001f) ||
+                !this->orientation_.equals(Quaternion(1,0,0,0), Degree(0.1f)));
+    }
+
+    void CollisionShape::setScale3D(const Vector3& scale)
+    {
+        CCOUT(2) << "Warning: Cannot set the scale of a collision shape: Not yet implemented." << std::endl;
+    }
+
+    void CollisionShape::setScale(float scale)
+    {
+        CCOUT(2) << "Warning: Cannot set the scale of a collision shape: Not yet implemented." << std::endl;
+    }
+
+    void CollisionShape::updateShape()
+    {
+        btCollisionShape* oldShape = this->collisionShape_;
+        this->collisionShape_ = this->createNewShape();
+        // When we recreate the shape, we have to inform the parent about this to update the shape
+        this->updateParent();
+        if (oldShape)
+            delete oldShape;
+    }
+
+    void CollisionShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const
+    {
+        if (this->collisionShape_)
+            this->collisionShape_->calculateLocalInertia(mass, inertia);
+        else
+            inertia.setValue(0, 0, 0);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/collisionshapes/CollisionShape.h
===================================================================
--- /code/branches/rocket2/src/orxonox/collisionshapes/CollisionShape.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/collisionshapes/CollisionShape.h	(revision 6952)
@@ -0,0 +1,96 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _CollisionShape_H__
+#define _CollisionShape_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/Math.h"
+#include "core/BaseObject.h"
+#include "network/synchronisable/Synchronisable.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport CollisionShape : public BaseObject, public Synchronisable
+    {
+        public:
+            CollisionShape(BaseObject* creator);
+            virtual ~CollisionShape();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            inline void setPosition(const Vector3& position)
+                { this->position_ = position; this->updateParent(); }
+            inline const Vector3& getPosition() const
+                { return this->position_; }
+
+            inline void setOrientation(const Quaternion& orientation)
+                { this->orientation_ = orientation; this->updateParent(); }
+            inline const Quaternion& getOrientation() const
+                { return this->orientation_; }
+
+            void yaw(const Degree& angle)   { this->setOrientation(this->orientation_ * Quaternion(angle, Vector3::UNIT_Y)); }
+            void pitch(const Degree& angle) { this->setOrientation(this->orientation_ * Quaternion(angle, Vector3::UNIT_X)); }
+            void roll(const Degree& angle)  { this->setOrientation(this->orientation_ * Quaternion(angle, Vector3::UNIT_Z)); }
+
+            virtual void setScale3D(const Vector3& scale);
+            virtual void setScale(float scale);
+            inline const Vector3& getScale3D() const
+                { return this->scale_; }
+
+            void updateShape();
+
+            void calculateLocalInertia(float mass, btVector3& inertia) const;
+
+            inline btCollisionShape* getCollisionShape() const
+                { return this->collisionShape_; }
+
+            bool hasTransform() const;
+
+            bool notifyBeingAttached(CompoundCollisionShape* newParent);
+            void notifyDetached();
+
+        protected:
+            virtual void updateParent();
+            virtual void parentChanged();
+            virtual btCollisionShape* createNewShape() const = 0;
+
+            btCollisionShape*       collisionShape_;
+            CompoundCollisionShape* parent_;
+            unsigned int            parentID_;
+
+        private:
+            Vector3                 position_;
+            Quaternion              orientation_;
+            Vector3                 scale_;
+    };
+}
+
+#endif /* _CollisionShape_H__ */
Index: /code/branches/rocket2/src/orxonox/collisionshapes/CompoundCollisionShape.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/collisionshapes/CompoundCollisionShape.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/collisionshapes/CompoundCollisionShape.cc	(revision 6952)
@@ -0,0 +1,192 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "CompoundCollisionShape.h"
+
+#include <BulletCollision/CollisionShapes/btCompoundShape.h>
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "tools/BulletConversions.h"
+
+namespace orxonox
+{
+    CreateFactory(CompoundCollisionShape);
+
+    CompoundCollisionShape::CompoundCollisionShape(BaseObject* creator) : CollisionShape(creator)
+    {
+        RegisterObject(CompoundCollisionShape);
+
+        this->compoundShape_  = new btCompoundShape();
+    }
+
+    CompoundCollisionShape::~CompoundCollisionShape()
+    {
+        if (this->isInitialized())
+        {
+            // Delete all children
+            for (std::map<CollisionShape*, btCollisionShape*>::iterator it = this->attachedShapes_.begin();
+                it != this->attachedShapes_.end(); ++it)
+            {
+                // make sure that the child doesn't want to detach itself --> speedup because of the missing update
+                it->first->notifyDetached();
+                it->first->destroy();
+            }
+
+            delete this->compoundShape_;
+        }
+    }
+
+    void CompoundCollisionShape::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(CompoundCollisionShape, XMLPort, xmlelement, mode);
+        // Attached collision shapes
+        XMLPortObject(CompoundCollisionShape, CollisionShape, "", attach, detach, xmlelement, mode);
+    }
+
+    void CompoundCollisionShape::attach(CollisionShape* shape)
+    {
+        if (!shape || static_cast<CollisionShape*>(this) == shape)
+            return;
+        if (this->attachedShapes_.find(shape) != this->attachedShapes_.end())
+        {
+            CCOUT(2) << "Warning: Attaching a CollisionShape twice is not yet supported." << std::endl;
+            return;
+        }
+
+        if (!shape->notifyBeingAttached(this))
+            return;
+
+        this->attachedShapes_[shape] = shape->getCollisionShape();
+
+        if (shape->getCollisionShape())
+        {
+            // Only actually attach if we didn't pick a CompoundCollisionShape with no content
+            btTransform transf(multi_cast<btQuaternion>(shape->getOrientation()), multi_cast<btVector3>(shape->getPosition()));
+            this->compoundShape_->addChildShape(transf, shape->getCollisionShape());
+
+            this->updatePublicShape();
+        }
+    }
+
+    void CompoundCollisionShape::detach(CollisionShape* shape)
+    {
+        if (this->attachedShapes_.find(shape) != this->attachedShapes_.end())
+        {
+            this->attachedShapes_.erase(shape);
+            if (shape->getCollisionShape())
+                this->compoundShape_->removeChildShape(shape->getCollisionShape());
+            shape->notifyDetached();
+
+            this->updatePublicShape();
+        }
+        else
+            CCOUT(2) << "Warning: Cannot detach non child collision shape" << std::endl;
+    }
+
+    void CompoundCollisionShape::detachAll()
+    {
+        while (this->attachedShapes_.size() > 0)
+            this->detach(this->attachedShapes_.begin()->first);
+    }
+
+    void CompoundCollisionShape::updateAttachedShape(CollisionShape* shape)
+    {
+        if (!shape)
+            return;
+        std::map<CollisionShape*, btCollisionShape*>::iterator it = this->attachedShapes_.find(shape);
+        if (it == this->attachedShapes_.end())
+        {
+            CCOUT(2) << "Warning: Cannot update child shape: Instance not a child." << std::endl;
+            return;
+        }
+
+        // Remove old btCollisionShape, stored in the children map
+        if (it->second)
+            this->compoundShape_->removeChildShape(it->second);
+        if (shape->getCollisionShape())
+        {
+            // Only actually attach if we didn't pick a CompoundCollisionShape with no content
+            btTransform transf(multi_cast<btQuaternion>(shape->getOrientation()), multi_cast<btVector3>(shape->getPosition()));
+            this->compoundShape_->addChildShape(transf, shape->getCollisionShape());
+            it->second = shape->getCollisionShape();
+        }
+
+        this->updatePublicShape();
+    }
+
+    void CompoundCollisionShape::updatePublicShape()
+    {
+        btCollisionShape* primitive = 0;
+        bool bPrimitive = true;
+        bool bEmpty = true;
+        for (std::map<CollisionShape*, btCollisionShape*>::const_iterator it = this->attachedShapes_.begin(); it != this->attachedShapes_.end(); ++it)
+        {
+            if (it->second)
+            {
+                bEmpty = false;
+                if (!it->first->hasTransform() && !bPrimitive)
+                    primitive = it->second;
+                else
+                    bPrimitive = false;
+            }
+        }
+        if (bEmpty)
+        {
+            if (this->collisionShape_ == 0)
+            {
+                this->collisionShape_ = 0;
+                return;
+            }
+            this->collisionShape_ = 0;
+        }
+        else if (bPrimitive)
+        {
+            // --> Only one shape to be added, no transform; return it directly
+            this->collisionShape_ = primitive;
+        }
+        else
+        {
+            // Make sure we use the compound shape when returning a btCollisionShape
+            this->collisionShape_ = this->compoundShape_;
+        }
+        this->updateParent();
+    }
+
+    CollisionShape* CompoundCollisionShape::getAttachedShape(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::map<CollisionShape*, btCollisionShape*>::const_iterator it = this->attachedShapes_.begin(); it != this->attachedShapes_.end(); ++it)
+        {
+            if (i == index)
+                return it->first;
+            ++i;
+        }
+        return 0;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/collisionshapes/CompoundCollisionShape.h
===================================================================
--- /code/branches/rocket2/src/orxonox/collisionshapes/CompoundCollisionShape.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/collisionshapes/CompoundCollisionShape.h	(revision 6952)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _CompoundCollisionShape_H__
+#define _CompoundCollisionShape_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <cassert>
+#include <map>
+#include "CollisionShape.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport CompoundCollisionShape : public CollisionShape
+    {
+        public:
+            CompoundCollisionShape(BaseObject* creator);
+            virtual ~CompoundCollisionShape();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            void attach(CollisionShape* shape);
+            void detach(CollisionShape* shape);
+            void detachAll();
+            CollisionShape* getAttachedShape(unsigned int index) const;
+
+            void updateAttachedShape(CollisionShape* shape);
+
+        private:
+            void updatePublicShape();
+            inline virtual btCollisionShape* createNewShape() const
+                { assert(false); return 0; }
+
+            btCompoundShape* compoundShape_;
+            std::map<CollisionShape*, btCollisionShape*> attachedShapes_;
+    };
+}
+
+#endif /* _CompoundCollisionShape_H__ */
Index: /code/branches/rocket2/src/orxonox/collisionshapes/WorldEntityCollisionShape.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/collisionshapes/WorldEntityCollisionShape.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/collisionshapes/WorldEntityCollisionShape.cc	(revision 6952)
@@ -0,0 +1,68 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "WorldEntityCollisionShape.h"
+
+#include <BulletCollision/CollisionShapes/btCompoundShape.h>
+
+#include "util/OrxAssert.h"
+#include "core/CoreIncludes.h"
+#include "worldentities/WorldEntity.h"
+
+namespace orxonox
+{
+    WorldEntityCollisionShape::WorldEntityCollisionShape(WorldEntity* creator) : CompoundCollisionShape(creator)
+    {
+        RegisterObject(WorldEntityCollisionShape);
+
+        this->worldEntityOwner_ = creator;
+        // suppress synchronisation
+        this->setSyncMode(0x0);
+    }
+
+    WorldEntityCollisionShape::~WorldEntityCollisionShape()
+    {
+        // Called always by WE destructor
+    }
+
+    void WorldEntityCollisionShape::updateParent()
+    {
+        // Note: This shape may also be attached to a CompoundCollisionShape because it's hosting
+        // WorldEntity has been attached to another one.
+        CollisionShape::updateParent();
+
+        assert(this->worldEntityOwner_ != 0);
+        this->worldEntityOwner_->notifyCollisionShapeChanged();
+    }
+
+    void WorldEntityCollisionShape::parentChanged()
+    {
+        // This object does not get synchronised. This method should never be called then!
+        OrxAssert(false, "parentChanged has been called on a non synchronised WorldEntityCollisionShape!");
+    }
+}
Index: /code/branches/rocket2/src/orxonox/collisionshapes/WorldEntityCollisionShape.h
===================================================================
--- /code/branches/rocket2/src/orxonox/collisionshapes/WorldEntityCollisionShape.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/collisionshapes/WorldEntityCollisionShape.h	(revision 6952)
@@ -0,0 +1,56 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _WorldEntityCollisionShape_H__
+#define _WorldEntityCollisionShape_H__
+
+#include "OrxonoxPrereqs.h"
+#include "CompoundCollisionShape.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport WorldEntityCollisionShape : public CompoundCollisionShape
+    {
+        public:
+            WorldEntityCollisionShape(WorldEntity* creator);
+            virtual ~WorldEntityCollisionShape();
+
+            inline WorldEntity* getWorldEntityOwner()
+                { return this->worldEntityOwner_; }
+
+        protected:
+            virtual void updateParent();
+
+        private:
+            void parentChanged();
+
+            WorldEntity* worldEntityOwner_;
+    };
+}
+
+#endif /* _WorldEntityCollisionShape_H__ */
Index: /code/branches/rocket2/src/orxonox/controllers/AIController.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/AIController.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/AIController.cc	(revision 6952)
@@ -0,0 +1,116 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "AIController.h"
+
+#include "util/Math.h"
+#include "core/CoreIncludes.h"
+#include "core/Executor.h"
+#include "worldentities/ControllableEntity.h"
+
+namespace orxonox
+{
+    static const float ACTION_INTERVAL = 1.0f;
+
+    CreateFactory(AIController);
+
+    AIController::AIController(BaseObject* creator) : ArtificialController(creator)
+    {
+        RegisterObject(AIController);
+
+        this->actionTimer_.setTimer(ACTION_INTERVAL, true, createExecutor(createFunctor(&AIController::action, this)));
+    }
+
+    AIController::~AIController()
+    {
+    }
+
+    void AIController::action()
+    {
+        float random;
+        float maxrand = 100.0f / ACTION_INTERVAL;
+
+        // search enemy
+      /*  random = rnd(maxrand);
+        if (random < 15 && (!this->target_))
+            this->searchNewTarget();*/
+
+        // forget enemy
+        //random = rnd(maxrand);
+        //if (random < 5 && (this->target_))
+        //    this->forgetTarget();
+
+        // next enemy
+  /*      random = rnd(maxrand);
+        if (random < 10 && (this->target_))
+            this->searchNewTarget();*/
+
+        // fly somewhere
+        random = rnd(maxrand);
+        if (random < 50 && (!this->bHasTargetPosition_ && !this->target_))
+            this->searchRandomTargetPosition();
+
+        // stop flying
+        random = rnd(maxrand);
+        if (random < 10 && (this->bHasTargetPosition_ && !this->target_))
+            this->bHasTargetPosition_ = false;
+
+        // fly somewhere else
+        random = rnd(maxrand);
+        if (random < 30 && (this->bHasTargetPosition_ && !this->target_))
+            this->searchRandomTargetPosition();
+
+        // shoot
+        //random = rnd(maxrand);
+        //if (random < 75 && (this->target_ && !this->bShooting_))
+        //    this->bShooting_ = true;
+
+        //// stop shooting
+        //random = rnd(maxrand);
+        //if (random < 25 && (this->bShooting_))
+        //    this->bShooting_ = false;
+    }
+
+    void AIController::tick(float dt)
+    {
+        if (!this->isActive())
+            return;
+
+        if (this->target_)
+            this->aimAtTarget();
+
+        if (this->bHasTargetPosition_)
+            this->moveToTargetPosition();
+
+        if (this->getControllableEntity() && this->bShooting_ && this->isCloseAtTarget(1000) && this->isLookingAtTarget(Ogre::Math::PI / 20.0f))
+            this->getControllableEntity()->fire(0);
+
+        SUPER(AIController, tick, dt);
+    }
+
+}
Index: /code/branches/rocket2/src/orxonox/controllers/AIController.h
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/AIController.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/AIController.h	(revision 6952)
@@ -0,0 +1,56 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _AIController_H__
+#define _AIController_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "tools/Timer.h"
+#include "tools/interfaces/Tickable.h"
+#include "ArtificialController.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport AIController : public ArtificialController, public Tickable
+    {
+        public:
+            AIController(BaseObject* creator);
+            virtual ~AIController();
+
+            virtual void tick(float dt);
+
+        protected:
+            virtual void action();
+
+        private:
+            Timer actionTimer_;
+    };
+}
+
+#endif /* _AIController_H__ */
Index: /code/branches/rocket2/src/orxonox/controllers/ArtificialController.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/ArtificialController.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/ArtificialController.cc	(revision 6952)
@@ -0,0 +1,249 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ArtificialController.h"
+
+#include "core/CoreIncludes.h"
+#include "worldentities/ControllableEntity.h"
+#include "worldentities/pawns/Pawn.h"
+#include "worldentities/pawns/TeamBaseMatchBase.h"
+#include "gametypes/TeamDeathmatch.h"
+#include "controllers/WaypointPatrolController.h"
+
+namespace orxonox
+{
+    ArtificialController::ArtificialController(BaseObject* creator) : Controller(creator)
+    {
+        RegisterObject(ArtificialController);
+
+        this->target_ = 0;
+        this->bShooting_ = false;
+        this->bHasTargetPosition_ = false;
+        this->targetPosition_ = Vector3::ZERO;
+
+        this->target_.setCallback(createFunctor(&ArtificialController::targetDied, this));
+    }
+
+    ArtificialController::~ArtificialController()
+    {
+    }
+
+    void ArtificialController::moveToPosition(const Vector3& target)
+    {
+        if (!this->getControllableEntity())
+            return;
+
+        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
+        float distance = (target - this->getControllableEntity()->getPosition()).length();
+
+        if (this->target_ || distance > 10)
+        {
+            // Multiply with 0.8 to make them a bit slower
+            this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x);
+            this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y);
+        }
+
+        if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength())
+            this->getControllableEntity()->moveFrontBack(-0.5f); // They don't brake with full power to give the player a chance
+        else
+            this->getControllableEntity()->moveFrontBack(0.8f);
+    }
+
+    void ArtificialController::moveToTargetPosition()
+    {
+        this->moveToPosition(this->targetPosition_);
+    }
+
+    void ArtificialController::setTargetPosition(const Vector3& target)
+    {
+        this->targetPosition_ = target;
+        this->bHasTargetPosition_ = true;
+    }
+
+    void ArtificialController::searchRandomTargetPosition()
+    {
+        this->targetPosition_ = Vector3(rnd(-2000,2000), rnd(-2000,2000), rnd(-2000,2000));
+        this->bHasTargetPosition_ = true;
+    }
+
+    void ArtificialController::setTarget(Pawn* target)
+    {
+        this->target_ = target;
+
+        if (target)
+            this->targetPosition_ = target->getPosition();
+    }
+
+    void ArtificialController::searchNewTarget()
+    {
+        if (!this->getControllableEntity())
+            return;
+
+        this->targetPosition_ = this->getControllableEntity()->getPosition();
+        this->forgetTarget();
+
+        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
+        {
+            if (ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
+                continue;
+
+            if (static_cast<ControllableEntity*>(*it) != this->getControllableEntity())
+            {
+                float speed = this->getControllableEntity()->getVelocity().length();
+                Vector3 distanceCurrent = this->targetPosition_ - this->getControllableEntity()->getPosition();
+                Vector3 distanceNew = it->getPosition() - this->getControllableEntity()->getPosition();
+                if (!this->target_ || it->getPosition().squaredDistance(this->getControllableEntity()->getPosition()) * (1.5f + acos((this->getControllableEntity()->getOrientation() * WorldEntity::FRONT).dotProduct(distanceNew) / speed / distanceNew.length()) / (2 * Ogre::Math::PI))
+                        < this->targetPosition_.squaredDistance(this->getControllableEntity()->getPosition()) * (1.5f + acos((this->getControllableEntity()->getOrientation() * WorldEntity::FRONT).dotProduct(distanceCurrent) / speed / distanceCurrent.length()) / (2 * Ogre::Math::PI)) + rnd(-250, 250))
+                {
+                    this->target_ = (*it);
+                    this->targetPosition_ = it->getPosition();
+                }
+            }
+        }
+    }
+
+    void ArtificialController::forgetTarget()
+    {
+        this->target_ = 0;
+        this->bShooting_ = false;
+    }
+
+    void ArtificialController::aimAtTarget()
+    {
+        if (!this->target_ || !this->getControllableEntity())
+            return;
+
+        static const float hardcoded_projectile_speed = 1250;
+
+        this->targetPosition_ = getPredictedPosition(this->getControllableEntity()->getPosition(), hardcoded_projectile_speed, this->target_->getPosition(), this->target_->getVelocity());
+        this->bHasTargetPosition_ = (this->targetPosition_ != Vector3::ZERO);
+
+        Pawn* pawn = dynamic_cast<Pawn*>(this->getControllableEntity());
+        if (pawn)
+            pawn->setAimPosition(this->targetPosition_);
+    }
+
+    bool ArtificialController::isCloseAtTarget(float distance) const
+    {
+        if (!this->getControllableEntity())
+            return false;
+
+        if (!this->target_)
+            return (this->getControllableEntity()->getPosition().squaredDistance(this->targetPosition_) < distance*distance);
+        else
+            return (this->getControllableEntity()->getPosition().squaredDistance(this->target_->getPosition()) < distance*distance);
+    }
+
+    bool ArtificialController::isLookingAtTarget(float angle) const
+    {
+        if (!this->getControllableEntity())
+            return false;
+
+        return (getAngle(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->targetPosition_) < angle);
+    }
+
+    void ArtificialController::abandonTarget(Pawn* target)
+    {
+        if (target == this->target_)
+            this->targetDied();
+    }
+
+    void ArtificialController::targetDied()
+    {
+        this->forgetTarget();
+        this->searchRandomTargetPosition();
+    }
+
+    bool ArtificialController::sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype)
+    {
+        if (entity1 == entity2)
+            return true;
+
+        int team1 = -1;
+        int team2 = -1;
+
+        if (entity1->getXMLController())
+        {
+            WaypointPatrolController* wpc = orxonox_cast<WaypointPatrolController*>(entity1->getXMLController());
+            if (wpc)
+                team1 = wpc->getTeam();
+        }
+        if (entity2->getXMLController())
+        {
+            WaypointPatrolController* wpc = orxonox_cast<WaypointPatrolController*>(entity2->getXMLController());
+            if (wpc)
+                team2 = wpc->getTeam();
+        }
+
+        TeamDeathmatch* tdm = orxonox_cast<TeamDeathmatch*>(gametype);
+        if (tdm)
+        {
+            if (entity1->getPlayer())
+                team1 = tdm->getTeam(entity1->getPlayer());
+
+            if (entity2->getPlayer())
+                team2 = tdm->getTeam(entity2->getPlayer());
+        }
+
+        TeamBaseMatchBase* base = 0;
+        base = orxonox_cast<TeamBaseMatchBase*>(entity1);
+        if (base)
+        {
+            switch (base->getState())
+            {
+                case BaseState::ControlTeam1:
+                    team1 = 0;
+                    break;
+                case BaseState::ControlTeam2:
+                    team1 = 1;
+                    break;
+                case BaseState::Uncontrolled:
+                default:
+                    team1 = -1;
+            }
+        }
+        base = orxonox_cast<TeamBaseMatchBase*>(entity2);
+        if (base)
+        {
+            switch (base->getState())
+            {
+                case BaseState::ControlTeam1:
+                    team2 = 0;
+                    break;
+                case BaseState::ControlTeam2:
+                    team2 = 1;
+                    break;
+                case BaseState::Uncontrolled:
+                default:
+                    team2 = -1;
+            }
+        }
+
+        return (team1 == team2 && team1 != -1);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/controllers/ArtificialController.h
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/ArtificialController.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/ArtificialController.h	(revision 6952)
@@ -0,0 +1,75 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ArtificialController_H__
+#define _ArtificialController_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/Math.h"
+#include "Controller.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport ArtificialController : public Controller
+    {
+        public:
+            ArtificialController(BaseObject* creator);
+            virtual ~ArtificialController();
+
+            void abandonTarget(Pawn* target);
+
+        protected:
+            void targetDied();
+
+            void moveToPosition(const Vector3& target);
+            void moveToTargetPosition();
+
+            void setTargetPosition(const Vector3& target);
+            void searchRandomTargetPosition();
+
+            void setTarget(Pawn* target);
+            void searchNewTarget();
+            void forgetTarget();
+            void aimAtTarget();
+
+            bool isCloseAtTarget(float distance) const;
+            bool isLookingAtTarget(float angle) const;
+
+            static bool sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype); // hack
+
+            bool bHasTargetPosition_;
+            Vector3 targetPosition_;
+            WeakPtr<Pawn> target_;
+            bool bShooting_;
+
+        private:
+    };
+}
+
+#endif /* _ArtificialController_H__ */
Index: /code/branches/rocket2/src/orxonox/controllers/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,11 @@
+ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+  Controller.cc
+  HumanController.cc
+  NewHumanController.cc
+  ArtificialController.cc
+  AIController.cc
+  ScriptController.cc
+  WaypointController.cc
+  WaypointPatrolController.cc
+  DroneController.cc
+)
Index: /code/branches/rocket2/src/orxonox/controllers/Controller.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/Controller.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/Controller.cc	(revision 6952)
@@ -0,0 +1,49 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Controller.h"
+#include "core/CoreIncludes.h"
+#include "worldentities/ControllableEntity.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(Controller);
+
+    Controller::Controller(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(Controller);
+
+        this->player_ = 0;
+        this->controllableEntity_ = 0;
+        this->bGodMode_ = false;
+    }
+
+    Controller::~Controller()
+    {
+    }
+}
Index: /code/branches/rocket2/src/orxonox/controllers/Controller.h
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/Controller.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/Controller.h	(revision 6952)
@@ -0,0 +1,80 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Controller_H__
+#define _Controller_H__
+
+#include "OrxonoxPrereqs.h"
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Controller : public BaseObject
+    {
+        // set friend classes to access setControllableEntity
+        friend class PlayerInfo;
+        friend class ControllableEntity;
+
+        public:
+            Controller(BaseObject* creator);
+            virtual ~Controller();
+
+            inline void setPlayer(PlayerInfo* player)
+                { this->player_ = player; }
+            inline PlayerInfo* getPlayer() const
+                { return this->player_; }
+
+            virtual inline void hit(Pawn* originator, btManifoldPoint& contactpoint, float damage) {};
+
+            void setGodMode( bool mode ){ this->bGodMode_ = mode; }
+            bool getGodMode(){ return this->bGodMode_; }
+
+            inline ControllableEntity* getControllableEntity() const
+                { return this->controllableEntity_; }
+            virtual void changedControllableEntity() {}
+
+        protected:
+            // don't use this directly, use getPlayer()->startControl(entity) (unless you know exactly what you do)
+            inline void setControllableEntity(ControllableEntity* entity)
+            {
+                if (entity != this->controllableEntity_)
+                {
+                    this->controllableEntity_ = entity;
+                    this->changedControllableEntity();
+                }
+            }
+
+        protected:
+            PlayerInfo* player_;
+            ControllableEntity* controllableEntity_;
+        private:
+            bool bGodMode_;
+    };
+}
+
+#endif /* _Controller_H__ */
Index: /code/branches/rocket2/src/orxonox/controllers/DroneController.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/DroneController.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/DroneController.cc	(revision 6952)
@@ -0,0 +1,78 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oli Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "DroneController.h"
+#include "worldentities/Drone.h"
+#include "util/Math.h"
+
+
+namespace orxonox
+{
+    /**
+    @brief
+        Constructor.
+    */
+    DroneController::DroneController(BaseObject* creator) : Controller(creator)
+    {
+		RegisterObject(DroneController);
+        // Place your code here:
+        // - make sure to register the object in the factory
+        // - do any kind of initialisation
+        
+        // this checks that our creator really is a drone
+        // and saves the pointer to the drone for the controlling commands
+        assert(dynamic_cast<Drone*>(creator)!=0);
+        this->setControllableEntity(dynamic_cast<Drone*>(creator));
+		this->counter=0;
+    }
+
+    DroneController::~DroneController()
+    {
+    }
+
+    /**
+    @brief
+        The controlling happens here. This method defines what the controller has to do each tick.
+    @param dt
+        The duration of the tick.
+    */
+    void DroneController::tick(float dt)
+    {
+		this->counter++;
+        // Place your code here:
+        // - steering commands
+        Drone *myDrone = static_cast<Drone*>(this->getControllableEntity());
+        // you can use the following commands for steering 
+        // - moveFrontBack, moveRightLeft, moveUpDown 
+        // - rotatePitch, rotateYaw, rotateRoll 
+        // - apply the to myDrone (e.g. myDrone->rotateYaw(..) ) 
+		myDrone->rotatePitch(0.08);
+		myDrone->moveFrontBack(1);
+
+    }
+}
Index: /code/branches/rocket2/src/orxonox/controllers/DroneController.h
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/DroneController.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/DroneController.h	(revision 6952)
@@ -0,0 +1,60 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oli Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _DroneController_H__
+#define _DroneController_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "Controller.h"
+#include "tools/interfaces/Tickable.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Controller for the Drone of the PPS tutorial.
+    @author
+        Oli Scheuss
+    */
+    class _OrxonoxExport DroneController : public Controller, public Tickable
+    {
+        public:
+            DroneController(BaseObject* creator);
+            virtual ~DroneController();
+            
+            virtual void tick(float dt); //!< The controlling happens here. This method defines what the controller has to do each tick.
+
+        protected:
+
+        private:
+			int counter;
+    };
+}
+
+#endif /* _DroneController_H__ */
Index: /code/branches/rocket2/src/orxonox/controllers/HumanController.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/HumanController.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/HumanController.cc	(revision 6952)
@@ -0,0 +1,259 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "HumanController.h"
+
+#include "core/CoreIncludes.h"
+#include "core/ConsoleCommand.h"
+#include "worldentities/ControllableEntity.h"
+#include "worldentities/pawns/Pawn.h"
+#include "gametypes/Gametype.h"
+#include "infos/PlayerInfo.h"
+#include "Radar.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    SetConsoleCommand(HumanController, moveFrontBack, true).setAsInputCommand();
+    SetConsoleCommand(HumanController, moveRightLeft, true).setAsInputCommand();
+    SetConsoleCommand(HumanController, moveUpDown,    true).setAsInputCommand();
+    SetConsoleCommand(HumanController, rotateYaw,     true).setAsInputCommand();
+    SetConsoleCommand(HumanController, rotatePitch,   true).setAsInputCommand();
+    SetConsoleCommand(HumanController, rotateRoll,    true).setAsInputCommand();
+    SetConsoleCommand(HumanController, fire,          true).keybindMode(KeybindMode::OnHold);
+    SetConsoleCommand(HumanController, reload,        true);
+    SetConsoleCommand(HumanController, boost,         true).keybindMode(KeybindMode::OnHold);
+    SetConsoleCommand(HumanController, greet,         true);
+    SetConsoleCommand(HumanController, switchCamera,  true);
+    SetConsoleCommand(HumanController, mouseLook,     true);
+    SetConsoleCommand(HumanController, suicide,       true);
+    SetConsoleCommand(HumanController, toggleGodMode, true);
+    SetConsoleCommand(HumanController, addBots,       true).defaultValues(1);
+    SetConsoleCommand(HumanController, killBots,      true).defaultValues(0);
+    SetConsoleCommand(HumanController, dropItems,     true);
+    SetConsoleCommand(HumanController, useItem,       true);
+    SetConsoleCommand(HumanController, cycleNavigationFocus,   true);
+    SetConsoleCommand(HumanController, releaseNavigationFocus, true);
+
+    CreateUnloadableFactory(HumanController);
+
+    HumanController* HumanController::localController_s = 0;
+
+    HumanController::HumanController(BaseObject* creator) : Controller(creator)
+    {
+        RegisterObject(HumanController);
+
+        controlPaused_ = false;
+
+        HumanController::localController_s = this;
+    }
+
+    HumanController::~HumanController()
+    {
+        HumanController::localController_s = 0;
+    }
+
+    void HumanController::tick(float dt)
+    {
+        if (GameMode::playsSound() && HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+        {
+            Camera* camera = HumanController::localController_s->controllableEntity_->getCamera();
+            if (!camera)
+                COUT(3) << "HumanController, Warning: Using a ControllableEntity without Camera" << std::endl;
+        }
+    }
+
+    void HumanController::moveFrontBack(const Vector2& value)
+    {
+        if (HumanController::localController_s)
+            HumanController::localController_s->frontback(value);
+    }
+
+    void HumanController::frontback(const Vector2& value)
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->moveFrontBack(value);
+    }
+
+    void HumanController::moveRightLeft(const Vector2& value)
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->moveRightLeft(value);
+    }
+
+    void HumanController::moveUpDown(const Vector2& value)
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->moveUpDown(value);
+    }
+
+    void HumanController::yaw(const Vector2& value)
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->rotateYaw(value);
+    }
+
+    void HumanController::pitch(const Vector2& value)
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->rotatePitch(value);
+    }
+
+    void HumanController::rotateYaw(const Vector2& value)
+    {
+        if (HumanController::localController_s)
+            HumanController::localController_s->yaw(value);
+    }
+
+    void HumanController::rotatePitch(const Vector2& value)
+    {
+        if (HumanController::localController_s)
+            HumanController::localController_s->pitch(value);
+    }
+
+    void HumanController::rotateRoll(const Vector2& value)
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->rotateRoll(value);
+    }
+
+    void HumanController::fire(unsigned int firemode)
+    {
+        if (HumanController::localController_s)
+            HumanController::localController_s->doFire(firemode);
+    }
+
+    void HumanController::doFire(unsigned int firemode)
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->fire(firemode);
+    }
+
+    void HumanController::reload()
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->reload();
+    }
+
+    void HumanController::boost()
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->boost();
+    }
+
+    void HumanController::greet()
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->greet();
+    }
+
+    void HumanController::switchCamera()
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->switchCamera();
+    }
+
+    void HumanController::mouseLook()
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->mouseLook();
+    }
+
+    void HumanController::suicide()
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+        {
+            Pawn* pawn = orxonox_cast<Pawn*>(HumanController::localController_s->controllableEntity_);
+            if (pawn)
+                pawn->kill();
+            else if (HumanController::localController_s->player_)
+                HumanController::localController_s->player_->stopControl();
+        }
+    }
+
+    void HumanController::toggleGodMode()
+    {
+        HumanController::getLocalControllerSingleton()->setGodMode( !HumanController::getLocalControllerSingleton()->getGodMode() );
+    }
+
+    void HumanController::useItem()
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->useItem();
+    }
+
+    void HumanController::addBots(unsigned int amount)
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_ && HumanController::localController_s->controllableEntity_->getGametype())
+            HumanController::localController_s->controllableEntity_->getGametype()->addBots(amount);
+    }
+
+    void HumanController::killBots(unsigned int amount)
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_ && HumanController::localController_s->controllableEntity_->getGametype())
+            HumanController::localController_s->controllableEntity_->getGametype()->killBots(amount);
+    }
+
+    void HumanController::dropItems()
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->dropItems();
+    }
+
+    Pawn* HumanController::getLocalControllerEntityAsPawn()
+    {
+        if (HumanController::localController_s)
+            return orxonox_cast<Pawn*>(HumanController::localController_s->getControllableEntity());
+        else
+            return NULL;
+    }
+
+    void HumanController::cycleNavigationFocus()
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->getScene()->getRadar()->cycleFocus();
+    }
+
+    void HumanController::releaseNavigationFocus()
+    {
+        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
+            HumanController::localController_s->controllableEntity_->getScene()->getRadar()->releaseFocus();
+    }
+
+    void HumanController::pauseControl()
+    {
+        if (HumanController::localController_s)
+            HumanController::localController_s->doPauseControl();
+    }
+
+    void HumanController::resumeControl()
+    {
+        if (HumanController::localController_s)
+            HumanController::localController_s->doResumeControl();
+    }
+}
Index: /code/branches/rocket2/src/orxonox/controllers/HumanController.h
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/HumanController.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/HumanController.h	(revision 6952)
@@ -0,0 +1,98 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _HumanController_H__
+#define _HumanController_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "tools/interfaces/Tickable.h"
+#include "Controller.h"
+
+// tolua_begin
+namespace orxonox
+{
+    class _OrxonoxExport HumanController
+// tolua_end
+        : public Controller, public Tickable
+    { // tolua_export
+        public:
+            HumanController(BaseObject* creator);
+            virtual ~HumanController();
+
+            virtual void tick(float dt);
+
+            static void moveFrontBack(const Vector2& value);
+            static void moveRightLeft(const Vector2& value);
+            static void moveUpDown(const Vector2& value);
+
+            static void rotateYaw(const Vector2& value);
+            static void rotatePitch(const Vector2& value);
+            static void rotateRoll(const Vector2& value);
+
+            virtual void frontback(const Vector2& value);
+            virtual void yaw(const Vector2& value);
+            virtual void pitch(const Vector2& value);
+
+            static void fire(unsigned int firemode);
+            virtual void doFire(unsigned int firemode);
+            static void reload();
+
+            static void boost();
+            static void greet();
+            static void switchCamera();
+            static void mouseLook();
+            static void dropItems();
+            static void useItem();
+            static void cycleNavigationFocus();
+            static void releaseNavigationFocus();
+
+            static void suicide();
+            static void toggleGodMode();
+
+            static void addBots(unsigned int amount);
+            static void killBots(unsigned int amount = 0);
+
+            static void pauseControl(); // tolua_export
+            static void resumeControl(); // tolua_export
+            virtual void doPauseControl() {};
+            virtual void doResumeControl() {};
+
+            static inline HumanController* getLocalControllerSingleton()
+                { return HumanController::localController_s; }
+            static Pawn* getLocalControllerEntityAsPawn();
+            //friend class, for mouselook
+            friend class Map;
+
+        protected:
+            static HumanController* localController_s;
+            bool controlPaused_;
+    }; // tolua_export
+} // tolua_export
+
+#endif /* _HumanController_H__ */
Index: /code/branches/rocket2/src/orxonox/controllers/NewHumanController.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/NewHumanController.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/NewHumanController.cc	(revision 6952)
@@ -0,0 +1,593 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Michael Wirth
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "NewHumanController.h"
+
+#include <cmath>
+#include <OgreRay.h>
+#include <OgreSceneQuery.h>
+#include <OgreCamera.h>
+#include <OgreSceneManager.h>
+#include <bullet/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h>
+
+#include "core/CoreIncludes.h"
+#include "core/ConsoleCommand.h"
+#include "worldentities/ControllableEntity.h"
+#include "worldentities/pawns/Pawn.h"
+#include "infos/PlayerInfo.h"
+#include "overlays/OrxonoxOverlay.h"
+#include "graphics/Camera.h"
+#include "sound/SoundManager.h"
+#include "tools/BulletConversions.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    SetConsoleCommand(NewHumanController, changeMode, false).keybindMode(KeybindMode::OnPress);
+    SetConsoleCommand(NewHumanController, accelerate, false).keybindMode(KeybindMode::OnPress);
+    SetConsoleCommand(NewHumanController, decelerate, false).keybindMode(KeybindMode::OnPress);
+    SetConsoleCommand(NewHumanController, unfire,      true).keybindMode(KeybindMode::OnRelease);
+
+    CreateUnloadableFactory(NewHumanController);
+
+    NewHumanController* NewHumanController::localController_s = 0;
+
+    NewHumanController::NewHumanController(BaseObject* creator)
+        : HumanController(creator)
+        , crossHairOverlay_(NULL)
+        , centerOverlay_(NULL)
+        , damageOverlayTop_(NULL)
+        , damageOverlayRight_(NULL)
+        , damageOverlayBottom_(NULL)
+        , damageOverlayLeft_(NULL)
+        , damageOverlayTT_(0)
+        , arrowsOverlay1_(NULL)
+        , arrowsOverlay2_(NULL)
+        , arrowsOverlay3_(NULL)
+        , arrowsOverlay4_(NULL)
+    {
+        RegisterObject(NewHumanController);
+
+        overlaySize_ = 0.08f;
+        arrowsSize_ = 0.4f;
+
+        damageOverlayTime_ = 0.6f;
+
+        controlMode_ = 0;
+        acceleration_ = 0;
+        accelerating_ = false;
+        firemode_ = -1;
+
+        showArrows_ = true;
+        showOverlays_ = false;
+        showDamageOverlay_ = true;
+
+        //currentPitch_ = 1;
+        //currentYaw_ = 1;
+
+        if (GameMode::showsGraphics())
+        {
+            crossHairOverlay_ = new OrxonoxOverlay(this);
+            crossHairOverlay_->setBackgroundMaterial("Orxonox/Crosshair3");
+            crossHairOverlay_->setSize(Vector2(overlaySize_, overlaySize_));
+            crossHairOverlay_->hide();
+            //crossHairOverlay_->setAspectCorrection(true); not working
+
+            centerOverlay_ = new OrxonoxOverlay(this);
+            centerOverlay_->setBackgroundMaterial("Orxonox/CenterOverlay");
+            centerOverlay_->setSize(Vector2(overlaySize_ * 2.5f, overlaySize_ * 2.5f));
+            centerOverlay_->setPosition(Vector2(0.5f - overlaySize_*2.5f/2.0f, 0.5f - overlaySize_*2.5f/2.0f));
+            centerOverlay_->hide();
+
+            if (showDamageOverlay_)
+            {
+                damageOverlayTop_ = new OrxonoxOverlay(this);
+                damageOverlayTop_->setBackgroundMaterial("Orxonox/DamageOverlayTop");
+                damageOverlayTop_->setSize(Vector2(overlaySize_ * 2.5f, overlaySize_ * 2.5f));
+                damageOverlayTop_->setPosition(Vector2(0.5f - overlaySize_*2.5f/2.0f, 0.5f - overlaySize_*2.5f/2.0f));
+                damageOverlayTop_->hide();
+
+                damageOverlayRight_ = new OrxonoxOverlay(this);
+                damageOverlayRight_->setBackgroundMaterial("Orxonox/DamageOverlayRight");
+                damageOverlayRight_->setSize(Vector2(overlaySize_ * 2.5f, overlaySize_ * 2.5f));
+                damageOverlayRight_->setPosition(Vector2(0.5f - overlaySize_*2.5f/2.0f, 0.5f - overlaySize_*2.5f/2.0f));
+                damageOverlayRight_->hide();
+
+                damageOverlayBottom_ = new OrxonoxOverlay(this);
+                damageOverlayBottom_->setBackgroundMaterial("Orxonox/DamageOverlayBottom");
+                damageOverlayBottom_->setSize(Vector2(overlaySize_ * 2.5f, overlaySize_ * 2.5f));
+                damageOverlayBottom_->setPosition(Vector2(0.5f - overlaySize_*2.5f/2.0f, 0.5f - overlaySize_*2.5f/2.0f));
+                damageOverlayBottom_->hide();
+
+                damageOverlayLeft_ = new OrxonoxOverlay(this);
+                damageOverlayLeft_->setBackgroundMaterial("Orxonox/DamageOverlayLeft");
+                damageOverlayLeft_->setSize(Vector2(overlaySize_ * 2.5f, overlaySize_ * 2.5f));
+                damageOverlayLeft_->setPosition(Vector2(0.5f - overlaySize_*2.5f/2.0f, 0.5f - overlaySize_*2.5f/2.0f));
+                damageOverlayLeft_->hide();
+            }
+
+            if (showArrows_)
+            {
+                arrowsOverlay1_ = new OrxonoxOverlay(this);
+                arrowsOverlay1_->setBackgroundMaterial("Orxonox/DirectionArrows1");
+                arrowsOverlay1_->setSize(Vector2(0.02727f, 0.36f * arrowsSize_));
+                arrowsOverlay1_->setPickPoint(Vector2(0.5f, 0.5f));
+                arrowsOverlay1_->setPosition(Vector2(0.5f, 0.5f));
+                arrowsOverlay1_->hide();
+
+                arrowsOverlay2_ = new OrxonoxOverlay(this);
+                arrowsOverlay2_->setBackgroundMaterial("Orxonox/DirectionArrows2");
+                arrowsOverlay2_->setSize(Vector2(0.02727f, 0.59f * arrowsSize_));
+                arrowsOverlay2_->setPickPoint(Vector2(0.5f, 0.5f));
+                arrowsOverlay2_->setPosition(Vector2(0.5f, 0.5f));
+                arrowsOverlay2_->hide();
+
+                arrowsOverlay3_ = new OrxonoxOverlay(this);
+                arrowsOverlay3_->setBackgroundMaterial("Orxonox/DirectionArrows3");
+                arrowsOverlay3_->setSize(Vector2(0.02727f, 0.77f * arrowsSize_));
+                arrowsOverlay3_->setPickPoint(Vector2(0.5f, 0.5f));
+                arrowsOverlay3_->setPosition(Vector2(0.5f, 0.5f));
+                arrowsOverlay3_->hide();
+
+                arrowsOverlay4_ = new OrxonoxOverlay(this);
+                arrowsOverlay4_->setBackgroundMaterial("Orxonox/DirectionArrows4");
+                arrowsOverlay4_->setSize(Vector2(0.02727f, arrowsSize_));
+                arrowsOverlay4_->setPickPoint(Vector2(0.5f, 0.5f));
+                arrowsOverlay4_->setPosition(Vector2(0.5f, 0.5f));
+                arrowsOverlay4_->hide();
+            }
+        }
+
+        // HACK: Define which objects are targetable when considering the creator of an orxonox::Model
+        this->targetMask_.exclude(ClassByString("BaseObject"));
+        this->targetMask_.include(ClassByString("WorldEntity"));
+        this->targetMask_.exclude(ClassByString("Projectile"));
+
+        NewHumanController::localController_s = this;
+
+        controlPaused_ = false;
+
+        //HumanController::localController_s->getControllableEntity()->getCamera()->setDrag(true);
+    }
+
+    NewHumanController::~NewHumanController()
+    {
+        if (this->isInitialized())
+        {
+            if (this->crossHairOverlay_)
+                this->crossHairOverlay_->destroy();
+            if (this->centerOverlay_)
+                this->centerOverlay_->destroy();
+
+            if (this->arrowsOverlay1_)
+                this->arrowsOverlay1_->destroy();
+            if (this->arrowsOverlay2_)
+                this->arrowsOverlay2_->destroy();
+            if (this->arrowsOverlay3_)
+                this->arrowsOverlay3_->destroy();
+            if (this->arrowsOverlay4_)
+                this->arrowsOverlay4_->destroy();
+            if (this->damageOverlayTop_)
+                this->damageOverlayTop_->destroy();
+            if (this->damageOverlayLeft_)
+                this->damageOverlayLeft_->destroy();
+            if (this->damageOverlayRight_)
+                this->damageOverlayRight_->destroy();
+            if (this->damageOverlayBottom_)
+                this->damageOverlayBottom_->destroy();
+        }
+    }
+
+    void NewHumanController::tick(float dt)
+    {
+        if (GameMode::showsGraphics())
+        {
+
+            if (this->controllableEntity_ && !this->controllableEntity_->isInMouseLook())
+            {
+                this->updateTarget();
+
+                if (!controlPaused_ )
+                {
+                    if (this->getControllableEntity() && (this->getControllableEntity()->isExactlyA(ClassByString("SpaceShip")) || this->getControllableEntity()->isExactlyA(ClassByString("Rocket"))))
+                        this->showOverlays();
+
+                    this->crossHairOverlay_->setPosition(Vector2(static_cast<float>(this->currentYaw_)/2*-1+.5f-overlaySize_/2, static_cast<float>(this->currentPitch_)/2*-1+.5f-overlaySize_/2));
+
+                    if (this->controlMode_ == 0 || (this->controlMode_ == 1 && this->firemode_ == 1))
+                    {
+                        if (this->showOverlays_ && this->showArrows_)
+                            alignArrows();
+                    }
+                    else
+                        hideArrows();
+
+                    if (this->showDamageOverlay_ && (this->damageOverlayTT_ > 0 || this->damageOverlayTR_ > 0 || this->damageOverlayTB_ > 0 || this->damageOverlayTL_ > 0))
+                    {
+                        this->damageOverlayTT_ -= dt;
+                        this->damageOverlayTR_ -= dt;
+                        this->damageOverlayTB_ -= dt;
+                        this->damageOverlayTL_ -= dt;
+                        if (this->damageOverlayTT_ <= 0)
+                            this->damageOverlayTop_->hide();
+                        if (this->damageOverlayTR_ <= 0)
+                            this->damageOverlayRight_->hide();
+                        if (this->damageOverlayTB_ <= 0)
+                            this->damageOverlayBottom_->hide();
+                        if (this->damageOverlayTL_ <= 0)
+                            this->damageOverlayLeft_->hide();
+                    }
+                }
+            }
+            else
+                this->hideOverlays();
+
+            if (this->acceleration_ > 0)
+            {
+                if (this->accelerating_)
+                    HumanController::moveFrontBack(Vector2(1, 0));
+                else
+                    HumanController::moveFrontBack(Vector2(this->acceleration_, 0));
+                this->accelerating_ = false;
+                //HumanController::moveFrontBack(Vector2(clamp(this->acceleration_ + this->currentAcceleration_, 0.0f, 1.0f), 0));
+            }
+        }
+
+        // Reset pitch and yaw rates
+        // TODO: Reactivate this to fix the game pad problem with 0 input
+        //this->currentPitch_ = 0;
+        //this->currentYaw_ = 0;
+
+        HumanController::tick(dt);
+    }
+
+    void NewHumanController::doFire(unsigned int firemode)
+    {
+        if (!this->controllableEntity_)
+            return;
+
+        this->firemode_ = firemode;
+
+        if (firemode == 1 && this->controlMode_ == 1)
+        {
+            //unlocked steering, steer on right mouse click
+            HumanController::yaw(Vector2(this->currentYaw_, 0));
+            HumanController::pitch(Vector2(this->currentPitch_, 0));
+        }
+        else
+            HumanController::localController_s->getControllableEntity()->fire(firemode);
+
+    }
+
+    void NewHumanController::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage)
+    {
+        if (this->showDamageOverlay_ && !this->controlPaused_ && this->controllableEntity_ && !this->controllableEntity_->isInMouseLook())
+        {
+            Vector3 posA;
+            if (originator)
+                posA = originator->getWorldPosition();
+            else
+                posA = multi_cast<Vector3>(contactpoint.getPositionWorldOnA());
+            //Vector3 posB = multi_cast<Vector3>(contactpoint.getPositionWorldOnB());
+            //posA and posB are almost identical
+
+            Vector3 relativeHit = this->getControllableEntity()->getWorldOrientation().UnitInverse() * (this->getControllableEntity()->getWorldPosition() - posA);
+
+            //back is z positive
+            //x is left positive
+            //y is down positive
+            relativeHit.normalise();
+
+            float threshold = 0.3f;
+            if (relativeHit.x > threshold) // Left
+            {
+                this->damageOverlayLeft_->show();
+                this->damageOverlayTL_ = this->damageOverlayTime_;
+                //this->damageOverlayLeft_->setBackgroundAlpha(0.3);
+            }
+            if (relativeHit.x < -threshold) //Right
+            {
+                this->damageOverlayRight_->show();
+                this->damageOverlayTR_ = this->damageOverlayTime_;
+                //this->damageOverlayRight_->setBackgroundAlpha(0.3);
+            }
+            if (relativeHit.y > threshold) //Top
+            {
+                this->damageOverlayBottom_->show();
+                this->damageOverlayTB_ = this->damageOverlayTime_;
+                //this->damageOverlayTop_->setBackgroundAlpha(0.3);
+            }
+            if (relativeHit.y < -threshold) //Bottom
+            {
+                this->damageOverlayTop_->show();
+                this->damageOverlayTT_ = this->damageOverlayTime_;
+                //this->damageOverlayBottom_->setBackgroundAlpha(0.3);
+            }
+        }
+    }
+
+    void NewHumanController::unfire()
+    {
+        if (NewHumanController::localController_s)
+            NewHumanController::localController_s->doUnfire();
+    }
+
+    void NewHumanController::doUnfire()
+    {
+        this->firemode_ = -1;
+        hideArrows();
+    }
+
+    void NewHumanController::updateTarget()
+    {
+        Ogre::RaySceneQuery * rsq = HumanController::localController_s->getControllableEntity()->getScene()->getSceneManager()->createRayQuery(Ogre::Ray());
+
+        Ogre::Ray mouseRay = HumanController::localController_s->getControllableEntity()->getCamera()->getOgreCamera()->getCameraToViewportRay(static_cast<float>(this->currentYaw_)/2*-1+.5f, static_cast<float>(this->currentPitch_)/2*-1+.5f);
+
+        rsq->setRay(mouseRay);
+        rsq->setSortByDistance(true);
+
+        /*
+        Distance of objects:
+        ignore everything under 200 maybe even take 1000 as min distance to shoot at
+
+        shots are regularly traced and are entities!!!!!!!!! this is the biggest problem
+        they vanish only after a distance of 10'000
+        */
+
+
+        Ogre::RaySceneQueryResult& result = rsq->execute();
+        Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
+        WorldEntity* myWe = static_cast<WorldEntity*>(this->getControllableEntity());
+
+        Ogre::RaySceneQueryResult::iterator itr;
+        for (itr = result.begin(); itr != result.end(); ++itr)
+        {
+//             CCOUT(0) << "testing object as target" << endl;
+            if (itr->movable->isInScene() && itr->movable->getMovableType() == "Entity" /*&& itr->distance > 500*/)
+            {
+                // Try to cast the user pointer
+                WorldEntity* wePtr = dynamic_cast<WorldEntity*>(Ogre::any_cast<OrxonoxClass*>(itr->movable->getUserAny()));
+                
+                // make sure we don't shoot ourselves
+                if( wePtr==myWe )
+                    continue;
+                
+                if (wePtr)
+                {
+                    // go through all parents of object and look whether they are sightable or not
+                    bool isSightable = false;
+                    WorldEntity* parent = wePtr->getParent();
+                    while (parent)
+                    {
+                        if (this->targetMask_.isExcluded(parent->getIdentifier()) || parent==myWe)
+                        {
+                            parent = parent->getParent();
+                            continue;
+                        }
+                        else
+                        {
+                            isSightable = true;
+                            break;
+                        }
+                    }
+                    if (!isSightable)
+                        continue;
+                }
+
+                if (this->getControllableEntity() && this->getControllableEntity()->getTarget() != wePtr)
+                    this->getControllableEntity()->setTarget(wePtr);
+
+                if (pawn)
+                    pawn->setAimPosition( mouseRay.getOrigin() + mouseRay.getDirection() * itr->distance );
+
+                //itr->movable->getParentSceneNode()->showBoundingBox(true);
+                //return mouseRay.getOrigin() + mouseRay.getDirection() * itr->distance; //or itr->movable->getParentSceneNode()->_getDerivedPosition()
+                return;
+            }
+        }
+
+        if (pawn)
+            pawn->setAimPosition( mouseRay.getOrigin() + mouseRay.getDirection() * 1200 );
+
+        if( this->getControllableEntity() && this->getControllableEntity()->getTarget() != 0 )
+            this->getControllableEntity()->setTarget( 0 );
+
+        //return this->controllableEntity_->getWorldPosition() + (this->controllableEntity_->getWorldOrientation() * Vector3::NEGATIVE_UNIT_Z * 2000);
+        //return this->controllableEntity_->getWorldPosition() + (this->controllableEntity_->getCamera()->getOgreCamera()->getOrientation() * Vector3::NEGATIVE_UNIT_Z);
+    }
+
+    void NewHumanController::frontback(const Vector2& value)
+    {
+        this->accelerating_ = true;
+
+        //if (this->acceleration_ == 0)
+        HumanController::frontback(value);
+    }
+
+    void NewHumanController::yaw(const Vector2& value)
+    {
+        //SUPER(NewHumanController, yaw, value);
+        if (this->controlMode_ == 0 || (this->controllableEntity_ && this->controllableEntity_->isInMouseLook()))
+            HumanController::yaw(value);
+
+        this->currentYaw_ = value.x;
+    }
+
+    void NewHumanController::pitch(const Vector2& value)
+    {
+        //SUPER(NewHumanController, pitch, value);
+        if (this->controlMode_ == 0 || (this->controllableEntity_ && this->controllableEntity_->isInMouseLook()))
+            HumanController::pitch(value);
+
+        this->currentPitch_ = value.x;
+    }
+
+    void NewHumanController::changeMode()
+    {
+        if (NewHumanController::localController_s)
+        {
+            if (NewHumanController::localController_s->controlMode_ == 0)
+            {
+                NewHumanController::localController_s->controlMode_ = 1;
+                NewHumanController::localController_s->hideArrows();
+            }
+            else
+                NewHumanController::localController_s->controlMode_ = 0;
+        }
+    }
+
+    void NewHumanController::changedControllableEntity()
+    {
+        this->controlMode_ = 0;
+        this->currentYaw_ = 0;
+        this->currentPitch_ = 0;
+        if (this->getControllableEntity() && (this->getControllableEntity()->isExactlyA(ClassByString("SpaceShip")) || this->getControllableEntity()->isExactlyA(ClassByString("Rocket"))))
+        {
+            this->showOverlays_ = true;
+            if (!this->controlPaused_)
+            {
+                this->showOverlays();
+                this->alignArrows();
+            }
+        }
+        else
+        {
+            this->showOverlays_ = false;
+            this->hideOverlays();
+        }
+    }
+
+    void NewHumanController::accelerate()
+    {
+        if (NewHumanController::localController_s)
+            NewHumanController::localController_s->acceleration_ = clamp(NewHumanController::localController_s->acceleration_ + 0.2f, 0.00f, 1.0f);
+    }
+
+    void NewHumanController::decelerate()
+    {
+        if (NewHumanController::localController_s)
+            NewHumanController::localController_s->acceleration_ = clamp(NewHumanController::localController_s->acceleration_ - 0.1f, 0.0f, 1.0f);
+    }
+
+    void NewHumanController::doResumeControl()
+    {
+        this->controlPaused_ = false;
+        if (this->showOverlays_)
+            this->showOverlays();
+    }
+
+    void NewHumanController::doPauseControl()
+    {
+        this->controlPaused_ = true;
+        this->hideOverlays();
+    }
+
+    void NewHumanController::alignArrows()
+    {
+        if (showArrows_)
+        {
+            hideArrows();
+
+            float distance = sqrt(pow(static_cast<float>(this->currentYaw_)/2*-1,2) + pow(static_cast<float>(this->currentPitch_)/2*-1,2));
+
+            if (distance > 0.04f && distance <= 0.59f * arrowsSize_ / 2.0f )
+            {
+                this->arrowsOverlay1_->setRotation(Degree(-90 + -1.0f * atan2(static_cast<float>(this->currentPitch_)/2*-1, static_cast<float>(this->currentYaw_)/2*-1) / (2.0f * Ogre::Math::PI) * 360.0f));
+                this->arrowsOverlay1_->show();
+            }
+            else if (distance > 0.59f * arrowsSize_ / 2.0f && distance <= 0.77f * arrowsSize_ / 2.0f )
+            {
+                this->arrowsOverlay2_->setRotation(Degree(-90 + -1.0f * atan2(static_cast<float>(this->currentPitch_)/2*-1, static_cast<float>(this->currentYaw_)/2*-1) / (2.0f * Ogre::Math::PI) * 360.0f));
+                this->arrowsOverlay2_->show();
+            }
+            else if (distance > 0.77f * arrowsSize_ / 2.0f && distance <= arrowsSize_ / 2.0f)
+            {
+                this->arrowsOverlay3_->setRotation(Degree(-90 + -1.0f * atan2(static_cast<float>(this->currentPitch_)/2*-1, static_cast<float>(this->currentYaw_)/2*-1) / (2.0f * Ogre::Math::PI) * 360.0f));
+                this->arrowsOverlay3_->show();
+            }
+            else if (distance > arrowsSize_ / 2.0f)
+            {
+                this->arrowsOverlay4_->setRotation(Degree(-90 + -1.0f * atan2(static_cast<float>(this->currentPitch_)/2*-1, static_cast<float>(this->currentYaw_)/2*-1) / (2.0f * Ogre::Math::PI) * 360.0f));
+                this->arrowsOverlay4_->show();
+            }
+        }
+    }
+
+    void NewHumanController::showOverlays()
+    {
+        if (!GameMode::showsGraphics())
+            return;
+        this->crossHairOverlay_->show();
+        this->centerOverlay_->show();
+
+        if (showArrows_)
+        {
+            this->arrowsOverlay1_->show();
+            this->arrowsOverlay2_->show();
+            this->arrowsOverlay3_->show();
+            this->arrowsOverlay4_->show();
+        }
+    }
+
+    void NewHumanController::hideOverlays()
+    {
+        if (!GameMode::showsGraphics())
+            return;
+        this->crossHairOverlay_->hide();
+        this->centerOverlay_->hide();
+
+        if (showDamageOverlay_)
+        {
+            this->damageOverlayTop_->hide();
+            this->damageOverlayRight_->hide();
+            this->damageOverlayBottom_->hide();
+            this->damageOverlayLeft_->hide();
+        }
+
+        this->hideArrows();
+    }
+
+    void NewHumanController::hideArrows()
+    {
+        if(!GameMode::showsGraphics())
+            return;
+        if (showArrows_)
+        {
+            this->arrowsOverlay1_->hide();
+            this->arrowsOverlay2_->hide();
+            this->arrowsOverlay3_->hide();
+            this->arrowsOverlay4_->hide();
+        }
+    }
+        
+
+    
+
+
+}
Index: /code/branches/rocket2/src/orxonox/controllers/NewHumanController.h
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/NewHumanController.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/NewHumanController.h	(revision 6952)
@@ -0,0 +1,113 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Michael Wirth
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NewNewHumanController_H__
+#define _NewNewHumanController_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/Math.h"
+
+#include "core/ClassTreeMask.h"
+#include "HumanController.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport NewHumanController : public HumanController
+    {
+        public:
+            NewHumanController(BaseObject* creator);
+            virtual ~NewHumanController();
+
+            virtual void tick(float dt);
+
+            virtual void frontback(const Vector2& value);
+            virtual void yaw(const Vector2& value);
+            virtual void pitch(const Vector2& value);
+
+            static void accelerate();
+            static void decelerate();
+
+            virtual void doFire(unsigned int firemode);
+
+            virtual void hit(Pawn* originator, btManifoldPoint& contactpoint, float damage);
+
+            static void unfire();
+            virtual void doUnfire();
+
+            static void changeMode();
+
+            virtual void changedControllableEntity();
+            virtual void doPauseControl();
+            virtual void doResumeControl();
+
+
+        protected:
+            void updateTarget();
+            void alignArrows();
+            void showOverlays();
+            void hideOverlays();
+            void hideArrows();
+
+            unsigned int                controlMode_;
+            static NewHumanController*  localController_s;
+
+        private:
+            float                       currentYaw_;
+            float                       currentPitch_;
+            OrxonoxOverlay*             crossHairOverlay_;
+            OrxonoxOverlay*             centerOverlay_;
+
+            OrxonoxOverlay*             damageOverlayTop_;
+            OrxonoxOverlay*             damageOverlayRight_;
+            OrxonoxOverlay*             damageOverlayBottom_;
+            OrxonoxOverlay*             damageOverlayLeft_;
+            float                       damageOverlayTime_;
+            float                       damageOverlayTT_;
+            float                       damageOverlayTR_;
+            float                       damageOverlayTB_;
+            float                       damageOverlayTL_;
+
+            OrxonoxOverlay*             arrowsOverlay1_;
+            OrxonoxOverlay*             arrowsOverlay2_;
+            OrxonoxOverlay*             arrowsOverlay3_;
+            OrxonoxOverlay*             arrowsOverlay4_;
+
+            float                       overlaySize_;
+            float                       arrowsSize_;
+            bool                        accelerating_;
+            float                       acceleration_;
+            int                         firemode_;
+            bool                        showArrows_;
+            bool                        showDamageOverlay_;
+            bool                        showOverlays_;
+            ClassTreeMask               targetMask_;
+    };
+}
+
+#endif /* _NewHumanController_H__ */
Index: /code/branches/rocket2/src/orxonox/controllers/ScriptController.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/ScriptController.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/ScriptController.cc	(revision 6952)
@@ -0,0 +1,40 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ScriptController.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    CreateFactory(ScriptController);
+
+    ScriptController::ScriptController(BaseObject* creator) : ArtificialController(creator)
+    {
+        RegisterObject(ScriptController);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/controllers/ScriptController.h
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/ScriptController.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/ScriptController.h	(revision 6952)
@@ -0,0 +1,47 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ScriptController_H__
+#define _ScriptController_H__
+
+#include "OrxonoxPrereqs.h"
+#include "ArtificialController.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport ScriptController : public ArtificialController
+    {
+        public:
+            ScriptController(BaseObject* creator);
+            virtual ~ScriptController() { }
+
+        private:
+    };
+}
+
+#endif /* _ScriptController_H__ */
Index: /code/branches/rocket2/src/orxonox/controllers/WaypointController.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/WaypointController.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/WaypointController.cc	(revision 6952)
@@ -0,0 +1,90 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "WaypointController.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "worldentities/ControllableEntity.h"
+
+namespace orxonox
+{
+    CreateFactory(WaypointController);
+
+    WaypointController::WaypointController(BaseObject* creator) : ArtificialController(creator)
+    {
+        RegisterObject(WaypointController);
+
+        this->currentWaypoint_ = 0;
+        this->setAccuracy(100);
+    }
+
+    WaypointController::~WaypointController()
+    {
+        if (this->isInitialized())
+        {
+            for (size_t i = 0; i < this->waypoints_.size(); ++i)
+                this->waypoints_[i]->destroy();
+        }
+    }
+
+    void WaypointController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(WaypointController, XMLPort, xmlelement, mode);
+
+        XMLPortParam(WaypointController, "accuracy", setAccuracy, getAccuracy, xmlelement, mode).defaultValues(100.0f);
+        XMLPortObject(WaypointController, WorldEntity, "waypoints", addWaypoint, getWaypoint,  xmlelement, mode);
+    }
+
+    void WaypointController::tick(float dt)
+    {
+        if (!this->isActive())
+            return;
+
+        if (this->waypoints_.size() == 0 || !this->getControllableEntity())
+            return;
+
+        if (this->waypoints_[this->currentWaypoint_]->getWorldPosition().squaredDistance(this->getControllableEntity()->getPosition()) <= this->squaredaccuracy_)
+            this->currentWaypoint_ = (this->currentWaypoint_ + 1) % this->waypoints_.size();
+
+        this->moveToPosition(this->waypoints_[this->currentWaypoint_]->getWorldPosition());
+    }
+
+    void WaypointController::addWaypoint(WorldEntity* waypoint)
+    {
+        this->waypoints_.push_back(waypoint);
+    }
+
+    WorldEntity* WaypointController::getWaypoint(unsigned int index) const
+    {
+        if (index < this->waypoints_.size())
+            return this->waypoints_[index];
+        else
+            return 0;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/controllers/WaypointController.h
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/WaypointController.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/WaypointController.h	(revision 6952)
@@ -0,0 +1,64 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _WaypointController_H__
+#define _WaypointController_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <vector>
+#include "tools/interfaces/Tickable.h"
+#include "ArtificialController.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport WaypointController : public ArtificialController, public Tickable
+    {
+        public:
+            WaypointController(BaseObject* creator);
+            virtual ~WaypointController();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void tick(float dt);
+
+            void addWaypoint(WorldEntity* waypoint);
+            WorldEntity* getWaypoint(unsigned int index) const;
+
+            inline void setAccuracy(float accuracy)
+                { this->squaredaccuracy_ = accuracy*accuracy; }
+            inline float getAccuracy() const
+                { return sqrt(this->squaredaccuracy_); }
+
+        protected:
+            std::vector<WorldEntity*> waypoints_;
+            size_t currentWaypoint_;
+            float squaredaccuracy_;
+    };
+}
+
+#endif /* _WaypointController_H__ */
Index: /code/branches/rocket2/src/orxonox/controllers/WaypointPatrolController.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/WaypointPatrolController.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/WaypointPatrolController.cc	(revision 6952)
@@ -0,0 +1,105 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "WaypointPatrolController.h"
+
+#include "util/Math.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateFactory(WaypointPatrolController);
+
+    WaypointPatrolController::WaypointPatrolController(BaseObject* creator) : WaypointController(creator)
+    {
+        RegisterObject(WaypointPatrolController);
+
+        this->team_ = 0;
+        this->alertnessradius_ = 500;
+
+        this->patrolTimer_.setTimer(rnd(), true, createExecutor(createFunctor(&WaypointPatrolController::searchEnemy, this)));
+    }
+
+    void WaypointPatrolController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(WaypointPatrolController, XMLPort, xmlelement, mode);
+
+        XMLPortParam(WaypointPatrolController, "alertnessradius", setAlertnessRadius, getAlertnessRadius, xmlelement, mode).defaultValues(500.0f);
+        XMLPortParam(WaypointPatrolController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(0);
+    }
+
+    void WaypointPatrolController::tick(float dt)
+    {
+        if (!this->isActive())
+            return;
+
+        if (this->target_)
+        {
+            this->aimAtTarget();
+
+            if (this->bHasTargetPosition_)
+                this->moveToTargetPosition();
+
+            if (this->getControllableEntity() && this->isCloseAtTarget(1000) && this->isLookingAtTarget(Ogre::Math::PI / 20.0f))
+                this->getControllableEntity()->fire(0);
+        }
+        else
+        {
+            SUPER(WaypointPatrolController, tick, dt);
+        }
+    }
+
+    void WaypointPatrolController::searchEnemy()
+    {
+        this->patrolTimer_.setInterval(rnd());
+
+        if (!this->getControllableEntity())
+            return;
+
+        Vector3 myposition = this->getControllableEntity()->getPosition();
+        float shortestsqdistance = (float)static_cast<unsigned int>(-1);
+
+        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it != ObjectList<Pawn>::end(); ++it)
+        {
+            if (ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
+                continue;
+
+            float sqdistance = it->getPosition().squaredDistance(myposition);
+            if (sqdistance < shortestsqdistance)
+            {
+                shortestsqdistance = sqdistance;
+                this->target_ = (*it);
+            }
+        }
+
+        if (shortestsqdistance > (this->alertnessradius_ * this->alertnessradius_))
+            this->target_ = 0;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/controllers/WaypointPatrolController.h
===================================================================
--- /code/branches/rocket2/src/orxonox/controllers/WaypointPatrolController.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/controllers/WaypointPatrolController.h	(revision 6952)
@@ -0,0 +1,67 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _WaypointPatrolController_H__
+#define _WaypointPatrolController_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "tools/Timer.h"
+#include "WaypointController.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport WaypointPatrolController : public WaypointController
+    {
+        public:
+            WaypointPatrolController(BaseObject* creator);
+            virtual ~WaypointPatrolController() {}
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void tick(float dt);
+
+            inline void setTeam(int team)
+                { this->team_ = team; }
+            inline int getTeam() const
+                { return this->team_; }
+
+            inline void setAlertnessRadius(float radius)
+                { this->alertnessradius_ = radius; }
+            inline float getAlertnessRadius() const
+                { return this->alertnessradius_; }
+
+        protected:
+            void searchEnemy();
+
+            int team_;
+            float alertnessradius_;
+            Timer patrolTimer_;
+    };
+}
+
+#endif /* _WaypointPatrolController_H__ */
Index: /code/branches/rocket2/src/orxonox/gamestates/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,9 @@
+ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+  GSClient.cc
+  GSGraphics.cc
+  GSLevel.cc
+  GSMainMenu.cc
+  GSRoot.cc
+  GSServer.cc
+  GSStandalone.cc
+)
Index: /code/branches/rocket2/src/orxonox/gamestates/GSClient.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/GSClient.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/GSClient.cc	(revision 6952)
@@ -0,0 +1,83 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      Fabian 'x3n' Landau
+ *
+ */
+
+#include "GSClient.h"
+
+#include "util/Debug.h"
+#include "util/Exception.h"
+#include "core/CommandLineParser.h"
+#include "core/Game.h"
+#include "core/GameMode.h"
+#include "network/Client.h"
+
+namespace orxonox
+{
+    DeclareGameState(GSClient, "client", false, false);
+
+    SetCommandLineArgument(ip, "127.0.0.1").information("Sever IP as string in the form #.#.#.#");
+
+    GSClient::GSClient(const GameStateInfo& info)
+        : GameState(info)
+        , client_(0)
+    {
+    }
+
+    GSClient::~GSClient()
+    {
+    }
+
+    void GSClient::activate()
+    {
+        GameMode::setIsClient(true);
+
+        this->client_ = new Client(CommandLineParser::getValue("ip").getString(), CommandLineParser::getValue("port"));
+
+        if(!client_->establishConnection())
+        {
+            delete this->client_;
+            ThrowException(InitialisationFailed, "Could not establish connection with server.");
+        }
+
+        client_->update(Game::getInstance().getGameClock());
+    }
+
+    void GSClient::deactivate()
+    {
+        client_->closeConnection();
+
+        // destroy client
+        delete this->client_;
+
+        GameMode::setIsClient(false);
+    }
+
+    void GSClient::update(const Clock& time)
+    {
+        client_->update(time);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/gamestates/GSClient.h
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/GSClient.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/GSClient.h	(revision 6952)
@@ -0,0 +1,54 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GSClient_H__
+#define _GSClient_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "core/GameState.h"
+#include "network/NetworkPrereqs.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport GSClient : public GameState
+    {
+    public:
+        GSClient(const GameStateInfo& info);
+        ~GSClient();
+
+        void activate();
+        void deactivate();
+        void update(const Clock& time);
+
+    private:
+        Client* client_;
+    };
+}
+
+#endif /* _GSClient_H__ */
Index: /code/branches/rocket2/src/orxonox/gamestates/GSGraphics.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/GSGraphics.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/GSGraphics.cc	(revision 6952)
@@ -0,0 +1,85 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      Benjamin Knecht
+ *
+ */
+
+/**
+@file
+@brief
+    Implementation of Graphics GameState class.
+ */
+
+#include "GSGraphics.h"
+
+#include "core/CommandExecutor.h"
+#include "core/ConsoleCommand.h"
+#include "core/Game.h"
+#include "core/GUIManager.h"
+
+namespace orxonox
+{
+    DeclareGameState(GSGraphics, "graphics", false, true);
+
+    GSGraphics::GSGraphics(const GameStateInfo& info)
+        : GameState(info)
+    {
+    }
+
+    GSGraphics::~GSGraphics()
+    {
+    }
+
+    /**
+    @brief
+        This function is called when we enter this game state.
+
+        There is only one thing to do here:
+        \li create console command to toggle GUI
+    */
+    void GSGraphics::activate()
+    {
+
+    }
+
+    /**
+    @brief
+        This function is called when the game state is left
+    */
+    void GSGraphics::deactivate()
+    {
+
+    }
+
+    void GSGraphics::update(const Clock& time)
+    {
+        if (this->getActivity().topState)
+        {
+            // This state can not 'survive' on its own.
+            // Load a user interface therefore
+            Game::getInstance().requestState("mainMenu");
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/gamestates/GSGraphics.h
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/GSGraphics.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/GSGraphics.h	(revision 6952)
@@ -0,0 +1,63 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      Benjamin Knecht (documentation)
+ *
+ */
+
+/**
+@file
+@brief
+    Declaration of the Graphics GameState class.
+*/
+
+#ifndef _GSGraphics_H__
+#define _GSGraphics_H__
+
+#include "OrxonoxPrereqs.h"
+#include "core/GameState.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Game state used when displaying graphics of any kind. Another blubb resides here.
+
+        This game state is only left out if we start a dedicated server where no graphics are present.
+    */
+    class _OrxonoxExport GSGraphics : public GameState
+    {
+    public:
+        GSGraphics(const GameStateInfo& info);
+        ~GSGraphics();
+
+        void activate();
+        void deactivate();
+        void update(const Clock& time);
+
+    private:
+    };
+}
+
+#endif /* _GSGraphics_H__ */
Index: /code/branches/rocket2/src/orxonox/gamestates/GSLevel.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/GSLevel.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/GSLevel.cc	(revision 6952)
@@ -0,0 +1,165 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      Fabian 'x3n' Landau
+ *      Benjamin Knecht
+ *
+ */
+
+#include "GSLevel.h"
+
+#include <OgreCompositorManager.h>
+
+#include "util/Clock.h"
+#include "core/input/InputManager.h"
+#include "core/input/InputState.h"
+#include "core/input/KeyBinderManager.h"
+#include "core/ConsoleCommand.h"
+#include "core/Game.h"
+#include "core/GameMode.h"
+#include "core/GUIManager.h"
+#include "core/Loader.h"
+#include "core/XMLFile.h"
+
+#include "LevelManager.h"
+#include "PlayerManager.h"
+
+namespace orxonox
+{
+    DeclareGameState(GSLevel, "level", false, false);
+
+    GSLevel::GSLevel(const GameStateInfo& info)
+        : GameState(info)
+        , gameInputState_(0)
+        , guiMouseOnlyInputState_(0)
+        , guiKeysOnlyInputState_(0)
+        , startFile_(0)
+        , bShowIngameGUI_(false)
+    {
+    }
+
+    GSLevel::~GSLevel()
+    {
+    }
+
+    void GSLevel::activate()
+    {
+        if (GameMode::showsGraphics())
+        {
+            gameInputState_ = InputManager::getInstance().createInputState("game");
+            gameInputState_->setMouseExclusive(TriBool::True);
+            gameInputState_->setHandler(KeyBinderManager::getInstance().getDefaultAsHandler());
+            KeyBinderManager::getInstance().setToDefault();
+
+            guiMouseOnlyInputState_ = InputManager::getInstance().createInputState("guiMouseOnly");
+            guiMouseOnlyInputState_->setMouseExclusive(TriBool::True);
+            guiMouseOnlyInputState_->setMouseHandler(&GUIManager::getInstance());
+
+            guiKeysOnlyInputState_ = InputManager::getInstance().createInputState("guiKeysOnly");
+            guiKeysOnlyInputState_->setKeyHandler(&GUIManager::getInstance());
+        }
+
+        if (GameMode::isMaster())
+        {
+            this->loadLevel();
+        }
+
+        if (GameMode::showsGraphics())
+        {
+            // level is loaded: we can start capturing the input
+            InputManager::getInstance().enterState("game");
+
+            // connect the HumanPlayer to the game
+            PlayerManager::getInstance().clientConnected(0);
+        }
+    }
+
+    void GSLevel::deactivate()
+    {
+        if (GameMode::showsGraphics())
+        {
+            // unload all compositors (this is only necessary because we don't yet destroy all resources!)
+            Ogre::CompositorManager::getSingleton().removeAll();
+
+            InputManager::getInstance().leaveState("game");
+        }
+
+        // disconnect all HumanPlayers
+        PlayerManager::getInstance().disconnectAllClients();
+
+        if (GameMode::isMaster())
+            this->unloadLevel();
+
+        if (GameMode::showsGraphics())
+        {
+            gameInputState_->setHandler(0);
+            guiMouseOnlyInputState_->setHandler(0);
+            guiKeysOnlyInputState_->setHandler(0);
+            InputManager::getInstance().destroyState("game");
+            InputManager::getInstance().destroyState("guiKeysOnly");
+            InputManager::getInstance().destroyState("guiMouseOnly");
+        }
+    }
+
+    void GSLevel::update(const Clock& time)
+    {
+        // Note: Temporarily moved to GSRoot.
+        //// Call the scene objects
+        //for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; ++it)
+        //    it->tick(time.getDeltaTime() * this->timeFactor_);
+    }
+
+    void GSLevel::loadLevel()
+    {
+        for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it != ObjectList<BaseObject>::end(); ++it)
+            this->staticObjects_.insert(*it);
+
+        // call the loader
+        COUT(0) << "Loading level..." << std::endl;
+        startFile_ = new XMLFile(LevelManager::getInstance().getDefaultLevel());
+        Loader::open(startFile_);
+    }
+
+    void GSLevel::unloadLevel()
+    {
+        Loader::unload(startFile_);
+        delete startFile_;
+
+        COUT(3) << "Unloaded level. Remaining objects:" << std::endl;
+        unsigned int i = 0;
+        for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it != ObjectList<BaseObject>::end(); ++it)
+        {
+            std::set<BaseObject*>::const_iterator find = this->staticObjects_.find(*it);
+            if (find == this->staticObjects_.end())
+            {
+                COUT(3) << ++i << ": " << it->getIdentifier()->getName() << " (" << *it << ')' << std::endl;
+            }
+        }
+        COUT(3) << i << " objects remaining.";
+        if (i == 0)
+            COUT(3) << " Well done!" << std::endl;
+        else
+            COUT(3) << " Try harder!" << std::endl;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/gamestates/GSLevel.h
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/GSLevel.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/GSLevel.h	(revision 6952)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      Benjamin Knecht
+ *
+ */
+
+#ifndef _GSLevel_H__
+#define _GSLevel_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include <set>
+#include "core/OrxonoxClass.h"
+#include "core/GameState.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport GSLevel : public GameState
+    {
+    public:
+        GSLevel(const GameStateInfo& info);
+        ~GSLevel();
+
+        void activate();
+        void deactivate();
+        void update(const Clock& time);
+
+    protected:
+        void loadLevel();
+        void unloadLevel();
+
+        InputState*              gameInputState_;          //!< input state for normal ingame playing
+        InputState*              guiMouseOnlyInputState_;  //!< input state if we only need the mouse to use the GUI
+        InputState*              guiKeysOnlyInputState_;   //!< input state if we only need the keys to use the GUI
+
+        XMLFile* startFile_;
+        std::set<BaseObject*> staticObjects_;
+        bool bShowIngameGUI_;
+    };
+}
+
+#endif /* _GSLevel_H__ */
Index: /code/branches/rocket2/src/orxonox/gamestates/GSMainMenu.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/GSMainMenu.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/GSMainMenu.cc	(revision 6952)
@@ -0,0 +1,190 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "GSMainMenu.h"
+
+#include <OgreSceneManager.h>
+
+#include "core/input/KeyBinderManager.h"
+#include "core/Game.h"
+#include "core/ConsoleCommand.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
+#include "core/GraphicsManager.h"
+#include "core/GUIManager.h"
+#include "Scene.h"
+#include "sound/AmbientSound.h"
+// HACK
+#include "core/input/InputManager.h"
+#include "core/input/InputState.h"
+
+namespace orxonox
+{
+    DeclareGameState(GSMainMenu, "mainMenu", false, true);
+
+    GSMainMenu::GSMainMenu(const GameStateInfo& info)
+        : GameState(info)
+    {
+        RegisterRootObject(GSMainMenu);
+
+        InputManager::getInstance().createInputState("MainMenuHackery")->setKeyHandler(KeyBinderManager::getInstance().getDefaultAsHandler());
+
+        // create an empty Scene
+        this->scene_ = new Scene(NULL);
+        this->scene_->setSyncMode( 0x0 );
+        // and a Camera
+        this->camera_ = this->scene_->getSceneManager()->createCamera("mainMenu/Camera");
+        if (GameMode::playsSound())
+        {
+            // Load sound
+            this->ambient_ = new AmbientSound(0);
+            this->ambient_->setSyncMode(0x0);
+        }
+    }
+
+    GSMainMenu::~GSMainMenu()
+    {
+        if (GameMode::playsSound())
+            this->ambient_->destroy();
+
+        InputManager::getInstance().destroyState("MainMenuHackery");
+
+        this->scene_->getSceneManager()->destroyCamera(this->camera_);
+        this->scene_->destroy();
+    }
+
+    void GSMainMenu::activate()
+    {
+        // show main menu
+        GUIManager::getInstance().showGUI("MainMenu", true);
+        GUIManager::getInstance().setCamera(this->camera_);
+        GUIManager::getInstance().setBackgroundImage("MainMenuBackground", "Background");
+        GraphicsManager::getInstance().setCamera(this->camera_);
+
+        InputManager::getInstance().enterState("MainMenuHackery");
+
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&GSMainMenu::startStandalone), "startGame"));
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&GSMainMenu::startServer), "startServer"));
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&GSMainMenu::startClient), "startClient"));
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&GSMainMenu::startDedicated), "startDedicated"));
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&GSMainMenu::startMainMenu), "startMainMenu"));
+
+        // create command to change sound path
+        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&GSMainMenu::setMainMenuSoundPath, this), "setMMSoundPath"));
+
+        KeyBinderManager::getInstance().setToDefault();
+
+        this->setConfigValues();
+
+        if (GameMode::playsSound())
+        {
+            this->ambient_->setLooping(true);
+            this->ambient_->play(); // works without source
+        }
+    }
+
+    void GSMainMenu::deactivate()
+    {
+        if (GameMode::playsSound())
+        {
+            this->ambient_->stop();
+        }
+
+        InputManager::getInstance().leaveState("MainMenuHackery");
+
+        GUIManager::getInstance().setCamera(0);
+        GUIManager::getInstance().setBackgroundImage("");
+        GUIManager::hideGUI("MainMenu");
+        GraphicsManager::getInstance().setCamera(0);
+    }
+
+    void GSMainMenu::update(const Clock& time)
+    {
+    }
+
+    void GSMainMenu::setConfigValues()
+    {
+        SetConfigValue(soundPathMain_, "mainmenu.ogg")
+            .description("Contains the path to the main menu sound file.")
+            .callback(this, &GSMainMenu::reloadSound);
+    }
+
+    void GSMainMenu::reloadSound()
+    {
+        if (GameMode::playsSound())
+        {
+            this->ambient_->setAmbientSource(soundPathMain_);
+        }
+    }
+
+    const std::string& GSMainMenu::getMainMenuSoundPath()
+    {
+        return soundPathMain_;
+    }
+
+    void GSMainMenu::setMainMenuSoundPath(const std::string& path)
+    {
+        ModifyConfigValue(soundPathMain_, set, path);
+    }
+
+    void GSMainMenu::startStandalone()
+    {
+        // HACK - HACK
+        Game::getInstance().popState();
+        Game::getInstance().requestStates("standalone, level");
+    }
+
+    void GSMainMenu::startServer()
+    {
+        // HACK - HACK
+        Game::getInstance().popState();
+        Game::getInstance().requestStates("server, level");
+    }
+
+    void GSMainMenu::startClient()
+    {
+        // HACK - HACK
+        Game::getInstance().popState();
+        Game::getInstance().requestStates("client, level");
+    }
+
+    void GSMainMenu::startDedicated()
+    {
+        // HACK - HACK
+        Game::getInstance().popState();
+        Game::getInstance().popState();
+        Game::getInstance().requestStates("server, level");
+    }
+    void GSMainMenu::startMainMenu()
+    {
+        // HACK - HACK
+        Game::getInstance().popState();
+        Game::getInstance().popState();
+        Game::getInstance().requestStates("mainmenu");
+    }
+}
Index: /code/branches/rocket2/src/orxonox/gamestates/GSMainMenu.h
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/GSMainMenu.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/GSMainMenu.h	(revision 6952)
@@ -0,0 +1,72 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GSMainMenu_H__
+#define _GSMainMenu_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/OgreForwardRefs.h"
+#include "core/GameState.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport GSMainMenu : public GameState, public OrxonoxClass
+    {
+    public:
+        GSMainMenu(const GameStateInfo& info);
+        ~GSMainMenu();
+
+        void activate();
+        void deactivate();
+        void update(const Clock& time);
+
+        void setConfigValues();
+        void reloadSound();
+        const std::string& getMainMenuSoundPath();
+        void setMainMenuSoundPath(const std::string& path);
+
+        static void startStandalone();
+        static void startServer();
+        static void startClient();
+        static void startDedicated();
+        static void startMainMenu();
+        static void startIOConsole();
+
+    private:
+        Scene*            scene_;
+        Ogre::Camera*     camera_;
+
+        // ambient sound for the main menu
+        AmbientSound*     ambient_;
+        std::string       soundPathMain_;
+    };
+}
+
+#endif /* _GSMainMenu_H__ */
Index: /code/branches/rocket2/src/orxonox/gamestates/GSRoot.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/GSRoot.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/GSRoot.cc	(revision 6952)
@@ -0,0 +1,159 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "GSRoot.h"
+
+#include "util/Clock.h"
+#include "core/BaseObject.h"
+#include "core/ConsoleCommand.h"
+#include "core/Game.h"
+#include "core/GameMode.h"
+#include "network/NetworkFunction.h"
+#include "tools/Timer.h"
+#include "tools/interfaces/TimeFactorListener.h"
+#include "tools/interfaces/Tickable.h"
+
+namespace orxonox
+{
+    DeclareGameState(GSRoot, "root", false, false);
+    SetConsoleCommandShortcut(GSRoot, printObjects);
+
+    GSRoot::GSRoot(const GameStateInfo& info)
+        : GameState(info)
+        , bPaused_(false)
+        , timeFactorPauseBackup_(1.0f)
+    {
+    }
+
+    GSRoot::~GSRoot()
+    {
+        NetworkFunctionBase::destroyAllNetworkFunctions();
+    }
+
+    void GSRoot::printObjects()
+    {
+        unsigned int nr=0;
+        for (ObjectList<BaseObject>::iterator it = ObjectList<BaseObject>::begin(); it; ++it)
+        {
+            if (dynamic_cast<Synchronisable*>(*it))
+                COUT(0) << "object: " << it->getIdentifier()->getName() << " id: " << dynamic_cast<Synchronisable*>(*it)->getObjectID() << std::endl;
+            else
+                COUT(0) << "object: " << it->getIdentifier()->getName() << std::endl;
+            nr++;
+        }
+        COUT(0) << "currently got " << nr << " objects" << std::endl;
+    }
+
+    void GSRoot::activate()
+    {
+        // reset game speed to normal
+        TimeFactorListener::setTimeFactor(1.0f);
+
+        // time factor console command
+        ConsoleCommand* command = createConsoleCommand(createFunctor(&GSRoot::setTimeFactor, this), "setTimeFactor");
+        CommandExecutor::addConsoleCommandShortcut(command).accessLevel(AccessLevel::Offline).defaultValue(0, 1.0);
+
+        // time factor console command
+        command = createConsoleCommand(createFunctor(&GSRoot::pause, this), "pause");
+        CommandExecutor::addConsoleCommandShortcut(command).accessLevel(AccessLevel::Offline);
+    }
+
+    void GSRoot::deactivate()
+    {
+    }
+
+    void GSRoot::update(const Clock& time)
+    {
+        for (ObjectList<Timer>::iterator it = ObjectList<Timer>::begin(); it; )
+        {
+            Timer* object = *it;
+            ++it;
+            object->tick(time);
+        }
+
+        /*** HACK *** HACK ***/
+        // Call the Tickable objects
+        float leveldt = time.getDeltaTime();
+        if (leveldt > 1.0f)
+        {
+            // just loaded
+            leveldt = 0.0f;
+        }
+        float realdt = leveldt * TimeFactorListener::getTimeFactor();
+        for (ObjectList<Tickable>::iterator it = ObjectList<Tickable>::begin(); it; )
+        {
+            Tickable* object = *it;
+            ++it;
+            object->tick(realdt);
+        }
+        /*** HACK *** HACK ***/
+    }
+
+    /**
+    @brief
+        Changes the speed of Orxonox
+    @remark
+        This function is a hack when placed here!
+        Timefactor should be related to the scene (level or so), not the game
+    */
+    void GSRoot::setTimeFactor(float factor)
+    {
+        if (GameMode::isMaster())
+        {
+            if (!this->bPaused_)
+            {
+                TimeFactorListener::setTimeFactor(factor);
+            }
+            else
+                this->timeFactorPauseBackup_ = factor;
+        }
+    }
+
+    void GSRoot::pause()
+    {
+        if (GameMode::isMaster())
+        {
+            if (!this->bPaused_)
+            {
+                this->timeFactorPauseBackup_ = TimeFactorListener::getTimeFactor();
+                this->setTimeFactor(0.0f);
+                this->bPaused_ = true;
+            }
+            else
+            {
+                this->bPaused_ = false;
+                this->setTimeFactor(this->timeFactorPauseBackup_);
+            }
+        }
+    }
+
+    float GSRoot::getTimeFactor()
+    {
+        return TimeFactorListener::getTimeFactor();
+    }
+}
Index: /code/branches/rocket2/src/orxonox/gamestates/GSRoot.h
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/GSRoot.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/GSRoot.h	(revision 6952)
@@ -0,0 +1,61 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GSRoot_H__
+#define _GSRoot_H__
+
+#include "OrxonoxPrereqs.h"
+#include "core/GameState.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport GSRoot : public GameState
+    {
+    public:
+        GSRoot(const GameStateInfo& info);
+        ~GSRoot();
+
+        static void printObjects();
+
+        void activate();
+        void deactivate();
+        void update(const Clock& time);
+
+        // this has to be public because proteced triggers a bug in msvc
+        // when taking the function address.
+        void setTimeFactor(float factor);
+        void pause();
+        float getTimeFactor();
+
+    private:
+        bool                  bPaused_;
+        float                 timeFactorPauseBackup_;
+    };
+}
+
+#endif /* _GSRoot_H__ */
Index: /code/branches/rocket2/src/orxonox/gamestates/GSServer.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/GSServer.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/GSServer.cc	(revision 6952)
@@ -0,0 +1,75 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      Fabian 'x3n' Landau
+ *
+ */
+
+#include "GSServer.h"
+
+#include "util/Debug.h"
+#include "core/CommandLineParser.h"
+#include "core/Game.h"
+#include "core/GameMode.h"
+#include "network/Server.h"
+
+namespace orxonox
+{
+    DeclareGameState(GSServer, "server", false, false);
+
+    SetCommandLineArgument(port, 55556).shortcut("p").information("Network communication port to be used 0-65535 (default: 55556)");
+
+    GSServer::GSServer(const GameStateInfo& info)
+        : GameState(info)
+        , server_(0)
+    {
+    }
+
+    GSServer::~GSServer()
+    {
+    }
+
+    void GSServer::activate()
+    {
+        GameMode::setHasServer(true);
+
+        this->server_ = new Server(CommandLineParser::getValue("port"));
+        COUT(0) << "Loading scene in server mode" << std::endl;
+
+        server_->open();
+    }
+
+    void GSServer::deactivate()
+    {
+        this->server_->close();
+        delete this->server_;
+
+        GameMode::setHasServer(false);
+    }
+
+    void GSServer::update(const Clock& time)
+    {
+        server_->update(time);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/gamestates/GSServer.h
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/GSServer.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/GSServer.h	(revision 6952)
@@ -0,0 +1,54 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GSServer_H__
+#define _GSServer_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "core/GameState.h"
+#include "network/NetworkPrereqs.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport GSServer : public GameState
+    {
+    public:
+        GSServer(const GameStateInfo& info);
+        ~GSServer();
+
+        void activate();
+        void deactivate();
+        void update(const Clock& time);
+
+    private:
+        Server* server_;
+    };
+}
+
+#endif /* _GSServer_H__ */
Index: /code/branches/rocket2/src/orxonox/gamestates/GSStandalone.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/GSStandalone.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/GSStandalone.cc	(revision 6952)
@@ -0,0 +1,61 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      Fabian 'x3n' Landau
+ *
+ */
+
+#include "GSStandalone.h"
+
+#include "core/Game.h"
+#include "core/GameMode.h"
+
+namespace orxonox
+{
+    DeclareGameState(GSStandalone, "standalone", false, true);
+
+    GSStandalone::GSStandalone(const GameStateInfo& info)
+        : GameState(info)
+    {
+    }
+
+    GSStandalone::~GSStandalone()
+    {
+    }
+
+
+    void GSStandalone::activate()
+    {
+        GameMode::setIsStandalone(true);
+    }
+
+    void GSStandalone::deactivate()
+    {
+        GameMode::setIsStandalone(false);
+    }
+
+    void GSStandalone::update(const Clock& time)
+    {
+    }
+}
Index: /code/branches/rocket2/src/orxonox/gamestates/GSStandalone.h
===================================================================
--- /code/branches/rocket2/src/orxonox/gamestates/GSStandalone.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gamestates/GSStandalone.h	(revision 6952)
@@ -0,0 +1,51 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GSStandalone_H__
+#define _GSStandalone_H__
+
+#include "OrxonoxPrereqs.h"
+#include "core/GameState.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport GSStandalone : public GameState
+    {
+    public:
+        GSStandalone(const GameStateInfo& info);
+        ~GSStandalone();
+
+        void activate();
+        void deactivate();
+        void update(const Clock& time);
+
+    private:
+    };
+}
+
+#endif /* _GSStandalone_H__ */
Index: /code/branches/rocket2/src/orxonox/gametypes/Asteroids.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/Asteroids.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/Asteroids.cc	(revision 6952)
@@ -0,0 +1,87 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Aurelian Jaggi
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Asteroids.h"
+
+#include "core/CoreIncludes.h"
+#include "network/Host.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(Asteroids);
+
+    Asteroids::Asteroids(BaseObject* creator) : Gametype(creator)
+    {
+        RegisterObject(Asteroids);
+        this->firstCheckpointReached_ = false;
+    }
+
+    void Asteroids::tick(float dt)
+    {
+        SUPER(Asteroids, tick, dt);
+
+        if (firstCheckpointReached_ && !this->timerIsActive_)
+        {
+            this->startTimer();
+        }
+
+        if (this->time_ < 0 && !this->hasEnded() && this->timerIsActive_)
+        {
+            this->gtinfo_->sendAnnounceMessage("Time's up - you have lost the match!");
+            this->end();
+        }
+    }
+
+    void Asteroids::pawnKilled(Pawn* victim, Pawn* killer)
+    {
+        if (victim && victim->getPlayer())
+        {
+            this->gtinfo_->sendAnnounceMessage("You're dead - you have lost the match!");
+            this->end();
+        }
+    }
+
+    void Asteroids::start()
+    {
+        Gametype::start();
+
+        std::string message("The match has started! Reach the first chekpoint within 15 seconds! But be aware, there may be pirates around...");
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+    }
+
+    void Asteroids::end()
+    {
+        Gametype::end();
+
+        std::string message("The match has ended.");
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/gametypes/Asteroids.h
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/Asteroids.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/Asteroids.h	(revision 6952)
@@ -0,0 +1,60 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Aurelian Jaggi
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Asteroids_H__
+#define _Asteroids_H__
+
+#include "OrxonoxPrereqs.h"
+#include "Gametype.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Asteroids : public Gametype
+    {
+        public:
+            Asteroids(BaseObject* creator);
+            virtual ~Asteroids() {}
+
+            virtual void tick(float dt);
+
+            virtual void start();
+            virtual void end();
+
+            inline void firstCheckpointReached(bool reached)
+                { this->firstCheckpointReached_ = reached; }
+
+        protected:
+            virtual void pawnKilled(Pawn* victim, Pawn* killer = 0);
+
+        private:
+            bool firstCheckpointReached_;
+            bool gameEnded_;
+    };
+}
+
+#endif /* _Asteroids_H__ */
Index: /code/branches/rocket2/src/orxonox/gametypes/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,8 @@
+ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+  Gametype.cc
+  Deathmatch.cc
+  TeamDeathmatch.cc
+  TeamBaseMatch.cc
+  UnderAttack.cc
+  Asteroids.cc
+)
Index: /code/branches/rocket2/src/orxonox/gametypes/Deathmatch.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/Deathmatch.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/Deathmatch.cc	(revision 6952)
@@ -0,0 +1,133 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Deathmatch.h"
+
+#include "core/CoreIncludes.h"
+#include "network/Host.h"
+#include "infos/PlayerInfo.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(Deathmatch);
+
+    Deathmatch::Deathmatch(BaseObject* creator) : Gametype(creator)
+    {
+        RegisterObject(Deathmatch);
+    }
+
+    void Deathmatch::start()
+    {
+        Gametype::start();
+
+        std::string message("The match has started!");
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+    }
+
+    void Deathmatch::end()
+    {
+        Gametype::end();
+
+        std::string message("The match has ended.");
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+    }
+
+    void Deathmatch::playerEntered(PlayerInfo* player)
+    {
+        Gametype::playerEntered(player);
+
+        const std::string& message = player->getName() + " entered the game";
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+    }
+
+    bool Deathmatch::playerLeft(PlayerInfo* player)
+    {
+        bool valid_player = Gametype::playerLeft(player);
+
+        if (valid_player)
+        {
+            const std::string& message = player->getName() + " left the game";
+            COUT(0) << message << std::endl;
+            Host::Broadcast(message);
+        }
+
+        return valid_player;
+    }
+
+    bool Deathmatch::playerChangedName(PlayerInfo* player)
+    {
+        bool valid_player = Gametype::playerChangedName(player);
+
+        if (valid_player)
+        {
+            const std::string& message = player->getOldName() + " changed name to " + player->getName();
+            COUT(0) << message << std::endl;
+            Host::Broadcast(message);
+        }
+
+        return valid_player;
+    }
+
+    void Deathmatch::pawnKilled(Pawn* victim, Pawn* killer)
+    {
+        if (victim && victim->getPlayer())
+        {
+            std::string message;
+            if (killer)
+            {
+                if (killer->getPlayer())
+                    message = victim->getPlayer()->getName() + " was killed by " + killer->getPlayer()->getName();
+                else
+                    message = victim->getPlayer()->getName() + " was killed";
+            }
+            else
+                message = victim->getPlayer()->getName() + " died";
+
+            COUT(0) << message << std::endl;
+            Host::Broadcast(message);
+        }
+
+        Gametype::pawnKilled(victim, killer);
+    }
+
+    void Deathmatch::playerScored(PlayerInfo* player)
+    {
+        Gametype::playerScored(player);
+
+        if (player)
+        {
+            const std::string& message = player->getName() + " scores!";
+            COUT(0) << message << std::endl;
+            Host::Broadcast(message);
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/gametypes/Deathmatch.h
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/Deathmatch.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/Deathmatch.h	(revision 6952)
@@ -0,0 +1,54 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Deathmatch_H__
+#define _Deathmatch_H__
+
+#include "OrxonoxPrereqs.h"
+#include "Gametype.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Deathmatch : public Gametype
+    {
+        public:
+            Deathmatch(BaseObject* creator);
+            virtual ~Deathmatch() {}
+
+            virtual void start();
+            virtual void end();
+            virtual void playerEntered(PlayerInfo* player);
+            virtual bool playerLeft(PlayerInfo* player);
+            virtual bool playerChangedName(PlayerInfo* player);
+
+            virtual void pawnKilled(Pawn* victim, Pawn* killer = 0);
+            virtual void playerScored(PlayerInfo* player);
+    };
+}
+
+#endif /* _Deathmatch_H__ */
Index: /code/branches/rocket2/src/orxonox/gametypes/Gametype.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/Gametype.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/Gametype.cc	(revision 6952)
@@ -0,0 +1,477 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Gametype.h"
+
+#include "util/Math.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/GameMode.h"
+#include "core/ConsoleCommand.h"
+
+#include "infos/PlayerInfo.h"
+#include "infos/Bot.h"
+#include "graphics/Camera.h"
+#include "worldentities/ControllableEntity.h"
+#include "worldentities/SpawnPoint.h"
+#include "worldentities/pawns/Spectator.h"
+#include "worldentities/pawns/Pawn.h"
+#include "overlays/OverlayGroup.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(Gametype);
+
+    Gametype::Gametype(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(Gametype);
+
+        this->gtinfo_ = new GametypeInfo(creator);
+
+        this->setGametype(SmartPtr<Gametype>(this, false));
+
+        this->defaultControllableEntity_ = Class(Spectator);
+
+        this->bAutoStart_ = false;
+        this->bForceSpawn_ = false;
+        this->numberOfBots_ = 0;
+
+        this->timeLimit_ = 0;
+        this->time_ = 0;
+        this->timerIsActive_ = false;
+
+        this->initialStartCountdown_ = 3;
+
+        this->setConfigValues();
+
+        // load the corresponding score board
+        if (GameMode::showsGraphics() && !this->scoreboardTemplate_.empty())
+        {
+            this->scoreboard_ = new OverlayGroup(this);
+            this->scoreboard_->addTemplate(this->scoreboardTemplate_);
+            this->scoreboard_->setGametype(this);
+        }
+        else
+            this->scoreboard_ = 0;
+
+        /* HACK HACK HACK */
+        this->hackAddBots_ = createConsoleCommand( createFunctor(&Gametype::addBots, this), "hackAddBots");
+        this->hackKillBots_ = createConsoleCommand( createFunctor(&Gametype::killBots, this), "hackKillBots");
+        CommandExecutor::addConsoleCommandShortcut( this->hackAddBots_ );
+        CommandExecutor::addConsoleCommandShortcut( this->hackKillBots_ );
+        /* HACK HACK HACK */
+    }
+
+    Gametype::~Gametype()
+    {
+        if (this->isInitialized())
+        {
+            this->gtinfo_->destroy();
+            if( this->hackAddBots_ )
+                delete this->hackAddBots_;
+            if( this->hackKillBots_ )
+                delete this->hackKillBots_;
+        }
+    }
+
+    void Gametype::setConfigValues()
+    {
+        SetConfigValue(initialStartCountdown_, 3.0f);
+        SetConfigValue(bAutoStart_, false);
+        SetConfigValue(bForceSpawn_, false);
+        SetConfigValue(numberOfBots_, 0);
+        SetConfigValue(scoreboardTemplate_, "defaultScoreboard");
+    }
+
+    void Gametype::tick(float dt)
+    {
+        SUPER(Gametype, tick, dt);
+
+        //count timer
+        if (timerIsActive_)
+        {
+            if (this->timeLimit_ == 0)
+                this->time_ += dt;
+            else
+                this->time_ -= dt;
+        }
+
+        if (this->gtinfo_->bStartCountdownRunning_ && !this->gtinfo_->bStarted_)
+            this->gtinfo_->startCountdown_ -= dt;
+
+        if (!this->gtinfo_->bStarted_)
+            this->checkStart();
+        else if (!this->gtinfo_->bEnded_)
+            this->spawnDeadPlayersIfRequested();
+
+        this->assignDefaultPawnsIfNeeded();
+    }
+
+    void Gametype::start()
+    {
+        this->addBots(this->numberOfBots_);
+
+        this->gtinfo_->bStarted_ = true;
+
+        this->spawnPlayersIfRequested();
+    }
+
+    void Gametype::end()
+    {
+        this->gtinfo_->bEnded_ = true;
+
+        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
+        {
+            if (it->first->getControllableEntity())
+            {
+                ControllableEntity* oldentity = it->first->getControllableEntity();
+
+                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(oldentity);
+                if (oldentity->getCamera())
+                {
+                    entity->setPosition(oldentity->getCamera()->getWorldPosition());
+                    entity->setOrientation(oldentity->getCamera()->getWorldOrientation());
+                }
+                else
+                {
+                    entity->setPosition(oldentity->getWorldPosition());
+                    entity->setOrientation(oldentity->getWorldOrientation());
+                }
+
+                it->first->startControl(entity);
+            }
+            else
+                this->spawnPlayerAsDefaultPawn(it->first);
+        }
+    }
+
+    void Gametype::playerEntered(PlayerInfo* player)
+    {
+        this->players_[player].state_ = PlayerState::Joined;
+    }
+
+    bool Gametype::playerLeft(PlayerInfo* player)
+    {
+        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
+        if (it != this->players_.end())
+        {
+            this->players_.erase(it);
+            return true;
+        }
+        return false;
+    }
+
+    void Gametype::playerSwitched(PlayerInfo* player, Gametype* newgametype)
+    {
+    }
+
+    void Gametype::playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype)
+    {
+    }
+
+    bool Gametype::playerChangedName(PlayerInfo* player)
+    {
+        if (this->players_.find(player) != this->players_.end())
+        {
+            if (player->getName() != player->getOldName())
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    void Gametype::pawnPreSpawn(Pawn* pawn)
+    {
+    }
+
+    void Gametype::pawnPostSpawn(Pawn* pawn)
+    {
+    }
+
+    void Gametype::playerPreSpawn(PlayerInfo* player)
+    {
+    }
+
+    void Gametype::playerPostSpawn(PlayerInfo* player)
+    {
+    }
+
+    void Gametype::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
+    {
+    }
+
+    void Gametype::playerStopsControllingPawn(PlayerInfo* player, Pawn* pawn)
+    {
+    }
+
+    bool Gametype::allowPawnHit(Pawn* victim, Pawn* originator)
+    {
+        return true;
+    }
+
+    bool Gametype::allowPawnDamage(Pawn* victim, Pawn* originator)
+    {
+        return true;
+    }
+
+    bool Gametype::allowPawnDeath(Pawn* victim, Pawn* originator)
+    {
+        return true;
+    }
+
+    void Gametype::pawnKilled(Pawn* victim, Pawn* killer)
+    {
+        if (victim && victim->getPlayer())
+        {
+            std::map<PlayerInfo*, Player>::iterator it = this->players_.find(victim->getPlayer());
+            if (it != this->players_.end())
+            {
+                it->second.state_ = PlayerState::Dead;
+                it->second.killed_++;
+
+                // Reward killer
+                if (killer && killer->getPlayer())
+                {
+                    std::map<PlayerInfo*, Player>::iterator it = this->players_.find(killer->getPlayer());
+                    if (it != this->players_.end())
+                    {
+                        it->second.frags_++;
+
+                        if (killer->getPlayer()->getClientID() != CLIENTID_UNKNOWN)
+                            this->gtinfo_->sendKillMessage("You killed " + victim->getPlayer()->getName(), killer->getPlayer()->getClientID());
+                        if (victim->getPlayer()->getClientID() != CLIENTID_UNKNOWN)
+                            this->gtinfo_->sendDeathMessage("You were killed by " + killer->getPlayer()->getName(), victim->getPlayer()->getClientID());
+                    }
+                }
+
+                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(victim->getCreator());
+                if (victim->getCamera())
+                {
+                    entity->setPosition(victim->getCamera()->getWorldPosition());
+                    entity->setOrientation(victim->getCamera()->getWorldOrientation());
+                }
+                else
+                {
+                    entity->setPosition(victim->getWorldPosition());
+                    entity->setOrientation(victim->getWorldOrientation());
+                }
+                it->first->startControl(entity);
+            }
+            else
+                COUT(2) << "Warning: Killed Pawn was not in the playerlist" << std::endl;
+        }
+    }
+
+    void Gametype::playerScored(PlayerInfo* player)
+    {
+        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
+        if (it != this->players_.end())
+            it->second.frags_++;
+    }
+
+    int Gametype::getScore(PlayerInfo* player) const
+    {
+        std::map<PlayerInfo*, Player>::const_iterator it = this->players_.find(player);
+        if (it != this->players_.end())
+            return it->second.frags_;
+        else
+            return 0;
+    }
+
+    SpawnPoint* Gametype::getBestSpawnPoint(PlayerInfo* player) const
+    {
+        if (this->spawnpoints_.size() > 0)
+        {
+            unsigned int randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(this->spawnpoints_.size())));
+            unsigned int index = 0;
+            for (std::set<SpawnPoint*>::const_iterator it = this->spawnpoints_.begin(); it != this->spawnpoints_.end(); ++it)
+            {
+                if (index == randomspawn)
+                    return (*it);
+
+                ++index;
+            }
+        }
+        return 0;
+    }
+
+    void Gametype::assignDefaultPawnsIfNeeded()
+    {
+        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
+        {
+            if (!it->first->getControllableEntity())
+            {
+                it->second.state_ = PlayerState::Dead;
+
+                if (!it->first->isReadyToSpawn() || !this->gtinfo_->bStarted_)
+                {
+                    this->spawnPlayerAsDefaultPawn(it->first);
+                    it->second.state_ = PlayerState::Dead;
+                }
+            }
+        }
+    }
+
+    void Gametype::checkStart()
+    {
+        if (!this->gtinfo_->bStarted_)
+        {
+            if (this->gtinfo_->bStartCountdownRunning_)
+            {
+                if (this->gtinfo_->startCountdown_ <= 0)
+                {
+                    this->gtinfo_->bStartCountdownRunning_ = false;
+                    this->gtinfo_->startCountdown_ = 0;
+                    this->start();
+                }
+            }
+            else if (this->players_.size() > 0)
+            {
+                if (this->bAutoStart_)
+                {
+                    this->start();
+                }
+                else
+                {
+                    bool allplayersready = true;
+                    bool hashumanplayers = false;
+                    for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
+                    {
+                        if (!it->first->isReadyToSpawn())
+                            allplayersready = false;
+                        if (it->first->isHumanPlayer())
+                            hashumanplayers = true;
+                    }
+                    if (allplayersready && hashumanplayers)
+                    {
+                        this->gtinfo_->startCountdown_ = this->initialStartCountdown_;
+                        this->gtinfo_->bStartCountdownRunning_ = true;
+                    }
+                }
+            }
+        }
+    }
+
+    void Gametype::spawnPlayersIfRequested()
+    {
+        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
+            if (it->first->isReadyToSpawn() || this->bForceSpawn_)
+                this->spawnPlayer(it->first);
+    }
+
+    void Gametype::spawnDeadPlayersIfRequested()
+    {
+        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
+            if (it->second.state_ == PlayerState::Dead)
+                if (it->first->isReadyToSpawn() || this->bForceSpawn_)
+                    this->spawnPlayer(it->first);
+    }
+
+    void Gametype::spawnPlayer(PlayerInfo* player)
+    {
+        SpawnPoint* spawnpoint = this->getBestSpawnPoint(player);
+        if (spawnpoint)
+        {
+            this->playerPreSpawn(player);
+            player->startControl(spawnpoint->spawn());
+            this->players_[player].state_ = PlayerState::Alive;
+            this->playerPostSpawn(player);
+        }
+        else
+        {
+            COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
+            abort();
+        }
+    }
+
+    void Gametype::spawnPlayerAsDefaultPawn(PlayerInfo* player)
+    {
+        SpawnPoint* spawn = this->getBestSpawnPoint(player);
+        if (spawn)
+        {
+            // force spawn at spawnpoint with default pawn
+            ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
+            spawn->spawn(entity);
+            player->startControl(entity);
+        }
+        else
+        {
+            COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
+            abort();
+        }
+    }
+
+    void Gametype::addBots(unsigned int amount)
+    {
+        for (unsigned int i = 0; i < amount; ++i)
+            this->botclass_.fabricate(this);
+    }
+
+    void Gametype::killBots(unsigned int amount)
+    {
+        unsigned int i = 0;
+        for (ObjectList<Bot>::iterator it = ObjectList<Bot>::begin(); (it != ObjectList<Bot>::end()) && ((amount == 0) || (i < amount)); )
+        {
+            if (it->getGametype() == this)
+            {
+                (it++)->destroy();
+                ++i;
+            }
+            else
+                ++it;
+        }
+    }
+
+    void Gametype::addTime(float t)
+    {
+        if (this->timeLimit_ == 0)
+          this->time_ -= t;
+        else
+          this->time_ += t;
+    }
+
+    void Gametype::removeTime(float t)
+    {
+        if (this->timeLimit_ == 0)
+          this->time_ += t;
+        else
+          this->time_ -= t;
+    }
+
+    void Gametype::resetTimer()
+    {
+        this->resetTimer(timeLimit_);
+    }
+
+    void Gametype::resetTimer(float t)
+    {
+        this->timeLimit_ = t;
+        this->time_ = t;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/gametypes/Gametype.h
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/Gametype.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/Gametype.h	(revision 6952)
@@ -0,0 +1,194 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Gametype_H__
+#define _Gametype_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "core/BaseObject.h"
+#include "core/SubclassIdentifier.h"
+#include "tools/interfaces/Tickable.h"
+#include "infos/GametypeInfo.h"
+
+namespace orxonox
+{
+    namespace PlayerState
+    {
+        enum Value
+        {
+            Uninitialized,
+            Joined,
+            Alive,
+            Dead
+        };
+    }
+
+    struct Player
+    {
+        PlayerInfo* info_;
+        PlayerState::Value state_;
+        int frags_;
+        int killed_;
+    };
+
+    class _OrxonoxExport Gametype : public BaseObject, public Tickable
+    {
+        friend class PlayerInfo;
+
+        public:
+            Gametype(BaseObject* creator);
+            virtual ~Gametype();
+
+            void setConfigValues();
+
+            virtual void tick(float dt);
+
+            inline const GametypeInfo* getGametypeInfo() const
+                { return this->gtinfo_; }
+
+            inline bool hasStarted() const
+                { return this->gtinfo_->bStarted_; }
+            inline bool hasEnded() const
+                { return this->gtinfo_->bEnded_; }
+
+            virtual void start();
+            virtual void end();
+            virtual void playerEntered(PlayerInfo* player);
+            virtual bool playerLeft(PlayerInfo* player);
+            virtual void playerSwitched(PlayerInfo* player, Gametype* newgametype);
+            virtual void playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype);
+            virtual bool playerChangedName(PlayerInfo* player);
+
+            virtual void playerScored(PlayerInfo* player);
+
+            virtual bool allowPawnHit(Pawn* victim, Pawn* originator = 0);
+            virtual bool allowPawnDamage(Pawn* victim, Pawn* originator = 0);
+            virtual bool allowPawnDeath(Pawn* victim, Pawn* originator = 0);
+
+            virtual void pawnKilled(Pawn* victim, Pawn* killer = 0);
+            virtual void pawnPreSpawn(Pawn* pawn);
+            virtual void pawnPostSpawn(Pawn* pawn);
+            virtual void playerPreSpawn(PlayerInfo* player);
+            virtual void playerPostSpawn(PlayerInfo* player);
+
+            virtual void playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn);
+            virtual void playerStopsControllingPawn(PlayerInfo* player, Pawn* pawn);
+
+            inline const std::map<PlayerInfo*, Player>& getPlayers() const
+                { return this->players_; }
+
+            int getScore(PlayerInfo* player) const;
+
+            inline void registerSpawnPoint(SpawnPoint* spawnpoint)
+                { this->spawnpoints_.insert(spawnpoint); }
+
+            inline bool isStartCountdownRunning() const
+                { return this->gtinfo_->bStartCountdownRunning_; }
+            inline float getStartCountdown() const
+                { return this->gtinfo_->startCountdown_; }
+
+            inline void setHUDTemplate(const std::string& name)
+                { this->gtinfo_->hudtemplate_ = name; }
+            inline const std::string& getHUDTemplate() const
+                { return this->gtinfo_->hudtemplate_; }
+
+            void addBots(unsigned int amount);
+            void killBots(unsigned int amount = 0);
+
+            inline unsigned int getNumberOfPlayers() const
+                { return this->players_.size(); }
+
+            virtual void addTime(float t);
+            virtual void removeTime(float t);
+
+            inline  void startTimer()
+            {
+                this->time_ = this->timeLimit_;
+                this->timerIsActive_ = true;
+            }
+
+            inline void stopTimer()
+              { this->timerIsActive_ = false; }
+
+            inline float getTime()
+              { return this->time_; }
+
+            inline bool getTimerIsActive()
+              { return timerIsActive_; }
+
+            inline void setTimeLimit(float t)
+              { this->timeLimit_ = t; }
+
+            virtual void resetTimer();
+            virtual void resetTimer(float t);
+
+        protected:
+            virtual SpawnPoint* getBestSpawnPoint(PlayerInfo* player) const;
+
+            virtual void assignDefaultPawnsIfNeeded();
+            virtual void checkStart();
+            virtual void spawnPlayer(PlayerInfo* player);
+            virtual void spawnPlayerAsDefaultPawn(PlayerInfo* player);
+            virtual void spawnPlayersIfRequested();
+            virtual void spawnDeadPlayersIfRequested();
+
+            SmartPtr<GametypeInfo> gtinfo_;
+
+            bool bAutoStart_;
+            bool bForceSpawn_;
+
+            float time_;
+            float timeLimit_;
+            bool timerIsActive_;
+
+            float initialStartCountdown_;
+            unsigned int numberOfBots_;
+            SubclassIdentifier<Bot> botclass_;
+
+            std::map<PlayerInfo*, Player> players_;
+            std::set<SpawnPoint*> spawnpoints_;
+            SubclassIdentifier<ControllableEntity> defaultControllableEntity_;
+
+            OverlayGroup* scoreboard_;
+
+            // Config Values
+            std::string scoreboardTemplate_;
+
+            /* HACK HACK HACK */
+            ConsoleCommand* hackAddBots_;
+            ConsoleCommand* hackKillBots_;
+            /* HACK HACK HACK */
+    };
+}
+
+#endif /* _Gametype_H__ */
Index: /code/branches/rocket2/src/orxonox/gametypes/TeamBaseMatch.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/TeamBaseMatch.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/TeamBaseMatch.cc	(revision 6952)
@@ -0,0 +1,272 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Val Mikos
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "TeamBaseMatch.h"
+
+#include "core/CoreIncludes.h"
+#include "core/Executor.h"
+#include "worldentities/pawns/TeamBaseMatchBase.h"
+#include "infos/PlayerInfo.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(TeamBaseMatch);
+
+    TeamBaseMatch::TeamBaseMatch(BaseObject* creator) : TeamDeathmatch(creator)
+    {
+        RegisterObject(TeamBaseMatch);
+
+        this->scoreTimer_.setTimer(10, true, createExecutor(createFunctor(&TeamBaseMatch::winPoints, this)));
+        this->outputTimer_.setTimer(10, true, createExecutor(createFunctor(&TeamBaseMatch::showPoints, this)));
+
+        this->pointsTeam1_ = 0;
+        this->pointsTeam2_ = 0;
+
+        this->setHUDTemplate("TeamBaseMatchHUD");
+    }
+
+    // Change the control of the defeated base and respawn it with its initial health
+    bool TeamBaseMatch::allowPawnDeath(Pawn* victim, Pawn* originator)
+    {
+        TeamBaseMatchBase* base = orxonox_cast<TeamBaseMatchBase*>(victim);
+        if (base)
+        {
+            if (!originator)
+                return false;
+
+            std::set<TeamBaseMatchBase*>::const_iterator it = this->bases_.find(base);
+            if (it != this->bases_.end())
+            {
+                int teamnr = this->getTeam(originator->getPlayer());
+                if (teamnr == 0)
+                {
+                    base->setState(BaseState::ControlTeam1);
+                    this->gtinfo_->sendAnnounceMessage("The red team captured a base");
+                }
+                if (teamnr == 1)
+                {
+                    base->setState(BaseState::ControlTeam2);
+                    this->gtinfo_->sendAnnounceMessage("The blue team captured a base");
+                }
+            }
+
+            victim->setHealth(victim->getInitialHealth());
+            return false;
+        }
+
+        return TeamDeathmatch::allowPawnDeath(victim, originator);
+    }
+
+
+    // if the player is in the same team as the base, he can't make any damage to it
+    bool TeamBaseMatch::allowPawnDamage(Pawn* victim, Pawn* originator)
+    {
+        TeamBaseMatchBase* base = orxonox_cast<TeamBaseMatchBase*>(victim);
+        if (base)
+        {
+            std::set<TeamBaseMatchBase*>::const_iterator it = this->bases_.find(base);
+            if (it != this->bases_.end())
+                return (!this->pawnsAreInTheSameTeam(originator, base));
+        }
+        return TeamDeathmatch::allowPawnDamage(victim, originator);
+    }
+
+    bool TeamBaseMatch::pawnsAreInTheSameTeam(Pawn* pawn1, TeamBaseMatchBase* base)
+    {
+        if (pawn1 && base)
+        {
+            std::map<PlayerInfo*, int>::const_iterator it1 = this->teamnumbers_.find(pawn1->getPlayer());
+            int teamnrbase = -1;
+            int teamnrplayer = this->getTeam(pawn1->getPlayer());
+
+            switch (base->getState())
+            {
+                case BaseState::ControlTeam1:
+                    teamnrbase = 0;
+                    break;
+                case BaseState::ControlTeam2:
+                    teamnrbase = 1;
+                    break;
+                case BaseState::Uncontrolled:
+                default:
+                    teamnrbase = -1;
+            }
+
+            if (teamnrbase == teamnrplayer)
+                return true;
+        }
+        return false;
+    }
+
+
+
+
+
+    // collect Points for killing oppenents
+    void TeamBaseMatch::playerScored(PlayerInfo* player)
+    {
+        int teamnr = this->getTeam(player);
+        this->addTeamPoints(teamnr, 5);
+    }
+
+    // show points or each interval of time
+    void TeamBaseMatch::showPoints()
+    {
+        if (!this->hasStarted() || this->hasEnded())
+            return;
+
+        COUT(0) << "Points standing:" << std::endl << "Team 1: "<< pointsTeam1_ << std::endl << "Team 2: " << pointsTeam2_ << std::endl;
+        if(pointsTeam1_ >=1700 && pointsTeam1_ < 2000) COUT(0) << "Team 1 is near victory!" << std::endl;
+        if(pointsTeam2_ >=1700 && pointsTeam2_ < 2000) COUT(0) << "Team 2 is near victory!" << std::endl;
+    }
+
+
+    // collect Points while controlling Bases
+    void TeamBaseMatch::winPoints()
+    {
+        int amountControlled = 0;
+        int amountControlled2 = 0;
+
+        for (std::set<TeamBaseMatchBase*>::const_iterator it = this->bases_.begin(); it != this->bases_.end(); ++it)
+        {
+            if((*it)->getState() == BaseState::ControlTeam1)
+            {
+                amountControlled++;
+            }
+            if((*it)->getState() == BaseState::ControlTeam2)
+            {
+                amountControlled2++;
+            }
+        }
+
+        this->addTeamPoints(0, (amountControlled * 30));
+        this->addTeamPoints(1, (amountControlled2 * 30));
+    }
+
+
+    // end game if one team reaches 2000 points
+    void TeamBaseMatch::endGame()
+    {
+        if (this->pointsTeam1_ >= 2000 || this->pointsTeam2_ >= 2000)
+        {
+            int winningteam = -1;
+
+            if (this->pointsTeam1_ > this->pointsTeam2_)
+            {
+                COUT(0) << "Team 1 has won the match" << std::endl;
+                winningteam = 0;
+            }
+            else
+            {
+                COUT(0) << "Team 2 has won the match" << std::endl;
+                winningteam = 1;
+            }
+
+            for (std::map<PlayerInfo*, int>::iterator it = this->teamnumbers_.begin(); it != this->teamnumbers_.end(); ++it)
+            {
+                if (it->first->getClientID() == CLIENTID_UNKNOWN)
+                    continue;
+
+                if (it->second == winningteam)
+                    this->gtinfo_->sendAnnounceMessage("You have won the match!", it->first->getClientID());
+                else
+                    this->gtinfo_->sendAnnounceMessage("You have lost the match!", it->first->getClientID());
+            }
+
+            this->end();
+            this->scoreTimer_.stopTimer();
+            this->outputTimer_.stopTimer();
+        }
+    }
+
+
+    // this function is called by the function winPoints() which adds points to the teams for every base and killed openents at a certain time
+    void TeamBaseMatch::addTeamPoints(int team, int points)
+    {
+        if(team == 0)
+        {
+            this->pointsTeam1_ += points;
+        }
+        if(team == 1)
+        {
+            this->pointsTeam2_ += points;
+        }
+
+        this->endGame();
+    }
+
+    int TeamBaseMatch::getTeamPoints(int team)
+    {
+        if(team == 0)
+        {
+            return this->pointsTeam1_;
+        }
+        if(team == 1)
+        {
+            return this->pointsTeam2_;
+        }
+
+        return 0;
+    }
+
+    int TeamBaseMatch::getTeamBases(int team)
+    {
+        int count = 0;
+
+        for (std::set<TeamBaseMatchBase*>::const_iterator it = this->bases_.begin(); it != this->bases_.end(); ++it)
+        {
+            if ((*it)->getState() == BaseState::ControlTeam1 && team == 0)
+                count++;
+            if ((*it)->getState() == BaseState::ControlTeam2 && team == 1)
+                count++;
+        }
+
+        return count;
+    }
+
+    void TeamBaseMatch::addBase(TeamBaseMatchBase* base)
+    {
+        this->bases_.insert(base);
+        base->setState(BaseState::Uncontrolled);
+    }
+
+    TeamBaseMatchBase* TeamBaseMatch::getBase(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::set<TeamBaseMatchBase*>::const_iterator it = this->bases_.begin(); it != this->bases_.end(); ++it)
+        {
+            i++;
+            if (i > index)
+                return (*it);
+        }
+        return 0;
+    }
+
+}
+
+
Index: /code/branches/rocket2/src/orxonox/gametypes/TeamBaseMatch.h
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/TeamBaseMatch.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/TeamBaseMatch.h	(revision 6952)
@@ -0,0 +1,76 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Val Mikos
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TeamBaseMatch_H__
+#define _TeamBaseMatch_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <set>
+#include "tools/Timer.h"
+#include "TeamDeathmatch.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport TeamBaseMatch : public TeamDeathmatch
+    {
+        public:
+            TeamBaseMatch(BaseObject* creator);
+            virtual ~TeamBaseMatch() {}
+
+            virtual bool allowPawnDeath(Pawn* victim, Pawn* originator = 0);
+            virtual bool allowPawnDamage(Pawn* victim, Pawn* originator);
+
+            virtual void playerScored(PlayerInfo* player);
+            virtual void showPoints();
+            virtual void endGame();
+
+            void addBase(TeamBaseMatchBase* base);
+            TeamBaseMatchBase* getBase(unsigned int index) const;
+
+            void addTeamPoints(int team, int points);
+            int getTeamPoints(int team);
+            int getTeamBases(int team);
+
+        protected:
+            void winPoints();
+
+            bool pawnsAreInTheSameTeam(Pawn* pawn1, TeamBaseMatchBase* base);
+            using TeamDeathmatch::pawnsAreInTheSameTeam;
+
+            std::set<TeamBaseMatchBase*> bases_;
+            Timer scoreTimer_;
+            Timer outputTimer_;
+
+            //points for each team
+            int pointsTeam1_;
+            int pointsTeam2_;
+    };
+}
+
+#endif /* _TeamBaseMatch_H__ */
Index: /code/branches/rocket2/src/orxonox/gametypes/TeamDeathmatch.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/TeamDeathmatch.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/TeamDeathmatch.cc	(revision 6952)
@@ -0,0 +1,235 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "TeamDeathmatch.h"
+
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "interfaces/TeamColourable.h"
+#include "worldentities/TeamSpawnPoint.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(TeamDeathmatch);
+
+    TeamDeathmatch::TeamDeathmatch(BaseObject* creator) : Deathmatch(creator)
+    {
+        RegisterObject(TeamDeathmatch);
+
+        this->teams_ = 2;
+
+        this->setConfigValues();
+    }
+
+    void TeamDeathmatch::setConfigValues()
+    {
+        SetConfigValue(teams_, 2);
+
+        static ColourValue colours[] =
+        {
+            ColourValue(1.0f, 0.3f, 0.3f),
+            ColourValue(0.3f, 0.3f, 1.0f),
+            ColourValue(0.3f, 1.0f, 0.3f),
+            ColourValue(1.0f, 1.0f, 0.0f)
+        };
+        static std::vector<ColourValue> defaultcolours(colours, colours + sizeof(colours) / sizeof(ColourValue));
+
+        SetConfigValue(teamcolours_, defaultcolours);
+    }
+
+    void TeamDeathmatch::playerEntered(PlayerInfo* player)
+    {
+        Deathmatch::playerEntered(player);
+
+        std::vector<unsigned int> playersperteam(this->teams_, 0);
+
+        for (std::map<PlayerInfo*, int>::iterator it = this->teamnumbers_.begin(); it != this->teamnumbers_.end(); ++it)
+            if (it->second < static_cast<int>(this->teams_) && it->second >= 0)
+                playersperteam[it->second]++;
+
+        unsigned int minplayers = static_cast<unsigned int>(-1);
+        size_t minplayersteam = 0;
+        for (size_t i = 0; i < this->teams_; ++i)
+        {
+            if (playersperteam[i] < minplayers)
+            {
+                minplayers = playersperteam[i];
+                minplayersteam = i;
+            }
+        }
+
+        this->teamnumbers_[player] = minplayersteam;
+    }
+
+    bool TeamDeathmatch::playerLeft(PlayerInfo* player)
+    {
+        bool valid_player = Deathmatch::playerLeft(player);
+
+        if (valid_player)
+            this->teamnumbers_.erase(player);
+
+        return valid_player;
+    }
+
+    bool TeamDeathmatch::allowPawnHit(Pawn* victim, Pawn* originator)
+    {
+        return (!this->pawnsAreInTheSameTeam(victim, originator) || !originator);
+    }
+
+    bool TeamDeathmatch::allowPawnDamage(Pawn* victim, Pawn* originator)
+    {
+        return (!this->pawnsAreInTheSameTeam(victim, originator) || !originator);
+    }
+
+    bool TeamDeathmatch::allowPawnDeath(Pawn* victim, Pawn* originator)
+    {
+        return (!this->pawnsAreInTheSameTeam(victim, originator) || !originator);
+    }
+
+    SpawnPoint* TeamDeathmatch::getBestSpawnPoint(PlayerInfo* player) const
+    {
+        int desiredTeamNr = -1;
+        std::map<PlayerInfo*, int>::const_iterator it_player = this->teamnumbers_.find(player);
+        if (it_player != this->teamnumbers_.end())
+            desiredTeamNr = it_player->second;
+
+        // Only use spawnpoints of the own team (or non-team-spawnpoints)
+        std::set<SpawnPoint*> teamSpawnPoints = this->spawnpoints_;
+        for (std::set<SpawnPoint*>::iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); )
+        {
+            if ((*it)->isA(Class(TeamSpawnPoint)))
+            {
+                TeamSpawnPoint* tsp = orxonox_cast<TeamSpawnPoint*>(*it);
+                if (tsp && static_cast<int>(tsp->getTeamNumber()) != desiredTeamNr)
+                {
+                    teamSpawnPoints.erase(it++);
+                    continue;
+                }
+            }
+
+            ++it;
+        }
+
+        SpawnPoint* fallbackSpawnPoint = NULL;
+        if (teamSpawnPoints.size() > 0)
+        {
+            unsigned int randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(teamSpawnPoints.size())));
+            unsigned int index = 0;
+            // Get random fallback spawnpoint in case there is no active SpawnPoint.
+            for (std::set<SpawnPoint*>::const_iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); ++it)
+            {
+                if (index == randomspawn)
+                {
+                    fallbackSpawnPoint = (*it);
+                    break;
+                }
+
+                ++index;
+            }
+
+            // Remove all inactive SpawnPoints from the list.
+            for (std::set<SpawnPoint*>::const_iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); )
+            {
+                if(!(*it)->isActive())
+                {
+                    COUT(1) << (*it)->getName() << " is inactive." << std::endl;
+                    teamSpawnPoints.erase(it++);
+                    continue;
+                }
+                COUT(1) << (*it)->getName() << " is active." << std::endl;
+
+                ++it;
+            }
+
+            COUT(1) << "MUP " << teamSpawnPoints.size() << std::endl;
+
+            randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(teamSpawnPoints.size())));
+            index = 0;
+            for (std::set<SpawnPoint*>::const_iterator it = teamSpawnPoints.begin(); it != teamSpawnPoints.end(); ++it)
+            {
+                if (index == randomspawn)
+                    return (*it);
+
+                ++index;
+            }
+
+            return fallbackSpawnPoint;
+        }
+
+        return 0;
+    }
+
+    void TeamDeathmatch::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
+    {
+        if (!player)
+            return;
+
+        // Set the team colour
+        std::map<PlayerInfo*, int>::const_iterator it_player = this->teamnumbers_.find(player);
+        if (it_player != this->teamnumbers_.end() && it_player->second >= 0 && it_player->second < static_cast<int>(this->teamcolours_.size()))
+        {
+            if (pawn)
+            {
+                pawn->setRadarObjectColour(this->teamcolours_[it_player->second]);
+
+                std::set<WorldEntity*> pawnAttachments = pawn->getAttachedObjects();
+                for (std::set<WorldEntity*>::iterator it = pawnAttachments.begin(); it != pawnAttachments.end(); ++it)
+                {
+                    if ((*it)->isA(Class(TeamColourable)))
+                    {
+                        TeamColourable* tc = orxonox_cast<TeamColourable*>(*it);
+                        tc->setTeamColour(this->teamcolours_[it_player->second]);
+                    }
+                }
+            }
+        }
+    }
+
+    bool TeamDeathmatch::pawnsAreInTheSameTeam(Pawn* pawn1, Pawn* pawn2)
+    {
+        if (pawn1 && pawn2)
+        {
+            std::map<PlayerInfo*, int>::const_iterator it1 = this->teamnumbers_.find(pawn1->getPlayer());
+            std::map<PlayerInfo*, int>::const_iterator it2 = this->teamnumbers_.find(pawn2->getPlayer());
+
+            if (it1 != this->teamnumbers_.end() && it2 != this->teamnumbers_.end())
+                return (it1->second == it2->second);
+        }
+        return false;
+    }
+
+    int TeamDeathmatch::getTeam(PlayerInfo* player)
+    {
+        std::map<PlayerInfo*, int>::const_iterator it_player = this->teamnumbers_.find(player);
+        if (it_player != this->teamnumbers_.end())
+            return it_player->second;
+        else
+            return -1;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/gametypes/TeamDeathmatch.h
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/TeamDeathmatch.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/TeamDeathmatch.h	(revision 6952)
@@ -0,0 +1,72 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TeamDeathmatch_H__
+#define _TeamDeathmatch_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <map>
+#include <vector>
+#include "Deathmatch.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport TeamDeathmatch : public Deathmatch
+    {
+        public:
+            TeamDeathmatch(BaseObject* creator);
+            virtual ~TeamDeathmatch() {}
+
+            void setConfigValues();
+
+            virtual void playerEntered(PlayerInfo* player);
+            virtual bool playerLeft(PlayerInfo* player);
+
+            virtual bool allowPawnHit(Pawn* victim, Pawn* originator = 0);
+            virtual bool allowPawnDamage(Pawn* victim, Pawn* originator = 0);
+            virtual bool allowPawnDeath(Pawn* victim, Pawn* originator = 0);
+
+            virtual void playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn);
+
+            int getTeam(PlayerInfo* player);
+
+            inline const ColourValue& getTeamColour(int teamnr) const
+                { return this->teamcolours_[teamnr]; }
+
+        protected:
+            virtual SpawnPoint* getBestSpawnPoint(PlayerInfo* player) const;
+            bool pawnsAreInTheSameTeam(Pawn* pawn1, Pawn* pawn2);
+
+            std::map<PlayerInfo*, int> teamnumbers_;
+            std::vector<ColourValue> teamcolours_;
+            unsigned int teams_;
+    };
+}
+
+#endif /* _TeamDeathmatch_H__ */
Index: /code/branches/rocket2/src/orxonox/gametypes/Testgame.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/Testgame.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/Testgame.cc	(revision 6952)
@@ -0,0 +1,87 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Aurelian Jaggi
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Asteroids.h"
+
+#include "core/CoreIncludes.h"
+#include "network/Host.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(Asteroids);
+
+    Asteroids::Asteroids(BaseObject* creator) : Gametype(creator)
+    {
+        RegisterObject(Asteroids);
+        this->firstCheckpointReached_ = false;
+    }
+
+    void Asteroids::tick(float dt)
+    {
+        SUPER(Asteroids, tick, dt);
+
+        if (firstCheckpointReached_ && !this->timerIsActive_)
+        {
+            this->startTimer();
+        }
+
+        if (this->time_ < 0 && !this->hasEnded() && this->timerIsActive_)
+        {
+            this->gtinfo_->sendAnnounceMessage("Time's up - you have lost the match!");
+            this->end();
+        }
+    }
+
+    void Asteroids::pawnKilled(Pawn* victim, Pawn* killer)
+    {
+        if (victim && victim->getPlayer())
+        {
+            this->gtinfo_->sendAnnounceMessage("You're dead - you have lost the match!");
+            this->end();
+        }
+    }
+
+    void Asteroids::start()
+    {
+        Gametype::start();
+
+        std::string message("The match has started! Reach the first chekpoint within 15 seconds! But be aware, there may be pirates around...");
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+    }
+
+    void Asteroids::end()
+    {
+        Gametype::end();
+
+        std::string message("The match has ended.");
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/gametypes/Testgame.h
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/Testgame.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/Testgame.h	(revision 6952)
@@ -0,0 +1,60 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Aurelian Jaggi
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Asteroids_H__
+#define _Asteroids_H__
+
+#include "OrxonoxPrereqs.h"
+#include "Gametype.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Asteroids : public Gametype
+    {
+        public:
+            Asteroids(BaseObject* creator);
+            virtual ~Asteroids() {}
+
+            virtual void tick(float dt);
+
+            virtual void start();
+            virtual void end();
+
+            inline void firstCheckpointReached(bool reached)
+                { this->firstCheckpointReached_ = reached; }
+
+        protected:
+            virtual void pawnKilled(Pawn* victim, Pawn* killer = 0);
+
+        private:
+            bool firstCheckpointReached_;
+            bool gameEnded_;
+    };
+}
+
+#endif /* _Asteroids_H__ */
Index: /code/branches/rocket2/src/orxonox/gametypes/UnderAttack.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/UnderAttack.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/UnderAttack.cc	(revision 6952)
@@ -0,0 +1,195 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Matthias Mock
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "UnderAttack.h"
+
+#include "util/Convert.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "network/Host.h"
+#include "worldentities/pawns/Destroyer.h"
+#include "infos/PlayerInfo.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(UnderAttack);
+
+    UnderAttack::UnderAttack(BaseObject* creator) : TeamDeathmatch(creator)
+    {
+        RegisterObject(UnderAttack);
+        this->gameTime_ = 180;
+        this->teams_ = 2;
+        this->destroyer_ = 0;
+        this->destroyer_.setCallback(createFunctor(&UnderAttack::killedDestroyer, this));
+        this->gameEnded_ = false;
+
+        this->setHUDTemplate("UnderAttackHUD");
+
+        this->setConfigValues();
+        this->timesequence_ = static_cast<int>(this->gameTime_);
+    }
+
+    void UnderAttack::setConfigValues()
+    {
+        SetConfigValue(gameTime_, 180);
+    }
+
+    void UnderAttack::addDestroyer(Destroyer* destroyer)
+    {
+        this->destroyer_ = destroyer;
+    }
+
+
+    void UnderAttack::killedDestroyer()
+    {
+        this->end(); //end gametype
+        std::string message("Ship destroyed! Team 0 has won!");
+        COUT(0) << message << std::endl;
+        Host::Broadcast(message);
+        this->gameEnded_ = true;
+
+        for (std::map<PlayerInfo*, int>::iterator it = this->teamnumbers_.begin(); it != this->teamnumbers_.end(); ++it)
+        {
+            if (it->first->getClientID() == CLIENTID_UNKNOWN)
+                continue;
+
+            if (it->second == 0)
+                this->gtinfo_->sendAnnounceMessage("You have won the match!", it->first->getClientID());
+            else
+                this->gtinfo_->sendAnnounceMessage("You have lost the match!", it->first->getClientID());
+        }
+    }
+
+    bool UnderAttack::allowPawnHit(Pawn* victim, Pawn* originator)
+    {
+        if (victim == this->destroyer_)
+        {
+            if (originator && originator->getPlayer() && !gameEnded_)
+            {
+                if (this->getTeam(originator->getPlayer()) == 0)
+                    return true;
+                else
+                    return false;
+            }
+
+            return false;
+        }
+
+        return TeamDeathmatch::allowPawnHit(victim, originator);
+    }
+
+    bool UnderAttack::allowPawnDamage(Pawn* victim, Pawn* originator)
+    {
+        if (victim == this->destroyer_)
+        {
+            if (originator && originator->getPlayer() && !gameEnded_)
+            {
+                if (this->getTeam(originator->getPlayer()) == 0)
+                    return true;
+                else
+                    return false;
+            }
+
+            return false;
+        }
+
+        return TeamDeathmatch::allowPawnDamage(victim, originator);
+    }
+
+    bool UnderAttack::allowPawnDeath(Pawn* victim, Pawn* originator)
+    {
+        if (victim == this->destroyer_)
+        {
+            if (originator && originator->getPlayer() && !gameEnded_)
+            {
+                if (this->getTeam(originator->getPlayer()) == 0)
+                    return true;
+                else
+                    return false;
+            }
+
+            return false;
+        }
+
+        return TeamDeathmatch::allowPawnDeath(victim, originator);
+    }
+
+
+    void UnderAttack::tick(float dt)
+    {
+        SUPER(UnderAttack, tick, dt);
+
+        if (this->hasStarted() && !gameEnded_)
+        {
+            gameTime_ = gameTime_ - dt;
+            if (gameTime_<= 0)
+            {
+                this->gameEnded_ = true;
+                this->end();
+                std::string message("Time is up! Team 1 has won!");
+                COUT(0) << message << std::endl;
+                Host::Broadcast(message);
+
+                for (std::map<PlayerInfo*, int>::iterator it = this->teamnumbers_.begin(); it != this->teamnumbers_.end(); ++it)
+                {
+                    if (it->first->getClientID() == CLIENTID_UNKNOWN)
+                        continue;
+
+                    if (it->second == 1)
+                        this->gtinfo_->sendAnnounceMessage("You have won the match!", it->first->getClientID());
+                    else
+                        this->gtinfo_->sendAnnounceMessage("You have lost the match!", it->first->getClientID());
+                }
+            }
+
+             //prints gametime
+            if ( gameTime_ <= timesequence_ && gameTime_ > 0)
+            {
+                const std::string& message = multi_cast<std::string>(timesequence_) + " seconds left!";
+/*
+                COUT(0) << message << std::endl;
+                Host::Broadcast(message);
+*/
+                this->gtinfo_->sendAnnounceMessage(message);
+
+                if (timesequence_ >= 30 && timesequence_ <= 60)
+                {
+                    timesequence_ = timesequence_ - 10;
+                }
+                else if (timesequence_ <= 30)
+                {
+                    timesequence_ = timesequence_ - 5;
+                }
+                else
+                {
+                    timesequence_ = timesequence_ - 30;
+                }
+            }
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/gametypes/UnderAttack.h
===================================================================
--- /code/branches/rocket2/src/orxonox/gametypes/UnderAttack.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/gametypes/UnderAttack.h	(revision 6952)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Matthias Mock
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _UnderAttack_H__
+#define _UnderAttack_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "TeamDeathmatch.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport UnderAttack : public TeamDeathmatch
+    {
+        public:
+            UnderAttack(BaseObject* creator);
+            virtual ~UnderAttack() {}
+
+            void setConfigValues();
+            void tick (float dt);
+            void addDestroyer(Destroyer* destroyer);
+            inline Destroyer* getDestroyer() const
+                { return this->destroyer_; }
+
+            virtual bool allowPawnHit(Pawn* victim, Pawn* originator = 0);
+            virtual bool allowPawnDamage(Pawn* victim, Pawn* originator = 0);
+            virtual bool allowPawnDeath(Pawn* victim, Pawn* originator = 0);
+
+        protected:
+            virtual void killedDestroyer();
+
+            WeakPtr<Destroyer> destroyer_;
+            unsigned int teams_;
+            float gameTime_;
+            int timesequence_;
+            bool gameEnded_;
+    };
+}
+
+#endif /* _TeamDeathmatch_H__ */
Index: /code/branches/rocket2/src/orxonox/graphics/AnimatedModel.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/AnimatedModel.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/AnimatedModel.cc	(revision 6952)
@@ -0,0 +1,126 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin de Capitani
+ *   Co-authors:
+ *      ...
+ *
+ */
+ #include "AnimatedModel.h"
+ #include <OgreEntity.h>
+#include <Ogre.h>
+#include <deque>
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    CreateFactory(AnimatedModel);
+
+    AnimatedModel::AnimatedModel(BaseObject* creator) : Model(creator)
+    {
+        RegisterObject(AnimatedModel);
+    }
+
+
+    AnimatedModel::~AnimatedModel()
+    {
+        if (this->isInitialized() && this->mesh_.getEntity())
+            this->detachOgreObject(this->mesh_.getEntity());
+    }
+
+    void AnimatedModel::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(AnimatedModel, XMLPort, xmlelement, mode);
+        XMLPortParam(AnimatedModel,"anims",setAnims,getAnims, xmlelement,mode).defaultValues("");
+        XMLPortParam(AnimatedModel,"loop", setAnimLoop,getAnimLoop, xmlelement,mode).defaultValues(true);
+        XMLPortParam(AnimatedModel,"enabled", setAnimEnabled,getAnimEnabled, xmlelement,mode).defaultValues(true);
+    }
+
+
+    void AnimatedModel::changedMesh()
+    {
+        if (GameMode::showsGraphics())
+        {
+            if (this->mesh_.getEntity())
+                this->detachOgreObject(this->mesh_.getEntity());
+
+            this->mesh_.setMeshSource(this->getScene()->getSceneManager(), this->meshSrc_);
+
+            if (this->mesh_.getEntity())
+            {
+                this->attachOgreObject(this->mesh_.getEntity());
+                this->mesh_.getEntity()->setCastShadows(this->bCastShadows_);
+                this->setAnimationState(this->bAnimLoop_, this->bAnimEnabled_, this->anims_);
+                this->mesh_.setVisible(this->isVisible());
+            }
+        }
+    }
+
+    void AnimatedModel::changedAnimationState()
+    {
+        this->setAnimationState(this->bAnimLoop_, this->bAnimEnabled_, this->anims_);
+    }
+    void AnimatedModel::setAnimationState(bool loop, bool enabled, const std::string& state)
+    {
+        if(state!="")
+        {
+        if(this->mesh_.getEntity()->getAnimationState(state))
+        {
+        Ogre::AnimationState* as = this->mesh_.getEntity()->getAnimationState(state);
+        as->setLoop(loop);
+        as->setEnabled(enabled);
+        this->anims_ = state;
+        }
+        }
+    }
+
+    void AnimatedModel::setAnimLoop(bool loop)
+    {
+        this->bAnimLoop_ = loop;
+    }
+    void AnimatedModel::setAnimEnabled(bool enabled)
+    {
+        this->bAnimEnabled_ = enabled;
+    }
+    void AnimatedModel::tick(float dt)
+    {
+        if(this->mesh_.getEntity()->getAnimationState(anims_))
+        {
+// Test to change Material at runtime!
+
+//            Ogre::MaterialPtr mat = this->mesh_.getEntity()->getSubEntity(0)->getMaterial();
+//            mat->setDiffuse(0.4, 0.3, 0.1, 0.1);
+//            mat->setAmbient(0.3, 0.7, 0.8);
+//            mat->setSpecular(0.5, 0.5, 0.5, 0.1);
+//            Ogre::SceneBlendType sbt = Ogre::SBT_ADD;
+//
+//            mat->setSceneBlending(sbt);
+
+            Ogre::AnimationState* as = this->mesh_.getEntity()->getAnimationState(anims_);
+            as->addTime(dt);
+    }
+}
+}
Index: /code/branches/rocket2/src/orxonox/graphics/AnimatedModel.h
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/AnimatedModel.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/AnimatedModel.h	(revision 6952)
@@ -0,0 +1,77 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _AnimatedModel_H__
+#define _AnimatedModel_H__
+#include "Model.h"
+#include "tools/interfaces/Tickable.h"
+#include "OrxonoxPrereqs.h"
+#include <deque>
+#include <string>
+#include "tools/Mesh.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport AnimatedModel : public Model, public Tickable
+    {
+        public:
+            AnimatedModel(BaseObject* creator);
+            virtual ~AnimatedModel();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            virtual void changedAnimationState();
+            virtual void setAnimationState(bool loop, bool enabled, const std::string& state);
+            virtual void setAnimEnabled(bool enabled);
+            virtual void setAnimLoop(bool loop);
+            virtual void tick(float dt);
+            virtual void changedMesh();
+
+
+            inline void setAnims(const std::string& anims)
+                { this->anims_ = anims; this->changedAnimationState(); }
+            inline const std::string& getAnims() const
+                { return this->anims_; }
+
+            inline const std::string& getAnimationState() const
+                { return this->anims_; }
+            inline const bool&  getAnimLoop() const
+                { return this->bAnimLoop_; }
+            inline const bool&  getAnimEnabled() const
+                { return this->bAnimEnabled_; }
+
+        private:
+            std::string anims_;
+            bool bAnimEnabled_;
+            bool bAnimLoop_;
+    };
+}
+
+#endif /* _AnimatedModel_H__ */
Index: /code/branches/rocket2/src/orxonox/graphics/Backlight.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/Backlight.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/Backlight.cc	(revision 6952)
@@ -0,0 +1,234 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Backlight.h"
+
+#include <algorithm>
+#include <OgreRibbonTrail.h>
+#include <OgreSceneManager.h>
+#include <OgreSceneNode.h>
+
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    CreateFactory(Backlight);
+
+    Backlight::Backlight(BaseObject* creator) : FadingBillboard(creator)
+    {
+        RegisterObject(Backlight);
+
+        this->ribbonTrail_ = 0;
+        this->ribbonTrailNode_ = 0;
+
+        this->width_ = 0;
+        this->length_ = 1.0f;
+        this->lifetime_ = 0.001f;
+        this->maxelements_ = 1;
+
+        this->tickcount_ = 0;
+
+        if (GameMode::showsGraphics())
+        {
+            if (!this->getScene())
+                ThrowException(AbortLoading, "Can't create Backlight, no scene given.");
+            if (!this->getScene()->getSceneManager())
+                ThrowException(AbortLoading, "Can't create Backlight, no scene manager given.");
+            if (!this->getScene()->getRootSceneNode())
+                ThrowException(AbortLoading, "Can't create Backlight, no root scene node given.");
+
+            this->ribbonTrail_ = this->getScene()->getSceneManager()->createRibbonTrail(this->getNode()->getName());
+
+            this->ribbonTrailNode_ = this->getScene()->getRootSceneNode()->createChildSceneNode();
+            this->ribbonTrailNode_->attachObject(this->ribbonTrail_);
+
+            this->ribbonTrail_->setMaxChainElements(this->maxelements_);
+            this->ribbonTrail_->setTrailLength(this->length_);
+            this->ribbonTrail_->setInitialWidth(0, 0);
+        }
+
+        this->registerVariables();
+    }
+
+    Backlight::~Backlight()
+    {
+        if (this->isInitialized())
+        {
+            if (this->ribbonTrail_)
+            {
+                if (this->ribbonTrailNode_)
+                {
+                    this->ribbonTrailNode_->detachObject(this->ribbonTrail_);
+                    this->getScene()->getSceneManager()->destroySceneNode(this->ribbonTrailNode_->getName());
+                }
+                this->getScene()->getSceneManager()->destroyRibbonTrail(this->ribbonTrail_);
+            }
+        }
+    }
+
+    void Backlight::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Backlight, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Backlight, "length",        setLength,        getLength,        xmlelement, mode).defaultValues(100.0f);
+        XMLPortParam(Backlight, "width",         setWidth,         getWidth,         xmlelement, mode).defaultValues(1.0f);
+        XMLPortParam(Backlight, "elements",      setMaxElements,   getMaxElements,   xmlelement, mode).defaultValues(10);
+        XMLPortParam(Backlight, "lifetime",      setLifetime,      getLifetime,      xmlelement, mode).defaultValues(1.0f);
+        XMLPortParam(Backlight, "trailmaterial", setTrailMaterial, getTrailMaterial, xmlelement, mode);
+    }
+
+    void Backlight::registerVariables()
+    {
+        registerVariable(this->width_,         VariableDirection::ToClient, new NetworkCallback<Backlight>(this, &Backlight::update_width));
+        registerVariable(this->lifetime_,      VariableDirection::ToClient, new NetworkCallback<Backlight>(this, &Backlight::update_lifetime));
+        registerVariable(this->length_,        VariableDirection::ToClient, new NetworkCallback<Backlight>(this, &Backlight::update_length));
+        registerVariable(this->maxelements_,   VariableDirection::ToClient, new NetworkCallback<Backlight>(this, &Backlight::update_maxelements));
+        registerVariable(this->trailmaterial_, VariableDirection::ToClient, new NetworkCallback<Backlight>(this, &Backlight::update_trailmaterial));
+    }
+
+    void Backlight::changedColour()
+    {
+        FadingBillboard::changedColour();
+
+        if (this->ribbonTrail_ && this->tickcount_ >= 2)
+            this->ribbonTrail_->setInitialColour(0, this->getFadedColour());
+    }
+
+    void Backlight::update_width()
+    {
+        if (this->ribbonTrail_ && this->tickcount_ >= 2)
+            this->ribbonTrail_->setInitialWidth(0, this->width_ * this->getWorldScale());
+        this->update_lifetime();
+    }
+
+    void Backlight::update_lifetime()
+    {
+        if (this->ribbonTrail_ && this->tickcount_ >= 2)
+        {
+            this->ribbonTrail_->setWidthChange(0, this->width_ * this->getWorldScale() / this->lifetime_ * this->getTimeFactor());
+            this->ribbonTrail_->setColourChange(0, 0, 0, 0, 1.0f / this->lifetime_ * this->getTimeFactor());
+        }
+    }
+
+    void Backlight::update_length()
+    {
+        if (this->ribbonTrail_ && this->tickcount_ >= 2)
+            this->ribbonTrail_->setTrailLength(this->length_ * this->getWorldScale());
+    }
+
+    void Backlight::update_maxelements()
+    {
+        if (this->ribbonTrail_ && this->tickcount_ >= 2)
+            this->ribbonTrail_->setMaxChainElements(this->maxelements_);
+    }
+
+    void Backlight::update_trailmaterial()
+    {
+        if (this->ribbonTrail_ && this->tickcount_ >= 2)
+            this->ribbonTrail_->setMaterialName(this->trailmaterial_);
+    }
+
+    void Backlight::changedVisibility()
+    {
+        SUPER(Backlight, changedVisibility);
+
+        if (this->ribbonTrail_)
+            this->ribbonTrail_->setVisible(this->isVisible());
+    }
+
+    void Backlight::startturnonoff()
+    {
+        FadingBillboard::startturnonoff();
+
+        if (this->ribbonTrail_ && this->isActive() && this->isVisible())
+            this->ribbonTrail_->setVisible(true);
+    }
+
+    void Backlight::stopturnonoff()
+    {
+        this->postprocessingtime_ = std::max(0.0f, this->lifetime_ - this->turnofftime_);
+
+        FadingBillboard::stopturnonoff();
+
+        if (this->ribbonTrail_)
+            this->ribbonTrail_->setInitialColour(0, this->getFadedColour());
+    }
+
+    void Backlight::poststopturnonoff()
+    {
+        FadingBillboard::poststopturnonoff();
+
+        if (this->ribbonTrail_)
+            this->ribbonTrail_->setVisible(false);
+    }
+
+    void Backlight::changedScale()
+    {
+        SUPER(Backlight, changedScale);
+
+        this->update_width();
+        this->update_length();
+    }
+
+    void Backlight::tick(float dt)
+    {
+        if (this->tickcount_ < 2)
+        {
+            ++this->tickcount_;
+            if (this->tickcount_ == 2)
+            {
+                this->changedColour();
+                this->update_width();
+                this->update_lifetime();
+                this->update_length();
+                this->update_maxelements();
+                this->update_trailmaterial();
+                if (this->ribbonTrail_)
+                    this->ribbonTrail_->addNode(this->node_);
+            }
+        }
+
+        SUPER(Backlight, tick, dt);
+
+        if (this->ribbonTrail_ && this->changedirection_ != 0)
+        {
+            // we use alpha_blend, only adjust alpha
+            const ColourValue& colour = this->getColour();
+            this->ribbonTrail_->setInitialColour(0, colour.r, colour.g, colour.b, this->getFadedColour().a);
+        }
+    }
+
+    void Backlight::changedTimeFactor(float factor_new, float factor_old)
+    {
+        this->update_lifetime();
+    }
+}
Index: /code/branches/rocket2/src/orxonox/graphics/Backlight.h
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/Backlight.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/Backlight.h	(revision 6952)
@@ -0,0 +1,104 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Backlight_H__
+#define _Backlight_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "tools/interfaces/TimeFactorListener.h"
+#include "FadingBillboard.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Backlight : public FadingBillboard, public TimeFactorListener
+    {
+        public:
+            Backlight(BaseObject* creator);
+            virtual ~Backlight();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            virtual void tick(float dt);
+            virtual void changedVisibility();
+
+            inline void setWidth(float width)
+                { this->width_ = width; this->update_width(); }
+            inline float getWidth() const
+                { return this->width_; }
+
+            inline void setLifetime(float lifetime)
+                { this->lifetime_ = lifetime; this->update_lifetime(); }
+            inline float getLifetime() const
+                { return this->lifetime_; }
+
+            inline void setLength(float length)
+                { this->length_ = length; this->update_length(); }
+            inline float getLength() const
+                { return this->length_; }
+
+            inline void setMaxElements(size_t maxelements)
+                { this->maxelements_ = maxelements; this->update_maxelements(); }
+            inline size_t getMaxElements() const
+                { return this->maxelements_; }
+
+            inline void setTrailMaterial(const std::string& material)
+                { this->trailmaterial_ = material; this->update_trailmaterial(); }
+            inline const std::string& getTrailMaterial() const
+                { return this->trailmaterial_; }
+
+            virtual void changedScale();
+
+        protected:
+            virtual void changedTimeFactor(float factor_new, float factor_old);
+
+        private:
+            virtual void startturnonoff();
+            virtual void stopturnonoff();
+            virtual void poststopturnonoff();
+            virtual void changedColour();
+            void update_width();
+            void update_lifetime();
+            void update_length();
+            void update_maxelements();
+            void update_trailmaterial();
+
+            Ogre::RibbonTrail* ribbonTrail_;
+            Ogre::SceneNode* ribbonTrailNode_;
+            float width_;
+            float length_;
+            float lifetime_;
+            size_t maxelements_;
+            std::string trailmaterial_;
+            char tickcount_;
+    };
+}
+
+#endif /* _Backlight_H__ */
Index: /code/branches/rocket2/src/orxonox/graphics/Billboard.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/Billboard.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/Billboard.cc	(revision 6952)
@@ -0,0 +1,127 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Billboard.h"
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    CreateFactory(Billboard);
+
+    Billboard::Billboard(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(Billboard);
+
+        this->colour_ = ColourValue::White;
+//        this->rotation_ = 0;
+
+        this->registerVariables();
+    }
+
+    Billboard::~Billboard()
+    {
+        if (this->isInitialized())
+        {
+            if (this->isInitialized() && this->billboard_.getBillboardSet())
+                this->detachOgreObject(this->billboard_.getBillboardSet());
+        }
+    }
+
+    void Billboard::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Billboard, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Billboard, "material", setMaterial, getMaterial, xmlelement, mode);
+        XMLPortParam(Billboard, "colour",   setColour,   getColour,   xmlelement, mode).defaultValues(ColourValue::White);
+//        XMLPortParam(Billboard, "rotation", setRotation, getRotation, xmlelement, mode).defaultValues(0);
+    }
+
+    void Billboard::registerVariables()
+    {
+        registerVariable(this->material_, VariableDirection::ToClient, new NetworkCallback<Billboard>(this, &Billboard::changedMaterial));
+        registerVariable(this->colour_,   VariableDirection::ToClient, new NetworkCallback<Billboard>(this, &Billboard::changedColour));
+//        registerVariable(this->rotation_, VariableDirection::ToClient, new NetworkCallback<Billboard>(this, &Billboard::changedRotation));
+    }
+
+    void Billboard::changedMaterial()
+    {
+        if (this->material_.empty())
+            return;
+
+        if (!this->billboard_.getBillboardSet())
+        {
+            if (this->getScene() && GameMode::showsGraphics())
+            {
+                this->billboard_.setBillboardSet(this->getScene()->getSceneManager(), this->material_, this->colour_, 1);
+                if (this->billboard_.getBillboardSet())
+                     this->attachOgreObject(this->billboard_.getBillboardSet());
+                this->billboard_.setVisible(this->isVisible());
+//                this->changedRotation();
+            }
+        }
+        else
+            this->billboard_.setMaterial(this->material_);
+    }
+
+    void Billboard::changedColour()
+    {
+        if (!this->billboard_.getBillboardSet())
+        {
+/*
+            if (this->getScene() && GameMode::showsGraphics() && !this->material_.empty())
+            {
+                this->billboard_.setBillboardSet(this->getScene()->getSceneManager(), this->material_, this->colour_, 1);
+                if (this->billboard_.getBillboardSet())
+                    this->attachOgreObject(this->billboard_.getBillboardSet());
+                this->billboard_.setVisible(this->isVisible());
+            }
+*/
+        }
+        else
+            this->billboard_.setColour(this->colour_);
+    }
+
+/*
+    void Billboard::changedRotation()
+    {
+        if (this->billboard_.getBillboardSet())
+            this->billboard_.getBillboardSet()->setRotation(this->rotation_);
+    }
+*/
+
+    void Billboard::changedVisibility()
+    {
+        SUPER(Billboard, changedVisibility);
+
+        this->billboard_.setVisible(this->isVisible());
+    }
+}
Index: /code/branches/rocket2/src/orxonox/graphics/Billboard.h
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/Billboard.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/Billboard.h	(revision 6952)
@@ -0,0 +1,90 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Billboard_H__
+#define _Billboard_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/Math.h"
+#include "tools/BillboardSet.h"
+#include "interfaces/TeamColourable.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Billboard : public StaticEntity, public TeamColourable
+    {
+        public:
+            Billboard(BaseObject* creator);
+            virtual ~Billboard();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            virtual void changedVisibility();
+
+            inline const BillboardSet& getBillboardSet() const
+                { return this->billboard_; }
+
+            inline void setMaterial(const std::string& material)
+                { this->material_ = material; this->changedMaterial(); }
+            inline const std::string& getMaterial() const
+                { return this->material_; }
+
+            inline void setColour(const ColourValue& colour)
+                { this->colour_ = colour; this->changedColour(); }
+            inline const ColourValue& getColour() const
+                { return this->colour_; }
+/*
+            inline void setRotation(const Radian& rotation)
+                { this->rotation_ = rotation; this->changedRotation(); }
+            inline const Radian& getRotation() const
+                { return this->rotation_; }
+*/
+            virtual void setTeamColour(const ColourValue& colour)
+                { this->setColour(colour); }
+
+        protected:
+            inline BillboardSet& getBillboardSet()
+                { return this->billboard_; }
+
+            virtual void changedColour();
+
+        private:
+            void changedMaterial();
+//            void changedRotation();
+
+            BillboardSet billboard_;
+            std::string material_;
+            ColourValue colour_;
+//            Radian rotation_;
+    };
+}
+
+#endif /* _Billboard_H__ */
Index: /code/branches/rocket2/src/orxonox/graphics/BlinkingBillboard.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/BlinkingBillboard.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/BlinkingBillboard.cc	(revision 6952)
@@ -0,0 +1,86 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "BlinkingBillboard.h"
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(BlinkingBillboard);
+
+    BlinkingBillboard::BlinkingBillboard(BaseObject* creator) : Billboard(creator)
+    {
+        RegisterObject(BlinkingBillboard);
+
+        this->amplitude_ = 1.0f;
+        this->frequency_ = 1.0f;
+        this->phase_ = 0;
+        this->bQuadratic_ = false;
+        this->time_ = 0;
+
+        this->registerVariables();
+    }
+
+    BlinkingBillboard::~BlinkingBillboard()
+    {
+    }
+
+    void BlinkingBillboard::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(BlinkingBillboard, XMLPort, xmlelement, mode);
+
+        XMLPortParam(BlinkingBillboard, "amplitude", setAmplitude, getAmplitude, xmlelement, mode).defaultValues(1.0f);
+        XMLPortParam(BlinkingBillboard, "frequency", setFrequency, getFrequency, xmlelement, mode).defaultValues(1.0f);
+        XMLPortParam(BlinkingBillboard, "phase",     setPhase,     getPhase,     xmlelement, mode).defaultValues(Degree(0));
+        XMLPortParam(BlinkingBillboard, "quadratic", setQuadratic, isQuadratic,  xmlelement, mode).defaultValues(false);
+    }
+
+    void BlinkingBillboard::registerVariables()
+    {
+//        registerVariable(this->amplitude_, VariableDirection::ToClient);
+//        registerVariable(this->frequency_, VariableDirection::ToClient);
+//        registerVariable(this->phase_,     VariableDirection::ToClient);
+    }
+
+    void BlinkingBillboard::tick(float dt)
+    {
+        SUPER(BlinkingBillboard, tick, dt);
+
+        if (GameMode::isMaster() && this->isActive())
+        {
+            this->time_ += dt;
+            if (this->bQuadratic_)
+                this->setScale(this->amplitude_ * static_cast<float>(square(sin((6.2831853 * this->time_ + this->phase_.valueRadians()) * this->frequency_))));
+            else
+                this->setScale(this->amplitude_ * static_cast<float>(fabs(sin((6.2831853 * this->time_ + this->phase_.valueRadians()) * this->frequency_))));
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/graphics/BlinkingBillboard.h
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/BlinkingBillboard.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/BlinkingBillboard.h	(revision 6952)
@@ -0,0 +1,80 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _BlinkingBillboard_H__
+#define _BlinkingBillboard_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/Math.h"
+#include "tools/interfaces/Tickable.h"
+#include "Billboard.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport BlinkingBillboard : public Billboard, public Tickable
+    {
+        public:
+            BlinkingBillboard(BaseObject* creator);
+            virtual ~BlinkingBillboard();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            virtual void tick(float dt);
+
+            inline void setAmplitude(float amplitude)
+                { this->amplitude_ = amplitude; }
+            inline float getAmplitude() const
+                { return this->amplitude_; }
+
+            inline void setFrequency(float frequency)
+                { this->frequency_ = frequency; }
+            inline float getFrequency() const
+                { return this->frequency_; }
+
+            inline void setPhase(const Degree& phase)
+                { this->phase_ = phase; }
+            inline const Degree& getPhase() const
+                { return this->phase_; }
+
+            inline void setQuadratic(bool bQuadratic)
+                { this->bQuadratic_ = bQuadratic; }
+            inline bool isQuadratic() const
+                { return this->bQuadratic_; }
+
+        private:
+            float amplitude_;
+            float frequency_;
+            Degree phase_;
+            bool bQuadratic_;
+            long double time_;
+    };
+}
+
+#endif /* _BlinkingBillboard_H__ */
Index: /code/branches/rocket2/src/orxonox/graphics/CEGuiSample.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/CEGuiSample.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/CEGuiSample.cc	(revision 6952)
@@ -0,0 +1,304 @@
+/***********************************************************************
+    filename:   CEGuiSample.cpp
+    created:    24/9/2004
+    author:     Paul D Turner
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2008 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#include "CEGuiSample.h"
+
+#ifdef HAVE_CONFIG_H
+#   include "config.h"
+#endif
+#include "CEGUISamplesConfig.h"
+
+// includes for renderer selector classes
+#if defined( __WIN32__ ) || defined( _WIN32 )
+#   include "Win32CEGuiRendererSelector.h"
+#elif defined(__linux__)
+#   ifdef CEGUI_SAMPLES_USE_GTK2
+#       include "GTK2CEGuiRendererSelector.h"
+#   else
+#       include "CLICEGuiRendererSelector.h"
+#   endif
+#elif defined(__APPLE__)
+#   include "MacCEGuiRendererSelector.h"
+#endif
+
+// includes for application types
+#ifdef CEGUI_SAMPLES_USE_OGRE
+#   include "CEGuiOgreBaseApplication.h"
+#endif
+#ifdef CEGUI_SAMPLES_USE_OPENGL
+#   include "CEGuiOpenGLBaseApplication.h"
+#endif
+#ifdef CEGUI_SAMPLES_USE_IRRLICHT
+#   include "CEGuiIrrlichtBaseApplication.h"
+#endif
+#ifdef CEGUI_SAMPLES_USE_DIRECTFB
+#   include "CEGuiDirectFBBaseApplication.h"
+#endif
+#if defined( __WIN32__ ) || defined( _WIN32 )
+#   ifdef CEGUI_SAMPLES_USE_DIRECTX_8
+#       include "CEGuiD3D81BaseApplication.h"
+#   endif
+#   ifdef CEGUI_SAMPLES_USE_DIRECTX_9
+#       include "CEGuiD3D9BaseApplication.h"
+#   endif
+#   ifdef CEGUI_SAMPLES_USE_DIRECTX_10
+#       include "CEGuiD3D10BaseApplication.h"
+#   endif
+#endif
+// now we include the base CEGuiBaseApplication just in case someone has managed to
+// get this far without any of the renderers.  This ensures the framework will build,
+// although there will be no renderers available for selection in the samples.
+#include "CEGuiBaseApplication.h"
+
+#include "CEGUI.h"
+
+#ifdef CEGUI_WITH_XERCES
+#   include "CEGUIXercesParser.h"
+#endif
+
+// Include iostream if not on windows.
+#if defined( __WIN32__ ) || defined( _WIN32 )
+#else
+#    include <iostream>
+#endif
+
+
+/*************************************************************************
+    Constructor
+*************************************************************************/
+CEGuiSample::CEGuiSample() :
+        d_rendererSelector(0),
+        d_sampleApp(0)
+{}
+
+
+/*************************************************************************
+    Destructor
+*************************************************************************/
+CEGuiSample::~CEGuiSample()
+{
+    if (d_sampleApp)
+    {
+        d_sampleApp->cleanup();
+        delete d_sampleApp;
+    }
+
+    if (d_rendererSelector)
+    {
+        delete d_rendererSelector;
+    }
+
+}
+
+
+/*************************************************************************
+    Application entry point
+*************************************************************************/
+int CEGuiSample::run()
+{
+    try
+    {
+        if (initialise())
+            cleanup();
+    }
+    catch (CEGUI::Exception& exc)
+    {
+        outputExceptionMessage(exc.getMessage().c_str());
+    }
+    catch (std::exception& exc)
+    {
+        outputExceptionMessage(exc.what());
+    }
+    catch(...)
+    {
+        outputExceptionMessage("Unknown exception was caught!");
+    }
+
+    return 0;
+}
+
+
+/*************************************************************************
+    Initialise the sample application
+*************************************************************************/
+bool CEGuiSample::initialise()
+{
+    // Setup renderer selection dialog for Win32
+#if defined( __WIN32__ ) || defined( _WIN32 )
+    d_rendererSelector = new Win32CEGuiRendererSelector;
+
+    // enable renderer types supported for Win32
+#ifdef CEGUI_SAMPLES_USE_DIRECTX_8
+    d_rendererSelector->setRendererAvailability(Direct3D81GuiRendererType);
+#endif
+#ifdef CEGUI_SAMPLES_USE_DIRECTX_9
+    d_rendererSelector->setRendererAvailability(Direct3D9GuiRendererType);
+#endif
+#ifdef CEGUI_SAMPLES_USE_DIRECTX_10
+    d_rendererSelector->setRendererAvailability(Direct3D10GuiRendererType);
+#endif
+
+#elif defined(__linux__)
+    // decide which method to use for renderer selection
+#   ifdef CEGUI_SAMPLES_USE_GTK2
+        d_rendererSelector = new GTK2CEGuiRendererSelector();
+#   else
+        d_rendererSelector = new CLICEGuiRendererSelector();
+#   endif
+
+#elif defined(__APPLE__)
+     d_rendererSelector = new MacCEGuiRendererSelector();
+#endif
+
+    // enable available renderer types
+#ifdef CEGUI_SAMPLES_USE_OGRE
+    d_rendererSelector->setRendererAvailability(OgreGuiRendererType);
+#endif
+#ifdef CEGUI_SAMPLES_USE_OPENGL
+    d_rendererSelector->setRendererAvailability(OpenGLGuiRendererType);
+#endif
+#ifdef CEGUI_SAMPLES_USE_IRRLICHT
+    d_rendererSelector->setRendererAvailability(IrrlichtGuiRendererType);
+#endif
+#ifdef CEGUI_SAMPLES_USE_DIRECTFB
+    d_rendererSelector->setRendererAvailability(DirectFBGuiRendererType);
+#endif
+
+    // get selection from user
+    if (d_rendererSelector->invokeDialog())
+    {
+        // create appropriate application type based upon users selection
+        switch(d_rendererSelector->getSelectedRendererType())
+        {
+#ifdef CEGUI_SAMPLES_USE_OGRE
+        case OgreGuiRendererType:
+            d_sampleApp = new CEGuiOgreBaseApplication();
+            break;
+#endif
+#if defined( __WIN32__ ) || defined( _WIN32 )
+#ifdef CEGUI_SAMPLES_USE_DIRECTX_8
+        case Direct3D81GuiRendererType:
+            d_sampleApp = new CEGuiD3D81BaseApplication();
+            break;
+#endif
+#ifdef CEGUI_SAMPLES_USE_DIRECTX_9
+        case Direct3D9GuiRendererType:
+            d_sampleApp = new CEGuiD3D9BaseApplication();
+            break;
+#endif // DX9
+#ifdef CEGUI_SAMPLES_USE_DIRECTX_10
+        case Direct3D10GuiRendererType:
+            d_sampleApp = new CEGuiD3D10BaseApplication();
+            break;
+#endif // DX10
+#endif // Win32
+#ifdef CEGUI_SAMPLES_USE_OPENGL
+        case OpenGLGuiRendererType:
+            d_sampleApp = new CEGuiOpenGLBaseApplication();
+            break;
+#endif
+#ifdef CEGUI_SAMPLES_USE_IRRLICHT
+        case IrrlichtGuiRendererType:
+            d_sampleApp = new CEGuiIrrlichtBaseApplication();
+            break;
+#endif
+#ifdef CEGUI_SAMPLES_USE_DIRECTFB
+        case DirectFBGuiRendererType:
+            d_sampleApp = new CEGuiDirectFBBaseApplication();
+            break;
+#endif
+
+        default:
+            throw CEGUI::GenericException("No renderer was selected!");
+            break;
+        }
+
+        // set the default resource groups to be used
+        CEGUI::Imageset::setDefaultResourceGroup("imagesets");
+        CEGUI::Font::setDefaultResourceGroup("fonts");
+        CEGUI::Scheme::setDefaultResourceGroup("schemes");
+        CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
+        CEGUI::WindowManager::setDefaultResourceGroup("layouts");
+        CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
+#ifdef CEGUI_WITH_XERCES
+        CEGUI::XercesParser::setSchemaDefaultResourceGroup("schemas");
+#endif
+
+        // execute the base application (which sets up the demo via 'this' and runs it.
+        if (d_sampleApp->execute(this))
+        {
+            // signal that app initialised and ran
+            return true;
+        }
+
+        // sample app did not initialise, delete the object.
+        delete d_sampleApp;
+        d_sampleApp = 0;
+    }
+
+    // delete renderer selector object
+    delete d_rendererSelector;
+    d_rendererSelector = 0;
+
+    // signal app did not initialise and run.
+    return false;
+}
+
+
+/*************************************************************************
+    Cleanup the sample application.
+*************************************************************************/
+void CEGuiSample::cleanup()
+{
+    if (d_sampleApp)
+    {
+        d_sampleApp->cleanup();
+        delete d_sampleApp;
+        d_sampleApp = 0;
+    }
+
+    if (d_rendererSelector)
+    {
+        delete d_rendererSelector;
+        d_rendererSelector = 0;
+    }
+
+}
+
+
+/*************************************************************************
+    Output a message to the user in some OS independant way.
+*************************************************************************/
+void CEGuiSample::outputExceptionMessage(const char* message) const
+{
+#if defined(__WIN32__) || defined(_WIN32)
+    MessageBoxA(0, message, "CEGUI - Exception", MB_OK|MB_ICONERROR);
+#else
+    std::cout << "An exception was thrown within the sample framework:" << std::endl;
+    std::cout << message << std::endl;
+#endif
+}
Index: /code/branches/rocket2/src/orxonox/graphics/CEGuiSample.h
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/CEGuiSample.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/CEGuiSample.h	(revision 6952)
@@ -0,0 +1,130 @@
+/***********************************************************************
+    filename:   CEGuiSample.h
+    created:    24/9/2004
+    author:     Paul D Turner
+*************************************************************************/
+/***************************************************************************
+ *   Copyright (C) 2004 - 2006 Paul D Turner & The CEGUI Development Team
+ *
+ *   Permission is hereby granted, free of charge, to any person obtaining
+ *   a copy of this software and associated documentation files (the
+ *   "Software"), to deal in the Software without restriction, including
+ *   without limitation the rights to use, copy, modify, merge, publish,
+ *   distribute, sublicense, and/or sell copies of the Software, and to
+ *   permit persons to whom the Software is furnished to do so, subject to
+ *   the following conditions:
+ *
+ *   The above copyright notice and this permission notice shall be
+ *   included in all copies or substantial portions of the Software.
+ *
+ *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ *   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ *   IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ *   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ *   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *   OTHER DEALINGS IN THE SOFTWARE.
+ ***************************************************************************/
+#ifndef _CEGuiSample_h_
+#define _CEGuiSample_h_
+
+#if (defined( __WIN32__ ) || defined( _WIN32 )) && !defined (CEGUI_STATIC)
+#   ifdef CEGUISAMPLE_EXPORTS
+#       define CEGUISAMPLE_API __declspec(dllexport)
+#   else
+#       define CEGUISAMPLE_API __declspec(dllimport)
+#   endif
+#else
+#       define CEGUISAMPLE_API
+#endif
+
+
+// forward declarations
+class CEGuiBaseApplication;
+class CEGuiRendererSelector;
+
+
+/*!
+\brief
+    This is a base class that is intended to be used for all sample applications.
+    Here we take care of common things such the renderer selection and application
+    startup.
+*/
+class CEGUISAMPLE_API CEGuiSample
+{
+public:
+    /*!
+    \brief
+        Constructor.
+    */
+    CEGuiSample();
+
+
+    /*!
+    \brief
+        Destructor.
+    */
+    virtual ~CEGuiSample();
+
+
+    /*!
+    \brief
+        Application entry point.
+
+    \return
+        code to be returned by the application.
+    */
+    int run();
+
+
+    /*!
+    \brief
+        Sample specific initialisation goes here.  This method is called by the application base object created
+        as part of the initialise call.
+
+    \return
+        false if something went wrong.
+    */
+    virtual bool initialiseSample()  = 0;
+
+
+    /*!
+    \brief
+        Cleans up resources allocated in the initialiseSample call.
+    */
+    virtual void cleanupSample() = 0;
+
+
+protected:
+    /*!
+    \brief
+        Initialises the sample system, this includes asking the user for a render to use and
+        the subsequent creation of the required systems to support that renderer.
+
+    \return
+        false if anything went wrong.
+    */
+    virtual bool initialise();
+
+
+    /*!
+    \brief
+        Cleans up all resources allocated by the initialise call.
+    */
+    virtual void cleanup();
+
+
+    /*!
+    \brief
+        Output a message to the user in some OS independant way.
+    */
+    void outputExceptionMessage(const char* message) const;
+
+    /*************************************************************************
+        Data fields
+    *************************************************************************/
+    CEGuiRendererSelector*  d_rendererSelector;     //!< Points to the renderer selector object.
+    CEGuiBaseApplication*   d_sampleApp;            //!< Pointer to the base application object.
+};
+
+#endif  // end of guard _CEGuiSample_h_
Index: /code/branches/rocket2/src/orxonox/graphics/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,16 @@
+ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+  Billboard.cc
+  BlinkingBillboard.cc
+  FadingBillboard.cc
+  GlobalShader.cc
+  MeshLodInformation.cc
+  Model.cc
+  AnimatedModel.cc
+  ParticleEmitter.cc
+  ParticleSpawner.cc
+COMPILATION_BEGIN GraphicsCompilation.cc
+  Backlight.cc
+  Camera.cc
+  Light.cc
+COMPILATION_END
+)
Index: /code/branches/rocket2/src/orxonox/graphics/Camera.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/Camera.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/Camera.cc	(revision 6952)
@@ -0,0 +1,199 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Benjamin Knecht
+ *
+ */
+
+#include "Camera.h"
+
+#include <algorithm>
+#include <OgreCamera.h>
+#include <OgreSceneManager.h>
+#include <OgreSceneNode.h>
+
+#include "util/Exception.h"
+#include "util/StringUtils.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/GameMode.h"
+#include "core/GUIManager.h"
+#include "Scene.h"
+#include "CameraManager.h"
+#include "sound/SoundManager.h"
+
+namespace orxonox
+{
+    CreateFactory(Camera);
+
+    Camera::Camera(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(Camera);
+
+        if (!GameMode::showsGraphics())
+            ThrowException(AbortLoading, "Can't create Camera, no graphics.");
+        if (!this->getScene())
+            ThrowException(AbortLoading, "Can't create Camera, no scene.");
+        if (!this->getScene()->getSceneManager())
+            ThrowException(AbortLoading, "Can't create Camera, no scene-manager given.");
+        if (!this->getScene()->getRootSceneNode())
+            ThrowException(AbortLoading, "Can't create Camera, no root-scene-node given.");
+
+        this->camera_ = this->getScene()->getSceneManager()->createCamera(getUniqueNumberString());
+        static_cast<Ogre::MovableObject*>(this->camera_)->setUserAny(Ogre::Any(static_cast<OrxonoxClass*>(this)));
+        this->cameraNode_ = this->getScene()->getRootSceneNode()->createChildSceneNode();
+        this->attachNode(this->cameraNode_);
+        this->cameraNode_->attachObject(this->camera_);
+
+        this->bHasFocus_ = false;
+        this->bDrag_ = false;
+        this->nearClipDistance_ = 1;
+        this->lastDtLagged_ = false;
+
+        this->setSyncMode(0x0);
+
+        this->setConfigValues();
+        this->configvaluecallback_changedNearClipDistance();
+    }
+
+    Camera::~Camera()
+    {
+        if (this->isInitialized())
+        {
+            if (GUIManager::getInstance().getCamera() == this->camera_)
+                GUIManager::getInstance().setCamera(NULL);
+            this->releaseFocus();
+
+            this->cameraNode_->detachAllObjects();
+            this->getScene()->getSceneManager()->destroyCamera(this->camera_);
+
+            if (this->bDrag_)
+                this->detachNode(this->cameraNode_);
+
+            if (this->getScene()->getSceneManager())
+                this->getScene()->getSceneManager()->destroySceneNode(this->cameraNode_->getName());
+        }
+    }
+
+    void Camera::setConfigValues()
+    {
+        SetConfigValue(nearClipDistance_, 1.0f).callback(this, &Camera::configvaluecallback_changedNearClipDistance);
+    }
+
+    void Camera::configvaluecallback_changedNearClipDistance()
+    {
+        this->camera_->setNearClipDistance(this->nearClipDistance_);
+    }
+
+    void Camera::tick(float dt)
+    {
+        SUPER(Camera, tick, dt);
+
+        if (this->bDrag_)
+        {
+            // this stuff here may need some adjustments
+            float poscoeff = 15.0f * dt / this->getTimeFactor();
+            float anglecoeff = 7.0f * dt / this->getTimeFactor();
+            // Only clamp if fps rate is actually falling. Occasional high dts should
+            // not be clamped to reducing lagging effects.
+            if (poscoeff > 1.0f)
+            {
+                if (this->lastDtLagged_)
+                    poscoeff = 1.0f;
+                else
+                    this->lastDtLagged_ = true;
+            }
+            else
+                this->lastDtLagged_ = false;
+
+            if (anglecoeff > 1.0f)
+            {
+                if (this->lastDtLagged_)
+                    anglecoeff = 1.0f;
+                else
+                    this->lastDtLagged_ = true;
+            }
+            else
+                this->lastDtLagged_ = false;
+
+            Vector3 offset = this->getWorldPosition() - this->cameraNode_->_getDerivedPosition();
+            this->cameraNode_->translate(poscoeff * offset);
+
+            this->cameraNode_->setOrientation(Quaternion::Slerp(anglecoeff, this->cameraNode_->_getDerivedOrientation(), this->getWorldOrientation(), true));
+        }
+
+        // Update sound listener transformation
+        if (GameMode::playsSound() && this->bHasFocus_)
+        {
+            SoundManager::getInstance().setListenerPosition(this->getWorldPosition());
+            SoundManager::getInstance().setListenerOrientation(this->getWorldOrientation());
+        }
+    }
+
+    void Camera::requestFocus()
+    {
+        CameraManager::getInstance().requestFocus(this);
+    }
+
+    void Camera::releaseFocus()
+    {
+        CameraManager::getInstance().releaseFocus(this);
+    }
+
+    /**
+        what to do when camera loses focus (do not request focus in this function!!)
+        this is called by the CameraManager singleton class to notify the camera
+    */
+    void Camera::removeFocus()
+    {
+        this->bHasFocus_ = false;
+    }
+
+    void Camera::setFocus()
+    {
+        this->bHasFocus_ = true;
+        CameraManager::getInstance().useCamera(this->camera_);
+    }
+
+    void Camera::setDrag(bool bDrag)
+    {
+        if (bDrag != this->bDrag_)
+        {
+            this->bDrag_ = bDrag;
+
+            if (!bDrag)
+            {
+                this->attachNode(this->cameraNode_);
+                this->cameraNode_->setPosition(Vector3::ZERO);
+                this->cameraNode_->setOrientation(Quaternion::IDENTITY);
+            }
+            else
+            {
+                this->detachNode(this->cameraNode_);
+                this->cameraNode_->setPosition(this->getWorldPosition());
+                this->cameraNode_->setOrientation(this->getWorldOrientation());
+            }
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/graphics/Camera.h
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/Camera.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/Camera.h	(revision 6952)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Benjamin Knecht
+ *
+ */
+
+#ifndef _Camera_H__
+#define _Camera_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/OgreForwardRefs.h"
+#include "tools/interfaces/Tickable.h"
+#include "tools/interfaces/TimeFactorListener.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Camera : public StaticEntity, public Tickable, public TimeFactorListener
+    {
+        friend class CameraManager;
+
+        public:
+            Camera(BaseObject* creator);
+            virtual ~Camera();
+
+            void setConfigValues();
+            virtual void tick(float dt);
+
+            void requestFocus();
+            void releaseFocus();
+
+            inline Ogre::Camera* getOgreCamera()
+               { return this->camera_; }
+
+            inline bool hasFocus()
+                { return this->bHasFocus_; }
+
+            void setDrag(bool bDrag);
+            inline bool getDrag() const
+                { return this->bDrag_; }
+
+        private:
+            void removeFocus();
+            void setFocus();
+            void configvaluecallback_changedNearClipDistance();
+
+            Ogre::Camera*    camera_;
+            Ogre::SceneNode* cameraNode_;
+            float            nearClipDistance_;
+            bool             bHasFocus_;
+            bool             bDrag_;
+            bool             lastDtLagged_;
+    };
+}
+
+#endif /* _Camera_H__ */
Index: /code/branches/rocket2/src/orxonox/graphics/FadingBillboard.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/FadingBillboard.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/FadingBillboard.cc	(revision 6952)
@@ -0,0 +1,163 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "FadingBillboard.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(FadingBillboard);
+
+    FadingBillboard::FadingBillboard(BaseObject* creator) : Billboard(creator)
+    {
+        RegisterObject(FadingBillboard);
+
+        this->turnontime_ = 0.0f;
+        this->turnofftime_ = 0.0f;
+        this->postprocessingtime_ = 0.0f;
+        this->changedirection_ = 0;
+
+        this->fadedColour_ = ColourValue::White;
+
+        this->registerVariables();
+    }
+
+    FadingBillboard::~FadingBillboard()
+    {
+    }
+
+    void FadingBillboard::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(FadingBillboard, XMLPort, xmlelement, mode);
+
+        XMLPortParam(FadingBillboard, "turnontime",  setTurnOnTime,  getTurnOnTime,  xmlelement, mode).defaultValues(0.5f);
+        XMLPortParam(FadingBillboard, "turnofftime", setTurnOffTime, getTurnOffTime, xmlelement, mode).defaultValues(0.5f);
+    }
+
+    void FadingBillboard::registerVariables()
+    {
+        registerVariable(this->turnontime_,  VariableDirection::ToClient);
+        registerVariable(this->turnofftime_, VariableDirection::ToClient);
+    }
+
+    void FadingBillboard::changedColour()
+    {
+        Billboard::changedColour();
+
+        if (this->isActive())
+            this->fadedColour_ = this->getColour();
+        else
+            this->fadedColour_ = ColourValue::ZERO;
+
+        this->getBillboardSet().setColour(this->fadedColour_);
+    }
+
+    void FadingBillboard::changedActivity()
+    {
+        SUPER(FadingBillboard, changedActivity);
+
+        this->startturnonoff();
+    }
+
+    void FadingBillboard::changedVisibility()
+    {
+        SUPER(FadingBillboard, changedVisibility);
+
+        if (this->isVisible() && !this->isActive() && this->changedirection_ == 0)
+        {
+            // Billboard shouldn't be visible
+            this->getBillboardSet().setVisible(false);
+        }
+    }
+
+    void FadingBillboard::startturnonoff()
+    {
+        if (this->isActive())
+        {
+            this->changedirection_ = 1;
+            this->turnonofftimer_.setTimer(this->turnontime_, false, createExecutor(createFunctor(&FadingBillboard::stopturnonoff, this)));
+
+            if (this->isVisible())
+                this->getBillboardSet().setVisible(true);
+        }
+        else
+        {
+            this->changedirection_ = -1;
+            this->turnonofftimer_.setTimer(this->turnofftime_, false, createExecutor(createFunctor(&FadingBillboard::stopturnonoff, this)));
+        }
+    }
+
+    void FadingBillboard::stopturnonoff()
+    {
+        if (this->changedirection_ > 0)
+        {
+            this->fadedColour_ = this->getColour();
+            this->getBillboardSet().setColour(this->fadedColour_);
+        }
+        else if (this->changedirection_ < 0)
+        {
+            this->fadedColour_ = ColourValue::ZERO;
+            this->getBillboardSet().setColour(this->fadedColour_);
+            this->turnonofftimer_.setTimer(this->postprocessingtime_, false, createExecutor(createFunctor(&FadingBillboard::poststopturnonoff, this)));
+        }
+        this->changedirection_ = 0;
+    }
+
+    void FadingBillboard::poststopturnonoff()
+    {
+        this->getBillboardSet().setVisible(false);
+    }
+
+    void FadingBillboard::tick(float dt)
+    {
+        SUPER(FadingBillboard, tick, dt);
+
+        if (this->changedirection_ > 0 && (this->fadedColour_.a < this->getColour().a))
+        {
+            ColourValue colour = this->fadedColour_ + this->getColour() / this->turnontime_ * dt;
+
+            if (colour.a < this->getColour().a)
+            {
+                this->fadedColour_ = colour;
+                this->getBillboardSet().setColour(this->fadedColour_);
+            }
+        }
+        else if (this->changedirection_ < 0 && (this->fadedColour_.a > 0))
+        {
+            ColourValue colour = this->fadedColour_ - this->getColour() / this->turnofftime_ * dt;
+
+            if (colour.a > 0)
+            {
+                this->fadedColour_ = colour;
+                this->getBillboardSet().setColour(this->fadedColour_);
+            }
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/graphics/FadingBillboard.h
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/FadingBillboard.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/FadingBillboard.h	(revision 6952)
@@ -0,0 +1,82 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _FadingBillboard_H__
+#define _FadingBillboard_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/Math.h"
+#include "tools/Timer.h"
+#include "tools/interfaces/Tickable.h"
+#include "Billboard.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport FadingBillboard : public Billboard, public Tickable
+    {
+        public:
+            FadingBillboard(BaseObject* creator);
+            virtual ~FadingBillboard();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            virtual void tick(float dt);
+            virtual void changedActivity();
+            virtual void changedVisibility();
+
+            inline void setTurnOnTime(float turnontime)
+                { this->turnontime_ = turnontime; }
+            inline float getTurnOnTime() const
+                { return this->turnontime_; }
+
+            inline void setTurnOffTime(float turnofftime)
+                { this->turnofftime_ = turnofftime; }
+            inline float getTurnOffTime() const
+                { return this->turnofftime_; }
+
+            inline const ColourValue& getFadedColour() const
+                { return this->fadedColour_; }
+
+        protected:
+            virtual void startturnonoff();
+            virtual void stopturnonoff();
+            virtual void poststopturnonoff();
+            virtual void changedColour();
+
+            float turnontime_;
+            float turnofftime_;
+            float postprocessingtime_;
+            Timer turnonofftimer_;
+            char changedirection_;
+            ColourValue fadedColour_;
+    };
+}
+
+#endif /* _FadingBillboard_H__ */
Index: /code/branches/rocket2/src/orxonox/graphics/GlobalShader.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/GlobalShader.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/GlobalShader.cc	(revision 6952)
@@ -0,0 +1,78 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "GlobalShader.h"
+
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    CreateFactory(GlobalShader);
+
+    GlobalShader::GlobalShader(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
+    {
+        RegisterObject(GlobalShader);
+
+        if (!this->getScene())
+            ThrowException(AbortLoading, "Can't create GlobalShader, no scene given.");
+//        if (!this->getScene()->getSceneManager())
+//            ThrowException(AbortLoading, "Can't create GlobalShader, no scene manager given.");
+
+        if (this->getScene()->getSceneManager())
+            this->shader_.setSceneManager(this->getScene()->getSceneManager());
+
+        this->registerVariables();
+    }
+
+    GlobalShader::~GlobalShader()
+    {
+    }
+
+    void GlobalShader::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(GlobalShader, XMLPort, xmlelement, mode);
+
+        XMLPortParamExtern(GlobalShader, Shader, &this->shader_, "compositor", setCompositor, getCompositor, xmlelement, mode);
+    }
+
+    void GlobalShader::registerVariables()
+    {
+        registerVariable(this->bVisible_,                                         VariableDirection::ToClient, new NetworkCallback<GlobalShader>(this, &GlobalShader::changedVisibility));
+        registerVariable(const_cast<std::string&>(this->shader_.getCompositor()), VariableDirection::ToClient, new NetworkCallback<Shader>(&this->shader_, &Shader::changedCompositor));
+    }
+
+    void GlobalShader::changedVisibility()
+    {
+        SUPER(GlobalShader, changedVisibility);
+
+        this->shader_.setVisible(this->isVisible());
+    }
+}
Index: /code/branches/rocket2/src/orxonox/graphics/GlobalShader.h
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/GlobalShader.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/GlobalShader.h	(revision 6952)
@@ -0,0 +1,61 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GlobalShader_H__
+#define _GlobalShader_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "core/BaseObject.h"
+#include "network/synchronisable/Synchronisable.h"
+#include "tools/Shader.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport GlobalShader : public BaseObject, public Synchronisable
+    {
+        public:
+            GlobalShader(BaseObject* creator);
+            virtual ~GlobalShader();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            virtual void changedVisibility();
+
+            inline const Shader& getShader() const
+                { return this->shader_; }
+
+        private:
+            void changedCompositor();
+
+            Shader shader_;
+    };
+}
+
+#endif /* _GlobalShader_H__ */
Index: /code/branches/rocket2/src/orxonox/graphics/Light.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/Light.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/Light.cc	(revision 6952)
@@ -0,0 +1,185 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Light.h"
+
+#include <OgreSceneManager.h>
+#include <OgreLight.h>
+#include <boost/static_assert.hpp>
+
+#include "util/StringUtils.h"
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    CreateFactory(Light);
+
+    // Be sure we don't do bad conversions
+    BOOST_STATIC_ASSERT((int)Ogre::Light::LT_POINT       == (int)Light::Point);
+    BOOST_STATIC_ASSERT((int)Ogre::Light::LT_DIRECTIONAL == (int)Light::Directional);
+    BOOST_STATIC_ASSERT((int)Ogre::Light::LT_SPOTLIGHT   == (int)Light::Spotlight);
+
+    Light::Light(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(Light);
+
+        this->light_ = 0;
+        this->diffuse_ = ColourValue::White;
+        this->specular_ = ColourValue::White;
+        this->type_ = Light::Point;
+        this->attenuation_ = Vector4(100000, 1, 0, 0);
+        this->spotlightRange_ = Vector3(40.0f, 30.0f, 1.0f);
+
+        if (GameMode::showsGraphics())
+        {
+            if (!this->getScene())
+                ThrowException(AbortLoading, "Can't create Light, no scene given.");
+            if (!this->getScene()->getSceneManager())
+                ThrowException(AbortLoading, "Can't create Light, no scene manager given.");
+
+            if (this->getScene() && this->getScene()->getSceneManager())
+            {
+                this->light_ = this->getScene()->getSceneManager()->createLight("Light" + getUniqueNumberString());
+                this->light_->setDirection(WorldEntity::FRONT);
+                this->attachOgreObject(this->light_);
+
+                this->updateType();
+                this->updateDiffuseColour();
+                this->updateSpecularColour();
+                this->updateAttenuation();
+                this->updateSpotlightRange();
+            }
+        }
+
+        this->registerVariables();
+    }
+
+    Light::~Light()
+    {
+        if (this->isInitialized())
+        {
+            if (this->light_ && this->getScene() && this->getScene()->getSceneManager())
+                this->getScene()->getSceneManager()->destroyLight(this->light_);
+        }
+    }
+
+    void Light::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Light, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Light, "type",           setTypeString,     getTypeString,     xmlelement, mode).defaultValues("point");
+        XMLPortParam(Light, "diffuse",        setDiffuseColour,  getDiffuseColour,  xmlelement, mode).defaultValues(ColourValue::White);
+        XMLPortParam(Light, "specular",       setSpecularColour, getSpecularColour, xmlelement, mode).defaultValues(ColourValue::White);
+        XMLPortParam(Light, "attenuation",    setAttenuation,    getAttenuation,    xmlelement, mode).defaultValues(Vector4(100000, 1, 0, 0));
+        XMLPortParam(Light, "spotlightrange", setSpotlightRange, getSpotlightRange, xmlelement, mode).defaultValues(Vector3(40.0f, 30.0f, 1.0f));
+    }
+
+    void Light::registerVariables()
+    {
+        registerVariable((int&)this->type_,     VariableDirection::ToClient, new NetworkCallback<Light>(this, &Light::updateType));
+        registerVariable(this->diffuse_,        VariableDirection::ToClient, new NetworkCallback<Light>(this, &Light::updateDiffuseColour));
+        registerVariable(this->specular_,       VariableDirection::ToClient, new NetworkCallback<Light>(this, &Light::updateSpecularColour));
+        registerVariable(this->attenuation_,    VariableDirection::ToClient, new NetworkCallback<Light>(this, &Light::updateAttenuation));
+        registerVariable(this->spotlightRange_, VariableDirection::ToClient, new NetworkCallback<Light>(this, &Light::updateSpotlightRange));
+    }
+
+    void Light::updateDiffuseColour()
+    {
+        if (this->light_)
+            this->light_->setDiffuseColour(this->diffuse_);
+    }
+
+    void Light::updateSpecularColour()
+    {
+        if (this->light_)
+            this->light_->setSpecularColour(this->specular_);
+    }
+
+    void Light::updateAttenuation()
+    {
+        if (this->light_ && this->type_ != Light::Directional)
+            this->light_->setAttenuation(this->attenuation_.x, this->attenuation_.y, this->attenuation_.z, this->attenuation_.w);
+    }
+
+    void Light::updateSpotlightRange()
+    {
+        if (this->light_ && this->type_ == Light::Spotlight)
+            this->light_->setSpotlightRange(Degree(this->spotlightRange_.x), Degree(this->spotlightRange_.y), this->spotlightRange_.z);
+    }
+
+    void Light::setTypeString(const std::string& type)
+    {
+        if (type == "point")
+            this->setType(Light::Point);
+        else if (type == "directional")
+            this->setType(Light::Directional);
+        else if (type == "spotlight")
+            this->setType(Light::Spotlight);
+        else
+            this->setType(Light::Point);
+    }
+
+    std::string Light::getTypeString() const
+    {
+        switch (this->type_)
+        {
+            case Light::Directional:
+                return "directional";
+            case Light::Spotlight:
+                return "spotlight";
+            case Light::Point:
+            default:
+                return "point";
+        }
+    }
+
+    void Light::updateType()
+    {
+        if (this->light_)
+        {
+            this->light_->setType(static_cast<Ogre::Light::LightTypes>(this->type_));
+
+            if (this->type_ != Light::Directional)
+                this->updateAttenuation();
+            if (this->type_ == Light::Spotlight)
+                this->updateSpotlightRange();
+        }
+    }
+
+    void Light::changedVisibility()
+    {
+        SUPER(Light, changedVisibility);
+
+        if (this->light_)
+            this->light_->setVisible(this->isVisible());
+    }
+}
Index: /code/branches/rocket2/src/orxonox/graphics/Light.h
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/Light.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/Light.h	(revision 6952)
@@ -0,0 +1,152 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Light_H__
+#define _Light_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "util/Math.h"
+#include "interfaces/TeamColourable.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Light : public StaticEntity, public TeamColourable
+    {
+        public:
+            enum LightTypes // Copy from the Ogre enum
+            {
+                /// Point light sources give off light equally in all directions, so require only position not direction
+                Point,
+                /// Directional lights simulate parallel light beams from a distant source, hence have direction but no position
+                Directional,
+                /// Spotlights simulate a cone of light from a source so require position and direction, plus extra values for falloff
+                Spotlight
+            };
+
+        public:
+            Light(BaseObject* creator);
+            virtual ~Light();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            virtual void changedVisibility();
+
+            inline Ogre::Light* getLight()
+                { return this->light_; }
+
+            inline void setType(Light::LightTypes type)
+                { this->type_ = type; this->updateType(); }
+            inline Light::LightTypes getType() const
+                { return this->type_; }
+
+            inline void setDiffuseColour(const ColourValue& colour)
+                { this->diffuse_ = colour; this->updateDiffuseColour(); }
+            inline const ColourValue& getDiffuseColour() const
+                { return this->diffuse_; }
+
+            inline void setSpecularColour(const ColourValue& colour)
+                { this->specular_ = colour; this->updateSpecularColour(); }
+            inline const ColourValue& getSpecularColour() const
+                { return this->specular_; }
+
+            virtual void setTeamColour(const ColourValue& colour)
+                { this->setDiffuseColour(colour); this->setSpecularColour(colour); }
+
+            /**
+                @brief Sets the attenuation parameters of the light source i.e. how it diminishes with distance.
+
+                @param attenuation.x range (The absolute upper range of the light in world units)
+                @param attenuation.y constant (The constant factor in the attenuation formula: 1.0 means never attenuate, 0.0 is complete attenuation)
+                @param attenuation.z linear (The linear factor in the attenuation formula: 1 means attenuate evenly over the distance)
+                @param attenuation.w quadratic (The quadratic factor in the attenuation formula: adds a curvature to the attenuation formula)
+
+                Quote from the Ogre API:
+                Lights normally get fainter the further they are away. Also, each light is given a maximum range beyond which it cannot affect any objects.
+                Light attenuation is not applicable to directional lights since they have an infinite range and constant intensity.
+                This follows a standard attenuation approach - see any good 3D text for the details of what they mean since i don't have room here!
+
+                Quote from the Ogre wiki:
+                "Using these numbers, the light has 100% intensity at 0 distance, and
+                trails off to near black at a distance equal to the Range. Keep in mind
+                that most of the light falls in the first 20% of the range."
+
+                Range   Constant   Linear     Quadratic
+                3250,     1.0,     0.0014,    0.000007
+                600,      1.0,     0.007,     0.0002
+                325,      1.0,     0.014,     0.0007
+                200,      1.0,     0.022,     0.0019
+                160,      1.0,     0.027,     0.0028
+                100,      1.0,     0.045,     0.0075
+                65,       1.0,     0.07,      0.017
+                50,       1.0,     0.09,      0.032
+                32,       1.0,     0.14,      0.07
+                20,       1.0,     0.22,      0.20
+                13,       1.0,     0.35,      0.44
+                7,        1.0,     0.7,       1.8
+            */
+            inline void setAttenuation(const Vector4& attenuation)
+                { this->attenuation_ = attenuation; this->updateAttenuation(); }
+            inline const Vector4& getAttenuation() const
+                { return this->attenuation_; }
+
+            /**
+                @brief Sets the range of a spotlight, i.e. the angle of the inner and outer cones and the rate of falloff between them.
+
+                @param spotlightRange.x innerAngle (The angle covered by the bright inner cone)
+                @param spotlightRange.x outerAngle (The angle covered by the outer cone)
+                @param spotlightRange.x falloff (The rate of falloff between the inner and outer cones. 1.0 means a linear falloff, less means slower falloff, higher means faster falloff.)
+            */
+            inline void setSpotlightRange(const Vector3& spotlightRange)
+                { this->spotlightRange_ = spotlightRange; this->updateSpotlightRange(); }
+            inline const Vector3& getSpotlightRange() const
+                { return this->spotlightRange_; }
+
+        private:
+            void setTypeString(const std::string& type);
+            std::string getTypeString() const;
+
+            void updateType();
+            void updateDiffuseColour();
+            void updateSpecularColour();
+            void updateAttenuation();
+            void updateSpotlightRange();
+
+            Ogre::Light* light_;
+            LightTypes type_;
+            ColourValue diffuse_;
+            ColourValue specular_;
+            Vector4 attenuation_;
+            Vector3 spotlightRange_;
+    };
+}
+
+#endif /* _Light_H__ */
Index: /code/branches/rocket2/src/orxonox/graphics/MeshLodInformation.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/MeshLodInformation.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/MeshLodInformation.cc	(revision 6952)
@@ -0,0 +1,82 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Jan Bernegger
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "MeshLodInformation.h"
+
+#include <OgreEntity.h>
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    CreateFactory(MeshLodInformation);
+
+    MeshLodInformation::MeshLodInformation(BaseObject* creator) 
+	: BaseObject(creator), lodLevel_(-1)
+    {
+        RegisterObject(MeshLodInformation);
+    }
+
+    MeshLodInformation::~MeshLodInformation()
+    {    }
+
+    void MeshLodInformation::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(MeshLodInformation, XMLPort, xmlelement, mode);
+
+        XMLPortParam(MeshLodInformation, "mesh", setMeshSource, getMeshSource, xmlelement, mode);
+        XMLPortParam(MeshLodInformation, "lodQuality", setLodLevel, getLodLevel, xmlelement, mode);
+    }
+    
+    std::string MeshLodInformation::getMeshName()
+    {
+		return MeshLodInformation::getMeshSource();
+    }
+	
+	void MeshLodInformation::setLodLevel(float lodLevel)
+	{
+        if(lodLevel>=0)
+		    lodLevel_=lodLevel;
+	}
+	float MeshLodInformation::getLodLevel()
+	{
+		return lodLevel_;
+	} 
+	void MeshLodInformation::setMeshSource(std::string meshSource)
+	{
+		meshSource_ = meshSource;
+	}
+	std::string MeshLodInformation::getMeshSource()
+	{
+		return meshSource_;
+	}
+ 
+}
Index: /code/branches/rocket2/src/orxonox/graphics/MeshLodInformation.h
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/MeshLodInformation.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/MeshLodInformation.h	(revision 6952)
@@ -0,0 +1,60 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Jan Bernegger
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _MeshLodInformation_H__
+#define _MeshLodInformation_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "tools/Mesh.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport MeshLodInformation : public BaseObject
+    {
+		private:
+			void setLodLevel(float lodLevel);
+			void setMeshSource(std::string meshSource);
+			std::string getMeshSource();
+			std::string meshSource_;
+			float lodLevel_;
+		
+        public:
+            MeshLodInformation(BaseObject* creator);
+            virtual ~MeshLodInformation();
+            
+			float getLodLevel();
+            std::string getMeshName();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+    };
+}
+
+#endif /* _MeshLodInformation_H__ */
Index: /code/branches/rocket2/src/orxonox/graphics/Model.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/Model.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/Model.cc	(revision 6952)
@@ -0,0 +1,179 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Model.h"
+
+#include <OgreEntity.h>
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+#include "graphics/MeshLodInformation.h"
+#include "Level.h"
+
+namespace orxonox
+{
+    CreateFactory(Model);
+
+    Model::Model(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(Model);
+
+        this->bCastShadows_ = true;
+
+        this->registerVariables();
+        //LoD
+        this->lodLevel_=5;
+    }
+
+    Model::~Model()
+    {
+        if (this->isInitialized() && this->mesh_.getEntity())
+            this->detachOgreObject(this->mesh_.getEntity());
+    }
+
+    void Model::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Model, XMLPort, xmlelement, mode);
+        
+        XMLPortParam(Model, "lodLevel", setLodLevel, getLodLevel, xmlelement, mode);
+        
+        XMLPortParam(Model, "mesh", setMeshSource, getMeshSource, xmlelement, mode);
+        XMLPortParam(Model, "shadow", setCastShadows, getCastShadows, xmlelement, mode).defaultValues(true);
+    }
+
+    void Model::registerVariables()
+    {
+        registerVariable(this->meshSrc_,    VariableDirection::ToClient, new NetworkCallback<Model>(this, &Model::changedMesh));
+        registerVariable(this->bCastShadows_, VariableDirection::ToClient, new NetworkCallback<Model>(this, &Model::changedShadows));
+    }
+
+    float Model::getBiggestScale(Vector3 scale3d)
+    {
+        float scaleFactor = scale3d.x;
+        if(scale3d.y>scaleFactor)
+            scaleFactor = scale3d.y;
+        if(scale3d.z>scaleFactor)
+            scaleFactor = scale3d.z;
+        return scaleFactor;
+    }
+    
+    void Model::changedMesh()
+    {
+        if (GameMode::showsGraphics())
+        {
+            if (this->mesh_.getEntity())
+                this->detachOgreObject(this->mesh_.getEntity());
+            
+            this->mesh_.setMeshSource(this->getScene()->getSceneManager(), this->meshSrc_);
+
+            if (this->mesh_.getEntity())
+            {
+                this->attachOgreObject(this->mesh_.getEntity());
+                this->mesh_.getEntity()->setCastShadows(this->bCastShadows_);
+                this->mesh_.setVisible(this->isVisible());
+                
+                //LOD
+                if(this->mesh_.getEntity()->getMesh()->getNumLodLevels()==1
+                    &&this->meshSrc_!="laserbeam.mesh")
+                {
+                    float scaleFactor = 1;
+                    BaseObject* creatorPtr = this;
+                    
+                    while(creatorPtr!=NULL&&orxonox_cast<WorldEntity*>(creatorPtr))
+                    {
+                        scaleFactor *= getBiggestScale(((WorldEntity*) creatorPtr)->getScale3D());
+                        creatorPtr = creatorPtr->getCreator();
+                    }
+                    
+                    Level* level_ = this->getLevel();
+                    
+                    MeshLodInformation* lodInfo = level_->getLodInfo(this->meshSrc_);
+                    
+                    if(lodInfo!=0)
+                        setLodLevel(lodInfo->getLodLevel());
+                    
+                    COUT(4) << "Setting lodLevel for " << this->meshSrc_<< " with lodLevel_: " << this->lodLevel_ <<" and scale: "<< scaleFactor << ":" << std::endl;
+
+#if OGRE_VERSION >= 0x010700
+                    Ogre::Mesh::LodValueList distList;
+#else
+                    Ogre::Mesh::LodDistanceList distList;
+#endif
+
+                    if(lodLevel_>0&&lodLevel_<=5)
+                    {
+                        float factor = scaleFactor*5/lodLevel_;
+                        
+                        COUT(4)<<"LodLevel set with factor: "<<factor<<std::endl;
+
+                        distList.push_back(70.0f*factor);
+                        distList.push_back(140.0f*factor);
+                        distList.push_back(170.0f*factor);
+                        distList.push_back(200.0f*factor);
+                        distList.push_back(230.0f*factor);
+                        distList.push_back(250.0f*factor);
+                        distList.push_back(270.0f*factor);
+                        distList.push_back(290.0f*factor);
+                        distList.push_back(310.0f*factor);
+                        distList.push_back(330.0f*factor);
+
+                        float reductionValue = 0.15f;
+
+                        
+                        //Generiert LOD-Levels
+                        this->mesh_.getEntity()->getMesh()->generateLodLevels(distList, Ogre::ProgressiveMesh::VRQ_PROPORTIONAL, reductionValue);
+                    }
+                    else
+                    {
+                        std::string what;
+                        if(lodLevel_>5)
+                            what = ">5";
+                        else
+                            what = "<0";
+                        
+                        COUT(4)<<"LodLevel not set because lodLevel("<<lodLevel_<<") was "<<what<<"."<<std::endl;
+                    }
+                }
+            }
+        }
+    }
+
+    void Model::changedShadows()
+    {
+        this->mesh_.setCastShadows(this->bCastShadows_);
+    }
+
+    void Model::changedVisibility()
+    {
+        SUPER(Model, changedVisibility);
+
+        this->mesh_.setVisible(this->isVisible());
+    }
+}
Index: /code/branches/rocket2/src/orxonox/graphics/Model.h
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/Model.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/Model.h	(revision 6952)
@@ -0,0 +1,84 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Model_H__
+#define _Model_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "tools/Mesh.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Model : public StaticEntity
+    {
+        public:
+            Model(BaseObject* creator);
+            virtual ~Model();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            virtual void changedVisibility();
+
+            inline const Mesh& getMesh() const
+                { return this->mesh_; }
+
+            inline void setMeshSource(const std::string& meshname)
+                { this->meshSrc_ = meshname; this->changedMesh(); }
+            inline const std::string& getMeshSource() const
+                { return this->meshSrc_; }
+
+            inline void setCastShadows(bool bCastShadows)
+                { this->bCastShadows_ = bCastShadows; this->changedShadows(); }
+            inline bool getCastShadows() const
+                { return this->bCastShadows_; }
+                
+        protected:
+            void changedMesh();
+            void changedShadows();
+            
+            //LoD
+            inline void setLodLevel(float lodLevel)
+                { this->lodLevel_ =  lodLevel; }
+            inline float getLodLevel() const
+                { return this->lodLevel_; }
+            float getBiggestScale(Vector3 scale3d);
+
+            std::string meshSrc_;
+            Mesh mesh_;
+            bool bCastShadows_;
+            
+            //LoD
+            float lodLevel_;
+    };
+}
+
+#endif /* _Model_H__ */
Index: /code/branches/rocket2/src/orxonox/graphics/ParticleEmitter.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/ParticleEmitter.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/ParticleEmitter.cc	(revision 6952)
@@ -0,0 +1,129 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+* @file
+* @brief class to control praticle effects
+*/
+
+#include "ParticleEmitter.h"
+
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+#include "tools/ParticleInterface.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    CreateFactory(ParticleEmitter);
+
+    ParticleEmitter::ParticleEmitter(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(ParticleEmitter);
+
+        if (GameMode::showsGraphics() && (!this->getScene() || !this->getScene()->getSceneManager()))
+            ThrowException(AbortLoading, "Can't create ParticleEmitter, no scene or no scene manager given.");
+
+        this->particles_ = 0;
+        this->LOD_ = LODParticle::Normal;
+
+        this->registerVariables();
+    }
+
+    ParticleEmitter::~ParticleEmitter()
+    {
+        if (this->isInitialized() && this->particles_)
+        {
+            this->detachOgreObject(this->particles_->getParticleSystem());
+            this->particles_->destroy();
+        }
+    }
+
+    void ParticleEmitter::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(ParticleEmitter, XMLPort, xmlelement, mode);
+
+        XMLPortParam(ParticleEmitter, "lod",    setLODxml, getLODxml, xmlelement, mode).defaultValues(LODParticle::Normal);
+        XMLPortParam(ParticleEmitter, "source", setSource, getSource, xmlelement, mode);
+    }
+
+    void ParticleEmitter::registerVariables()
+    {
+        registerVariable(this->source_, VariableDirection::ToClient, new NetworkCallback<ParticleEmitter>(this, &ParticleEmitter::sourceChanged));
+        registerVariable((int&)(this->LOD_),    VariableDirection::ToClient, new NetworkCallback<ParticleEmitter>(this, &ParticleEmitter::LODchanged));
+    }
+
+    void ParticleEmitter::changedVisibility()
+    {
+        SUPER(ParticleEmitter, changedVisibility);
+
+        if (this->particles_)
+            this->particles_->setVisible(this->isVisible());
+    }
+
+    void ParticleEmitter::changedActivity()
+    {
+        SUPER(ParticleEmitter, changedActivity);
+
+        if (this->particles_)
+            this->particles_->setEnabled(this->isActive());
+    }
+
+    void ParticleEmitter::sourceChanged()
+    {
+        if (this->particles_)
+        {
+            this->particles_->destroy();
+            this->particles_ = 0;
+        }
+
+        if (GameMode::showsGraphics() && this->getScene() && this->getScene()->getSceneManager())
+        {
+            try
+            {
+                this->particles_ = new ParticleInterface(this->getScene()->getSceneManager(), this->source_, this->LOD_);
+                this->attachOgreObject(this->particles_->getParticleSystem());
+                this->particles_->setVisible(this->isVisible());
+                this->particles_->setEnabled(this->isActive());
+            }
+            catch (...)
+            {
+                COUT(1) << "Error: Couln't load particle effect \"" << this->source_ << "\" because:" << std::endl
+                        << Exception::handleMessage() << std::endl;
+            }
+        }
+    }
+
+    void ParticleEmitter::LODchanged()
+    {
+        if (this->particles_)
+            this->particles_->setDetailLevel(this->LOD_);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/graphics/ParticleEmitter.h
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/ParticleEmitter.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/ParticleEmitter.h	(revision 6952)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ParticleEmitter_H__
+#define _ParticleEmitter_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport ParticleEmitter : public StaticEntity
+    {
+        public:
+            ParticleEmitter(BaseObject* creator);
+            ~ParticleEmitter();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            virtual void changedVisibility();
+            virtual void changedActivity();
+
+            inline ParticleInterface* getParticleInterface() const
+                { return this->particles_; }
+
+            inline void setSource(const std::string& source)
+                { this->source_ = source; this->sourceChanged(); }
+            inline const std::string& getSource() const
+                { return this->source_; }
+
+            inline void setLOD(LODParticle::Value level)
+                { this->LOD_ = level; this->LODchanged(); }
+            inline LODParticle::Value getLOD() const
+                { return this->LOD_; }
+
+        protected:
+            inline void setLODxml(unsigned int level)
+                { this->LOD_ = static_cast<LODParticle::Value>(level); this->LODchanged(); }
+            inline unsigned int getLODxml() const
+                { return static_cast<unsigned int>(this->LOD_); }
+
+            void sourceChanged();
+            void LODchanged();
+
+            ParticleInterface* particles_;
+            std::string        source_;
+            LODParticle::Value   LOD_;
+    };
+}
+
+#endif /* _ParticleEmitter_H__ */
Index: /code/branches/rocket2/src/orxonox/graphics/ParticleSpawner.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/ParticleSpawner.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/ParticleSpawner.cc	(revision 6952)
@@ -0,0 +1,130 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ParticleSpawner.h"
+
+#include "core/CoreIncludes.h"
+#include "core/EventIncludes.h"
+#include "core/Executor.h"
+#include "core/XMLPort.h"
+#include "tools/ParticleInterface.h"
+
+namespace orxonox
+{
+    CreateFactory(ParticleSpawner);
+
+    ParticleSpawner::ParticleSpawner(BaseObject* creator) : ParticleEmitter(creator)
+    {
+        RegisterObject(ParticleSpawner);
+
+        this->bAutostart_ = true;
+        this->bSuppressStart_ = false;
+        this->bAutoDestroy_ = true;
+        this->bForceDestroy_ = false;
+        this->bLoop_ = false;
+        this->startdelay_ = 0;
+        this->lifetime_ = 0;
+        this->destroydelay_ = 0;
+
+        this->startParticleSpawner();
+    }
+
+    ParticleSpawner::~ParticleSpawner()
+    {
+    }
+
+    void ParticleSpawner::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(ParticleSpawner, XMLPort, xmlelement, mode);
+
+        XMLPortParam(ParticleSpawner, "autostart",    setAutoStart,        getAutoStart,        xmlelement, mode).defaultValues(true);
+        XMLPortParam(ParticleSpawner, "autodestroy",  setDestroyAfterLife, getDestroyAfterLife, xmlelement, mode).defaultValues(false);
+        XMLPortParam(ParticleSpawner, "loop",         setLoop,             getLoop,             xmlelement, mode).defaultValues(false);
+        XMLPortParam(ParticleSpawner, "lifetime",     setLifetime,         getLifetime,         xmlelement, mode).defaultValues(0.0f);
+        XMLPortParam(ParticleSpawner, "startdelay",   setStartdelay,       getStartdelay,       xmlelement, mode).defaultValues(0.0f);
+        XMLPortParam(ParticleSpawner, "destroydelay", setDestroydelay,     getDestroydelay,     xmlelement, mode).defaultValues(0.0f);
+    }
+
+    void ParticleSpawner::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(ParticleSpawner, XMLEventPort, xmlelement, mode);
+
+        XMLPortEventState(ParticleSpawner, BaseObject, "spawn", spawn, xmlelement, mode);
+    }
+
+    void ParticleSpawner::configure(float lifetime, float startdelay, float destroydelay, bool autodestroy)
+    {
+        this->bAutoDestroy_ = autodestroy;
+        this->startdelay_ = startdelay;
+        this->lifetime_ = lifetime;
+        this->destroydelay_ = destroydelay;
+    }
+
+    void ParticleSpawner::startParticleSpawner()
+    {
+        this->setActive(false);
+
+        if (this->bForceDestroy_ || this->bSuppressStart_)
+        {
+            this->timer_.stopTimer();
+            return;
+        }
+
+        this->timer_.setTimer(this->startdelay_, false, createExecutor(createFunctor(&ParticleSpawner::fireParticleSpawner, this)));
+    }
+
+    void ParticleSpawner::fireParticleSpawner()
+    {
+        this->setActive(true);
+        if (this->lifetime_ != 0)
+            this->timer_.setTimer(this->lifetime_, false, createExecutor(createFunctor(&ParticleSpawner::stopParticleSpawner, this)));
+    }
+
+    void ParticleSpawner::stopParticleSpawner()
+    {
+        this->setActive(false);
+
+        if (this->bAutoDestroy_ || this->bForceDestroy_)
+        {
+            this->setPosition(this->getWorldPosition());
+            this->detachFromParent();
+
+            if (!this->timer_.isActive() || this->timer_.getRemainingTime() > this->destroydelay_)
+                this->timer_.setTimer(this->destroydelay_, false, createExecutor(createFunctor(&ParticleSpawner::destroyParticleSpawner, this)));
+        }
+        else if (this->bLoop_)
+        {
+            this->timer_.setTimer(this->destroydelay_, false, createExecutor(createFunctor(&ParticleSpawner::startParticleSpawner, this)));
+        }
+    }
+
+    void ParticleSpawner::destroyParticleSpawner()
+    {
+        this->destroy();
+    }
+}
Index: /code/branches/rocket2/src/orxonox/graphics/ParticleSpawner.h
===================================================================
--- /code/branches/rocket2/src/orxonox/graphics/ParticleSpawner.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/graphics/ParticleSpawner.h	(revision 6952)
@@ -0,0 +1,104 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ParticleSpawner_H__
+#define _ParticleSpawner_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "tools/Timer.h"
+#include "ParticleEmitter.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport ParticleSpawner : public ParticleEmitter
+    {
+        public:
+            ParticleSpawner(BaseObject* creator);
+            virtual ~ParticleSpawner();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
+
+            inline void stop(bool bDestroy)
+                { this->bForceDestroy_ = bDestroy; this->stopParticleSpawner(); }
+            inline void spawn()
+                { this->bSuppressStart_ = false; this->startParticleSpawner(); }
+
+            void configure(float lifetime = 0, float startdelay = 0, float destroydelay = 0, bool autodestroy = true);
+
+            inline void setAutoStart(bool autostart)
+                { this->bAutostart_ = autostart; this->bSuppressStart_ = !autostart; }
+            inline bool getAutoStart() const
+                { return this->bAutostart_; }
+
+            inline void setDestroyAfterLife(bool destroy)
+                { this->bAutoDestroy_ = destroy; }
+            inline bool getDestroyAfterLife() const
+                { return this->bAutoDestroy_; }
+
+            inline void setLoop(bool loop)
+                { this->bLoop_ = loop; }
+            inline bool getLoop() const
+                { return this->bLoop_; }
+
+            inline void setLifetime(float lifetime)
+                { this->lifetime_ = lifetime; this->startParticleSpawner(); }
+            inline float getLifetime() const
+                { return this->lifetime_; }
+
+            inline void setStartdelay(float startdelay)
+                { this->startdelay_ = startdelay; this->startParticleSpawner(); }
+            inline float getStartdelay() const
+                { return this->startdelay_; }
+
+            inline void setDestroydelay(float destroydelay)
+                { this->destroydelay_ = destroydelay; this->startParticleSpawner(); }
+            inline float getDestroydelay() const
+                { return this->destroydelay_; }
+
+        private:
+            void startParticleSpawner();
+            void fireParticleSpawner();
+            void stopParticleSpawner();
+            void destroyParticleSpawner();
+
+            Timer timer_;
+
+            bool  bSuppressStart_;
+            bool  bAutostart_;
+            bool  bForceDestroy_;
+            bool  bAutoDestroy_;
+            bool  bLoop_;
+            float startdelay_;
+            float lifetime_;
+            float destroydelay_;
+    };
+}
+
+#endif /* _ParticleSpawner_H__ */
Index: /code/branches/rocket2/src/orxonox/infos/Bot.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/infos/Bot.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/infos/Bot.cc	(revision 6952)
@@ -0,0 +1,98 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Bot.h"
+
+#include "util/Math.h"
+#include "core/GameMode.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "gametypes/Gametype.h"
+#include "controllers/AIController.h"
+
+namespace orxonox
+{
+    CreateFactory(Bot);
+
+    Bot::Bot(BaseObject* creator) : PlayerInfo(creator)
+    {
+        RegisterObject(Bot);
+
+        this->bHumanPlayer_ = false;
+        this->bLocalPlayer_ = GameMode::isMaster();
+        this->bSetUnreadyAfterSpawn_ = false;
+        this->setReadyToSpawn(true);
+        this->defaultController_ = Class(AIController);
+
+        this->setConfigValues();
+
+        this->setName(this->names_[static_cast<size_t>(rnd() * this->names_.size())]);
+
+        if (this->getGametype())
+            this->getGametype()->playerEntered(this);
+
+        this->createController();
+    }
+
+    Bot::~Bot()
+    {
+    }
+
+    void Bot::setConfigValues()
+    {
+        static const std::string names[] =
+        {
+            "Dr. Julius No",
+            "Rosa Klebb",
+            "Auric Goldfinger",
+            "Emilio Largo",
+            "Ernst Stavro Blofeld",
+            "Dr. Kananga",
+            "Francisco Scaramanga",
+            "Karl Stromberg",
+            "Sir Hugo Drax",
+            "Aris Kristatos",
+            "Kamal Khan",
+            "General Orlov",
+            "Max Zorin",
+            "Brad Whitaker",
+            "General Koskov",
+            "Franz Sanchez",
+            "Alec Trevelyan",
+            "Elliot Carver",
+            "Viktor Zokas",
+            "Gustav Graves",
+            "Le Chiffre",
+            "Mr. White",
+            "Dominic Greene"
+        };
+        static std::vector<std::string> defaultnames(names, names + sizeof(names) / sizeof(std::string));
+
+        SetConfigValue(names_, defaultnames);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/infos/Bot.h
===================================================================
--- /code/branches/rocket2/src/orxonox/infos/Bot.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/infos/Bot.h	(revision 6952)
@@ -0,0 +1,59 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Bot_H__
+#define _Bot_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <vector>
+#include "PlayerInfo.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Bot : public PlayerInfo
+    {
+        public:
+            Bot(BaseObject* creator);
+            virtual ~Bot();
+
+            void setConfigValues();
+
+            inline bool isInitialized() const
+                { return true; }
+            inline float getPing() const
+                { return 0; }
+            inline float getPacketLossRatio() const
+                { return 0; }
+
+        private:
+            std::vector<std::string> names_;
+    };
+}
+
+#endif /* _Bot_H__ */
Index: /code/branches/rocket2/src/orxonox/infos/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/infos/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/infos/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,7 @@
+ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+  Bot.cc
+  Info.cc
+  PlayerInfo.cc
+  HumanPlayer.cc
+  GametypeInfo.cc
+)
Index: /code/branches/rocket2/src/orxonox/infos/GametypeInfo.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/infos/GametypeInfo.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/infos/GametypeInfo.cc	(revision 6952)
@@ -0,0 +1,129 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "GametypeInfo.h"
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "network/NetworkFunction.h"
+#include "network/Host.h"
+#include "interfaces/GametypeMessageListener.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(GametypeInfo);
+
+    registerMemberNetworkFunction(GametypeInfo, dispatchAnnounceMessage);
+    registerMemberNetworkFunction(GametypeInfo, dispatchKillMessage);
+    registerMemberNetworkFunction(GametypeInfo, dispatchDeathMessage);
+
+    GametypeInfo::GametypeInfo(BaseObject* creator) : Info(creator)
+    {
+        RegisterObject(GametypeInfo);
+
+        this->bStarted_ = false;
+        this->bEnded_ = false;
+        this->startCountdown_ = 0;
+        this->bStartCountdownRunning_ = false;
+
+        this->registerVariables();
+    }
+
+    GametypeInfo::~GametypeInfo()
+    {
+    }
+
+    void GametypeInfo::registerVariables()
+    {
+        registerVariable(this->bStarted_,               VariableDirection::ToClient);
+        registerVariable(this->bEnded_,                 VariableDirection::ToClient);
+        registerVariable(this->startCountdown_,         VariableDirection::ToClient);
+        registerVariable(this->bStartCountdownRunning_, VariableDirection::ToClient);
+        registerVariable(this->hudtemplate_,            VariableDirection::ToClient);
+    }
+
+    void GametypeInfo::sendAnnounceMessage(const std::string& message)
+    {
+        if (GameMode::isMaster())
+        {
+            callMemberNetworkFunction(GametypeInfo, dispatchAnnounceMessage, this->getObjectID(), CLIENTID_UNKNOWN, message);
+            this->dispatchAnnounceMessage(message);
+        }
+    }
+
+    void GametypeInfo::sendAnnounceMessage(const std::string& message, unsigned int clientID)
+    {
+        if (GameMode::isMaster())
+        {
+            if (clientID == CLIENTID_SERVER)
+                this->dispatchAnnounceMessage(message);
+            else
+                callMemberNetworkFunction(GametypeInfo, dispatchAnnounceMessage, this->getObjectID(), clientID, message);
+        }
+    }
+
+    void GametypeInfo::sendKillMessage(const std::string& message, unsigned int clientID)
+    {
+        if (GameMode::isMaster())
+        {
+            if (clientID == CLIENTID_SERVER)
+                this->dispatchKillMessage(message);
+            else
+                callMemberNetworkFunction(GametypeInfo, dispatchKillMessage, this->getObjectID(), clientID, message);
+        }
+    }
+
+    void GametypeInfo::sendDeathMessage(const std::string& message, unsigned int clientID)
+    {
+        if (GameMode::isMaster())
+        {
+            if (clientID == CLIENTID_SERVER)
+                this->dispatchDeathMessage(message);
+            else
+                callMemberNetworkFunction(GametypeInfo, dispatchDeathMessage, this->getObjectID(), clientID, message);
+        }
+    }
+
+    void GametypeInfo::dispatchAnnounceMessage(const std::string& message)
+    {
+        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
+            it->announcemessage(this, message);
+    }
+
+    void GametypeInfo::dispatchKillMessage(const std::string& message)
+    {
+        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
+            it->killmessage(this, message);
+    }
+
+    void GametypeInfo::dispatchDeathMessage(const std::string& message)
+    {
+        for (ObjectList<GametypeMessageListener>::iterator it = ObjectList<GametypeMessageListener>::begin(); it != ObjectList<GametypeMessageListener>::end(); ++it)
+            it->deathmessage(this, message);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/infos/GametypeInfo.h
===================================================================
--- /code/branches/rocket2/src/orxonox/infos/GametypeInfo.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/infos/GametypeInfo.h	(revision 6952)
@@ -0,0 +1,80 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GametypeInfo_H__
+#define _GametypeInfo_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "Info.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport GametypeInfo : public Info
+    {
+        friend class Gametype;
+
+        public:
+            GametypeInfo(BaseObject* creator);
+            virtual ~GametypeInfo();
+
+            void registerVariables();
+
+            inline bool hasStarted() const
+                { return this->bStarted_; }
+            inline bool hasEnded() const
+                { return this->bEnded_; }
+
+            inline bool isStartCountdownRunning() const
+                { return this->bStartCountdownRunning_; }
+            inline float getStartCountdown() const
+                { return this->startCountdown_; }
+
+            inline const std::string& getHUDTemplate() const
+                { return this->hudtemplate_; }
+
+            void sendAnnounceMessage(const std::string& message);
+            void sendAnnounceMessage(const std::string& message, unsigned int clientID);
+            void sendKillMessage(const std::string& message, unsigned int clientID);
+            void sendDeathMessage(const std::string& message, unsigned int clientID);
+
+            void dispatchAnnounceMessage(const std::string& message);
+            void dispatchKillMessage(const std::string& message);
+            void dispatchDeathMessage(const std::string& message);
+
+        private:
+            bool bStarted_;
+            bool bEnded_;
+            bool bStartCountdownRunning_;
+            float startCountdown_;
+            std::string hudtemplate_;
+    };
+}
+
+#endif /* _GametypeInfo_H__ */
Index: /code/branches/rocket2/src/orxonox/infos/HumanPlayer.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/infos/HumanPlayer.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/infos/HumanPlayer.cc	(revision 6952)
@@ -0,0 +1,204 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "HumanPlayer.h"
+
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/GameMode.h"
+#include "network/ClientInformation.h"
+#include "network/Host.h"
+#include "controllers/HumanController.h"
+#include "controllers/NewHumanController.h"
+#include "gametypes/Gametype.h"
+#include "overlays/OverlayGroup.h"
+
+namespace orxonox
+{
+    CreateUnloadableFactory(HumanPlayer);
+
+    HumanPlayer::HumanPlayer(BaseObject* creator) : PlayerInfo(creator)
+    {
+        RegisterObject(HumanPlayer);
+
+        this->server_initialized_ = GameMode::isMaster();
+        this->client_initialized_ = false;
+
+        this->bHumanPlayer_ = true;
+        this->defaultController_ = Class(NewHumanController);
+
+        this->humanHud_ = 0;
+        this->gametypeHud_ = 0;
+
+        this->setConfigValues();
+        this->registerVariables();
+    }
+
+    HumanPlayer::~HumanPlayer()
+    {
+        if (this->BaseObject::isInitialized())
+        {
+            if (this->humanHud_)
+                this->humanHud_->destroy();
+
+            if (this->gametypeHud_)
+                this->gametypeHud_->destroy();
+        }
+    }
+
+    void HumanPlayer::setConfigValues()
+    {
+        SetConfigValue(nick_, "Player").callback(this, &HumanPlayer::configvaluecallback_changednick);
+        SetConfigValue(hudtemplate_, "defaultHUD").callback(this, &HumanPlayer::configvaluecallback_changedHUDTemplate);
+    }
+
+    void HumanPlayer::registerVariables()
+    {
+        registerVariable(this->synchronize_nick_, VariableDirection::ToServer, new NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_changednick));
+
+        registerVariable(this->clientID_,           VariableDirection::ToClient, new NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_clientIDchanged));
+        registerVariable(this->server_initialized_, VariableDirection::ToClient, new NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_server_initialized));
+        registerVariable(this->client_initialized_, VariableDirection::ToServer, new NetworkCallback<HumanPlayer>(this, &HumanPlayer::networkcallback_client_initialized));
+    }
+
+    void HumanPlayer::configvaluecallback_changednick()
+    {
+        if (this->isLocalPlayer())
+        {
+            this->synchronize_nick_ = this->nick_;
+
+            if (GameMode::isMaster())
+                this->setName(this->nick_);
+        }
+    }
+
+    void HumanPlayer::configvaluecallback_changedHUDTemplate()
+    {
+        this->setHumanHUDTemplate(this->hudtemplate_);
+    }
+
+    void HumanPlayer::networkcallback_changednick()
+    {
+        this->setName(this->synchronize_nick_);
+    }
+
+    void HumanPlayer::networkcallback_clientIDchanged()
+    {
+        if (this->clientID_ == Host::getPlayerID())
+        {
+            this->bLocalPlayer_ = true;
+            this->synchronize_nick_ = this->nick_;
+            this->client_initialized_ = true;
+
+            if (!GameMode::isMaster())
+                this->setSyncMode(ObjectDirection::Bidirectional);
+            else
+                this->setName(this->nick_);
+
+            this->createController();
+            this->updateHumanHUD();
+        }
+    }
+
+    void HumanPlayer::networkcallback_server_initialized()
+    {
+        this->client_initialized_ = true;
+    }
+
+    void HumanPlayer::networkcallback_client_initialized()
+    {
+        if (this->getGametype())
+            this->getGametype()->playerEntered(this);
+    }
+
+    bool HumanPlayer::isInitialized() const
+    {
+        return (this->server_initialized_ && this->client_initialized_);
+    }
+
+    float HumanPlayer::getPing() const
+    {
+        return static_cast<float>(ClientInformation::findClient(this->getClientID())->getRTT());
+    }
+
+    float HumanPlayer::getPacketLossRatio() const
+    {
+        return static_cast<float>(ClientInformation::findClient(this->getClientID())->getPacketLoss());
+    }
+
+    void HumanPlayer::setClientID(unsigned int clientID)
+    {
+        this->clientID_ = clientID;
+        this->networkcallback_clientIDchanged();
+    }
+
+    void HumanPlayer::changedGametype()
+    {
+        PlayerInfo::changedGametype();
+
+        if (this->isInitialized() && this->isLocalPlayer())
+        {
+            if (this->getGametype() && !this->getGametype()->getHUDTemplate().empty())
+                this->setGametypeHUDTemplate(this->getGametype()->getHUDTemplate());
+            else
+                this->setGametypeHUDTemplate("");
+        }
+    }
+
+    void HumanPlayer::updateHumanHUD()
+    {
+        if (this->humanHud_)
+        {
+            this->humanHud_->destroy();
+            this->humanHud_ = 0;
+        }
+
+        if (this->isLocalPlayer() && !this->humanHudTemplate_.empty() && GameMode::showsGraphics())
+        {
+            this->humanHud_ = new OverlayGroup(this);
+            this->humanHud_->addTemplate(this->humanHudTemplate_);
+            this->humanHud_->setOwner(this);
+        }
+    }
+
+    void HumanPlayer::updateGametypeHUD()
+    {
+        if (this->gametypeHud_)
+        {
+            this->gametypeHud_->destroy();
+            this->gametypeHud_ = 0;
+        }
+
+        if (this->isLocalPlayer() && !this->gametypeHudTemplate_.empty())
+        {
+            this->gametypeHud_ = new OverlayGroup(this);
+            this->gametypeHud_->addTemplate(this->gametypeHudTemplate_);
+            this->gametypeHud_->setOwner(this);
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/infos/HumanPlayer.h
===================================================================
--- /code/branches/rocket2/src/orxonox/infos/HumanPlayer.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/infos/HumanPlayer.h	(revision 6952)
@@ -0,0 +1,106 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _HumanPlayer_H__
+#define _HumanPlayer_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "PlayerInfo.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport HumanPlayer : public PlayerInfo
+    {
+        public:
+            HumanPlayer(BaseObject* creator);
+            virtual ~HumanPlayer();
+
+            void registerVariables();
+            void setConfigValues();
+
+            bool isInitialized() const;
+            float getPing() const;
+            float getPacketLossRatio() const;
+
+            void setClientID(unsigned int clientID);
+
+            virtual void changedGametype();
+
+            inline void setHumanHUDTemplate(const std::string& name)
+            {
+                if (name != this->humanHudTemplate_)
+                {
+                    this->humanHudTemplate_ = name;
+                    this->updateHumanHUD();
+                }
+            }
+            inline const std::string& getHumanHUDTemplate() const
+                { return this->humanHudTemplate_; }
+            inline OverlayGroup* getHumanHUD() const
+                { return this->humanHud_; }
+
+            inline void setGametypeHUDTemplate(const std::string& name)
+            {
+                if (name != this->gametypeHudTemplate_)
+                {
+                    this->gametypeHudTemplate_ = name;
+                    this->updateGametypeHUD();
+                }
+            }
+            inline const std::string& getGametypeHUDTemplate() const
+                { return this->gametypeHudTemplate_; }
+            inline OverlayGroup* getGametypeHUD() const
+                { return this->gametypeHud_; }
+
+        protected:
+            void configvaluecallback_changednick();
+            void configvaluecallback_changedHUDTemplate();
+            void networkcallback_changednick();
+            void networkcallback_clientIDchanged();
+            void networkcallback_server_initialized();
+            void networkcallback_client_initialized();
+
+            void updateHumanHUD();
+            void updateGametypeHUD();
+
+            std::string nick_;
+            std::string synchronize_nick_;
+            std::string hudtemplate_;
+            bool server_initialized_;
+            bool client_initialized_;
+
+            std::string humanHudTemplate_;
+            OverlayGroup* humanHud_;
+            std::string gametypeHudTemplate_;
+            OverlayGroup* gametypeHud_;
+    };
+}
+
+#endif /* _HumanPlayer_H__ */
Index: /code/branches/rocket2/src/orxonox/infos/Info.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/infos/Info.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/infos/Info.cc	(revision 6952)
@@ -0,0 +1,38 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Info.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    Info::Info(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
+    {
+        RegisterObject(Info);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/infos/Info.h
===================================================================
--- /code/branches/rocket2/src/orxonox/infos/Info.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/infos/Info.h	(revision 6952)
@@ -0,0 +1,47 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Info_H__
+#define _Info_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "network/synchronisable/Synchronisable.h"
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Info : public BaseObject, public Synchronisable
+    {
+        public:
+            Info(BaseObject* creator);
+            virtual ~Info() {}
+    };
+}
+
+#endif /* _Info_H__ */
Index: /code/branches/rocket2/src/orxonox/infos/PlayerInfo.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/infos/PlayerInfo.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/infos/PlayerInfo.cc	(revision 6952)
@@ -0,0 +1,262 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include <cassert>
+
+#include "PlayerInfo.h"
+
+#include "core/CoreIncludes.h"
+#include "network/ClientInformation.h"
+#include "gametypes/Gametype.h"
+#include "worldentities/ControllableEntity.h"
+#include "controllers/Controller.h"
+
+namespace orxonox
+{
+    PlayerInfo::PlayerInfo(BaseObject* creator) : Info(creator)
+    {
+        RegisterObject(PlayerInfo);
+
+        this->clientID_ = CLIENTID_UNKNOWN;
+        this->bHumanPlayer_ = false;
+        this->bLocalPlayer_ = false;
+        this->bReadyToSpawn_ = false;
+        this->bSetUnreadyAfterSpawn_ = true;
+        this->controller_ = 0;
+        this->controllableEntity_ = 0;
+        this->controllableEntityID_ = OBJECTID_UNKNOWN;
+        this->oldControllableEntity_ = 0;
+
+        this->gtinfo_ = 0;
+        this->gtinfoID_ = OBJECTID_UNKNOWN;
+        this->updateGametypeInfo();
+
+        this->registerVariables();
+    }
+
+    PlayerInfo::~PlayerInfo()
+    {
+        if (this->BaseObject::isInitialized())
+        {
+            this->stopControl();
+
+            if (this->controller_)
+            {
+                this->controller_->destroy();
+                this->controller_ = 0;
+            }
+
+            if (this->getGametype())
+                this->getGametype()->playerLeft(this);
+        }
+    }
+
+    void PlayerInfo::registerVariables()
+    {
+        registerVariable(this->name_,                 VariableDirection::ToClient, new NetworkCallback<PlayerInfo>(this, &PlayerInfo::changedName));
+        registerVariable(this->controllableEntityID_, VariableDirection::ToClient, new NetworkCallback<PlayerInfo>(this, &PlayerInfo::networkcallback_changedcontrollableentityID));
+        registerVariable(this->gtinfoID_,             VariableDirection::ToClient, new NetworkCallback<PlayerInfo>(this, &PlayerInfo::networkcallback_changedgtinfoID));
+    }
+
+    void PlayerInfo::changedName()
+    {
+        SUPER(PlayerInfo, changedName);
+
+        if (this->isInitialized() && this->getGametype())
+            this->getGametype()->playerChangedName(this);
+    }
+
+    void PlayerInfo::changedGametype()
+    {
+        this->updateGametypeInfo();
+
+        if (this->isInitialized())
+        {
+            if (this->getOldGametype())
+            {
+                if (this->getGametype())
+                    this->getOldGametype()->playerSwitched(this, this->getGametype());
+                else
+                    this->getOldGametype()->playerLeft(this);
+            }
+
+            if (this->getGametype())
+            {
+                if (this->getOldGametype())
+                    this->getGametype()->playerSwitchedBack(this, this->getOldGametype());
+                else
+                    this->getGametype()->playerEntered(this);
+            }
+        }
+    }
+
+    void PlayerInfo::updateGametypeInfo()
+    {
+        this->gtinfo_ = 0;
+        this->gtinfoID_ = OBJECTID_UNKNOWN;
+
+        if (this->getGametype() && this->getGametype()->getGametypeInfo())
+        {
+            this->gtinfo_ = this->getGametype()->getGametypeInfo();
+            this->gtinfoID_ = this->gtinfo_->getObjectID();
+        }
+    }
+
+    void PlayerInfo::createController()
+    {
+        if (this->controller_)
+        {
+            this->controller_->destroy();
+            this->controller_ = 0;
+        }
+        this->controller_ = this->defaultController_.fabricate(this);
+        assert(this->controller_);
+        this->controller_->setPlayer(this);
+        if (this->controllableEntity_)
+        {
+            this->controller_->setControllableEntity(this->controllableEntity_);
+            this->controllableEntity_->setController(this->controller_);
+        }
+        this->changedController();
+    }
+
+    void PlayerInfo::startControl(ControllableEntity* entity)
+    {
+        if (!entity || entity == this->controllableEntity_)
+            return;
+
+        if (this->oldControllableEntity_)
+            this->stopTemporaryControl();
+        if (this->controllableEntity_)
+            this->stopControl();
+
+        this->controllableEntity_ = entity;
+        this->controllableEntityID_ = entity->getObjectID();
+
+        entity->setPlayer(this);
+
+        this->bReadyToSpawn_ &= (!this->bSetUnreadyAfterSpawn_);
+
+        if (this->controller_)
+        {
+            this->controller_->setControllableEntity(entity);
+            this->controllableEntity_->setController(this->controller_);
+        }
+
+        this->changedControllableEntity();
+    }
+
+    void PlayerInfo::startTemporaryControl(ControllableEntity* entity)
+    {
+        if (!entity)
+            return;
+
+//         assert( this->temporaryControllableEntity_==0 );
+
+        this->oldControllableEntity_ = this->controllableEntity_;
+        this->controllableEntity_ = entity;
+        this->controllableEntityID_ = entity->getObjectID();
+
+        entity->setPlayer(this);
+
+        if (this->controller_)
+            this->controller_->setControllableEntity(entity);
+
+        this->changedControllableEntity();
+    }
+
+    void PlayerInfo::stopControl()
+    {
+        if ( this->oldControllableEntity_ )
+            this->stopTemporaryControl();
+
+        ControllableEntity* entity = this->controllableEntity_;
+
+        if (!entity)
+            return;
+
+        this->controllableEntity_->setController(0);
+        this->controllableEntity_ = 0;
+        this->controllableEntityID_ = OBJECTID_UNKNOWN;
+
+        if (this->controller_)
+            this->controller_->setControllableEntity(0);
+
+        if ( GameMode::isMaster() )
+            entity->removePlayer();
+
+        this->changedControllableEntity();
+    }
+
+    void PlayerInfo::stopTemporaryControl()
+    {
+        ControllableEntity* entity = this->controllableEntity_;
+
+        assert( this->controllableEntity_ && this->oldControllableEntity_ );
+        if( !entity || !this->oldControllableEntity_ )
+            return;
+
+        this->controllableEntity_ = this->oldControllableEntity_;
+        this->controllableEntityID_ = this->controllableEntity_->getObjectID();
+        this->oldControllableEntity_ = 0;
+
+        if ( this->controllableEntity_ && this->controller_)
+            this->controller_->setControllableEntity(this->controllableEntity_);
+
+        if ( GameMode::isMaster() )
+            entity->removePlayer();
+
+        this->changedControllableEntity();
+    }
+
+    void PlayerInfo::networkcallback_changedcontrollableentityID()
+    {
+        if (this->controllableEntityID_ != OBJECTID_UNKNOWN)
+        {
+            Synchronisable* temp = Synchronisable::getSynchronisable(this->controllableEntityID_);
+            ControllableEntity* entity = orxonox_cast<ControllableEntity*>(temp);
+            this->startControl(entity);
+        }
+        else
+        {
+            this->stopControl();
+        }
+    }
+
+
+    void PlayerInfo::networkcallback_changedgtinfoID()
+    {
+        if (this->gtinfoID_ != OBJECTID_UNKNOWN)
+        {
+            this->gtinfo_ = orxonox_cast<GametypeInfo*>(Synchronisable::getSynchronisable(this->gtinfoID_));
+
+            if (!this->gtinfo_)
+                this->gtinfoID_ = OBJECTID_UNKNOWN;
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/infos/PlayerInfo.h
===================================================================
--- /code/branches/rocket2/src/orxonox/infos/PlayerInfo.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/infos/PlayerInfo.h	(revision 6952)
@@ -0,0 +1,108 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _PlayerInfo_H__
+#define _PlayerInfo_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "Info.h"
+#include "core/SubclassIdentifier.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport PlayerInfo : public Info
+    {
+        public:
+            PlayerInfo(BaseObject* creator);
+            virtual ~PlayerInfo();
+
+            void registerVariables();
+
+            virtual void changedName();
+            virtual void changedGametype();
+
+            virtual void changedController() {}
+            virtual void changedControllableEntity() {}
+
+            inline bool isHumanPlayer() const
+                { return this->bHumanPlayer_; }
+            inline bool isLocalPlayer() const
+                { return this->bLocalPlayer_; }
+            inline unsigned int getClientID() const
+                { return this->clientID_; }
+
+            virtual bool isInitialized() const = 0;
+            virtual float getPing() const = 0;
+            virtual float getPacketLossRatio() const = 0;
+
+            inline void setReadyToSpawn(bool bReady)
+                { this->bReadyToSpawn_ = bReady; }
+            inline bool isReadyToSpawn() const
+                { return this->bReadyToSpawn_; }
+
+            void startControl(ControllableEntity* entity);
+            void stopControl();
+            void startTemporaryControl(ControllableEntity* entity);
+            void stopTemporaryControl();
+
+            inline ControllableEntity* getControllableEntity() const
+                { return this->controllableEntity_; }
+
+            inline Controller* getController() const
+                { return this->controller_; }
+
+            inline const GametypeInfo* getGametypeInfo() const
+                { return this->gtinfo_; }
+
+        protected:
+            void createController();
+
+            bool bHumanPlayer_;
+            bool bLocalPlayer_;
+            bool bSetUnreadyAfterSpawn_;
+            SubclassIdentifier<Controller> defaultController_;
+            unsigned int clientID_;
+
+        private:
+            void networkcallback_changedcontrollableentityID();
+            void networkcallback_changedgtinfoID();
+            void updateGametypeInfo();
+
+            bool bReadyToSpawn_;
+            Controller* controller_;
+            ControllableEntity* controllableEntity_;
+            ControllableEntity* oldControllableEntity_;
+            unsigned int controllableEntityID_;
+
+            const GametypeInfo* gtinfo_;
+            unsigned int gtinfoID_;
+    };
+}
+
+#endif /* _PlayerInfo_H__ */
Index: /code/branches/rocket2/src/orxonox/interfaces/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/interfaces/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/interfaces/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,5 @@
+ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+  InterfaceCompilation.cc
+  Pickupable.cc
+  RadarViewable.cc
+)
Index: /code/branches/rocket2/src/orxonox/interfaces/GametypeMessageListener.h
===================================================================
--- /code/branches/rocket2/src/orxonox/interfaces/GametypeMessageListener.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/interfaces/GametypeMessageListener.h	(revision 6952)
@@ -0,0 +1,49 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GametypeMessageListener_H__
+#define _GametypeMessageListener_H__
+
+#include "OrxonoxPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport GametypeMessageListener : virtual public OrxonoxClass
+    {
+        public:
+            GametypeMessageListener();
+            virtual ~GametypeMessageListener() {}
+
+            virtual void announcemessage(const GametypeInfo* gtinfo, const std::string& message) {}
+            virtual void killmessage(const GametypeInfo* gtinfo, const std::string& message) {}
+            virtual void deathmessage(const GametypeInfo* gtinfo, const std::string& message) {}
+    };
+}
+
+#endif /* _GametypeMessageListener_H__ */
Index: /code/branches/rocket2/src/orxonox/interfaces/InterfaceCompilation.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/interfaces/InterfaceCompilation.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/interfaces/InterfaceCompilation.cc	(revision 6952)
@@ -0,0 +1,118 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief
+    Compiles all the interfaces in the orxonox library with mostly just a constructor.
+*/
+
+#include "GametypeMessageListener.h"
+#include "PickupCarrier.h"
+#include "PlayerTrigger.h"
+#include "RadarListener.h"
+#include "Rewardable.h"
+#include "TeamColourable.h"
+#include "NotificationListener.h"
+
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    //----------------------------
+    // GametypeMessageListener
+    //----------------------------
+    GametypeMessageListener::GametypeMessageListener()
+    {
+        RegisterRootObject(GametypeMessageListener);
+    }
+    
+    //----------------------------
+    // PickupCarrier
+    //----------------------------
+    PickupCarrier::PickupCarrier()
+    {
+        RegisterRootObject(PickupCarrier);
+        
+        this->setCarrierName("PickupCarrier");
+    }
+    
+    PickupCarrier::~PickupCarrier()
+    {
+        std::set<Pickupable*>::iterator it = this->pickups_.begin();
+        while(it != this->pickups_.end())
+        {
+            (*(it++))->destroy();
+        }
+
+        this->pickups_.clear();
+    }
+
+    //----------------------------
+    // PlayerTrigger
+    //----------------------------
+    PlayerTrigger::PlayerTrigger()
+    {
+        RegisterRootObject(PlayerTrigger);
+
+        this->player_ = NULL;
+        this->isForPlayer_ = true;
+    }
+    
+    //----------------------------
+    // RadarListener
+    //----------------------------
+    RadarListener::RadarListener()
+    {
+        RegisterRootObject(RadarListener);
+    }
+
+    //----------------------------
+    // TeamColourable
+    //----------------------------
+    TeamColourable::TeamColourable()
+    {
+        RegisterRootObject(TeamColourable);
+    }
+
+    //----------------------------
+    // Rewardable
+    //----------------------------
+    Rewardable::Rewardable()
+    {
+        RegisterRootObject(Rewardable);
+    }
+
+    //----------------------------
+    // NotificationListener
+    //----------------------------
+    NotificationListener::NotificationListener()
+    {
+        RegisterRootObject(NotificationListener);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/interfaces/NotificationListener.h
===================================================================
--- /code/branches/rocket2/src/orxonox/interfaces/NotificationListener.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/interfaces/NotificationListener.h	(revision 6952)
@@ -0,0 +1,67 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the NotificationListener class.
+*/
+
+#ifndef _NotificationListener_H__
+#define _NotificationListener_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <ctime>
+#include <set>
+#include <string>
+
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class Notification;
+
+    /**
+    @brief
+        NotificationListener interface.
+    @author
+        Fabian 'x3n' Landau
+    */
+    class _OrxonoxExport NotificationListener : virtual public OrxonoxClass
+    {
+        public:
+            NotificationListener();
+            virtual ~NotificationListener() {}
+
+            virtual const std::set<std::string> & getTargetsSet() = 0;
+            virtual void update(void) = 0;
+            virtual void update(Notification* notification, const std::time_t & time) = 0;
+    };
+}
+
+#endif /* _NotificationListener_H__ */
Index: /code/branches/rocket2/src/orxonox/interfaces/PickupCarrier.h
===================================================================
--- /code/branches/rocket2/src/orxonox/interfaces/PickupCarrier.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/interfaces/PickupCarrier.h	(revision 6952)
@@ -0,0 +1,264 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file PickupCarrier.h
+    @brief Definition of the PickupCarrier class.
+*/
+
+#ifndef _PickupCarrier_H__
+#define _PickupCarrier_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <list>
+#include <set>
+#include "Pickupable.h"
+#include "core/Identifier.h"
+#include "core/WeakPtr.h"
+
+#include "core/OrxonoxClass.h"
+
+namespace orxonox // tolua_export
+{ // tolua_export
+
+    //! Forward-declarations.
+    class PickupManager;
+    class Pickup;
+    class HealthPickup;
+    class InvisiblePickup;
+    class MetaPickup;
+    class SpeedPickup;
+
+    /**
+    @brief
+        The PickupCarrier interface provides the means, for any class implementing it, to possess Pickupables.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _OrxonoxExport PickupCarrier  // tolua_export
+        : virtual public OrxonoxClass
+    { // tolua_export
+        //! So that the different Pickupables have full access to their PickupCarrier.
+        friend class Pickupable;
+        friend class PickupManager;
+        //! Friends. 
+        friend class Pickup;
+        friend class HealthPickup;
+        friend class InvisiblePickup;
+        friend class MetaPickup;
+        friend class SpeedPickup;
+
+        public:
+            PickupCarrier(); //!< Constructor.
+            virtual ~PickupCarrier(); //!< Destructor.
+
+            /**
+            @brief Can be called to pick up a Pickupable.
+            @param pickup A pointer to the Pickupable.
+            @return Returns true if the Pickupable was picked up, false if not.
+            */
+            bool pickup(Pickupable* pickup)
+                {
+                    bool pickedUp = this->pickups_.insert(pickup).second;
+                    if(pickedUp)
+                    {
+                        COUT(4) << "Picked up Pickupable " << pickup->getIdentifier()->getName() << "(&" << pickup << ")." << std::endl;
+                        pickup->pickedUp(this);
+                    }
+                    return pickedUp;
+                }
+
+            /**
+            @brief Can be called to drop a Pickupable.
+            @param pickup A pointer to the Pickupable.
+            @param drop If the Pickupable should just be removed from the PickupCarrier without further action, this can be set to false. true is default.
+            @return Returns true if the Pickupable has been dropped, false if not.
+            */
+            bool drop(Pickupable* pickup, bool drop = true)
+                {
+                    bool dropped = this->pickups_.erase(pickup) == 1;
+                    if(dropped && drop)
+                    {
+                        COUT(4) << "Dropping Pickupable " << pickup->getIdentifier()->getName() << "(&" << pickup << ")." << std::endl;
+                        pickup->dropped();
+                    }
+                    return dropped;
+                }
+
+            /**
+            @brief Can be used to check whether the PickupCarrier or a child of his is a target ot the input Pickupable.
+            @param pickup A pointer to the Pickupable.
+            @return Returns true if the PickupCarrier or one of its children is a target, false if not.
+            */
+            bool isTarget(const Pickupable* pickup)
+                {
+                    if(pickup->isTarget(this)) //!< If the PickupCarrier itself is a target.
+                        return true;
+
+                    //! Go recursively through all children to check whether they are a target.
+                    std::vector<PickupCarrier*>* children = this->getCarrierChildren();
+                    for(std::vector<PickupCarrier*>::const_iterator it = children->begin(); it != children->end(); it++)
+                    {
+                        if((*it)->isTarget(pickup))
+                            return true;
+                    }
+
+                    children->clear();
+                    delete children;
+
+                    return false;
+                }
+
+            /**
+            @brief Get the carrier that is both a child of the PickupCarrier (or the PickupCarrier itself) and a target of the input Pickupable.
+            @param pickup A pounter to the Pickupable.
+            @return Returns a pointer to the PickupCarrier that is the target of the input Pickupable.
+            */
+            PickupCarrier* getTarget(const Pickupable* pickup)
+                {
+                    if(!this->isTarget(pickup))
+                        return NULL;
+
+                    if(pickup->isTarget(this)) //!< If the PickupCarrier itself is a target.
+                        return this;
+
+                    //! Go recursively through all children to check whether they are the target.
+                    std::vector<PickupCarrier*>* children = this->getCarrierChildren();
+                    for(std::vector<PickupCarrier*>::iterator it = children->begin(); it != children->end(); it++)
+                    {
+                        if(pickup->isTarget(*it))
+                            return *it;
+                    }
+
+                    children->clear();
+                    delete children;
+
+                    return NULL;
+                }
+
+            /**
+            @brief Get the (absolute) position of the PickupCarrier.
+                   This method needs to be implemented by any direct derivative class of PickupCarrier.
+            @return Returns the position as a Vector3.
+            */
+            virtual const Vector3& getCarrierPosition(void) = 0;
+            
+            /**
+            @brief Get the name of this PickupCarrier.
+            @return Returns the name as a string.
+            */
+            const std::string& getCarrierName(void) { return this->carrierName_; } // tolua_export
+            
+        protected:        
+            /**
+            @brief Get all direct children of this PickupSpawner.
+                   This method needs to be implemented by any direct derivative class of PickupCarrier.
+                   The returned list will be deleted by the methods calling this function.
+            @return Returns a pointer to a list of all direct children.
+            */
+            virtual std::vector<PickupCarrier*>* getCarrierChildren(void) = 0;
+            /**
+            @brief Get the parent of this PickupSpawner
+                   This method needs to be implemented by any direct derivative class of PickupCarrier.
+            @return Returns a pointer to the parent.
+            */
+            virtual PickupCarrier* getCarrierParent(void) = 0;
+
+            /**
+            @brief Get all Pickupables this PickupCarrier has.
+            @return  Returns the set of all Pickupables this PickupCarrier has.
+            */
+            std::set<Pickupable*>& getPickups(void)
+                { return this->pickups_; }
+                
+            /**
+            @brief Set the name of this PickupCarrier.
+                   The name needs to be set in the constructor of every class inheriting from PickupCarrier, by calling setCarrierName().
+            @param name The name to be set.
+            */
+            void setCarrierName(const std::string& name)
+                { this->carrierName_ = name; }
+        
+        private:
+            std::set<Pickupable*> pickups_; //!< The list of Pickupables carried by this PickupCarrier.
+            std::string carrierName_; //!< The name of the PickupCarrier, as displayed in the PickupInventory.
+            
+            /**
+            @brief Get the number of carrier children this PickupCarrier has.
+            @return Returns the number of carrier children.
+            */
+            unsigned int getNumCarrierChildren(void)
+                {
+                    std::vector<PickupCarrier*>* list = this->getCarrierChildren();
+                    unsigned int size = list->size();
+                    delete list;
+                    return size;
+                }
+            
+            /**
+            @brief Get the index-th child of this PickupCarrier.
+            @param index The index of the child to return.
+            @return Returns the index-th child.
+            */
+            PickupCarrier* getCarrierChild(unsigned int index)
+                {
+                    std::vector<PickupCarrier*>* list = this->getCarrierChildren();
+                    if(list->size() < index)
+                        return NULL;
+                    PickupCarrier* carrier = (*list)[index];
+                    delete list;
+                    return carrier;
+                }
+            
+            /**
+            @brief Get the number of Pickupables this PickupCarrier carries.
+            @return returns the number of pickups.
+            */
+            unsigned int getNumPickups(void)
+                { return this->pickups_.size(); }
+            
+            /**
+            @brief Get the index-th Pickupable of this PickupCarrier.
+            @param index The index of the Pickupable to return.
+            @return Returns the index-th pickup.
+            */
+            Pickupable* getPickup(unsigned int index)
+                {
+                    std::set<Pickupable*>::iterator it;
+                    for(it = this->pickups_.begin(); index != 0 && it != this->pickups_.end(); it++)
+                        index--;
+                    if(it == this->pickups_.end())
+                        return NULL;
+                    return *it;
+                }
+            
+    }; // tolua_export
+} // tolua_export
+
+#endif /* _PickupCarrier_H__ */
Index: /code/branches/rocket2/src/orxonox/interfaces/Pickupable.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/interfaces/Pickupable.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/interfaces/Pickupable.cc	(revision 6952)
@@ -0,0 +1,276 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file Pickupable.cc
+    @brief Implementation of the Pickupable class.
+*/
+
+#include "Pickupable.h"
+
+#include "core/Identifier.h"
+#include "core/CoreIncludes.h"
+#include "pickup/PickupIdentifier.h"
+#include "PickupCarrier.h"
+
+namespace orxonox
+{
+    
+    /**
+    @brief
+        Constructor. Registers the objects and initializes its member variables.
+    */
+    Pickupable::Pickupable() : pickupIdentifier_(NULL), used_(false), pickedUp_(false)
+    {        
+        RegisterRootObject(Pickupable);
+        
+        this->carrier_ = NULL;
+        
+        this->pickupIdentifier_ = new PickupIdentifier(this);
+    }
+    
+    /**
+    @brief
+        Destructor. 
+    */
+    Pickupable::~Pickupable()
+    {
+        if(this->isUsed())
+            this->setUsed(false);
+        
+        if(this->isPickedUp() && this->getCarrier() != NULL)
+        {
+            this->getCarrier()->drop(this, false);
+            this->setCarrier(NULL);
+        }
+        
+        if(this->pickupIdentifier_ != NULL)
+            this->pickupIdentifier_->destroy();
+    }
+    
+    /**
+    @brief
+        Sets the Pickupable to used or unused, depending on the input.
+    @param used
+        If used is true the Pickupable is set to used, it is set to unused, otherwise.
+    @return
+        Returns true if the used state was changed, false if not.
+    */
+    bool Pickupable::setUsed(bool used)
+    {
+        if(this->used_ == used)
+            return false;
+        
+        COUT(4) << "Pickupable (&" << this << ") set to used " << used << "." << std::endl;
+        
+        this->used_ = used;
+        this->changedUsed();
+        return true;
+    }
+    
+    /**
+    @brief
+        Get whether the given PickupCarrier is a target of this Pickupable.
+    @param carrier
+        The PickupCarrier of which it has to be determinde whether it is a target of this Pickupable.
+    @return
+        Returns true if the given PickupCarrier is a target.
+    */
+    bool Pickupable::isTarget(PickupCarrier* carrier) const
+    {
+        if(carrier == NULL)
+            return false;
+        return this->isTarget(carrier->getIdentifier());
+    }
+    
+    /**
+    @brief
+        Get whether the given Identififer is a target of this Pickupable.
+    @param identifier
+        The PickupCarrier of which it has to be determinde whether it is a target of this Pickupable.
+    @return
+        Returns true if the given PickupCarrier is a target.
+    */
+    bool Pickupable::isTarget(const Identifier* identifier) const
+    {
+        //! Iterate through all targets of this Pickupable.
+        for(std::list<Identifier*>::const_iterator it = this->targets_.begin(); it != this->targets_.end(); it++)
+        {
+            if(identifier->isA(*it))
+                return true;
+        }
+        return false;
+    }
+        
+    /**
+    @brief
+        Add a PickupCarrier as target of this Pickupable.
+    @param target
+        The PickupCarrier to be added.
+    @return
+        Returns true if the target was added, false if not.
+    */
+    bool Pickupable::addTarget(PickupCarrier* target)
+    {
+        return this->addTarget(target->getIdentifier());
+    }
+    
+    /**
+    @brief
+        Add a class, representetd by the input Identifier, as target of this Pickupable.
+    @param target
+        The Identifier to be added.
+    @return
+        Returns true if the target was added, false if not.
+    */
+    bool Pickupable::addTarget(Identifier* target)
+    {
+        if(this->isTarget(target)) //!< If the input target is already present in the list of targets.
+            return false;
+        
+        COUT(4) << "Target " << target->getName() << " added to Pickupable (&" << this << ")." << std::endl;
+        this->targets_.push_back(target);
+        return true;
+    }
+    
+    /**
+    @brief  
+        Sets the Pickupable to picked up.
+        This method will be called by the PickupCarrier picking the Pickupable up.
+    @param carrier
+        The PickupCarrier that picked the Pickupable up.
+    @return
+        Returns false if, for some reason, the pickup could not be picked up, e.g. it was picked up already.
+    */
+    bool Pickupable::pickedUp(PickupCarrier* carrier)
+    {
+        if(this->isPickedUp()) //!< If the Pickupable is already picked up.
+            return false;
+        
+        COUT(4) << "Pickupable (&" << this << ") got picked up by a PickupCarrier (&" << carrier << ")." << std::endl;
+        this->setCarrier(carrier);
+        this->setPickedUp(true);
+        return true;
+    }
+    
+    /**
+    @brief
+        Helper method to set the Pickupable to either picked up or not picked up.
+    @param pickedUp
+        The value this->pickedUp_ should be set to.
+    @return
+        Returns true if the pickedUp status was changed, false if not.
+    */
+    bool Pickupable::setPickedUp(bool pickedUp)
+    {
+        if(this->pickedUp_ == pickedUp)
+            return false;
+        
+        COUT(4) << "Pickupable (&" << this << ") set to pickedUp " << pickedUp << "." << std::endl;
+        
+        this->pickedUp_ = pickedUp;
+        this->changedPickedUp();
+        return true;
+    }
+        
+    /**
+    @brief
+        Sets the carrier of the Pickupable.
+    @param carrier
+        Sets the input PickupCarrier as the carrier of the pickup.
+    */
+    inline bool Pickupable::setCarrier(PickupCarrier* carrier)
+    {
+        if(this->carrier_ == carrier)
+            return false;
+        
+        COUT(4) << "Pickupable (&" << this << ") changed Carrier (& " << carrier << ")." << std::endl;
+        
+        this->carrier_ = carrier;
+        this->changedCarrier();
+        return true;
+    }
+    
+    /**
+    @brief 
+        Sets the Pickupable to not picked up or dropped.
+        This method will be called by the PickupCarrier dropping the Pickupable.
+    @return
+        Returns false if the pickup could not be dropped.
+    */
+    bool Pickupable::dropped(void)
+    {
+        if(!this->isPickedUp()) //!< If the Pickupable is not picked up.
+            return false;
+        
+        COUT(4) << "Pickupable (&" << this << ") got dropped up by a PickupCarrier (&" << this->getCarrier() << ")." << std::endl;
+        this->setUsed(false);
+        this->setPickedUp(false);
+        
+        bool created = this->createSpawner();
+        
+        this->setCarrier(NULL);
+        
+        if(!created)
+        {
+            this->destroy();
+        }
+        
+        return true;
+    }
+    
+    /**
+    @brief
+        Creates a duplicate of the Pickupable.
+    @return
+        Returns the clone of this pickup as a pointer to a Pickupable.
+    */
+    Pickupable* Pickupable::clone(void)
+    {
+        OrxonoxClass* item = NULL;
+        this->clone(item);
+        
+        Pickupable* pickup = dynamic_cast<Pickupable*>(item);
+        
+        COUT(4) << "Pickupable (&" << this << ") cloned. Clone is new Pickupable (&" << pickup << ")." << std::endl;
+        return pickup;
+    }
+    
+    /**
+    @brief
+        Creates a duplicate of the input OrxonoxClass.
+        This method needs to be implemented by any Class inheriting from Pickupable.
+    @param item
+        A reference to a pointer to the OrxonoxClass that is to be duplicated.
+    */
+    void Pickupable::clone(OrxonoxClass*& item)
+    {
+        SUPER(Pickupable, clone, item);
+    }
+    
+}
Index: /code/branches/rocket2/src/orxonox/interfaces/Pickupable.h
===================================================================
--- /code/branches/rocket2/src/orxonox/interfaces/Pickupable.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/interfaces/Pickupable.h	(revision 6952)
@@ -0,0 +1,151 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file Pickupable.h
+    @brief Definition of the Pickupable class.
+*/
+
+#ifndef _Pickupable_H__
+#define _Pickupable_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <list>
+#include "core/Super.h"
+
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    
+    /**
+    @brief
+        An Interface (or more precisely an abstract class) to model and represent different (all kinds of) pickups.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _OrxonoxExport Pickupable : virtual public OrxonoxClass
+    {
+        protected:
+            Pickupable(); //!< Default constructor.
+        
+        public:
+            virtual ~Pickupable(); //!< Default destructor.
+            
+            /**
+            @brief Get whether the pickup is currently in use or not.
+            @return Returns true if the pickup is currently in use.
+            */
+            inline bool isUsed(void)
+                { return this->used_; }
+            /**
+            @brief  Should be called when the pickup has transited from used to unused or the other way around.
+                    Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedUsed); to their changdeUsed method.
+            */
+            virtual void changedUsed(void) {}
+            
+            /**
+            @brief Get the carrier of the pickup.
+            @return Returns a pointer to the carrier of the pickup.
+            */
+            inline PickupCarrier* getCarrier(void)
+                { return this->carrier_; }
+            /**
+            @brief Should be called when the pickup has changed its PickupCarrier.
+                   Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedCarrier); to their changedCarrier method.
+            */
+            virtual void changedCarrier(void) {}
+            
+            /**
+            @brief Returns whether the Pickupable is currently picked up.
+            @return Returns true if the Pickupable is currently picked up, false if not.
+            */
+            inline bool isPickedUp(void)
+                { return this->pickedUp_; }
+            /**
+            @brief  Should be called when the pickup has transited from picked up to dropped or the other way around.
+                    Any Class overwriting this method must call its SUPER function by adding SUPER(Classname, changedPickedUp); to their changedPickedUp method.
+            */
+            virtual void changedPickedUp(void) {}
+            
+            bool pickedUp(PickupCarrier* carrier); //!< Sets the Pickupable to picked up.
+            bool dropped(void); //!< Sets the Pickupable to not picked up or dropped.
+            
+            virtual bool isTarget(PickupCarrier* carrier) const; //!< Get whether the given PickupCarrier is a target of this pickup.
+            bool isTarget(const Identifier* identifier) const; //!< Get whether a given class, represented by the input Identifier, is a target of this Pickupable.
+            bool addTarget(PickupCarrier* target); //!< Add a PickupCarrier as target of this pickup.
+            bool addTarget(Identifier* identifier); //!< Add a class, representetd by the input Identifier, as target of this pickup.
+            
+            Pickupable* clone(void); //!< Creates a duplicate of the Pickupable.
+            virtual void clone(OrxonoxClass*& item); //!< Creates a duplicate of the input OrxonoxClass.
+            
+            /**
+            @brief Get the PickupIdentifier of this Pickupable.
+            @return Returns a pointer to the PickupIdentifier of this Pickupable.
+            */
+            virtual const PickupIdentifier* getPickupIdentifier(void)
+                { return this->pickupIdentifier_; }
+                
+            bool setUsed(bool used); //!< Sets the Pickupable to used or unused, depending on the input.
+            bool setPickedUp(bool pickedUp); //!< Helper method to set the Pickupable to either picked up or not picked up.
+            bool setCarrier(PickupCarrier* carrier); //!< Sets the carrier of the pickup.
+            
+        protected:
+            /**
+            @brief Helper method to initialize the PickupIdentifier.
+            */
+            void initializeIdentifier(void) {}
+            
+            /**
+            @brief Facilitates the creation of a PickupSpawner upon dropping of the Pickupable.
+                   This method must be implemented by any class directly inheriting from Pickupable. It is most easily done by just creating a new DroppedPickup, e.g.:
+                   DroppedPickup(BaseObject* creator, Pickupable* pickup, const Vector3& position, float triggerDistance);
+            @param position The position at which the PickupSpawner should be placed.
+            @return Returns true if a spawner was created, false if not.
+            */
+            virtual bool createSpawner(void) = 0;
+            
+            PickupIdentifier* pickupIdentifier_; //!< The PickupIdentifier of this Pickupable.
+            
+        private:
+            
+            bool used_; //!< Whether the pickup is currently in use or not.
+            bool pickedUp_; //!< Whether the pickup is currently picked up or not.
+            
+            PickupCarrier* carrier_; //!< The carrier of the pickup.
+            std::list<Identifier*> targets_; //!< The possible targets of this pickup.
+
+    };
+    
+    SUPER_FUNCTION(10, Pickupable, changedUsed, false);
+    SUPER_FUNCTION(12, Pickupable, changedCarrier, false);
+    SUPER_FUNCTION(13, Pickupable, changedPickedUp, false);
+}
+
+#endif /* _Pickupable_H__ */
Index: /code/branches/rocket2/src/orxonox/interfaces/PlayerTrigger.h
===================================================================
--- /code/branches/rocket2/src/orxonox/interfaces/PlayerTrigger.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/interfaces/PlayerTrigger.h	(revision 6952)
@@ -0,0 +1,92 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief
+    Definition of the PlayerTrigger class.
+*/
+
+#ifndef _PlayerTrigger_H__
+#define _PlayerTrigger_H__
+
+#include "OrxonoxPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        A PlayerTrigger is a trigger which is normally triggered by Pawns and can as such return a pointer to the Pawn which triggered it.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _OrxonoxExport PlayerTrigger : virtual public OrxonoxClass
+    {
+    public:
+        PlayerTrigger();
+        virtual ~PlayerTrigger() {}
+
+        /**
+        @brief Returns the player that triggered the PlayerTrigger.
+        @return Returns a pointer to the Pawn that triggered the PlayerTrigger.
+        */
+        inline Pawn* getTriggeringPlayer(void) const
+            { return this->player_; }
+
+        /**
+        @brief Checks whether the PlayerTrigger normally returns a Pawn.
+        @return Returns true if the PlayerTrigger normally returns a Pawn.
+        */
+        inline bool isForPlayer(void) const
+           { return this->isForPlayer_; }
+
+    protected:
+        /**
+        @brief Set the player that triggered the PlayerTrigger. This is normally done by classes inheriting vom PlayerTrigger.
+        @param player A pointer to the Pawn that triggered the PlayerTrigger.
+        */
+        inline void setTriggeringPlayer(Pawn* player)
+           { this->player_ = player; }
+
+            /**
+            @brief Set whether the PlayerTrigger normally is triggered by Pawns.
+            @param isForPlayer Should be true when the PlayerTrigger should be set to normally be triggered by Pawns, false if not.
+            */
+        inline void setForPlayer(bool isForPlayer)
+           { this->isForPlayer_ = isForPlayer; }
+
+    private:
+        Pawn* player_; //!< The player that triggered the PlayerTrigger.
+        bool isForPlayer_; //!< Is true when the PlayerTrigger should be set to normally be triggered by Pawns.
+
+    };
+
+}
+
+#endif /* _PlayerTrigger_H__ */
Index: /code/branches/rocket2/src/orxonox/interfaces/RadarListener.h
===================================================================
--- /code/branches/rocket2/src/orxonox/interfaces/RadarListener.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/interfaces/RadarListener.h	(revision 6952)
@@ -0,0 +1,51 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _RadarListener_H__
+#define _RadarListener_H__
+
+#include "OrxonoxPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport RadarListener : virtual public OrxonoxClass
+    {
+    public:
+        RadarListener();
+        virtual ~RadarListener() { }
+
+        virtual void addObject(RadarViewable* viewable) = 0;
+        virtual void removeObject(RadarViewable* viewable) = 0;
+        virtual void objectChanged(RadarViewable* viewable) = 0;
+        virtual float getRadarSensitivity() const = 0;
+        virtual void radarTick(float dt) = 0;
+    };
+}
+
+#endif /* _RadarListener_H__ */
Index: /code/branches/rocket2/src/orxonox/interfaces/RadarViewable.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/interfaces/RadarViewable.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/interfaces/RadarViewable.cc	(revision 6952)
@@ -0,0 +1,105 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "RadarViewable.h"
+
+#include "util/StringUtils.h"
+#include "core/CoreIncludes.h"
+#include "worldentities/WorldEntity.h"
+#include "Radar.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    /**
+        @brief Constructor.
+    */
+    RadarViewable::RadarViewable(BaseObject* creator)
+        : isHumanShip_(false)
+        , bVisibility_(true)
+        , bInitialized_(false)
+        , creator_(creator)
+        , radarObjectCamouflage_(0.0f)
+        , radarObjectShape_(Dot)
+        , radarObjectDescription_("staticObject")
+    {
+        RegisterRootObject(RadarViewable);
+
+        this->uniqueId_=getUniqueNumberString();
+        this->radar_ = this->creator_->getScene()->getRadar();
+        this->radar_->addRadarObject(this);
+        this->bInitialized_ = true;
+    }
+
+
+    RadarViewable::~RadarViewable()
+    {
+        if( this->bInitialized_ )
+            this->radar_->removeRadarObject(this);
+    }
+
+//     void RadarViewable::setRadarObjectDescription(const std::string& str)
+//     {
+//         Radar* radar = this->getWorldEntity()->getScene()->getRadar();
+//         if (radar)
+//             this->radarObjectShape_ = radar->addObjectDescription(str);
+//         else
+//         {
+//             CCOUT(2) << "Attempting to access the radar, but the radar is non existent." << std::endl;
+//         }
+//         this->radarObjectDescription_ = str;
+//     }
+
+    const Vector3& RadarViewable::getRVWorldPosition() const
+    {
+        const WorldEntity* object = this->getWorldEntity();
+        validate(object);
+        return object->getWorldPosition();
+    }
+
+    Vector3 RadarViewable::getRVOrientedVelocity() const
+    {
+        const WorldEntity* object = this->getWorldEntity();
+        validate(object);
+        return object->getWorldOrientation() * object->getVelocity();
+    }
+
+    void RadarViewable::validate(const WorldEntity* object) const
+    {
+        if (!object)
+        {
+            COUT(1) << "Assertion: Every RadarViewable has to be assigned a WorldEntity pointer!" << std::endl;
+            assert(0);
+        }
+    }
+    
+    void RadarViewable::settingsChanged()
+    {
+        this->radar_->radarObjectChanged(this);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/interfaces/RadarViewable.h
===================================================================
--- /code/branches/rocket2/src/orxonox/interfaces/RadarViewable.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/interfaces/RadarViewable.h	(revision 6952)
@@ -0,0 +1,144 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _RadarViewable_H__
+#define _RadarViewable_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include <cassert>
+
+#include "util/Math.h"
+#include "core/OrxonoxClass.h"
+#include "core/SmartPtr.h"
+
+namespace orxonox
+{
+    class BaseObject;
+
+    /**
+    @brief Interface for receiving window events.
+    */
+    class _OrxonoxExport RadarViewable : virtual public OrxonoxClass
+    {
+    public:
+        enum Shape
+        {
+            Square,
+            Dot,
+            Triangle
+        };
+
+
+    public:
+        RadarViewable(BaseObject* creator);
+        virtual ~RadarViewable();
+
+        inline void setRadarObjectCamouflage(float camouflage)
+            {
+                if( this->radarObjectCamouflage_ != camouflage )
+                {
+                    this->radarObjectCamouflage_ = camouflage;
+                    this->settingsChanged();
+                }
+            }
+        inline float getRadarObjectCamouflage() const
+            { return this->radarObjectCamouflage_; }
+
+        inline void setRadarObjectColour(const ColourValue& colour)
+            {
+                if(this->radarObjectColour_ != colour)
+                {
+                    this->radarObjectColour_ = colour;
+                    this->settingsChanged();
+                }
+            }
+        inline const ColourValue& getRadarObjectColour() const
+            { return this->radarObjectColour_; }
+
+//         void setRadarObjectDescription(const std::string& str);
+//         inline const std::string& getRadarObjectDescription() const
+//             { return this->radarObjectDescription_; }
+
+        inline void setRadarVisibility(bool b)
+            { 
+                if(b!=this->bVisibility_)
+                {
+                    this->bVisibility_ = b;
+                    this->settingsChanged();
+                }
+            }
+        inline bool getRadarVisibility() const
+            { return this->bVisibility_; }
+
+        virtual const WorldEntity* getWorldEntity() const = 0;
+
+        const Vector3& getRVWorldPosition() const;
+        Vector3 getRVOrientedVelocity() const;
+
+        inline void setRadarObjectShape(Shape shape)
+            {
+                if( this->radarObjectShape_ != shape )
+                {
+                    this->radarObjectShape_ = shape;
+                    this->settingsChanged();
+                }
+            }
+        inline Shape getRadarObjectShape() const
+            { return this->radarObjectShape_; }
+        void settingsChanged();
+
+
+        bool isHumanShip_;
+        inline const std::string& getUniqueId()
+        {
+            return this->uniqueId_;
+        }
+        //friend class Map;
+
+    private:
+        void validate(const WorldEntity* object) const;
+        bool bVisibility_;
+        bool bInitialized_;
+        //Map
+        std::string uniqueId_;
+        BaseObject* creator_;
+
+
+        //Radar
+        SmartPtr<Radar> radar_;
+        float radarObjectCamouflage_;
+        Shape radarObjectShape_;
+        std::string radarObjectDescription_;
+        ColourValue radarObjectColour_;
+
+    };
+}
+
+#endif /* _RadarViewable_H__ */
Index: /code/branches/rocket2/src/orxonox/interfaces/Rewardable.h
===================================================================
--- /code/branches/rocket2/src/orxonox/interfaces/Rewardable.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/interfaces/Rewardable.h	(revision 6952)
@@ -0,0 +1,70 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file
+    @brief Definition of the Rewardable class.
+*/
+
+#ifndef _Rewardable_H__
+#define _Rewardable_H__
+
+#include "OrxonoxPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Rewardable is an Interface, that can be implemented by any object to enable it to be given as reward to a player through QuestEffects. (With the AddReward effect.)
+
+        It just needs to inherit form Rewardable, and implement the reward() method.
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _OrxonoxExport Rewardable : public OrxonoxClass
+    {
+        public:
+            Rewardable();
+            virtual ~Rewardable() {}
+
+            /**
+            @brief
+                Method to transcribe a rewardable object to the player.
+                Must be implemented by every class inheriting from Rewardable.
+            @param player
+                A pointer to the ControllableEntity, do whatever you want with it.
+            @return
+                Return true if successful.
+            */
+            virtual bool reward(PlayerInfo* player) = 0;
+
+    };
+}
+
+#endif /* _Rewardable_H__ */
Index: /code/branches/rocket2/src/orxonox/interfaces/TeamColourable.h
===================================================================
--- /code/branches/rocket2/src/orxonox/interfaces/TeamColourable.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/interfaces/TeamColourable.h	(revision 6952)
@@ -0,0 +1,49 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TeamColourable_H__
+#define _TeamColourable_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/UtilPrereqs.h"
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport TeamColourable : virtual public OrxonoxClass
+    {
+        public:
+            virtual void setTeamColour(const ColourValue& colour) = 0;
+
+        protected:
+            TeamColourable();
+    };
+}
+
+#endif /* _TeamColourable_H__ */
Index: /code/branches/rocket2/src/orxonox/items/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/items/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/items/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,5 @@
+ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+  Item.cc
+  Engine.cc
+  MultiStateEngine.cc
+)
Index: /code/branches/rocket2/src/orxonox/items/Engine.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/items/Engine.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/items/Engine.cc	(revision 6952)
@@ -0,0 +1,260 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Engine.h"
+
+#include "util/Math.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+#include "worldentities/pawns/SpaceShip.h"
+#include "tools/Shader.h"
+
+namespace orxonox
+{
+    CreateFactory(Engine);
+
+    Engine::Engine(BaseObject* creator) : Item(creator)
+    {
+        RegisterObject(Engine);
+
+        this->ship_ = 0;
+        this->shipID_ = OBJECTID_UNKNOWN;
+
+        this->boostFactor_ = 1.5;
+        this->speedFactor_ = 1.0;
+
+        this->maxSpeedFront_ = 0.0;
+        this->maxSpeedBack_ = 0.0;
+        this->maxSpeedLeftRight_ = 0.0;
+        this->maxSpeedUpDown_ = 0.0;
+
+        this->accelerationFront_ = 0.0;
+        this->accelerationBrake_ = 0.0;
+        this->accelerationBack_ = 0.0;
+        this->accelerationLeftRight_ = 0.0;
+        this->accelerationUpDown_ = 0.0;
+
+        this->boostBlur_ = 0;
+
+        this->setCarrierName("Engine");
+        this->speedAdd_ = 0.0;
+        this->speedMultiply_ = 1.0;
+
+        this->setConfigValues();
+        this->registerVariables();
+    }
+
+    Engine::~Engine()
+    {
+        if (this->isInitialized() && this->ship_)
+        {
+            this->ship_->setEngine(0);
+
+            if (this->boostBlur_)
+                this->boostBlur_->destroy();
+        }
+    }
+
+    void Engine::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Engine, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Engine, "boostfactor", setBoostFactor, getBoostFactor, xmlelement, mode);
+
+        XMLPortParam(Engine, "speedfront",     setMaxSpeedFront,     setMaxSpeedFront,     xmlelement, mode);
+        XMLPortParam(Engine, "speedback",      setMaxSpeedBack,      setMaxSpeedBack,      xmlelement, mode);
+        XMLPortParam(Engine, "speedleftright", setMaxSpeedLeftRight, setMaxSpeedLeftRight, xmlelement, mode);
+        XMLPortParam(Engine, "speedupdown",    setMaxSpeedUpDown,    setMaxSpeedUpDown,    xmlelement, mode);
+
+        XMLPortParam(Engine, "accelerationfront",     setAccelerationFront,     setAccelerationFront,     xmlelement, mode);
+        XMLPortParam(Engine, "accelerationbrake",     setAccelerationBrake,     setAccelerationBrake,     xmlelement, mode);
+        XMLPortParam(Engine, "accelerationback",      setAccelerationBack,      setAccelerationBack,      xmlelement, mode);
+        XMLPortParam(Engine, "accelerationleftright", setAccelerationLeftRight, setAccelerationLeftRight, xmlelement, mode);
+        XMLPortParam(Engine, "accelerationupdown",    setAccelerationUpDown,    setAccelerationUpDown,    xmlelement, mode);
+    }
+
+    void Engine::setConfigValues()
+    {
+        SetConfigValue(blurStrength_, 3.0f);
+    }
+
+    void Engine::registerVariables()
+    {
+        registerVariable(this->shipID_, VariableDirection::ToClient, new NetworkCallback<Engine>(this, &Engine::networkcallback_shipID));
+
+        registerVariable(this->speedFactor_, VariableDirection::ToClient);
+        registerVariable(this->boostFactor_, VariableDirection::ToClient);
+
+        registerVariable(this->maxSpeedFront_,     VariableDirection::ToClient);
+        registerVariable(this->maxSpeedBack_,      VariableDirection::ToClient);
+        registerVariable(this->maxSpeedLeftRight_, VariableDirection::ToClient);
+        registerVariable(this->maxSpeedUpDown_,    VariableDirection::ToClient);
+
+        registerVariable(this->accelerationFront_,     VariableDirection::ToClient);
+        registerVariable(this->accelerationBrake_,     VariableDirection::ToClient);
+        registerVariable(this->accelerationBack_,      VariableDirection::ToClient);
+        registerVariable(this->accelerationLeftRight_, VariableDirection::ToClient);
+        registerVariable(this->accelerationUpDown_,    VariableDirection::ToClient);
+
+        registerVariable(this->speedAdd_, VariableDirection::ToClient);
+        registerVariable(this->speedMultiply_, VariableDirection::ToClient);
+    }
+
+    void Engine::networkcallback_shipID()
+    {
+        this->ship_ = 0;
+
+        if (this->shipID_ != OBJECTID_UNKNOWN)
+        {
+            Synchronisable* object = Synchronisable::getSynchronisable(this->shipID_);
+            if (object)
+                this->addToSpaceShip(orxonox_cast<SpaceShip*>(object));
+        }
+    }
+
+    void Engine::tick(float dt)
+    {
+        if (!this->ship_)
+        {
+            if (this->shipID_)
+            {
+                this->networkcallback_shipID();
+
+                if (!this->ship_)
+                    return;
+            }
+            else
+                return;
+        }
+
+        if (!this->isActive())
+            return;
+
+        SUPER(Engine, tick, dt);
+
+        const Vector3& direction = this->getDirection();
+        Vector3 velocity = this->ship_->getLocalVelocity();
+        Vector3 acceleration = Vector3::ZERO;
+
+        float factor = 1.0f / this->speedFactor_;
+        velocity *= factor;
+
+        if (direction.z < 0)
+        {
+            if (this->maxSpeedFront_ != 0)
+            {
+                float boostfactor = (this->ship_->getBoost() ? this->boostFactor_ : 1.0f);
+                acceleration.z = direction.z * this->accelerationFront_ * boostfactor * clamp((this->maxSpeedFront_ - -velocity.z/boostfactor) / this->maxSpeedFront_, 0.0f, 1.0f);
+            }
+        }
+        else if (direction.z > 0)
+        {
+            if (velocity.z < 0)
+                acceleration.z = direction.z * this->accelerationBrake_;
+            else if (this->maxSpeedBack_ != 0)
+                acceleration.z = direction.z * this->accelerationBack_ * clamp((this->maxSpeedBack_ - velocity.z) / this->maxSpeedBack_, 0.0f, 1.0f);
+        }
+
+        if (this->maxSpeedLeftRight_ != 0)
+        {
+            if (direction.x < 0)
+                acceleration.x = direction.x * this->accelerationLeftRight_ * clamp((this->maxSpeedLeftRight_ - -velocity.x) / this->maxSpeedLeftRight_, 0.0f, 1.0f);
+            else if (direction.x > 0)
+                acceleration.x = direction.x * this->accelerationLeftRight_ * clamp((this->maxSpeedLeftRight_ - velocity.x) / this->maxSpeedLeftRight_, 0.0f, 1.0f);
+        }
+
+        if (this->maxSpeedUpDown_ != 0)
+        {
+            if (direction.y < 0)
+                acceleration.y = direction.y * this->accelerationUpDown_ * clamp((this->maxSpeedUpDown_ - -velocity.y) / this->maxSpeedUpDown_, 0.0f, 1.0f);
+            else if (direction.y > 0)
+                acceleration.y = direction.y * this->accelerationUpDown_ * clamp((this->maxSpeedUpDown_ - velocity.y) / this->maxSpeedUpDown_, 0.0f, 1.0f);
+        }
+
+        this->ship_->setAcceleration(this->ship_->getOrientation() * (acceleration*this->getSpeedMultiply()+Vector3(0,0,-this->getSpeedAdd())));
+
+        if (!this->ship_->getPermanentBoost())
+            this->ship_->setBoost(false);
+        this->ship_->setSteeringDirection(Vector3::ZERO);
+
+        if (!this->boostBlur_ && this->ship_->hasLocalController() && this->ship_->hasHumanController())
+        {
+            this->boostBlur_ = new Shader(this->ship_->getScene()->getSceneManager());
+            this->boostBlur_->setCompositor("Radial Blur");
+        }
+
+        if (this->boostBlur_ && this->maxSpeedFront_ != 0 && this->boostFactor_ != 1)
+            this->boostBlur_->setParameter("Ogre/Compositor/Radial_Blur", 0, 0, "sampleStrength", this->blurStrength_ * clamp((-velocity.z - this->maxSpeedFront_) / ((this->boostFactor_ - 1) * this->maxSpeedFront_), 0.0f, 1.0f));
+    }
+
+    void Engine::changedActivity()
+    {
+        SUPER(Engine, changedActivity);
+
+        if (this->boostBlur_)
+            this->boostBlur_->setVisible(this->isVisible());
+    }
+
+    void Engine::addToSpaceShip(SpaceShip* ship)
+    {
+        this->ship_ = ship;
+
+        if (ship)
+        {
+            this->shipID_ = ship->getObjectID();
+            if (ship->getEngine() != this)
+                ship->setEngine(this);
+
+            if (this->boostBlur_)
+            {
+                this->boostBlur_->destroy();
+                this->boostBlur_ = 0;
+            }
+        }
+    }
+
+    const Vector3& Engine::getDirection() const
+    {
+        if (this->ship_)
+            return this->ship_->getSteeringDirection();
+        else
+            return Vector3::ZERO;
+    }
+
+    PickupCarrier* Engine::getCarrierParent(void)
+    {
+        return this->ship_;
+    }
+
+    const Vector3& Engine::getCarrierPosition(void)
+    {
+        return this->ship_->getWorldPosition();
+    }
+}
Index: /code/branches/rocket2/src/orxonox/items/Engine.h
===================================================================
--- /code/branches/rocket2/src/orxonox/items/Engine.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/items/Engine.h	(revision 6952)
@@ -0,0 +1,156 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Engine_H__
+#define _Engine_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "tools/interfaces/Tickable.h"
+#include "Item.h"
+
+#include "interfaces/PickupCarrier.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Engine : public Item, public Tickable, public PickupCarrier
+    {
+        public:
+            Engine(BaseObject* creator);
+            virtual ~Engine();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+            void setConfigValues();
+
+            virtual void tick(float dt);
+            virtual void changedActivity();
+
+            virtual void addToSpaceShip(SpaceShip* ship);
+            inline SpaceShip* getShip() const
+                { return this->ship_; }
+
+            inline void setBoostFactor(float factor)
+                { this->boostFactor_ = factor; }
+            inline float getBoostFactor() const
+                { return this->boostFactor_; }
+
+            inline void setSpeedFactor(float factor)
+                { this->speedFactor_ = factor; }
+            inline float getSpeedFactor() const
+                { return this->speedFactor_; }
+
+            inline void setMaxSpeedFront(float speed)
+                { this->maxSpeedFront_ = speed; }
+            inline void setMaxSpeedBack(float speed)
+                { this->maxSpeedBack_ = speed; }
+            inline void setMaxSpeedLeftRight(float speed)
+                { this->maxSpeedLeftRight_ = speed; }
+            inline void setMaxSpeedUpDown(float speed)
+                { this->maxSpeedUpDown_ = speed; }
+
+            inline float getMaxSpeedFront() const
+                { return this->maxSpeedFront_; }
+            inline float getMaxSpeedBack() const
+                { return this->maxSpeedBack_; }
+            inline float getMaxSpeedLeftRight() const
+                { return this->maxSpeedLeftRight_; }
+            inline float getMaxSpeedUpDown() const
+                { return this->maxSpeedUpDown_; }
+
+            inline void setAccelerationFront(float acceleration)
+                { this->accelerationFront_ = acceleration; }
+            inline void setAccelerationBrake(float acceleration)
+                { this->accelerationBrake_ = acceleration; }
+            inline void setAccelerationBack(float acceleration)
+                { this->accelerationBack_ = acceleration; }
+            inline void setAccelerationLeftRight(float acceleration)
+                { this->accelerationLeftRight_ = acceleration; }
+            inline void setAccelerationUpDown(float acceleration)
+                { this->accelerationUpDown_ = acceleration; }
+
+            inline float getAccelerationFront() const
+                { return this->accelerationFront_; }
+            inline float getAccelerationBrake() const
+                { return this->accelerationBrake_; }
+            inline float getAccelerationBack() const
+                { return this->accelerationBack_; }
+            inline float getAccelerationLeftRight() const
+                { return this->accelerationLeftRight_; }
+            inline float getAccelerationUpDown() const
+                { return this->accelerationUpDown_; }
+
+            inline float getSpeedAdd(void)
+                { return this->speedAdd_; }
+            inline float getSpeedMultiply(void)
+                { return this->speedMultiply_; }
+
+            virtual const Vector3& getDirection() const;
+
+            virtual const Vector3& getCarrierPosition(void);
+
+            //TODO: Move to protected or private. How?
+            inline void setSpeedAdd(float speedAdd)
+                { this->speedAdd_=speedAdd; }
+            inline void setSpeedMultiply(float speedMultiply)
+                { this->speedMultiply_=speedMultiply; }
+
+        protected:
+            virtual std::vector<PickupCarrier*>* getCarrierChildren(void)
+                { return new std::vector<PickupCarrier*>(); }
+            virtual PickupCarrier* getCarrierParent(void);
+
+        private:
+            void networkcallback_shipID();
+
+            SpaceShip* ship_;
+            unsigned int shipID_;
+
+            float boostFactor_;
+            float speedFactor_;
+
+            float speedAdd_;
+            float speedMultiply_;
+
+            float maxSpeedFront_;
+            float maxSpeedBack_;
+            float maxSpeedLeftRight_;
+            float maxSpeedUpDown_;
+
+            float accelerationFront_;
+            float accelerationBrake_;
+            float accelerationBack_;
+            float accelerationLeftRight_;
+            float accelerationUpDown_;
+
+            Shader* boostBlur_;
+            float blurStrength_;
+    };
+}
+
+#endif /* _Engine_H__ */
Index: /code/branches/rocket2/src/orxonox/items/Item.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/items/Item.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/items/Item.cc	(revision 6952)
@@ -0,0 +1,38 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Item.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    Item::Item(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
+    {
+        RegisterObject(Item);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/items/Item.h
===================================================================
--- /code/branches/rocket2/src/orxonox/items/Item.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/items/Item.h	(revision 6952)
@@ -0,0 +1,47 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Item_H__
+#define _Item_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "core/BaseObject.h"
+#include "network/synchronisable/Synchronisable.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Item : public BaseObject, public Synchronisable
+    {
+        public:
+            Item(BaseObject* creator);
+            virtual ~Item() {}
+    };
+}
+
+#endif /* _Item_H__ */
Index: /code/branches/rocket2/src/orxonox/items/MultiStateEngine.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/items/MultiStateEngine.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/items/MultiStateEngine.cc	(revision 6952)
@@ -0,0 +1,260 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "MultiStateEngine.h"
+
+extern "C" {
+#include <lua.h>
+}
+
+#include "util/Convert.h"
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/LuaState.h"
+#include "core/XMLPort.h"
+#include "worldentities/EffectContainer.h"
+#include "worldentities/pawns/SpaceShip.h"
+#include "sound/WorldSound.h"
+
+namespace orxonox
+{
+    static const float FORWARD_EFFECT_VELOCITY_THRESHOLD = 0;
+    static const float MAX_VELOCITY_NORMAL = 111;
+    static const float MAX_VELOCITY_BOOST = 221;
+
+    CreateFactory(MultiStateEngine);
+
+    MultiStateEngine::MultiStateEngine(BaseObject* creator) : Engine(creator)
+    {
+        RegisterObject(MultiStateEngine);
+
+        if (GameMode::isMaster())
+        {
+            this->defEngineSndNormal_ = new WorldSound(this);
+            this->defEngineSndBoost_  = new WorldSound(this);
+            this->defEngineSndNormal_->setLooping(true);
+            this->defEngineSndBoost_->setLooping(true);
+            this->lua_ = new LuaState();
+        }
+        else
+        {
+            this->defEngineSndBoost_ = 0;
+            this->defEngineSndNormal_ = 0;
+            this->lua_ = 0;
+        }
+        this->state_ = 0;
+        this->oldState_ = 0;
+
+        this->setSyncMode(ObjectDirection::Bidirectional);
+        this->registerVariables();
+    }
+
+    MultiStateEngine::~MultiStateEngine()
+    {
+        if (this->isInitialized())
+        {
+            if (!this->getShip())
+            {
+                // We have no ship, so the effects are not attached and won't be destroyed automatically
+                for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
+                    for (std::vector<WorldEntity*>::const_iterator it2 = (*it)->getEffectsBegin(); it2 != (*it)->getEffectsBegin(); ++it2)
+                        (*it2)->destroy();
+                if (this->defEngineSndNormal_)
+                    this->defEngineSndNormal_->destroy();
+                if (this->defEngineSndBoost_)
+                    this->defEngineSndBoost_->destroy();
+            }
+            if (this->lua_)
+                delete this->lua_;
+        }
+    }
+
+    void MultiStateEngine::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(MultiStateEngine, XMLPort, xmlelement, mode);
+        XMLPortObject(MultiStateEngine, EffectContainer, "",  addEffectContainer,  getEffectContainer,  xmlelement, mode);
+        XMLPortParam(MultiStateEngine, "defEngineSndNormal",  setDefEngSndNormal,  getDefEngSndNormal,  xmlelement, mode);
+        XMLPortParam(MultiStateEngine, "defEngineSndBoost",  setDefEngSndBoost,  getDefEngSndBoost,  xmlelement, mode);
+    }
+
+    void MultiStateEngine::registerVariables()
+    {
+        registerVariable(this->state_, VariableDirection::ToServer);
+    }
+
+    void MultiStateEngine::tick(float dt)
+    {
+        if (this->getShip())
+        {
+            const Vector3& velocity = this->getShip()->getLocalVelocity();
+
+            if (this->getShip()->hasLocalController())
+            {
+                const Vector3& direction = this->getDirection();
+                bool forward = (direction.z < 0.0 && velocity.z < -FORWARD_EFFECT_VELOCITY_THRESHOLD);
+
+                this->state_ = 0;
+                if (this->getShip()->getBoost() && forward)
+                    this->state_ = Boost;
+                else if (forward && !this->state_) // this->state_ == Boost
+                    this->state_ = Normal;
+                else if (direction.z > 0.0 && velocity.z < 0.0)
+                    this->state_ = Brake;
+                else
+                    this->state_ = Idle;
+
+                if (this->state_ == Idle && this->getSpeedAdd() > 0)
+                    this->state_ = Normal;
+            }
+
+            if (GameMode::isMaster())
+            {
+                int changes = this->state_ | this->oldState_;
+
+                float pitch = velocity.length();
+                if (this->state_ & Normal)
+                    defEngineSndNormal_->setPitch(clamp(pitch/MAX_VELOCITY_NORMAL + 1, 0.5f, 2.0f));
+                if (this->state_ & Boost)
+                    defEngineSndBoost_->setPitch(clamp(pitch/MAX_VELOCITY_BOOST + 1, 0.5f, 2.0f));
+
+                if (changes & Idle)
+                {
+                    lua_pushboolean(this->lua_->getInternalLuaState(), this->state_ & Idle);
+                    lua_setglobal(this->lua_->getInternalLuaState(), "idle");
+                }
+                if (changes & Normal)
+                {
+                    lua_pushboolean(this->lua_->getInternalLuaState(), this->state_ & Normal);
+                    lua_setglobal(this->lua_->getInternalLuaState(), "normal");
+                    if (this->state_ & Normal)
+                        defEngineSndNormal_->play();
+                    else
+                        defEngineSndNormal_->stop();
+                }
+                if (changes & Brake)
+                {
+                    lua_pushboolean(this->lua_->getInternalLuaState(), this->state_ & Brake);
+                    lua_setglobal(this->lua_->getInternalLuaState(), "brake");
+                }
+                if (changes & Boost)
+                {
+                    lua_pushboolean(this->lua_->getInternalLuaState(), this->state_ & Boost);
+                    lua_setglobal(this->lua_->getInternalLuaState(), "boost");
+                    if (this->state_ & Boost)
+                        defEngineSndBoost_->play();
+                    else
+                        defEngineSndBoost_->stop();
+                }
+
+                this->oldState_ = this->state_;
+
+                // Update all effect conditions
+                for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
+                    (*it)->updateCondition();
+            }
+        }
+
+        SUPER(MultiStateEngine, tick, dt);
+    }
+
+    void MultiStateEngine::addToSpaceShip(SpaceShip* ship)
+    {
+        Engine::addToSpaceShip(ship);
+
+        if (!ship)
+            return;
+
+        if( this->defEngineSndNormal_ )
+            this->getShip()->attach(defEngineSndNormal_);
+        if( this->defEngineSndBoost_ )
+            this->getShip()->attach(defEngineSndBoost_);
+
+        for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
+            for (std::vector<WorldEntity*>::const_iterator it2 = (*it)->getEffectsBegin(); it2 != (*it)->getEffectsEnd(); ++it2)
+                this->getShip()->attach(*it2);
+    }
+
+    void MultiStateEngine::addEffectContainer(EffectContainer* effect)
+    {
+        if (effect == NULL)
+            return;
+        effect->setLuaState(this->lua_, 'f' + multi_cast<std::string>(this->effectContainers_.size()));
+        this->effectContainers_.push_back(effect);
+        if (this->getShip())
+        {
+            for (std::vector<WorldEntity*>::const_iterator it = effect->getEffectsBegin(); it != effect->getEffectsBegin(); ++it)
+                this->getShip()->attach(*it);
+        }
+    }
+
+    EffectContainer* MultiStateEngine::getEffectContainer(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::vector<EffectContainer*>::const_iterator it = this->effectContainers_.begin(); it != this->effectContainers_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+        }
+        return NULL;
+    }
+
+    void MultiStateEngine::setDefEngSndNormal(const std::string &engineSound)
+    {
+        if( defEngineSndNormal_ )
+            defEngineSndNormal_->setSource(engineSound);
+        else
+            assert(0); // This should never happen, because soundpointer is only available on master
+    }
+
+    const std::string& MultiStateEngine::getDefEngSndNormal()
+    {
+        if( defEngineSndNormal_ )
+            return defEngineSndNormal_->getSource();
+        else
+            assert(0);
+        return BLANKSTRING;
+    }
+
+    void MultiStateEngine::setDefEngSndBoost(const std::string &engineSound)
+    {
+        if( defEngineSndBoost_ )
+            defEngineSndBoost_->setSource(engineSound);
+        else
+            assert(0);
+    }
+
+    const std::string& MultiStateEngine::getDefEngSndBoost()
+    {
+        if( this->defEngineSndBoost_ )
+            return defEngineSndBoost_->getSource();
+        else
+            assert(0);
+        return BLANKSTRING;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/items/MultiStateEngine.h
===================================================================
--- /code/branches/rocket2/src/orxonox/items/MultiStateEngine.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/items/MultiStateEngine.h	(revision 6952)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _MultiStateEngine_H__
+#define _MultiStateEngine_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <vector>
+#include "Engine.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport MultiStateEngine : public Engine
+    {
+        public:
+            enum EngineState
+            {
+                Idle    = 1,
+                Normal  = 2,
+                Brake   = 4,
+                Boost   = 8
+            };
+
+            MultiStateEngine(BaseObject* creator);
+            virtual ~MultiStateEngine();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            virtual void tick(float dt);
+
+            virtual void addToSpaceShip(SpaceShip* ship);
+
+            void addEffectContainer(EffectContainer* effect);
+            EffectContainer* getEffectContainer(unsigned int index) const;
+
+            void setDefEngSndNormal(const std::string& engineSound);
+            const std::string& getDefEngSndNormal();
+            void setDefEngSndBoost(const std::string& engineSound);
+            const std::string& getDefEngSndBoost();
+
+        private:
+            int state_;
+            int oldState_;
+            LuaState* lua_;
+            std::vector<EffectContainer*> effectContainers_;
+            WorldSound* defEngineSndNormal_;
+            WorldSound* defEngineSndBoost_;
+    };
+}
+
+#endif /* _MultiStateEngine_H__ */
Index: /code/branches/rocket2/src/orxonox/overlays/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/overlays/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/overlays/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,9 @@
+ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+  GUISheet.cc
+  OrxonoxOverlay.cc
+  OverlayGroup.cc
+
+#COMPILATION_BEGIN OverlayCompilation.cc
+  InGameConsole.cc
+#COMPILATION_END
+)
Index: /code/branches/rocket2/src/orxonox/overlays/GUISheet.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/overlays/GUISheet.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/overlays/GUISheet.cc	(revision 6952)
@@ -0,0 +1,96 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "GUISheet.h"
+
+#include "core/CoreIncludes.h"
+#include "core/GUIManager.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(GUISheet);
+
+    GUISheet::GUISheet(BaseObject* creator)
+        : BaseObject(creator)
+        , bShowOnLoad_(false)
+        , bHidePrevious_(false)
+        , bHidePreviousSet_(false)
+    {
+        RegisterObject(GUISheet);
+
+        if (!GameMode::showsGraphics())
+            ThrowException(NoGraphics, "GUISheet construction failed: no graphics");
+    }
+
+    GUISheet::~GUISheet()
+    {
+    }
+
+    void GUISheet::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        SUPER(GUISheet, XMLPort, xmlElement, mode);
+
+        XMLPortParam(GUISheet, "showOnLoad",   setShowOnLoad,     getShowOnLoad,     xmlElement, mode);
+        XMLPortParam(GUISheet, "hidePrevious", setPreviousHiding, getPreviousHiding, xmlElement, mode);
+        XMLPortParam(GUISheet, "sheetName",    setSheetName,      getSheetName,      xmlElement, mode);
+        XMLPortParam(GUISheet, "backgroundImage",  setBackgroundImage,  getBackgroundImage,  xmlElement, mode);
+
+        if (this->bShowOnLoad_)
+            this->show();
+    }
+
+    void GUISheet::show()
+    {
+        GUIManager::getInstance().setBackgroundImage(this->backgroundImage_);
+        if (this->bHidePreviousSet_)
+            GUIManager::getInstance().showGUI(this->sheetName_, this->bHidePrevious_);
+        else
+            GUIManager::getInstance().showGUI(this->sheetName_);
+    }
+
+    void GUISheet::hide()
+    {
+        GUIManager::getInstance().hideGUI(this->sheetName_);
+        if (!this->backgroundImage_.empty())
+            GUIManager::getInstance().setBackgroundImage("");
+    }
+
+    void GUISheet::setSheetName(const std::string& name)
+    {
+        this->sheetName_ = name;
+        GUIManager::getInstance().loadGUI(this->sheetName_);
+    }
+
+    void GUISheet::setPreviousHiding(bool bHide)
+    {
+        this->bHidePrevious_ = bHide;
+        this->bHidePreviousSet_ = true;
+        // Note: This call has no effect when already showing!
+    }
+}
Index: /code/branches/rocket2/src/orxonox/overlays/GUISheet.h
===================================================================
--- /code/branches/rocket2/src/orxonox/overlays/GUISheet.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/overlays/GUISheet.h	(revision 6952)
@@ -0,0 +1,78 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _GUISheet_H__
+#define _GUISheet_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    //! Simple XML loadable interface to the otherwise Lua coded GUI framework.
+    class _OrxonoxExport GUISheet : public BaseObject
+    {
+    public:
+        GUISheet(BaseObject* creator);
+        ~GUISheet();
+
+        void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+
+        void show();
+        void hide();
+
+        void setSheetName(const std::string& name);
+        inline const std::string& getSheetName() const
+            { return this->sheetName_; }
+
+        inline void setShowOnLoad(bool bShow)
+            { this->bShowOnLoad_ = bShow; }
+        inline bool getShowOnLoad() const
+            { return this->bShowOnLoad_; }
+
+        void setPreviousHiding(bool bHide);
+        inline bool getPreviousHiding() const
+            { return this->bHidePrevious_; }
+
+        void setBackgroundImage(const std::string& image)
+            { this->backgroundImage_ = image; }
+        inline const std::string& getBackgroundImage() const
+            { return this->backgroundImage_; }
+
+    private:
+        std::string sheetName_;
+        bool bShowOnLoad_;
+        bool bHidePrevious_;
+        bool bHidePreviousSet_;
+        std::string backgroundImage_;
+  };
+}
+
+#endif /* _GUISheet_H__ */
Index: /code/branches/rocket2/src/orxonox/overlays/InGameConsole.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/overlays/InGameConsole.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/overlays/InGameConsole.cc	(revision 6952)
@@ -0,0 +1,609 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Felix Schulthess
+ *   Co-authors:
+ *      Fabian 'x3n' Landau
+ *
+ */
+
+
+#include "InGameConsole.h"
+
+#include <algorithm>
+#include <string>
+#include <OgreOverlay.h>
+#include <OgreOverlayElement.h>
+#include <OgreOverlayManager.h>
+#include <OgreOverlayContainer.h>
+#include <OgreBorderPanelOverlayElement.h>
+#include <OgreTextAreaOverlayElement.h>
+#include <OgreFontManager.h>
+#include <OgreFont.h>
+
+#include "util/Clock.h"
+#include "util/Convert.h"
+#include "util/Math.h"
+#include "util/DisplayStringConversions.h"
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/ConsoleCommand.h"
+#include "core/ScopedSingletonManager.h"
+#include "core/input/InputManager.h"
+#include "core/input/InputState.h"
+#include "core/input/InputBuffer.h"
+
+namespace orxonox
+{
+    const int LINES = 30;
+    const float CHAR_WIDTH = 7.45f; // fix this please - determine the char-width dynamically
+
+    SetConsoleCommand(InGameConsole, openConsole, true);
+    SetConsoleCommand(InGameConsole, closeConsole, true);
+
+    ManageScopedSingleton(InGameConsole, ScopeID::Graphics, false);
+
+    /**
+        @brief Constructor: Creates and initializes the InGameConsole.
+    */
+    InGameConsole::InGameConsole()
+        : shell_(new Shell("InGameConsole", true))
+        , bShowCursor_(false)
+        , consoleOverlay_(0)
+        , consoleOverlayContainer_(0)
+        , consoleOverlayNoise_(0)
+        , consoleOverlayCursor_(0)
+        , consoleOverlayBorder_(0)
+        , consoleOverlayTextAreas_(0)
+        , inputState_(0)
+    {
+        RegisterObject(InGameConsole);
+
+        this->bActive_ = false;
+        this->cursor_ = 0.0f;
+        this->cursorSymbol_ = '|';
+        this->inputWindowStart_ = 0;
+        this->numLinesShifted_ = LINES - 1;
+        // for the beginning, don't scroll
+        this->scroll_ = 0;
+
+        this->setConfigValues();
+        this->initialise();
+    }
+
+    /**
+        @brief Destructor: Destroys the TextAreas.
+    */
+    InGameConsole::~InGameConsole()
+    {
+        this->deactivate();
+
+        // destroy the input state previously created (InputBuffer gets destroyed by the Shell)
+        InputManager::getInstance().destroyState("console");
+
+        // destroy the underlaying shell
+        this->shell_->destroy();
+
+        Ogre::OverlayManager* ovMan = Ogre::OverlayManager::getSingletonPtr();
+        if (ovMan)
+        {
+            if (this->consoleOverlayNoise_)
+                Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->consoleOverlayNoise_);
+            if (this->consoleOverlayCursor_)
+                Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->consoleOverlayCursor_);
+            Ogre::FontManager::getSingleton().remove("MonofurConsole");
+            if (this->consoleOverlayBorder_)
+                Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->consoleOverlayBorder_);
+            if (this->consoleOverlayTextAreas_)
+            {
+                for (int i = 0; i < LINES; i++)
+                {
+                    if (this->consoleOverlayTextAreas_[i])
+                      Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->consoleOverlayTextAreas_[i]);
+                    this->consoleOverlayTextAreas_[i] = 0;
+                }
+
+            }
+            if (this->consoleOverlayContainer_)
+                Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->consoleOverlayContainer_);
+        }
+        if (this->consoleOverlayTextAreas_)
+        {
+            delete[] this->consoleOverlayTextAreas_;
+            this->consoleOverlayTextAreas_ = 0;
+        }
+
+        if (this->consoleOverlay_)
+            Ogre::OverlayManager::getSingleton().destroy(consoleOverlay_);
+    }
+
+    /**
+        @brief Sets the config values, describing the size of the console.
+    */
+    void InGameConsole::setConfigValues()
+    {
+        SetConfigValue(relativeWidth, 0.8);
+        SetConfigValue(relativeHeight, 0.4);
+        SetConfigValue(blinkTime, 0.5);
+        SetConfigValue(scrollSpeed_, 3.0f);
+        SetConfigValue(noiseSize_, 1.0f);
+        SetConfigValue(cursorSymbol_, '|');
+        SetConfigValue(bHidesAllInput_, false).callback(this, &InGameConsole::bHidesAllInputChanged);
+    }
+
+    /**
+        @brief Called whenever bHidesAllInput_ changes.
+    */
+    void InGameConsole::bHidesAllInputChanged()
+    {
+        if (inputState_)
+        {
+            if (bHidesAllInput_)
+            {
+                inputState_->setMouseHandler(&InputHandler::EMPTY);
+                inputState_->setJoyStickHandler(&InputHandler::EMPTY);
+            }
+            else
+            {
+                inputState_->setMouseHandler(0);
+                inputState_->setJoyStickHandler(0);
+            }
+        }
+    }
+
+    /**
+        @brief Initializes the InGameConsole.
+    */
+    void InGameConsole::initialise()
+    {
+        // create the corresponding input state
+        inputState_ = InputManager::getInstance().createInputState("console", false, false, InputStatePriority::Console);
+        inputState_->setKeyHandler(this->shell_->getInputBuffer());
+        bHidesAllInputChanged();
+
+        // create overlay and elements
+        Ogre::OverlayManager* ovMan = Ogre::OverlayManager::getSingletonPtr();
+
+        // create actual overlay
+        this->consoleOverlay_ = ovMan->create("InGameConsoleConsole");
+
+        // create a container
+        this->consoleOverlayContainer_ = static_cast<Ogre::OverlayContainer*>(ovMan->createOverlayElement("Panel", "InGameConsoleContainer"));
+        this->consoleOverlayContainer_->setMetricsMode(Ogre::GMM_RELATIVE);
+        this->consoleOverlayContainer_->setPosition((1 - this->relativeWidth) / 2, 0);
+        this->consoleOverlayContainer_->setDimensions(this->relativeWidth, this->relativeHeight);
+        this->consoleOverlay_->add2D(this->consoleOverlayContainer_);
+
+        // create BorderPanel
+        this->consoleOverlayBorder_ = static_cast<Ogre::BorderPanelOverlayElement*>(ovMan->createOverlayElement("BorderPanel", "InGameConsoleBorderPanel"));
+        this->consoleOverlayBorder_->setMetricsMode(Ogre::GMM_PIXELS);
+        this->consoleOverlayBorder_->setMaterialName("ConsoleCenter");
+        this->consoleOverlayBorder_->setBorderSize(16, 16, 0, 16);
+        this->consoleOverlayBorder_->setBorderMaterialName("ConsoleBorder");
+        this->consoleOverlayBorder_->setLeftBorderUV(0.0f, 0.49f, 0.5f, 0.51f);
+        this->consoleOverlayBorder_->setRightBorderUV(0.5f, 0.49f, 1.0f, 0.5f);
+        this->consoleOverlayBorder_->setBottomBorderUV(0.49f, 0.5f, 0.51f, 1.0f);
+        this->consoleOverlayBorder_->setBottomLeftBorderUV(0.0f, 0.5f, 0.5f, 1.0f);
+        this->consoleOverlayBorder_->setBottomRightBorderUV(0.5f, 0.5f, 1.0f, 1.0f);
+        this->consoleOverlayContainer_->addChild(this->consoleOverlayBorder_);
+
+        // create a new font to match the requested size exactly
+        Ogre::FontPtr font = static_cast<Ogre::FontPtr>
+            (Ogre::FontManager::getSingleton().create("MonofurConsole", "General"));
+        font->setType(Ogre::FT_TRUETYPE);
+        font->setSource("Monofur.ttf");
+        font->setTrueTypeSize(18);
+        // reto: I don't know why, but setting the resolution twice as high makes the font look a lot clearer
+        font->setTrueTypeResolution(192);
+        font->addCodePointRange(Ogre::Font::CodePointRange(33, 126));
+        font->addCodePointRange(Ogre::Font::CodePointRange(161, 255));
+
+        // create noise
+        this->consoleOverlayNoise_ = static_cast<Ogre::PanelOverlayElement*>(ovMan->createOverlayElement("Panel", "InGameConsoleNoise"));
+        this->consoleOverlayNoise_->setMetricsMode(Ogre::GMM_PIXELS);
+        this->consoleOverlayNoise_->setPosition(5,0);
+        this->consoleOverlayNoise_->setMaterialName("ConsoleNoiseSmall");
+        // comment following line to disable noise
+        this->consoleOverlayBorder_->addChild(this->consoleOverlayNoise_);
+
+        // create the text lines
+        this->consoleOverlayTextAreas_ = new Ogre::TextAreaOverlayElement*[LINES];
+        for (int i = 0; i < LINES; i++)
+        {
+            this->consoleOverlayTextAreas_[i] = static_cast<Ogre::TextAreaOverlayElement*>(ovMan->createOverlayElement("TextArea", "InGameConsoleTextArea" + multi_cast<std::string>(i)));
+            this->consoleOverlayTextAreas_[i]->setMetricsMode(Ogre::GMM_PIXELS);
+            this->consoleOverlayTextAreas_[i]->setFontName("MonofurConsole");
+            this->consoleOverlayTextAreas_[i]->setCharHeight(18);
+            this->consoleOverlayTextAreas_[i]->setParameter("colour_top", "0.21 0.69 0.21");
+            this->consoleOverlayTextAreas_[i]->setLeft(8);
+            this->consoleOverlayTextAreas_[i]->setCaption("");
+            this->consoleOverlayNoise_->addChild(this->consoleOverlayTextAreas_[i]);
+        }
+
+        // create cursor (also a text area overlay element)
+        this->consoleOverlayCursor_ = static_cast<Ogre::TextAreaOverlayElement*>(ovMan->createOverlayElement("TextArea", "InGameConsoleCursor"));
+        this->consoleOverlayCursor_->setMetricsMode(Ogre::GMM_PIXELS);
+        this->consoleOverlayCursor_->setFontName("MonofurConsole");
+        this->consoleOverlayCursor_->setCharHeight(18);
+        this->consoleOverlayCursor_->setParameter("colour_top", "0.21 0.69 0.21");
+        this->consoleOverlayCursor_->setLeft(7);
+        this->consoleOverlayCursor_->setCaption(std::string(this->cursorSymbol_, 1));
+        this->consoleOverlayNoise_->addChild(this->consoleOverlayCursor_);
+
+        this->windowResized(this->getWindowWidth(), this->getWindowWidth());
+
+        // move overlay "above" the top edge of the screen
+        // we take -1.3 because the border makes the panel bigger
+        this->consoleOverlayContainer_->setTop(-1.3f * this->relativeHeight);
+
+        COUT(4) << "Info: InGameConsole initialized" << std::endl;
+    }
+
+    // ###############################
+    // ###  ShellListener methods  ###
+    // ###############################
+
+    /**
+        @brief Called if all output-lines have to be redrawn.
+    */
+    void InGameConsole::linesChanged()
+    {
+        Shell::LineList::const_iterator it = this->shell_->getNewestLineIterator();
+        int max = 0;
+        for (int i = 1; i < LINES; ++i)
+        {
+            if (it != this->shell_->getEndIterator())
+            {
+                ++it;
+                max = i;
+            }
+            else
+                break;
+        }
+
+        for (int i = LINES - 1; i > max; --i)
+            this->print("", Shell::None, i, true);
+
+        for (int i = max; i >= 1; --i)
+        {
+            --it;
+            this->print(it->first, it->second, i, true);
+        }
+    }
+
+    /**
+        @brief Called if only the last output-line has changed.
+    */
+    void InGameConsole::onlyLastLineChanged()
+    {
+        if (LINES > 1)
+            this->print(this->shell_->getNewestLineIterator()->first, this->shell_->getNewestLineIterator()->second, 1);
+    }
+
+    /**
+        @brief Called if a new output-line was added.
+    */
+    void InGameConsole::lineAdded()
+    {
+        this->numLinesShifted_ = 0;
+        this->shiftLines();
+        this->onlyLastLineChanged();
+    }
+
+    /**
+        @brief Called if the text in the input-line has changed.
+    */
+    void InGameConsole::inputChanged()
+    {
+        if (LINES > 0)
+            this->print(this->shell_->getInput(), Shell::Input, 0);
+
+        if (this->shell_->getInput().empty())
+            this->inputWindowStart_ = 0;
+    }
+
+    /**
+        @brief Called if the position of the cursor in the input-line has changed.
+    */
+    void InGameConsole::cursorChanged()
+    {
+        unsigned int pos = this->shell_->getCursorPosition() - inputWindowStart_;
+        if (pos > maxCharsPerLine_)
+            pos = maxCharsPerLine_;
+
+        this->consoleOverlayCursor_->setCaption(std::string(pos,' ') + cursorSymbol_);
+        this->consoleOverlayCursor_->setTop(static_cast<int>(this->windowH_ * this->relativeHeight) - 24.0f);
+    }
+
+    /**
+        @brief Called if a command is about to be executed
+    */
+    void InGameConsole::executed()
+    {
+        this->shell_->addOutput(this->shell_->getInput() + '\n', Shell::Command);
+    }
+
+    /**
+        @brief Called if the console gets closed.
+    */
+    void InGameConsole::exit()
+    {
+        this->deactivate();
+    }
+
+    // ###############################
+    // ###  other external calls   ###
+    // ###############################
+
+    /**
+        @brief Used to control the actual scrolling and the cursor.
+    */
+    void InGameConsole::preUpdate(const Clock& time)
+    {
+        if (this->scroll_ != 0)
+        {
+            float oldTop = this->consoleOverlayContainer_->getTop();
+
+            if (this->scroll_ > 0)
+            {
+                // scrolling down
+                // enlarge oldTop a little bit so that this exponential function
+                // reaches 0 before infinite time has passed...
+                float deltaScroll = (oldTop - 0.01f) * time.getDeltaTime() * this->scrollSpeed_;
+                if (oldTop - deltaScroll >= 0)
+                {
+                    // window has completely scrolled down
+                    this->consoleOverlayContainer_->setTop(0);
+                    this->scroll_ = 0;
+                }
+                else
+                    this->consoleOverlayContainer_->setTop(oldTop - deltaScroll);
+            }
+
+            else
+            {
+                // scrolling up
+                // note: +0.01 for the same reason as when scrolling down
+                float deltaScroll = (1.3f * this->relativeHeight + 0.01f + oldTop) * time.getDeltaTime() * this->scrollSpeed_;
+                if (oldTop - deltaScroll <= -1.3 * this->relativeHeight)
+                {
+                    // window has completely scrolled up
+                    this->consoleOverlayContainer_->setTop(-1.3f * this->relativeHeight);
+                    this->scroll_ = 0;
+                    this->consoleOverlay_->hide();
+                }
+                else
+                    this->consoleOverlayContainer_->setTop(oldTop - deltaScroll);
+            }
+        }
+
+        if (this->bActive_)
+        {
+            this->cursor_ += time.getDeltaTime();
+            if (this->cursor_ >= this->blinkTime)
+            {
+                this->cursor_ = 0;
+                bShowCursor_ = !bShowCursor_;
+                if (bShowCursor_)
+                    this->consoleOverlayCursor_->show();
+                else
+                    this->consoleOverlayCursor_->hide();
+            }
+
+            // this creates a flickering effect (extracts exactly 80% of the texture at a random location)
+            float uRand = (rand() & 1023) / 1023.0f * 0.2f;
+            float vRand = (rand() & 1023) / 1023.0f * 0.2f;
+            this->consoleOverlayNoise_->setUV(uRand, vRand, 0.8f + uRand, 0.8f + vRand);
+        }
+    }
+
+    /**
+        @brief Resizes the console elements. Call if window size changes.
+    */
+    void InGameConsole::windowResized(unsigned int newWidth, unsigned int newHeight)
+    {
+        this->windowW_ = newWidth;
+        this->windowH_ = newHeight;
+        this->consoleOverlayBorder_->setWidth((float)(int)(this->windowW_* this->relativeWidth));
+        this->consoleOverlayBorder_->setHeight((float)(int)(this->windowH_ * this->relativeHeight));
+        this->consoleOverlayNoise_->setWidth((float)(int)(this->windowW_ * this->relativeWidth) - 10.0f);
+        this->consoleOverlayNoise_->setHeight((float)(int)(this->windowH_ * this->relativeHeight) - 5.0f);
+        this->consoleOverlayNoise_->setTiling(consoleOverlayNoise_->getWidth() / (50.0f * this->noiseSize_), consoleOverlayNoise_->getHeight() / (50.0f * this->noiseSize_));
+
+        // now adjust the text lines...
+        this->desiredTextWidth_ = static_cast<int>(this->windowW_ * this->relativeWidth) - 12;
+
+        if (LINES > 0)
+            this->maxCharsPerLine_ = std::max(10U, static_cast<unsigned int>(static_cast<float>(this->desiredTextWidth_) / CHAR_WIDTH));
+        else
+            this->maxCharsPerLine_ = 10;
+
+        for (int i = 0; i < LINES; i++)
+        {
+            this->consoleOverlayTextAreas_[i]->setWidth((float)this->desiredTextWidth_);
+            this->consoleOverlayTextAreas_[i]->setTop((float)(int)(this->windowH_ * this->relativeHeight) - 24 - 14*i);
+        }
+
+        this->linesChanged();
+        this->cursorChanged();
+    }
+
+    // ###############################
+    // ###    internal methods     ###
+    // ###############################
+
+    /**
+        @brief Prints string to bottom line.
+        @param s String to be printed
+    */
+    void InGameConsole::print(const std::string& text, Shell::LineType type, int index, bool alwaysShift)
+    {
+        std::string output = text;
+        if (LINES > index)
+        {
+            this->colourLine(type, index);
+
+            if (index > 0)
+            {
+                unsigned int linesUsed = 1;
+                while (output.size() > this->maxCharsPerLine_)
+                {
+                    ++linesUsed;
+                    this->consoleOverlayTextAreas_[index]->setCaption(multi_cast<Ogre::DisplayString>(output.substr(0, this->maxCharsPerLine_)));
+                    output.erase(0, this->maxCharsPerLine_);
+                    output.insert(0, 1, ' ');
+                    if (linesUsed > numLinesShifted_ || alwaysShift)
+                        this->shiftLines();
+                    this->colourLine(type, index);
+                }
+                this->consoleOverlayTextAreas_[index]->setCaption(multi_cast<Ogre::DisplayString>(output));
+                this->displayedText_ = output;
+                this->numLinesShifted_ = linesUsed;
+            }
+            else
+            {
+                if (output.size() > this->maxCharsPerLine_)
+                {
+                    if (this->shell_->getInputBuffer()->getCursorPosition() < this->inputWindowStart_)
+                        this->inputWindowStart_ = this->shell_->getInputBuffer()->getCursorPosition();
+                    else if (this->shell_->getInputBuffer()->getCursorPosition() >= (this->inputWindowStart_ + this->maxCharsPerLine_ - 1))
+                        this->inputWindowStart_ = this->shell_->getInputBuffer()->getCursorPosition() - this->maxCharsPerLine_ + 1;
+
+                    output = output.substr(this->inputWindowStart_, this->maxCharsPerLine_);
+                }
+                else
+                  this->inputWindowStart_ = 0;
+                this->displayedText_ = output;
+                this->consoleOverlayTextAreas_[index]->setCaption(multi_cast<Ogre::DisplayString>(output));
+            }
+        }
+    }
+
+    /**
+        @brief Shows the InGameConsole.
+    */
+    void InGameConsole::activate()
+    {
+        if (!this->bActive_)
+        {
+            this->bActive_ = true;
+            InputManager::getInstance().enterState("console");
+            this->shell_->registerListener(this);
+
+            this->windowResized(this->windowW_, this->windowH_);
+            this->linesChanged();
+            this->cursorChanged();
+            this->consoleOverlay_->show();
+
+            // scroll down
+            this->scroll_ = 1;
+            // the rest is done by tick
+        }
+    }
+
+    /**
+    @brief Hides the InGameConsole.
+    */
+    void InGameConsole::deactivate()
+    {
+        if (this->bActive_)
+        {
+            this->bActive_ = false;
+            InputManager::getInstance().leaveState("console");
+            this->shell_->unregisterListener(this);
+
+            // scroll up
+            this->scroll_ = -1;
+            // the rest is done by tick
+        }
+    }
+
+    /**
+        @brief Shifts all output lines one line up
+    */
+    void InGameConsole::shiftLines()
+    {
+        for (unsigned int i = LINES - 1; i > 1; --i)
+        {
+            this->consoleOverlayTextAreas_[i]->setCaption(this->consoleOverlayTextAreas_[i - 1]->getCaption());
+            this->consoleOverlayTextAreas_[i]->setColourTop(this->consoleOverlayTextAreas_[i - 1]->getColourTop());
+            this->consoleOverlayTextAreas_[i]->setColourBottom(this->consoleOverlayTextAreas_[i - 1]->getColourBottom());
+        }
+    }
+
+    void InGameConsole::colourLine(Shell::LineType type, int index)
+    {
+        ColourValue colourTop, colourBottom;
+        switch (type)
+        {
+        case Shell::Error:   colourTop = ColourValue(0.95f, 0.25f, 0.25f, 1.00f);
+                          colourBottom = ColourValue(1.00f, 0.50f, 0.50f, 1.00f); break;
+
+        case Shell::Warning: colourTop = ColourValue(0.95f, 0.50f, 0.20f, 1.00f);
+                          colourBottom = ColourValue(1.00f, 0.70f, 0.50f, 1.00f); break;
+
+        case Shell::Info:    colourTop = ColourValue(0.50f, 0.50f, 0.95f, 1.00f);
+                          colourBottom = ColourValue(0.80f, 0.80f, 1.00f, 1.00f); break;
+
+        case Shell::Debug:   colourTop = ColourValue(0.65f, 0.48f, 0.44f, 1.00f);
+                          colourBottom = ColourValue(1.00f, 0.90f, 0.90f, 1.00f); break;
+
+        case Shell::Verbose: colourTop = ColourValue(0.40f, 0.20f, 0.40f, 1.00f);
+                          colourBottom = ColourValue(0.80f, 0.60f, 0.80f, 1.00f); break;
+
+        case Shell::Ultra:   colourTop = ColourValue(0.21f, 0.69f, 0.21f, 1.00f);
+                          colourBottom = ColourValue(0.80f, 1.00f, 0.80f, 1.00f); break;
+
+        case Shell::Command: colourTop = ColourValue(0.80f, 0.80f, 0.80f, 1.00f);
+                          colourBottom = ColourValue(0.90f, 0.90f, 0.90f, 0.90f); break;
+
+        case Shell::Hint:    colourTop = ColourValue(0.80f, 0.80f, 0.80f, 1.00f);
+                          colourBottom = ColourValue(0.90f, 0.90f, 0.90f, 1.00f); break;
+
+        default:             colourTop = ColourValue(0.90f, 0.90f, 0.90f, 1.00f);
+                          colourBottom = ColourValue(1.00f, 1.00f, 1.00f, 1.00f); break;
+        }
+
+        this->consoleOverlayTextAreas_[index]->setColourTop   (colourTop);
+        this->consoleOverlayTextAreas_[index]->setColourBottom(colourBottom);
+    }
+
+    // ################################
+    // ###      static methods      ###
+    // ################################
+
+    /**
+        @brief Activates the console.
+    */
+    /*static*/ void InGameConsole::openConsole()
+    {
+        InGameConsole::getInstance().activate();
+    }
+
+    /**
+        @brief Deactivates the console.
+    */
+    /*static*/ void InGameConsole::closeConsole()
+    {
+        InGameConsole::getInstance().deactivate();
+    }
+}
Index: /code/branches/rocket2/src/orxonox/overlays/InGameConsole.h
===================================================================
--- /code/branches/rocket2/src/orxonox/overlays/InGameConsole.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/overlays/InGameConsole.h	(revision 6952)
@@ -0,0 +1,119 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Felix Schulthess
+ *   Co-authors:
+ *      Fabian 'x3n' Landau
+ *
+ */
+
+#ifndef _InGameConsole_H__
+#define _InGameConsole_H__
+
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+
+#include "util/OgreForwardRefs.h"
+#include "util/Singleton.h"
+#include "core/Shell.h"
+#include "core/WindowEventListener.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport InGameConsole : public Singleton<InGameConsole>, public ShellListener, public WindowEventListener
+    {
+        friend class Singleton<InGameConsole>;
+    public: // functions
+        InGameConsole();
+        ~InGameConsole();
+
+        void initialise();
+        void setConfigValues();
+
+        void preUpdate(const Clock& time);
+
+        static void openConsole();
+        static void closeConsole();
+
+    private: // functions
+        InGameConsole(const InGameConsole& other);
+
+        void activate();
+        void deactivate();
+
+        void linesChanged();
+        void onlyLastLineChanged();
+        void lineAdded();
+        void inputChanged();
+        void cursorChanged();
+        void executed();
+        void exit();
+
+        void shiftLines();
+        void colourLine(Shell::LineType type, int index);
+        void setCursorPosition(unsigned int pos);
+        void print(const std::string& text, Shell::LineType type, int index, bool alwaysShift = false);
+
+        void windowResized(unsigned int newWidth, unsigned int newHeight);
+
+        // config value related
+        void bHidesAllInputChanged();
+
+    private: // variables
+        Shell* shell_;
+        bool bActive_;
+        int windowW_;
+        int windowH_;
+        int desiredTextWidth_;
+        unsigned int maxCharsPerLine_;
+        unsigned int numLinesShifted_;
+        int scroll_;
+        float cursor_;
+        unsigned int inputWindowStart_;
+        bool bShowCursor_;
+        std::string displayedText_;
+        Ogre::Overlay* consoleOverlay_;
+        Ogre::OverlayContainer* consoleOverlayContainer_;
+        Ogre::PanelOverlayElement* consoleOverlayNoise_;
+        Ogre::TextAreaOverlayElement* consoleOverlayCursor_;
+        Ogre::BorderPanelOverlayElement* consoleOverlayBorder_;
+        Ogre::TextAreaOverlayElement** consoleOverlayTextAreas_;
+
+        // input related
+        InputState* inputState_;
+
+        // config values
+        float relativeWidth;
+        float relativeHeight;
+        float blinkTime;
+        float scrollSpeed_;
+        float noiseSize_;
+        char cursorSymbol_;
+        bool bHidesAllInput_;
+
+        static InGameConsole* singletonPtr_s;
+    };
+}
+
+#endif /* _InGameConsole_H__ */
Index: /code/branches/rocket2/src/orxonox/overlays/OrxonoxOverlay.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/overlays/OrxonoxOverlay.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/overlays/OrxonoxOverlay.cc	(revision 6952)
@@ -0,0 +1,386 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief Definition of the OrxonoxOverlay class.
+*/
+
+#include "OrxonoxOverlay.h"
+
+#include <cmath>
+#include <OgreOverlay.h>
+#include <OgreOverlayManager.h>
+#include <OgrePanelOverlayElement.h>
+#include <OgreRenderWindow.h>
+#include <OgreMaterialManager.h>
+#include <OgreTechnique.h>
+#include <OgrePass.h>
+
+#include "util/Convert.h"
+#include "util/Exception.h"
+#include "core/GameMode.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "core/ConsoleCommand.h"
+
+#include "OverlayGroup.h"
+
+namespace orxonox
+{
+    unsigned int OrxonoxOverlay::hudOverlayCounter_s = 0;
+    std::map<std::string, OrxonoxOverlay*> OrxonoxOverlay::overlays_s;
+
+    SetConsoleCommand(OrxonoxOverlay, scaleOverlay, false).accessLevel(AccessLevel::User);
+    SetConsoleCommand(OrxonoxOverlay, scrollOverlay, false).accessLevel(AccessLevel::User);
+    SetConsoleCommand(OrxonoxOverlay, toggleVisibility, false).accessLevel(AccessLevel::User);
+    SetConsoleCommand(OrxonoxOverlay, rotateOverlay, false).accessLevel(AccessLevel::User);
+
+    OrxonoxOverlay::OrxonoxOverlay(BaseObject* creator)
+        : BaseObject(creator)
+    {
+        RegisterObject(OrxonoxOverlay);
+
+        this->owner_ = 0;
+        this->group_ = 0;
+
+        if (!GameMode::showsGraphics())
+            ThrowException(NoGraphics, "Can't create OrxonoxOverlay, graphics engine not initialized");
+
+        // create the Ogre::Overlay
+        overlay_ = Ogre::OverlayManager::getSingleton().create("OrxonoxOverlay_overlay_"
+            + multi_cast<std::string>(hudOverlayCounter_s++));
+
+        // create background panel (can be used to show any picture)
+        this->background_ = static_cast<Ogre::PanelOverlayElement*>(
+            Ogre::OverlayManager::getSingleton().createOverlayElement("Panel",
+            "OrxonoxOverlay_background_" + multi_cast<std::string>(hudOverlayCounter_s++)));
+        this->overlay_->add2D(this->background_);
+
+        // Get aspect ratio from the render window. Later on, we get informed automatically
+        this->windowAspectRatio_ = static_cast<float>(this->getWindowWidth()) / this->getWindowHeight();
+
+        this->size_ = Vector2(1.0f, 1.0f);
+        this->pickPoint_= Vector2(0.0f, 0.0f);
+        this->position_ = Vector2(0.0f, 0.0f);
+        this->angle_ = Degree(0.0);
+        this->bCorrectAspect_ = false;
+        this->rotState_ = Horizontal;
+        this->angleChanged(); // updates all other values as well
+
+        setBackgroundMaterial("");
+    }
+
+    /**
+    @brief
+        Make sure everything gets removed/destroyed.
+    @remark
+        We assume that the Ogre::OverlayManager exists (there is an assert in Ogre for that!)
+    */
+    OrxonoxOverlay::~OrxonoxOverlay()
+    {
+        if (this->isInitialized())
+        {
+            // erase ourself from the map with all overlays
+            std::map<std::string, OrxonoxOverlay*>::iterator it = overlays_s.find(this->getName());
+            if (it != overlays_s.end())
+                overlays_s.erase(it);
+
+            Ogre::OverlayManager::getSingleton().destroyOverlayElement(this->background_);
+            Ogre::OverlayManager::getSingleton().destroy(this->overlay_);
+        }
+    }
+
+    /**
+    @brief
+        Loads the OrxonoxOverlay.
+
+        This has to be called before usage, otherwise strange behaviour is
+        guaranteed! (there should be no segfaults however).
+    @copydoc
+        BaseObject::XMLPort()
+    */
+    void OrxonoxOverlay::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        SUPER(OrxonoxOverlay, XMLPort, xmlElement, mode);
+
+        XMLPortParam(OrxonoxOverlay, "size",      setSize,      getSize,      xmlElement, mode);
+        XMLPortParam(OrxonoxOverlay, "pickpoint", setPickPoint, getPickPoint, xmlElement, mode);
+        XMLPortParam(OrxonoxOverlay, "position",  setPosition,  getPosition,  xmlElement, mode);
+        XMLPortParam(OrxonoxOverlay, "rotation",  setRotation,  getRotation,  xmlElement, mode);
+        XMLPortParam(OrxonoxOverlay, "correctaspect", setAspectCorrection,   getAspectCorrection,   xmlElement, mode);
+        XMLPortParam(OrxonoxOverlay, "background",    setBackgroundMaterial, getBackgroundMaterial, xmlElement, mode);
+    }
+
+    void OrxonoxOverlay::changedName()
+    {
+        SUPER(OrxonoxOverlay, changedName);
+
+        OrxonoxOverlay::overlays_s.erase(this->getOldName());
+
+        if (OrxonoxOverlay::overlays_s.find(this->getName()) != OrxonoxOverlay::overlays_s.end())
+            COUT(1) << "Overlay names should be unique or you cannnot access them via console. Name: \"" << this->getName() << '"' << std::endl;
+
+        OrxonoxOverlay::overlays_s[this->getName()] = this;
+    }
+
+    //! Only sets the background material name if not ""
+    void OrxonoxOverlay::setBackgroundMaterial(const std::string& material)
+    {
+        if (this->background_ && !material.empty())
+            this->background_->setMaterialName(material);
+    }
+
+    //! Returns the the material name of the background
+    const std::string& OrxonoxOverlay::getBackgroundMaterial() const
+    {
+        if (this->background_)
+            return this->background_->getMaterialName();
+        else
+            return BLANKSTRING;
+    }
+
+    //! Called by BaseObject when visibility has changed.
+    void OrxonoxOverlay::changedVisibility()
+    {
+        SUPER( OrxonoxOverlay, changedVisibility );
+
+        if (!this->overlay_)
+            return;
+
+        // only set to visible if corresponding OverlayGroup is also visible
+        if (this->isVisible() && (!this->getOverlayGroup() || this->getOverlayGroup()->isVisible()) )
+            this->overlay_->show();
+        else
+            this->overlay_->hide();
+    }
+
+    /**
+    @brief
+        Called by the GraphicsManager whenever the window size changes.
+        Calculates the aspect ratio only.
+    */
+    void OrxonoxOverlay::windowResized(unsigned int newWidth, unsigned int newHeight)
+    {
+        this->windowAspectRatio_ = static_cast<float>(newWidth) / newHeight;
+        this->sizeCorrectionChanged();
+    }
+
+    /**
+    @brief
+        Called whenever the rotation angle has changed.
+    */
+    void OrxonoxOverlay::angleChanged()
+    {
+        if (!this->overlay_)
+            return;
+
+        this->overlay_->setRotate(this->angle_);
+        this->sizeCorrectionChanged();
+    }
+
+    /**
+    @brief
+        Called whenever the aspect ratio or the angle has changed.
+        The method calculates a correction factor for the size to compensate
+        for aspect distortion if desired.
+    @remarks
+        This only works when the angle is about 0 or 90 degrees.
+    */
+    void OrxonoxOverlay::sizeCorrectionChanged()
+    {
+        if (this->bCorrectAspect_)
+        {
+            float angle = this->angle_.valueDegrees();
+            if (angle < 0.0)
+                angle = -angle;
+            angle -= 180.0f * static_cast<int>(angle / 180.0);
+
+            // take the reverse if angle is about 90 degrees
+            float tempAspect;
+            if (angle > 89.0f && angle < 91.0f)
+            {
+                tempAspect = 1.0f / this->windowAspectRatio_;
+                rotState_ = Vertical;
+            }
+            else if (angle > 179 || angle < 1)
+            {
+                tempAspect = this->windowAspectRatio_;
+                rotState_ = Horizontal;
+            }
+            else
+            {
+                tempAspect = 1.0f;
+                rotState_ = Inbetween;
+            }
+
+            // note: this is only an approximation that is mostly valid when the
+            // magnitude of the width is about the magnitude of the height.
+            // Correctly we would have to take the square root of width*height
+            this->sizeCorrection_.x = 2.0f / (tempAspect + 1.0f);
+            this->sizeCorrection_.y = tempAspect * this->sizeCorrection_.x;
+        }
+        else
+        {
+            this->sizeCorrection_ = Vector2::UNIT_SCALE;
+        }
+
+        this->sizeChanged();
+    }
+
+    /**
+    @brief
+        Sets the overlay size using the actual corrected size.
+    */
+    void OrxonoxOverlay::sizeChanged()
+    {
+        if (!this->overlay_)
+            return;
+
+        this->overlay_->setScale(size_.x * sizeCorrection_.x, size_.y * sizeCorrection_.y);
+        positionChanged();
+    }
+
+    /**
+    @brief
+        Determines the position of the overlay.
+        This works also well when a rotation angle is applied. The overlay always
+        gets aligned correctly as well as possible.
+    */
+    void OrxonoxOverlay::positionChanged()
+    {
+        if (!this->overlay_)
+            return;
+
+        // transform the angle to a range of 0 - pi/2 first.
+        float angle = this->angle_.valueRadians();
+        if (angle < 0.0)
+            angle = -angle;
+        angle -= Ogre::Math::PI * static_cast<int>(angle / (Ogre::Math::PI));
+        if (angle > Ogre::Math::PI * 0.5)
+            angle = Ogre::Math::PI - angle;
+
+        // do some mathematical fiddling for a bounding box
+        Vector2 actualSize = size_ * sizeCorrection_;
+        float radius = actualSize.length();
+        float phi = atan(actualSize.y / actualSize.x);
+        Vector2 boundingBox(radius * cos(angle - phi), radius * sin(angle + phi));
+
+        // calculate the scrolling offset
+        Vector2 scroll = (position_ - 0.5 - boundingBox * (pickPoint_ - 0.5)) * 2.0;
+        this->overlay_->setScroll(scroll.x, -scroll.y);
+    }
+
+
+    //########### Console commands ############
+
+    /**
+    @brief
+        Scales an overlay by its name.
+    @param name
+        The name of the overlay defined BaseObject::setName() (usually done with the "name"
+        attribute in the xml file).
+    */
+    /*static*/ void OrxonoxOverlay::scaleOverlay(const std::string& name, float scale)
+    {
+        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
+        if (it != overlays_s.end())
+            it->second->scale(Vector2(scale, scale));
+    }
+
+    /**
+    @brief
+        Toggles the visibility of an Overlay by it's name.
+    @param name
+        The name of the overlay defined BaseObject::setName() (usually done with the "name"
+        attribute in the xml file).
+    */
+    /*static*/ void OrxonoxOverlay::toggleVisibility(const std::string& name)
+    {
+        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
+        if (it != overlays_s.end())
+        {
+            OrxonoxOverlay* overlay= it->second;
+            if(overlay->isVisible())
+            {
+                overlay->hide();
+                COUT(4) << "HIDE " << name << std::endl;
+            }
+            else
+            {
+                overlay->show();
+                COUT(4) << "SHOW " << name << std::endl;
+            }
+        }
+    }
+
+    /**
+    @brief
+        Scrolls an overlay by its name.
+    @param name
+        The name of the overlay defined BaseObject::setName() (usually done with the "name"
+        attribute in the xml file).
+    */
+    /*static*/ void OrxonoxOverlay::scrollOverlay(const std::string& name, const Vector2& scroll)
+    {
+        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
+        if (it != overlays_s.end())
+            it->second->scroll(scroll);
+    }
+
+    /**
+    @brief
+        Rotates an overlay by its name.
+    @param name
+        The name of the overlay defined BaseObject::setName() (usually done with the "name"
+        attribute in the xml file).
+    */
+    /*static*/ void OrxonoxOverlay::rotateOverlay(const std::string& name, const Degree& angle)
+    {
+        std::map<std::string, OrxonoxOverlay*>::const_iterator it = overlays_s.find(name);
+        if (it != overlays_s.end())
+            it->second->rotate(angle);
+    }
+
+    void OrxonoxOverlay::setOverlayGroup(OverlayGroup* group)
+    {
+        if (group != this->group_)
+        {
+            if (this->group_)
+                this->group_->removeElement(this);
+            this->group_ = group;
+            this->changedOverlayGroup();
+        }
+    }
+
+    void OrxonoxOverlay::setBackgroundAlpha(float alpha) {
+        Ogre::MaterialPtr ptr = this->background_->getMaterial();
+        Ogre::TextureUnitState* tempTx = ptr->getTechnique(0)->getPass(0)->getTextureUnitState(0);
+        tempTx->setAlphaOperation(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, alpha);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/overlays/OrxonoxOverlay.h
===================================================================
--- /code/branches/rocket2/src/orxonox/overlays/OrxonoxOverlay.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/overlays/OrxonoxOverlay.h	(revision 6952)
@@ -0,0 +1,217 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief Declaration of the OrxonoxOverlay class.
+*/
+
+#ifndef _OrxonoxOverlay_H__
+#define _OrxonoxOverlay_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+
+#include "util/Math.h"
+#include "util/OgreForwardRefs.h"
+#include "core/BaseObject.h"
+#include "core/Super.h"
+#include "core/WindowEventListener.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        Base class to display content directly onto the screen.
+        This is merely a wrapper of the Ogre::Overlay to implement more features and integrate it
+        in our class hierarchy for xml loading and config values.
+        The mentioned features are:
+        - Automatic positioning depending on the scale and the rotation angle.
+          You can specify a "pick point" relative to the overlay itself. This point will always be exactly
+          at the position (position_) of the overlay. That allows for margin/corner aligment.
+          It even works when a rotation angle is applied.
+        - Virtual methods for changedVisibilty() (BaseObject), angleChanged(), sizeCorrectionChanged(),
+          sizeChanged() and positionChanged(), that can be overridden by any derivative. This enables for
+          custom configurability of the size, position and rotation attributes. For intance, the HUDNavigation
+          should behave differently to sizeChanged() than a standard overlay.
+        - Console commands for scale, rotate and scroll (accessed by name)
+        - Standard Ogre::PanelOverlayElement for a background image (class doesn't have to be derived
+          only for displaying a picture).
+        - Reacts to changes of the window aspect
+        - Last but not least: On demand you can tell the overlay to automatically resale to correct for
+          aspect distortion. E.g. if you play 1024x768 you wouldn't want a round object to be oval.
+          Remark: This can (due to the Ogre::Overlay transformation order) only work for angle that are
+                  multiples of 90 degrees. But it's only a small drawback.
+    */
+    class _OrxonoxExport OrxonoxOverlay : public BaseObject, public WindowEventListener
+    {
+    public:
+        /**
+        @brief
+            Describes the rotational state of a an overlay.
+            Horizontal means 0/180 degrees, Vertical is 90/270 degrees
+            and Inbetween is everything else.
+        */
+        enum RotationState
+        {
+            Horizontal,
+            Vertical,
+            Inbetween
+        };
+
+    public:
+        OrxonoxOverlay(BaseObject* creator);
+        virtual ~OrxonoxOverlay();
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+
+        virtual void changedName();
+
+        //! Shows the overlay with an detour to BaseObject::visibility_
+        void show() { this->setVisible(true); }
+        //! Hides the overlay with an detour to BaseObject::visibility_
+        void hide() { this->setVisible(false); }
+
+        /** Sets whether the aspect of the overlay is corrected.
+            This is for instance useful for round objects that should stay round no matter
+            what the screen resolution is. */
+        void setAspectCorrection(bool val)        { this->bCorrectAspect_ = val; this->sizeCorrectionChanged(); }
+        //! Returns whether the window aspect is corrected
+        bool getAspectCorrection() const          { return this->bCorrectAspect_; }
+
+        //! Sets the position of this overlay on the screen.
+        void setPosition(Vector2 pos)             { this->position_ = pos; this->positionChanged(); }
+
+        //! Returns the current position on the screen.
+        const Vector2& getPosition() const        { return this->position_; }
+
+        //! Scrolls the overlay. @param offset The offset given.
+        void scroll(const Vector2& offset)        { this->position_ += offset; this->positionChanged(); }
+
+        /** Sets the point in the overlay where to pick it when translating.
+            For instance setting it to (1.0,1.0) means that the lower right corner of the
+            overlay will be put at position_.
+            This primarily helps aligning an overlay to any corner/margin on the screen. */
+        void setPickPoint(const Vector2& position){ this->pickPoint_ = position; this->positionChanged(); }
+
+        //! Gets the pick point of this overlay. @see setPickPoint()
+        const Vector2& getPickPoint() const       { return this->pickPoint_; }
+
+        //! Sets the rotation angle applied to this overlay in degrees.
+        void setRotation(const Degree& angle)     { this->angle_ = angle; this->angleChanged(); }
+
+        //! Gets the rotation angle applied to this overlay in degrees.
+        const Degree& getRotation() const         { return this->angle_; }
+
+        //! Rotates the overlay by angle degrees.
+        void rotate(const Degree& angle)          { this->angle_ += angle; this->angleChanged(); }
+
+        //! Sets the size of this overlay.
+        void setSize(const Vector2& size)         { this->size_ = size; this->sizeChanged(); }
+
+        //! Gets the current size that was set (uncorrected)
+        const Vector2& getSize() const            { return this->size_; }
+
+        //! Gets the actual size of the overlay on the screen (corrected)
+        Vector2 getActualSize() const             { return this->size_ * this->sizeCorrection_; }
+
+        //! Gets the current size correction (default: 1.0, 1.0)
+        const Vector2& getSizeCorrection() const  { return this->sizeCorrection_; }
+
+        //! Scales the overlay by scale.
+        void scale(const Vector2& scale)          { this->size_ *= scale; this->sizeChanged(); }
+
+        //! ConsoleCommand: Accesses the overlay by its name and scales it.
+        static void scaleOverlay(const std::string& name, float scale);
+        //! ConsoleCommand: Accesses the overlay by its name and scrolls it.
+        static void scrollOverlay(const std::string& name, const Vector2& scroll);
+        static void toggleVisibility(const std::string& name);
+        //! ConsoleCommand: Accesses the overlay by its name and rotates it.
+        static void rotateOverlay(const std::string& name, const Degree& angle);
+
+        void setBackgroundMaterial(const std::string& material);
+        const std::string& getBackgroundMaterial() const;
+
+        void setBackgroundAlpha(float alpha);
+
+        virtual void changedVisibility();
+
+        inline void setOwner(BaseObject* owner)
+        {
+            if (this->owner_ != owner)
+            {
+                this->owner_ = owner;
+                this->changedOwner();
+            }
+        }
+        inline BaseObject* getOwner() const
+            { return this->owner_; }
+        virtual void changedOwner() {}
+
+        void setOverlayGroup(OverlayGroup* group);
+        inline OverlayGroup* getOverlayGroup() const
+            { return this->group_; }
+        virtual void changedOverlayGroup()
+            { this->changedVisibility(); }
+
+    protected:
+        virtual void angleChanged();
+        virtual void sizeCorrectionChanged();
+        virtual void sizeChanged();
+        virtual void positionChanged();
+
+        Ogre::Overlay* overlay_;                   //!< The overlay the entire class is about.
+        Ogre::PanelOverlayElement* background_;    //!< Background image (blank per default).
+
+        float windowAspectRatio_;                  //!< Screen.width / screen.height
+        bool bCorrectAspect_;                      //!< Whether or not to correct the size. @see setAspectCorrection()
+        Vector2 size_;                             //!< Internal size of the overlay.
+        Vector2 sizeCorrection_;                   //!< Value to correct the size because of the window aspect.
+        Vector2 position_;                         //!< Position of the pickPoint on the screen.
+        Vector2 pickPoint_;                        //!< Point on the overlay to pick when translating
+        Degree angle_;                             //!< Rotation angle of the overlay
+        RotationState rotState_;                   //!< horizontal, vertical or inbetween
+
+    private:
+        void windowResized(unsigned int newWidth, unsigned int newHeight);
+
+        static unsigned int hudOverlayCounter_s;   //!< Static counter for hud elements
+        /** Contains all the overlays in a map for quick access via console commands.
+            We could also use the ObjectList, but that doesn't guarantee XMLPort(.) was called and is slower. */
+        static std::map<std::string, OrxonoxOverlay*> overlays_s;
+        BaseObject* owner_;
+        OverlayGroup* group_;
+        Ogre::Pass* backgroundAlphaPass_;
+  };
+
+  SUPER_FUNCTION(6, OrxonoxOverlay, changedOwner, false);
+  SUPER_FUNCTION(7, OrxonoxOverlay, changedOverlayGroup, false);
+}
+
+#endif /* _OrxonoxOverlay_H__ */
Index: /code/branches/rocket2/src/orxonox/overlays/OverlayGroup.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/overlays/OverlayGroup.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/overlays/OverlayGroup.cc	(revision 6952)
@@ -0,0 +1,208 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief Definition of the OverlayGroup class.
+*/
+
+#include "OverlayGroup.h"
+
+#include "core/ConsoleCommand.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "OrxonoxOverlay.h"
+
+namespace orxonox
+{
+    CreateFactory(OverlayGroup);
+
+    SetConsoleCommand(OverlayGroup, toggleVisibility, false).accessLevel(AccessLevel::User);
+    SetConsoleCommand(OverlayGroup, scaleGroup, false).accessLevel(AccessLevel::User);
+    SetConsoleCommand(OverlayGroup, scrollGroup, false).accessLevel(AccessLevel::User);
+
+    OverlayGroup::OverlayGroup(BaseObject* creator)
+        : BaseObject(creator)
+    {
+        RegisterObject(OverlayGroup);
+
+        this->owner_ = 0;
+
+        setScale(Vector2(1.0, 1.0));
+        setScroll(Vector2(0.0, 0.0));
+    }
+
+    OverlayGroup::~OverlayGroup()
+    {
+        for (std::set< SmartPtr<OrxonoxOverlay> >::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
+            (*it)->destroy();
+        this->hudElements_.clear();
+    }
+
+    /**
+    @brief
+        Loads the group and all its children OrxonoxOverlays.
+    @copydoc
+        BaseObject::XMLPort()
+    */
+    void OverlayGroup::XMLPort(Element& xmlElement, XMLPort::Mode mode)
+    {
+        SUPER(OverlayGroup, XMLPort, xmlElement, mode);
+
+        XMLPortParam(OverlayGroup, "scale",  setScale,  getScale,  xmlElement, mode);
+        XMLPortParam(OverlayGroup, "scroll", setScroll, getScroll, xmlElement, mode);
+        // loads all the child elements
+        XMLPortObject(OverlayGroup, OrxonoxOverlay, "", addElement, getElement, xmlElement, mode);
+    }
+
+    //! Scales every element in the set.
+    void OverlayGroup::setScale(const Vector2& scale)
+    {
+        for (std::set< SmartPtr<OrxonoxOverlay> >::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
+            (*it)->scale(scale / this->scale_);
+        this->scale_ = scale;
+    }
+
+    //! Scrolls every element in the set.
+    void OverlayGroup::setScroll(const Vector2& scroll)
+    {
+        for (std::set< SmartPtr<OrxonoxOverlay> >::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
+            (*it)->scroll(scroll - this->scroll_);
+        this->scroll_ = scroll;
+    }
+
+    /**
+    @brief
+        Adds an element to the set (used when loading with XMLPort).
+    @remarks
+        The names of the OrxonoxOverlays have to be unique!
+    */
+    void OverlayGroup::addElement(OrxonoxOverlay* element)
+    {
+        hudElements_.insert(SmartPtr<OrxonoxOverlay>(element));
+        element->setOverlayGroup( this );
+        if (this->owner_)
+            element->setOwner(this->owner_);
+    }
+
+    /**
+    @brief
+        Removes an element from the map.
+    @param name
+        The name of the element that is removed.
+    @return
+        Returns true if there was such an element to remove, false if not.
+    */
+    bool OverlayGroup::removeElement(OrxonoxOverlay* element)
+    {
+        if(this->hudElements_.erase(SmartPtr<OrxonoxOverlay>(element)) == 0)
+            return false;
+        return true;
+    }
+
+    //! Returns a different element as long as index < hudElements_.size().
+    OrxonoxOverlay* OverlayGroup::getElement(unsigned int index)
+    {
+        if (index < this->hudElements_.size())
+        {
+            std::set< SmartPtr<OrxonoxOverlay> >::const_iterator it = hudElements_.begin();
+            for (unsigned int i = 0; i != index; ++it, ++i)
+                ;
+            return it->get();
+        }
+        else
+            return 0;
+    }
+
+    //! Changes the visibility of all elements
+    void OverlayGroup::changedVisibility()
+    {
+        SUPER( OverlayGroup, changedVisibility );
+
+        for (std::set< SmartPtr<OrxonoxOverlay> >::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
+            (*it)->changedVisibility(); //inform all Child Overlays that our visibility has changed
+    }
+
+    void OverlayGroup::setOwner(BaseObject* owner)
+    {
+        this->owner_ = owner;
+
+        for (std::set< SmartPtr<OrxonoxOverlay> >::iterator it = hudElements_.begin(); it != hudElements_.end(); ++it)
+            (*it)->setOwner(owner);
+    }
+
+    //########### Console commands ############
+
+    /**
+    @brief
+        Hides/shows an overlay group by its name.
+    @param name
+        The name of the group defined BaseObject::setName() (usually done with the "name"
+        attribute in the xml file).
+    */
+    /*static*/ void OverlayGroup::toggleVisibility(const std::string& name)
+    {
+        for (ObjectList<OverlayGroup>::iterator it = ObjectList<OverlayGroup>::begin(); it; ++it)
+        {
+            if ((*it)->getName() == name)
+                (*it)->setVisible(!((*it)->isVisible()));
+        }
+    }
+
+    /**
+    @brief
+        Scales an overlay group by its name.
+    @param name
+        The name of the group defined BaseObject::setName() (usually done with the "name"
+        attribute in the xml file).
+    */
+    /*static*/ void OverlayGroup::scaleGroup(const std::string& name, float scale)
+    {
+        for (ObjectList<OverlayGroup>::iterator it = ObjectList<OverlayGroup>::begin(); it; ++it)
+        {
+            if ((*it)->getName() == name)
+                (*it)->scale(Vector2(scale, scale));
+        }
+    }
+
+    /**
+    @brief
+        Scrolls an overlay group by its name.
+    @param name
+        The name of the group defined BaseObject::setName() (usually done with the "name"
+        attribute in the xml file).
+    */
+    /*static*/ void OverlayGroup::scrollGroup(const std::string& name, const Vector2& scroll)
+    {
+        for (ObjectList<OverlayGroup>::iterator it = ObjectList<OverlayGroup>::begin(); it; ++it)
+        {
+            if ((*it)->getName() == name)
+                (*it)->scroll(scroll);
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/overlays/OverlayGroup.h
===================================================================
--- /code/branches/rocket2/src/orxonox/overlays/OverlayGroup.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/overlays/OverlayGroup.h	(revision 6952)
@@ -0,0 +1,99 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+@file
+@brief Declaration of the OverlayGroup class.
+*/
+
+#ifndef _OverlayGroup_H__
+#define _OverlayGroup_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <set>
+#include "util/Math.h"
+#include "util/OgreForwardRefs.h"
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        OverlayGroup does almost exactly what it says: It groups OrxonoxOverlays together.
+        You can scroll the entire group by a certain amount. Scale however works differently
+        than expected: Each OrxonoxOverlay scales individually. That's quite useful when you
+        create your HUD with an OverlayGroup and then want to alter its size.
+    */
+    class _OrxonoxExport OverlayGroup : public BaseObject
+    {
+    public:
+        OverlayGroup(BaseObject* creator);
+        //! Empty destructor.
+        ~OverlayGroup();
+
+        virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
+
+        static void toggleVisibility(const std::string& name);
+        static void scaleGroup(const std::string& name, float scale);
+        static void scrollGroup(const std::string& name, const Vector2& scroll);
+
+        inline const std::set< SmartPtr<OrxonoxOverlay> >& getOverlays() const
+            { return this->hudElements_; }
+
+        void changedVisibility();
+
+        void setOwner(BaseObject* owner);
+        inline BaseObject* getOwner() const
+            { return this->owner_; }
+
+        //! Scales each OrxonoxOverlay individually by scale.
+        void scale(const Vector2& scale) { this->setScale(scale * this->scale_); }
+        void setScale(const Vector2& scale);
+        //! Returns the current size of the group.
+        Vector2 getScale() const { return this->scale_; }
+
+        //! Scrolls each OrxonoxOverlay individually by scroll.
+        void scroll(const Vector2& scroll) { this->setScroll(scroll + this->scroll_); }
+        void setScroll(const Vector2& scroll);
+        //! Returns the current scrolling offset of the group.
+        Vector2 getScroll() const { return this->scale_; }
+
+        void addElement(OrxonoxOverlay* element);
+        bool removeElement(OrxonoxOverlay* element);
+        OrxonoxOverlay* getElement(unsigned int index);
+
+    private:
+        std::set< SmartPtr<OrxonoxOverlay> > hudElements_;    //!< Contains all the OrxonoxOverlays of the this group.
+        Vector2 scale_;                            //!< Current scale (independent of the elements).
+        Vector2 scroll_;                           //!< Current scrolling offset.
+        BaseObject* owner_;                        //!< The owner of this OverlayGroup
+    };
+}
+
+#endif /* _OverlayGroup_H__ */
Index: /code/branches/rocket2/src/orxonox/pickup/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/pickup/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/pickup/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,4 @@
+ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+  PickupIdentifier.cc
+)
+
Index: /code/branches/rocket2/src/orxonox/pickup/PickupIdentifier.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/pickup/PickupIdentifier.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/pickup/PickupIdentifier.cc	(revision 6952)
@@ -0,0 +1,148 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file PickupIdentifier.cc
+    @brief Implementation of the PickupIdentifier class.
+*/
+
+#include "PickupIdentifier.h"
+
+#include "core/CoreIncludes.h"
+#include "interfaces/Pickupable.h"
+
+namespace orxonox
+{
+    
+    /**
+    @brief
+        Constructor. Registers the object and initializes member variables.
+    */
+    PickupIdentifier::PickupIdentifier(Pickupable* pickup)
+    {
+        RegisterRootObject(PickupIdentifier);
+        
+        if(pickup == NULL)
+            COUT(1) << "Error, PickupIdentifier was created without a valid Pickupable." << std::endl;
+        
+        this->pickup_ = pickup;
+    }
+    
+    PickupIdentifier::~PickupIdentifier()
+    {
+
+    }
+    
+    /**
+    @brief
+        Compares two PickupIdentifiers and returns 0 if a == b, <0 if a < b and >0 if a > b for a.compare(b).
+    @param identifier
+        Pointer to the second PickupIdentifier, b.
+    @return
+        Returns an integer. 0 if the two compared PickupIdentifiers are the same, <0 if a < b and >0 if a > b.
+    */
+    int PickupIdentifier::compare(const PickupIdentifier* identifier) const
+    {
+        if(identifier == NULL)
+        {
+            return 1;
+            COUT(1) << "Error in PickupIdentifier::compare: Input Identifier is NULL." << std::endl;
+        }
+        
+        if(identifier->pickup_ == NULL && this->pickup_ == NULL)
+        {
+            return 0;
+            COUT(1) << "Error in PickupIdentifier::compare: Pickup stored by Identifier is NULL." << std::endl;
+        }
+        
+        if(identifier->pickup_ == NULL)
+        {
+            return 1;
+            COUT(1) << "Error in PickupIdentifier::compare: Pickup stored by Identifier is NULL." << std::endl;
+        }
+        
+        if(this->pickup_ == NULL)
+        {
+            return -1;
+            COUT(1) << "Error in PickupIdentifier::compare: Pickup stored by Identifier is NULL." << std::endl;
+        }
+        
+        //! If the classIdentifiers are not the same (meaning the PickupIdentifiers identify different classes), the obviously the two Pickupables identified by the PickupIdentifiers cannot be the same. An ordering is established through the alphabetical ordering of the respective classnames.
+        if(!identifier->pickup_->getIdentifier()->isExactlyA(this->pickup_->getIdentifier()))
+            return this->pickup_->getIdentifier()->getName().compare(identifier->pickup_->getIdentifier()->getName());
+        
+        //! If the class is the same for both PickupIdentifiers we go on to check the parameters of the class.
+        //! If the two have a different number of parameters then obviusly something is very wrong.
+        if(!(this->parameters_.size() == identifier->parameters_.size()))
+        {
+            COUT(1) << "Something went wrong in PickupIdentifier!" << std::endl;
+            return this->parameters_.size()-identifier->parameters_.size();
+        }
+        
+        //! We iterate through all parameters and compar their values (which are strings). The first parameter is the most significant. The ordering is once again established by the alphabetical comparison of the two value strings.
+        for(std::map<std::string, std::string>::const_iterator it = this->parameters_.begin(); it != this->parameters_.end(); it++)
+        {
+            //!< If a parameter present in one of the identifiers is not found in the other, once again, something is very wrong.
+            if(identifier->parameters_.find(it->first) == identifier->parameters_.end())
+            {
+                COUT(1) << "Something went wrong in PickupIdentifier!" << std::endl;
+                return -1;
+            }
+            if(identifier->parameters_.find(it->first)->second != it->second)
+                return it->second.compare(identifier->parameters_.find(it->first)->second);
+        }
+            
+        return 0;
+    }
+    
+    /**
+    @brief
+        Add a parameter to the PickupIdentifier.
+    @param name
+        The name of the parameter.
+    @param value
+        The value of the parameter.
+    @return
+        Returns false if the parameter already existed, true if not.
+    */
+    bool PickupIdentifier::addParameter(std::string & name, std::string & value)
+    {
+        COUT(4) << "PickupIdentifier " << name << ", " << value << std::endl;
+        
+        if(!(this->parameters_.find(name) == this->parameters_.end()))
+        {
+            COUT(4) << "Request for adding a parameter that already exists for the PickupIdentififer was denied. name: '" << name << "', value: '" << value << "'."<<  std::endl;
+            return false;
+        }
+        
+        this->parameters_[name] = value;
+        
+        return true;
+    }
+    
+}
Index: /code/branches/rocket2/src/orxonox/pickup/PickupIdentifier.h
===================================================================
--- /code/branches/rocket2/src/orxonox/pickup/PickupIdentifier.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/pickup/PickupIdentifier.h	(revision 6952)
@@ -0,0 +1,86 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Damian 'Mozork' Frick
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+/**
+    @file PickupIdentifier.h
+    @brief Definition of the PickupIdentifier class.
+*/
+
+#ifndef _PickupIdentifier_H__
+#define _PickupIdentifier_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <map>
+#include <string>
+#include "core/Identifier.h"
+
+#include "core/OrxonoxClass.h" 
+
+namespace orxonox
+{
+    
+    /**
+    @brief
+        The purpose of the PickupIdentifier class is to identify different types of pickups allthough they are of the same class.
+        This allows for more generic classes (or pickups in this case) that can be a number of different pickup types and can be identified as such without the need for a lot of different classes. An example is the HealthPickup class that encompasses a wide variety of different types of health pickups, e.g a HealthPickup that adds 10 health every second for 10 seconds or a HealthPickup that adds 100 health as soon as it is picked up, a.s.o.
+        To that purpose this class provides functionality to compare two PickupIdentifier (and since all Pickupables have an Identifier through that Pickupables can be compared). It als provides functionality to add parameters that distinguish between different types of pickups in the same pickup class.
+        Lastly a struct is provided that can be used in stl containers to establish a strictly lesser ordering between PickupIdentifiers (and thus Pickupables).
+    @author
+        Damian 'Mozork' Frick
+    */
+    class _OrxonoxExport PickupIdentifier : virtual public OrxonoxClass
+    {
+        
+        public:
+            PickupIdentifier(Pickupable* pickup); //!< Constructor.
+            ~PickupIdentifier(); //!< Destructor.
+            
+            virtual int compare(const PickupIdentifier* identifier) const; //!< Compares two PickupIdentifiers and returns 0 if a == b, <0 if a < b and >0 if a > b for a.compare(b).
+            
+            bool addParameter(std::string & name, std::string & value); //!< Add a parameter to the PickupIdentifier.
+            
+        private:
+            Pickupable* pickup_; //!< The Pickupable the PickupIdentififer is for.
+            std::map<std::string, std::string> parameters_; //!< The parameters identifying the type of the pickup beyond the class.
+            
+    };
+    
+    /**
+    @brief
+        Struct that overloads the compare operation between two PickupIdentifier pointers.
+    */
+    struct PickupIdentifierCompare
+    {
+        bool operator() (const PickupIdentifier* lhs, const PickupIdentifier* rhs) const
+            { return lhs->compare(rhs) < 0; }
+    };
+    
+}
+
+#endif // _PickupIdentifier_H__
Index: /code/branches/rocket2/src/orxonox/sound/AmbientSound.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/sound/AmbientSound.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/sound/AmbientSound.cc	(revision 6952)
@@ -0,0 +1,143 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "AmbientSound.h"
+
+#include "core/CoreIncludes.h"
+#include "core/EventIncludes.h"
+#include "core/GameMode.h"
+#include "core/Resource.h"
+#include "core/XMLPort.h"
+#include "SoundManager.h"
+
+namespace orxonox
+{
+    CreateFactory(AmbientSound);
+
+    AmbientSound::AmbientSound(BaseObject* creator)
+        : BaseObject(creator)
+        , Synchronisable(creator)
+        , bPlayOnLoad_(false)
+    {
+        RegisterObject(AmbientSound);
+
+        // Ambient sounds always fade in
+        this->setVolume(0);
+        this->registerVariables();
+    }
+
+    void AmbientSound::preDestroy()
+    {
+        if (GameMode::playsSound())
+        {
+            // Smoothly fade out by keeping a SmartPtr
+            SoundManager::getInstance().unregisterAmbientSound(this);
+        }
+    }
+
+    void AmbientSound::registerVariables()
+    {
+        registerVariable(ambientSource_, ObjectDirection::ToClient, new NetworkCallback<AmbientSound>(this, &AmbientSound::ambientSourceChanged));
+        registerVariable(bLooping_,      ObjectDirection::ToClient, new NetworkCallback<AmbientSound>(this, &AmbientSound::loopingChanged));
+        registerVariable(pitch_,         ObjectDirection::ToClient, new NetworkCallback<AmbientSound>(this, &AmbientSound::pitchChanged));
+        registerVariable(bPlayOnLoad_,   ObjectDirection::ToClient, new NetworkCallback<AmbientSound>(this, &AmbientSound::playOnLoadChanged));
+    }
+
+    void AmbientSound::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(AmbientSound, XMLPort, xmlelement, mode);
+        BaseSound::XMLPortExtern(xmlelement, mode);
+        XMLPortParam(AmbientSound, "ambientSource", setAmbientSource, getAmbientSource, xmlelement, mode);
+        XMLPortParam(AmbientSound, "playOnLoad", setPlayOnLoad, getPlayOnLoad, xmlelement, mode);
+    }
+
+    void AmbientSound::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(AmbientSound, XMLEventPort, xmlelement, mode);
+        XMLPortEventState(AmbientSound, BaseObject, "play", play, xmlelement, mode);
+    }
+
+    void AmbientSound::play()
+    {
+        if (GameMode::playsSound())
+            SoundManager::getInstance().registerAmbientSound(this);
+    }
+
+    void AmbientSound::stop()
+    {
+        if (GameMode::playsSound())
+            SoundManager::getInstance().unregisterAmbientSound(this);
+    }
+
+    void AmbientSound::pause()
+    {
+        if (GameMode::playsSound())
+            SoundManager::getInstance().pauseAmbientSound(this);
+    }
+
+    float AmbientSound::getRealVolume()
+    {
+        assert(GameMode::playsSound());
+        return SoundManager::getInstance().getRealVolume(SoundType::Music);
+    }
+
+    void AmbientSound::setAmbientSource(const std::string& source)
+    {
+        this->ambientSource_ = source;
+        this->moodChanged(this->getMood());
+    }
+
+    void AmbientSound::moodChanged(const std::string& mood)
+    {
+        if (GameMode::playsSound())
+        {
+            const std::string& path = "ambient/" + MoodManager::getInstance().getMood() + '/' + this->ambientSource_;
+            shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(path);
+            if (fileInfo != NULL)
+                this->setSource(path);
+            else
+                COUT(3) << "Sound: " << this->ambientSource_ << ": Not a valid name! Ambient sound will not change." << std::endl;
+        }
+    }
+
+    void AmbientSound::setPlayOnLoad(bool val)
+    {
+        this->bPlayOnLoad_ = val;
+        if (val)
+            this->play();
+    }
+
+    void AmbientSound::changedActivity()
+    {
+        SUPER(AmbientSound, changedActivity);
+        if (this->isActive())
+            this->play();
+        else
+            this->stop();
+    }
+}
Index: /code/branches/rocket2/src/orxonox/sound/AmbientSound.h
===================================================================
--- /code/branches/rocket2/src/orxonox/sound/AmbientSound.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/sound/AmbientSound.h	(revision 6952)
@@ -0,0 +1,88 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *      Kevin Young
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _AmbientSound_H__
+#define _AmbientSound_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "core/BaseObject.h"
+#include "network/synchronisable/Synchronisable.h"
+#include "BaseSound.h"
+#include "MoodManager.h"
+
+namespace orxonox
+{
+    /**
+     * The AmbientSound class is the base class for all sound file loader classes.
+     * It server as main interface to the OpenAL library.
+     *
+     */
+    class _OrxonoxExport AmbientSound : public BaseSound, public BaseObject, public Synchronisable, public MoodListener
+    {
+        friend class SoundManager;
+
+    public:
+        AmbientSound(BaseObject* creator);
+
+        void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+        void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
+        void changedActivity();
+
+        void play();
+        void stop();
+        void pause();
+
+        void setAmbientSource(const std::string& source);
+        inline const std::string& getAmbientSource() const
+            { return this->ambientSource_; }
+
+        void setPlayOnLoad(bool val);
+        bool getPlayOnLoad() const
+            { return this->bPlayOnLoad_; }
+
+    protected:
+        ~AmbientSound() { }
+
+    private:
+        void preDestroy();
+        void registerVariables();
+        float getRealVolume();
+        void moodChanged(const std::string& mood);
+        inline void ambientSourceChanged()
+            { this->setAmbientSource(this->ambientSource_); }
+        inline void playOnLoadChanged()
+            { this->setPlayOnLoad(this->bPlayOnLoad_); }
+
+        std::string ambientSource_; //!< Analogous to source_, but mood independent
+        bool        bPlayOnLoad_;   //!< Play the sound immediately when loaded
+    };
+}
+
+#endif /* _AmbientSound_H__ */
Index: /code/branches/rocket2/src/orxonox/sound/BaseSound.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/sound/BaseSound.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/sound/BaseSound.cc	(revision 6952)
@@ -0,0 +1,277 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Erwin 'vaiursch' Herrsche
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#include "BaseSound.h"
+
+#include <cassert>
+#include <vector>
+#include <al.h>
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/Resource.h"
+#include "core/XMLPort.h"
+#include "SoundBuffer.h"
+#include "SoundManager.h"
+
+namespace orxonox
+{
+    BaseSound::BaseSound()
+        : bPooling_(false)
+        , volume_(1.0)
+        , bLooping_(false)
+        , state_(Stopped)
+        , pitch_ (1.0)
+    {
+        RegisterRootObject(BaseSound);
+
+        // Initialise audioSource_ to a value that is not a source
+        // 0 is unfortunately not guaranteed to be no source ID.
+        this->audioSource_ = 123456789;
+        while (alIsSource(++this->audioSource_));
+    }
+
+    BaseSound::~BaseSound()
+    {
+        this->stop();
+        // Release buffer
+        if (this->soundBuffer_ != NULL)
+        {
+            assert(GameMode::playsSound());
+            SoundManager::getInstance().releaseSoundBuffer(this->soundBuffer_, this->bPooling_);
+        }
+    }
+
+    void BaseSound::XMLPortExtern(Element& xmlelement, XMLPort::Mode mode)
+    {
+        XMLPortParam(BaseSound, "volume",  setVolume,  getVolume,  xmlelement, mode);
+        XMLPortParam(BaseSound, "looping", setLooping, getLooping, xmlelement, mode);
+        XMLPortParam(BaseSound, "pitch",   setPitch,   getPitch,   xmlelement, mode);
+        XMLPortParam(BaseSound, "source",  setSource,  getSource,  xmlelement, mode);
+    }
+
+    void BaseSound::doPlay()
+    {
+        this->state_ = Playing;
+        if (GameMode::playsSound() && this->getSourceState() != AL_PLAYING && this->soundBuffer_ != NULL)
+        {
+            if (!alIsSource(this->audioSource_))
+            {
+                this->audioSource_ = SoundManager::getInstance().getSoundSource(this);
+                if (!alIsSource(this->audioSource_))
+                    return;
+                this->initialiseSource();
+            }
+
+            alSourcePlay(this->audioSource_);
+            if (int error = alGetError())
+                COUT(2) << "Sound: Error playing sound: " << SoundManager::getALErrorString(error) << std::endl;
+        }
+    }
+
+    void BaseSound::doStop()
+    {
+        this->state_ = Stopped;
+        if (alIsSource(this->audioSource_))
+        {
+            alSourceStop(this->audioSource_);
+            // Release buffer
+            alSourcei(this->audioSource_, AL_BUFFER, AL_NONE);
+            // Release source again
+            SoundManager::getInstance().releaseSoundSource(this->audioSource_);
+            // Get a no source ID
+            this->audioSource_ += 123455;
+            while (alIsSource(++this->audioSource_));
+        }
+    }
+
+    void BaseSound::doPause()
+    {
+        if (this->isStopped())
+            return;
+        this->state_ = Paused;
+        if (alIsSource(this->audioSource_))
+            alSourcePause(this->audioSource_);
+    }
+
+    ALint BaseSound::getSourceState() const
+    {
+        if (alIsSource(this->audioSource_))
+        {
+            ALint state;
+            alGetSourcei(this->audioSource_, AL_SOURCE_STATE, &state);
+            return state;
+        }
+        else
+            return AL_INITIAL;
+    }
+
+    void BaseSound::initialiseSource()
+    {
+        this->updateVolume();
+        this->setPitch(this->getPitch());
+        this->setLooping(this->getLooping());
+        alSource3f(this->audioSource_, AL_POSITION,  0, 0, 0);
+        alSource3f(this->audioSource_, AL_VELOCITY,  0, 0, 0);
+        alSource3f(this->audioSource_, AL_DIRECTION, 0, 0, 0);
+        if (ALint error = alGetError())
+            COUT(2) << "Sound Warning: Setting source parameters to 0 failed: "
+                    << SoundManager::getALErrorString(error) << std::endl;
+        assert(this->soundBuffer_ != NULL);
+        alSourcei(this->audioSource_, AL_BUFFER, this->soundBuffer_->getBuffer());
+        if (ALuint error = alGetError())
+            COUT(1) << "Sound Error: Could not set buffer \"" << this->source_ << "\": " << SoundManager::getALErrorString(error) << std::endl;
+    }
+
+    void BaseSound::setVolume(float vol)
+    {
+        this->volume_ = clamp(vol, 0.0f, 1.0f);
+        if (this->volume_ != vol)
+            COUT(2) << "Sound warning: volume out of range, clamping value." << std::endl;
+        this->updateVolume();
+    }
+
+    void BaseSound::updateVolume()
+    {
+        if (alIsSource(this->audioSource_))
+        {
+            float volume = this->volume_ * this->getRealVolume();
+            alSourcef(this->audioSource_, AL_GAIN, volume);
+            if (int error = alGetError())
+                COUT(2) << "Sound: Error setting volume to " << volume
+                        << ": " << SoundManager::getALErrorString(error) << std::endl;
+        }
+    }
+
+    void BaseSound::setLooping(bool val)
+    {
+        this->bLooping_ = val;
+        if (alIsSource(this->audioSource_))
+            alSourcei(this->audioSource_, AL_LOOPING, (val ? AL_TRUE : AL_FALSE));
+    }
+
+    void BaseSound::setPitch(float pitch)
+    {
+        if (pitch > 2 || pitch < 0.5f)
+        {
+            COUT(2) << "Sound warning: pitch out of range, cropping value." << std::endl;
+            pitch = pitch > 2.0f ? 2.0f : pitch;
+            pitch = pitch < 0.5f ? 0.5f : pitch;
+        }
+        this->pitch_ = pitch;
+        if (alIsSource(this->audioSource_))
+        {
+            alSourcef(this->audioSource_, AL_PITCH, pitch);
+            if (int error = alGetError())
+                COUT(2) << "Sound: Error setting pitch: " << SoundManager::getALErrorString(error) << std::endl;
+        }
+    }
+
+    void BaseSound::setSource(const std::string& source)
+    {
+        if (!GameMode::playsSound())
+        {
+            this->source_ = source;
+            return;
+        }
+
+        if (this->soundBuffer_ != NULL)
+        {
+            if (this->soundBuffer_->getFilename() == source)
+            {
+                assert(this->source_ == source_);
+                return;
+            }
+            // Stopping is imperative here!
+            if (alIsSource(this->audioSource_))
+            {
+                alSourceStop(this->audioSource_);
+                alSourcei(this->audioSource_, AL_BUFFER, AL_NONE);
+            }
+            SoundManager::getInstance().releaseSoundBuffer(this->soundBuffer_, this->bPooling_);
+            this->soundBuffer_.reset();
+        }
+
+        this->source_ = source;
+        // Don't load ""
+        if (source_.empty())
+            return;
+
+        // Get new sound buffer
+        this->soundBuffer_ = SoundManager::getInstance().getSoundBuffer(this->source_);
+        if (this->soundBuffer_ == NULL)
+            return;
+
+        if (alIsSource(this->audioSource_)) // already playing or paused
+        {
+            // Set new buffer
+            alSourcei(this->audioSource_, AL_BUFFER, this->soundBuffer_->getBuffer());
+            if (ALuint error = alGetError())
+            {
+                COUT(1) << "Sound Error: Could not set buffer \"" << source << "\": " << SoundManager::getALErrorString(error) << std::endl;
+                return;
+            }
+
+            // Sound was already playing or paused because there was a source acquired
+            assert(this->isPlaying() || this->isPaused());
+            alSourcePlay(this->audioSource_);
+            if (int error = alGetError())
+                COUT(2) << "Sound: Error playing sound: " << SoundManager::getALErrorString(error) << std::endl;
+            if (this->isPaused())
+                alSourcePause(this->audioSource_);
+        }
+        else // No source acquired so far, but might be set to playing or paused
+        {
+            State state = this->state_; // save
+            if (this->isPlaying() || this->isPaused())
+                doPlay();
+            if (state == Paused)
+            {
+                this->state_ = Paused;
+                doPause();
+            }
+        }
+    }
+
+    void BaseSound::stateChanged()
+    {
+        switch (this->state_)
+        {
+            case Playing:
+                this->play();
+                break;
+            case Paused:
+                this->pause();
+                break;
+            case Stopped:
+            default:
+                this->stop();
+                break;
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/sound/BaseSound.h
===================================================================
--- /code/branches/rocket2/src/orxonox/sound/BaseSound.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/sound/BaseSound.h	(revision 6952)
@@ -0,0 +1,122 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Erwin 'vaiursch' Herrsche
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#ifndef _BaseSound_H__
+#define _BaseSound_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include <OgreDataStream.h>
+#include "core/OrxonoxClass.h"
+
+namespace orxonox
+{
+    /**
+     * The BaseSound class is the base class for all sound file loader classes.
+     * It server as main interface to the OpenAL library.
+     *
+     */
+    class _OrxonoxExport BaseSound : virtual public OrxonoxClass
+    {
+    public:
+        BaseSound();
+
+        void XMLPortExtern(Element& xmlelement, XMLPort::Mode mode);
+
+        virtual void play()  { this->doPlay(); }
+        virtual void stop()  { this->doStop(); }
+        virtual void pause() { this->doPause(); }
+
+        bool isPlaying() const { return this->state_ == Playing; }
+        bool isPaused()  const { return this->state_ == Paused; }
+        bool isStopped() const { return this->state_ == Stopped; }
+
+        virtual void setSource(const std::string& source);
+        virtual const std::string& getSource() const
+            { return this->source_; }
+
+        void setVolume(float vol);
+        float getVolume() const
+            { return this->volume_; }
+        void updateVolume();
+
+        bool getLooping() const
+            { return this->bLooping_; }
+        void setLooping(bool val);
+
+        float getPitch() const
+            { return this->pitch_; }
+        void setPitch(float pitch);
+
+    protected:
+        enum State
+        {
+            Stopped,
+            Playing,
+            Paused
+        };
+
+        virtual ~BaseSound();
+
+        void doPlay();
+        void doStop();
+        void doPause();
+
+        // network callbacks
+        inline void pitchChanged()
+            { this->setPitch(this->pitch_); }
+        inline void loopingChanged()
+            { this->setLooping(this->bLooping_); }
+        inline void volumeChanged()
+            { this->setVolume(this->volume_); }
+        inline void sourceChanged()
+            { this->setSource(this->source_); }
+        void stateChanged();
+
+        virtual void initialiseSource();
+        ALint getSourceState() const;
+
+        virtual float getRealVolume() = 0;
+
+        ALuint          audioSource_;
+        bool            bPooling_;
+        shared_ptr<SoundBuffer> soundBuffer_;
+        std::string     source_;
+        float           volume_;
+        bool            bLooping_;
+        State           state_;
+        float           pitch_;
+
+    private:
+        DataStreamPtr   dataStream_;
+    };
+}
+
+#endif /* _BaseSound_H__ */
Index: /code/branches/rocket2/src/orxonox/sound/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/sound/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/sound/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,9 @@
+ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+    AmbientSound.cc
+    BaseSound.cc
+    SoundBuffer.cc
+    SoundManager.cc
+    WorldSound.cc
+    SoundStreamer.cc
+)
+
Index: /code/branches/rocket2/src/orxonox/sound/SoundBuffer.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/sound/SoundBuffer.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/sound/SoundBuffer.cc	(revision 6952)
@@ -0,0 +1,187 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *      Erwin 'vaiursch' Herrsche
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "SoundBuffer.h"
+
+#include <AL/alut.h>
+#include <vorbis/vorbisfile.h>
+
+#include "util/Exception.h"
+#include "util/StringUtils.h"
+#include "sound/SoundManager.h"
+
+namespace orxonox
+{
+    SoundBuffer::SoundBuffer(const std::string& filename, std::list<shared_ptr<SoundBuffer> >::iterator poolIterator)
+        : filename_(filename)
+        , audioBuffer_(AL_NONE)
+        , poolIterator_(poolIterator)
+    {
+        if (this->filename_.empty())
+            ThrowException(General, "SoundBuffer construction: fileInfo was NULL");
+
+        // Get resource info
+        shared_ptr<ResourceInfo> fileInfo = Resource::getInfo(filename);
+        if (fileInfo == NULL)
+        {
+            COUT(2) << "Sound: Warning: Sound file '" << filename << "' not found" << std::endl;
+            return;
+        }
+        // Open data stream
+        DataStreamPtr dataStream = Resource::open(fileInfo);
+
+        const std::string& extension = this->filename_.substr(this->filename_.find_last_of('.') + 1);
+        if (getLowercase(extension) == "ogg")
+        {
+            // Try ogg loader
+            this->loadOgg(fileInfo, dataStream);
+        }
+        else
+        {
+            // Try standard OpenAL loader
+            this->loadStandard(fileInfo, dataStream);
+        }
+    }
+
+    SoundBuffer::~SoundBuffer()
+    {
+        // Destroy buffer
+        alDeleteBuffers(1, &this->audioBuffer_);
+    }
+
+    unsigned int SoundBuffer::getSize() const
+    {
+        ALint size;
+        alGetBufferi(this->audioBuffer_, AL_SIZE, &size);
+        return alGetError() ? 0 : size;
+    }
+
+    void SoundBuffer::loadStandard(const shared_ptr<ResourceInfo>& fileInfo, DataStreamPtr dataStream)
+    {
+        // Read everything into a temporary buffer
+        char* buffer = new char[fileInfo->size];
+        dataStream->read(buffer, fileInfo->size);
+        dataStream->seek(0);
+
+        this->audioBuffer_ = alutCreateBufferFromFileImage(buffer, fileInfo->size);
+        delete[] buffer;
+
+        if (!alIsBuffer(this->audioBuffer_))
+            ThrowException(General, "Sound Error: Standard file loader failed: " << alutGetErrorString(alutGetError()));
+    }
+
+    size_t readVorbis(void* ptr, size_t size, size_t nmemb, void* datasource)
+    {
+        return static_cast<Ogre::DataStream*>(datasource)->read(ptr, size * nmemb);
+    }
+
+    int seekVorbis(void* datasource, ogg_int64_t offset, int whence)
+    {
+        Ogre::DataStream* stream = static_cast<Ogre::DataStream*>(datasource);
+        switch (whence)
+        {
+        case SEEK_SET:
+            stream->seek((size_t)offset);
+            break;
+        case SEEK_CUR:
+            stream->skip((size_t)offset);
+            break;
+        case SEEK_END:
+            stream->seek(stream->size() + (size_t)offset);
+            break;
+        default:
+            return -1;
+        }
+        return 0;
+    }
+
+    long tellVorbis(void* datasource)
+    {
+        return static_cast<long>(static_cast<Ogre::DataStream*>(datasource)->tell());
+    }
+
+    void SoundBuffer::loadOgg(const shared_ptr<ResourceInfo>& fileInfo, DataStreamPtr dataStream)
+    {
+        char inbuffer[256*1024];
+        std::vector<char> outbuffer;
+        outbuffer.reserve(80*1024*1024);
+
+        // Open file with custom streaming
+        ov_callbacks vorbisCallbacks;
+        vorbisCallbacks.read_func  = &readVorbis;
+        vorbisCallbacks.seek_func  = &seekVorbis;
+        vorbisCallbacks.tell_func  = &tellVorbis;
+        vorbisCallbacks.close_func = NULL;
+
+        OggVorbis_File vf;
+        int ret = ov_open_callbacks(dataStream.get(), &vf, NULL, 0, vorbisCallbacks);
+        if (ret < 0)
+        {
+            COUT(2) << "Sound: libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << std::endl;
+            ov_clear(&vf);
+            ThrowException(General, "Sound Error: Ogg file loader failed when opening the bitstream");
+        }
+
+        int current_section;
+        int eof = false;
+        while (!eof)
+        {
+            long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, &current_section);
+            if (ret == 0)
+            {
+                eof = true;
+            }
+            else if (ret < 0)
+            {
+                COUT(2) << "Sound: libvorbisfile: error reading the file" << std::endl;
+                ov_clear(&vf);
+                ThrowException(General, "Sound Error: Ogg file loader failed when decoding the file");
+            }
+            else
+            {
+                outbuffer.insert(outbuffer.end(), inbuffer, inbuffer + ret);
+            }
+        }
+
+        vorbis_info* vorbisInfo;
+        vorbisInfo = ov_info(&vf, -1);
+        ALenum format;
+        if (vorbisInfo->channels == 1)
+            format = AL_FORMAT_MONO16;
+        else
+            format = AL_FORMAT_STEREO16;
+
+        alGenBuffers(1, &this->audioBuffer_);
+        alBufferData(this->audioBuffer_, format, &outbuffer[0], outbuffer.size(), vorbisInfo->rate);
+        ov_clear(&vf);
+
+        if (!alIsBuffer(this->audioBuffer_))
+            ThrowException(General, "Sound: Ogg file loader failed when creating the buffer.");
+    }
+}
Index: /code/branches/rocket2/src/orxonox/sound/SoundBuffer.h
===================================================================
--- /code/branches/rocket2/src/orxonox/sound/SoundBuffer.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/sound/SoundBuffer.h	(revision 6952)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _SoundBuffer_H__
+#define _SoundBuffer_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <list>
+#include <boost/shared_ptr.hpp>
+#include "core/Resource.h"
+
+namespace orxonox
+{
+    /*
+    @brief
+        The SoundBuffer class is to be used for sounds with position and orientation.
+    */
+    class _OrxonoxExport SoundBuffer
+    {
+        friend class SoundManager;
+#if !defined(_MSC_VER) || _MSC_VER >= 1500
+        // Make sure nobody deletes an instance (using smart pointers)
+        template <class T>
+        friend void boost::checked_delete(T*);
+#endif
+
+    public:
+#if defined(_MSC_VER) && _MSC_VER < 1500
+        ~SoundBuffer();
+#endif
+        inline ALuint getBuffer()
+            { return this->audioBuffer_; }
+
+        unsigned int getSize() const;
+
+        const std::string& getFilename() const
+            { return this->filename_; }
+
+    private:
+        SoundBuffer(const std::string& filename, std::list<shared_ptr<SoundBuffer> >::iterator poolIterator);
+#if !defined(_MSC_VER) || _MSC_VER >= 1500
+        ~SoundBuffer();
+#endif
+        void loadStandard(const shared_ptr<ResourceInfo>& fileInfo, DataStreamPtr dataStream);
+        void loadOgg(const shared_ptr<ResourceInfo>& fileInfo, DataStreamPtr dataStream);
+
+        std::string filename_;
+        ALuint audioBuffer_;
+        std::list<shared_ptr<SoundBuffer> >::iterator poolIterator_;
+    };
+}
+
+#endif /* _SoundBuffer_H__ */
Index: /code/branches/rocket2/src/orxonox/sound/SoundManager.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/sound/SoundManager.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/sound/SoundManager.cc	(revision 6952)
@@ -0,0 +1,639 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *       Erwin 'vaiursch' Herrsche
+ *       Kevin Young
+ *       Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "SoundManager.h"
+
+#include <AL/alut.h>
+#include <utility>
+
+#include "util/Exception.h"
+#include "util/Math.h"
+#include "util/ScopeGuard.h"
+#include "util/Clock.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/ScopedSingletonManager.h"
+#include "core/Resource.h"
+#include "SoundBuffer.h"
+#include "BaseSound.h"
+#include "AmbientSound.h"
+#include "WorldSound.h"
+
+namespace orxonox
+{
+    ManageScopedSingleton(SoundManager, ScopeID::Graphics, true);
+
+    std::string SoundManager::getALErrorString(ALenum code)
+    {
+        switch (code)
+        {
+        case AL_NO_ERROR:          return "No error";
+        case AL_INVALID_NAME:      return "Invalid AL parameter name";
+        case AL_INVALID_ENUM:      return "Invalid AL enum";
+        case AL_INVALID_VALUE:     return "Invalid AL value";
+        case AL_INVALID_OPERATION: return "Invalid AL operation";
+        case AL_OUT_OF_MEMORY:     return "AL reports out of memory";
+        default:                   return "Unknown AL error";
+        }
+    }
+
+    SoundManager::SoundManager()
+        : effectsPoolSize_(0)
+    {
+        RegisterRootObject(SoundManager);
+
+        // See whether we even want to load
+        bool bDisableSound_ = false;
+        SetConfigValue(bDisableSound_, false);
+        if (bDisableSound_)
+            ThrowException(InitialisationAborted, "Sound: Not loading at all");
+
+        if (!alutInitWithoutContext(NULL, NULL))
+            ThrowException(InitialisationFailed, "Sound Error: ALUT initialisation failed: " << alutGetErrorString(alutGetError()));
+        Loki::ScopeGuard alutExitGuard = Loki::MakeGuard(&alutExit);
+
+/*
+        // Get list of available sound devices and display them
+        const char* devices = alcGetString(NULL, ALC_DEVICE_SPECIFIER);
+        char* device = new char[strlen(devices)+1];
+        strcpy(device, devices);
+        std::string renderDevice;
+        SetConfigValue(renderDevice, std::string(device)).description("Sound device used for rendering");
+        COUT(4) << "Sound: Available devices: ";
+        while (true)
+        {
+            this->deviceNames_.push_back(devices);
+            COUT(4) << '"' << devices << "\", ";
+            devices += strlen(devices) + 1;
+            if (*devices == '\0')
+                break;
+        }
+        COUT(4) << std::endl;
+
+        // Open the selected device
+        COUT(3) << "Sound: Opening device \"" << renderDevice << '\' << std::endl;
+        this->device_ = alcOpenDevice(renderDevice.c_str());
+*/
+        this->device_ = alcOpenDevice(NULL);
+        if (this->device_ == NULL)
+        {
+            COUT(1) << "Sound: Could not open sound device. Have you installed OpenAL?" << std::endl;
+#ifdef ORXONOX_PLATFORM_WINDOWS
+            COUT(1) << "Sound: Just getting the DLL with the dependencies is not enough for Windows (esp. Windows 7)!" << std::endl;
+#endif
+            ThrowException(InitialisationFailed, "Sound Error: Could not open sound device.");
+        }
+        Loki::ScopeGuard closeDeviceGuard = Loki::MakeGuard(&alcCloseDevice, this->device_);
+
+        // Create sound context and make it the currently used one
+        this->context_ = alcCreateContext(this->device_, NULL);
+        if (this->context_ == NULL)
+            ThrowException(InitialisationFailed, "Sound Error: Could not create ALC context");
+        Loki::ScopeGuard desroyContextGuard = Loki::MakeGuard(&alcDestroyContext, this->context_);
+        if (!alcMakeContextCurrent(this->context_))
+            ThrowException(InitialisationFailed, "Sound Error: Could not use ALC context");
+
+        GameMode::setPlaysSound(true);
+        Loki::ScopeGuard resetPlaysSoundGuard = Loki::MakeGuard(&GameMode::setPlaysSound, false);
+
+        // Get some information about the sound
+        if (const char* version = alGetString(AL_VERSION))
+            COUT(4) << "Sound: --- OpenAL Version: " << version << std::endl;
+        if (const char* vendor = alGetString(AL_VENDOR))
+            COUT(4) << "Sound: --- OpenAL Vendor : " << vendor << std::endl;
+        if (const char* types = alutGetMIMETypes(ALUT_LOADER_BUFFER))
+            COUT(4) << "Sound: --- Supported MIME Types: " << types << std::endl;
+        else
+            COUT(2) << "Sound Warning: MIME Type retrieval failed: " << alutGetErrorString(alutGetError()) << std::endl;
+
+        this->mute_[SoundType::All]     = 1.0f;
+        this->mute_[SoundType::Music]   = 1.0f;
+        this->mute_[SoundType::Effects] = 1.0f;
+
+        this->setConfigValues();
+
+        // Try to get at least one source
+        ALuint source;
+        alGenSources(1, &source);
+        if (!alGetError() && alIsSource(source))
+            this->availableSoundSources_.push_back(source);
+        else
+            ThrowException(InitialisationFailed, "Sound Error: Could not create even a single source");
+        // Create a few initial sources
+        this->createSoundSources(this->minSources_ - 1);
+
+        // Disarm guards
+        alutExitGuard.Dismiss();
+        closeDeviceGuard.Dismiss();
+        desroyContextGuard.Dismiss();
+        resetPlaysSoundGuard.Dismiss();
+
+        COUT(4) << "Sound: Initialisation complete" << std::endl;
+    }
+
+    SoundManager::~SoundManager()
+    {
+        // Erase fade lists because of the smart pointers
+        this->fadeInList_.clear();
+        this->fadeOutList_.clear();
+
+        // If there are still used buffers around, well, that's just very bad...
+        if (this->soundBuffers_.size() != this->effectsPool_.size())
+            COUT(1) << "Sound Error: Some sound buffers are still in use but OpenAL is about to shut down. Fix this!" << std::endl;
+        // Empty buffer pool and buffer list
+        this->effectsPool_.clear();
+        this->soundBuffers_.clear();
+
+        // There should not be any sources in use anymore
+        if (!this->usedSoundSources_.empty())
+            COUT(1) << "Sound Error: Some sound sources are still in use but OpenAL is about to shut down. Fix this!" << std::endl;
+        while (!this->availableSoundSources_.empty())
+        {
+            alDeleteSources(1, &this->availableSoundSources_.back());
+            this->availableSoundSources_.pop_back();
+        }
+
+        GameMode::setPlaysSound(false);
+
+        // Relieve context to destroy it
+        if (!alcMakeContextCurrent(NULL))
+            COUT(1) << "Sound Error: Could not unset ALC context" << std::endl;
+        alcDestroyContext(this->context_);
+        if (ALCenum error = alcGetError(this->device_))
+        {
+            if (error == AL_INVALID_OPERATION)
+                COUT(1) << "Sound Error: Could not destroy ALC context because it is the current one" << std::endl;
+            else
+                COUT(1) << "Sound Error: Could not destroy ALC context because it is invalid" << std::endl;
+        }
+#ifdef AL_VERSION_1_1
+        if (!alcCloseDevice(this->device_))
+            COUT(1) << "Sound Error: Could not destroy ALC device. This might be because there are still buffers in use!" << std::endl;
+#else
+        alcCloseDevice(this->device_);
+#endif
+        if (!alutExit())
+            COUT(1) << "Sound Error: Closing ALUT failed: " << alutGetErrorString(alutGetError()) << std::endl;
+    }
+
+    void SoundManager::setConfigValues()
+    {
+        SetConfigValue(crossFadeStep_, 0.2f)
+            .description("Determines how fast sounds should fade, per second.")
+            .callback(this, &SoundManager::checkFadeStepValidity);
+
+        SetConfigValueAlias(volume_[SoundType::All], "soundVolume_", 1.0f)
+            .description("Defines the overall volume.")
+            .callback(this, &SoundManager::checkSoundVolumeValidity);
+        SetConfigValueAlias(volume_[SoundType::Music], "ambientVolume_", 1.0f)
+            .description("Defines the ambient volume.")
+            .callback(this, &SoundManager::checkAmbientVolumeValidity);
+        SetConfigValueAlias(volume_[SoundType::Effects], "effectsVolume_", 1.0f)
+            .description("Defines the effects volume.")
+            .callback(this, &SoundManager::checkEffectsVolumeValidity);
+
+        SetConfigValue(minSources_, 16)
+            .description("Minimum number of sources being generated (if possible)");
+        SetConfigValue(maxSources_, 1024)
+            .description("Maximum number of sources to be made available");
+    }
+
+    void SoundManager::preUpdate(const Clock& time)
+    {
+        this->processCrossFading(time.getDeltaTime());
+
+        // Check whether a sound object has stopped playing
+        for (unsigned int i = 0; i < this->usedSoundSources_.size(); ++i)
+        {
+            ALint state;
+            alGetSourcei(this->usedSoundSources_[i].first, AL_SOURCE_STATE, &state);
+            if (state == AL_STOPPED)
+            {
+                this->usedSoundSources_[i].second->stop();
+                --i;
+            }
+        }
+    }
+
+    void SoundManager::checkFadeStepValidity()
+    {
+        if (crossFadeStep_ <= 0.0 || crossFadeStep_ >= 1.0 )
+        {
+            COUT(2) << "Sound warning: fade step out of range, ignoring change." << std::endl;
+            ResetConfigValue(crossFadeStep_);
+        }
+    }
+
+    void SoundManager::checkVolumeValidity(SoundType::Value type)
+    {
+        float clampedVolume = clamp(this->volume_[type], 0.0f, 1.0f);
+        if (clampedVolume != this->volume_[type])
+            COUT(2) << "Sound warning: Volume setting (" << type << ") out of range, clamping." << std::endl;
+        this->updateVolume(type);
+    }
+
+    void SoundManager::setVolume(float vol, SoundType::Value type)
+    {
+        if (type < 0 || type > SoundType::Effects)
+            return;
+        this->volume_[type] = vol;
+        this->checkVolumeValidity(type);
+    }
+
+    float SoundManager::getVolume(SoundType::Value type)
+    {
+        if (type < 0 || type > SoundType::Effects)
+            return 0.0f;
+        return this->volume_[type];
+    }
+
+    float SoundManager::getRealVolume(SoundType::Value type)
+    {
+        if (type != SoundType::Music && type != SoundType::Effects)
+            return 0.0f;
+        return this->volume_[SoundType::All] * this->mute_[SoundType::All] * this->volume_[type] * this->mute_[type];
+    }
+
+    void SoundManager::updateVolume(SoundType::Value type)
+    {
+        switch(type)
+        {
+        case SoundType::All:
+            for (ObjectList<BaseSound>::iterator it = ObjectList<BaseSound>::begin(); it != ObjectList<BaseSound>::end(); ++it)
+                (*it)->updateVolume();
+            break;
+        case SoundType::Music:
+            for (ObjectList<AmbientSound>::iterator it = ObjectList<AmbientSound>::begin(); it != ObjectList<AmbientSound>::end(); ++it)
+                (*it)->updateVolume();
+            break;
+        case SoundType::Effects:
+            for (ObjectList<WorldSound>::iterator it = ObjectList<WorldSound>::begin(); it != ObjectList<WorldSound>::end(); ++it)
+                (*it)->updateVolume();
+            break;
+        default:
+            assert(false);
+        }
+    }
+
+    void SoundManager::toggleMute(SoundType::Value type)
+    {
+        if (type < 0 || type > SoundType::Effects)
+            return;
+        this->mute_[type] = (this->mute_[type] == 0) ? 1.0f : 0.0f;
+        this->updateVolume(type);
+    }
+
+    bool SoundManager::getMute(SoundType::Value type)
+    {
+        if (type < 0 || type > SoundType::Effects)
+            return true;
+        return (this->mute_[type] == 0);
+    }
+
+    void SoundManager::setListenerPosition(const Vector3& position)
+    {
+        alListener3f(AL_POSITION, position.x, position.y, position.z);
+        ALenum error = alGetError();
+        if (error == AL_INVALID_VALUE)
+            COUT(2) << "Sound: OpenAL: Invalid listener position" << std::endl;
+    }
+
+    void SoundManager::setListenerOrientation(const Quaternion& orientation)
+    {
+        // update listener orientation
+        const Vector3& direction = -orientation.zAxis();
+        const Vector3& up = orientation.yAxis();
+
+        ALfloat orient[6] = { direction.x, direction.y, direction.z, up.x, up.y, up.z };
+
+        alListenerfv(AL_ORIENTATION, orient);
+        ALenum error = alGetError();
+        if (error == AL_INVALID_VALUE)
+            COUT(2) << "Sound: OpenAL: Invalid listener orientation" << std::endl;
+    }
+
+    void SoundManager::registerAmbientSound(AmbientSound* newAmbient)
+    {
+        if (newAmbient != NULL)
+        {
+            for (AmbientList::const_iterator it = this->ambientSounds_.begin(); it != this->ambientSounds_.end(); ++it)
+            {
+                if (it->first == newAmbient)
+                {
+                    COUT(2) << "Sound warning: Will not play an AmbientSound twice." << std::endl;
+                    return;
+                }
+            }
+
+            if (!this->ambientSounds_.empty())
+            {
+                this->fadeOut(ambientSounds_.front().first);
+            }
+            this->ambientSounds_.push_front(std::make_pair(newAmbient, false));
+            newAmbient->doPlay();
+            this->fadeIn(newAmbient);
+        }
+    }
+
+    void SoundManager::unregisterAmbientSound(AmbientSound* oldAmbient)
+    {
+        if (oldAmbient == NULL || ambientSounds_.empty())
+            return;
+
+        if (this->ambientSounds_.front().first == oldAmbient)
+        {
+            this->fadeOut(oldAmbient);
+            this->ambientSounds_.pop_front();
+            if (!this->ambientSounds_.empty())
+            {
+                if (!this->ambientSounds_.front().second) // Not paused before
+                {
+                    this->ambientSounds_.front().first->doPlay();
+                }
+                this->fadeIn(this->ambientSounds_.front().first);
+            }
+        }
+        else
+        {
+            for (AmbientList::iterator it = this->ambientSounds_.begin(); it != this->ambientSounds_.end(); ++it)
+            {
+                if (it->first == oldAmbient)
+                {
+                    this->fadeOut(oldAmbient);
+                    this->ambientSounds_.erase(it);
+                    break;
+                }
+            }
+        }
+    }
+
+    void SoundManager::pauseAmbientSound(AmbientSound* ambient)
+    {
+        if (ambient != NULL)
+        {
+            for (AmbientList::iterator it = this->ambientSounds_.begin(); it != this->ambientSounds_.end(); ++it)
+            {
+                if (it->first == ambient)
+                {
+                    it->second = true;
+                    this->fadeOut(it->first);
+                    return;
+                }
+            }
+        }
+    }
+
+    void SoundManager::fadeIn(const SmartPtr<AmbientSound>& sound)
+    {
+        // If we're already fading out --> remove that
+        for (std::list<SmartPtr<AmbientSound> >::iterator it = this->fadeOutList_.begin(); it != this->fadeOutList_.end(); it++)
+        {
+            if (*it == sound)
+            {
+                this->fadeOutList_.erase(it);
+                break;
+            }
+        }
+        // No duplicate entries
+        if (std::find(this->fadeInList_.begin(), this->fadeInList_.end(), sound) == this->fadeInList_.end())
+            this->fadeInList_.push_back(sound);
+    }
+
+    void SoundManager::fadeOut(const SmartPtr<AmbientSound>& sound)
+    {
+        // If we're already fading in --> remove that
+        for (std::list<SmartPtr<AmbientSound> >::iterator it = this->fadeInList_.begin(); it != this->fadeInList_.end(); it++)
+        {
+            if (*it == sound)
+            {
+                this->fadeInList_.erase(it);
+                break;
+            }
+        }
+        // No duplicate entries
+        if (std::find(this->fadeOutList_.begin(), this->fadeOutList_.end(), sound) == this->fadeOutList_.end())
+            this->fadeOutList_.push_back(sound);
+    }
+
+    void SoundManager::processCrossFading(float dt)
+    {
+
+        // Hacky solution to the fade delay while loading a level.
+        if(dt > 0.2)
+        {
+            return;
+        }
+
+        // FADE IN
+        for (std::list<SmartPtr<AmbientSound> >::iterator it= this->fadeInList_.begin(); it != this->fadeInList_.end(); )
+        {
+            if ((*it)->getVolume() + this->crossFadeStep_*dt > 1.0f)
+            {
+                (*it)->setVolume(1.0f);
+                this->fadeInList_.erase(it++);
+            }
+            else
+            {
+                (*it)->setVolume((*it)->getVolume() + this->crossFadeStep_*dt);
+                ++it;
+            }
+        }
+
+        // FADE OUT
+        for (std::list<SmartPtr<AmbientSound> >::iterator it = this->fadeOutList_.begin(); it != this->fadeOutList_.end(); )
+        {
+            if ((*it)->getVolume() - this->crossFadeStep_*dt < 0.0f)
+            {
+                (*it)->setVolume(0.0f);
+
+                // If sound is in the ambient list --> pause
+                for (AmbientList::const_iterator it2 = this->ambientSounds_.begin(); it2 != this->ambientSounds_.end(); ++it2)
+                {
+                    if (it2->first == *it)
+                    {
+                        (*it)->doPause();
+                        break;
+                    }
+                }
+                // If not pause (by loop above for instance) --> stop
+                if (!(*it)->isPaused())
+                    (*it)->doStop();
+
+                this->fadeOutList_.erase(it++);
+            }
+            else
+            {
+                (*it)->setVolume((*it)->getVolume() - this->crossFadeStep_*dt);
+                ++it;
+            }
+        }
+    }
+
+    shared_ptr<SoundBuffer> SoundManager::getSoundBuffer(const std::string& filename)
+    {
+        shared_ptr<SoundBuffer> buffer;
+        // Check active or pooled buffers
+        SoundBufferMap::const_iterator it = this->soundBuffers_.find(filename);
+        if (it != this->soundBuffers_.end())
+        {
+            buffer = it->second;
+
+            // Remove from effects pool if not active used before
+            if (buffer->poolIterator_ != this->effectsPool_.end())
+            {
+                this->effectsPoolSize_ -= buffer->getSize();
+                this->effectsPool_.erase(buffer->poolIterator_);
+                buffer->poolIterator_ = this->effectsPool_.end();
+            }
+        }
+        else
+        {
+            try
+            {
+                buffer.reset(new SoundBuffer(filename, this->effectsPool_.end()));
+            }
+            catch (...)
+            {
+                COUT(1) << Exception::handleMessage() << std::endl;
+                return buffer;
+            }
+            this->soundBuffers_[filename] = buffer;
+        }
+        return buffer;
+    }
+
+    void SoundManager::releaseSoundBuffer(const shared_ptr<SoundBuffer>& buffer, bool bPoolBuffer)
+    {
+        // Check if others are still using the buffer
+        if (buffer.use_count() != 2)
+            return;
+        SoundBufferMap::iterator it = this->soundBuffers_.find(buffer->getFilename());
+        if (it != this->soundBuffers_.end())
+        {
+            if (bPoolBuffer)
+            {
+                // Pool already too large?
+                while (this->effectsPoolSize_ + it->second->getSize() > this->maxEffectsPoolSize_s && !this->effectsPool_.empty())
+                {
+                    shared_ptr<SoundBuffer> bufferDel = this->effectsPool_.back();
+                    this->effectsPoolSize_ -= bufferDel->getSize();
+                    bufferDel->poolIterator_ = this->effectsPool_.end();
+                    this->effectsPool_.pop_back();
+                    // Remove from buffer map too
+                    SoundBufferMap::iterator itDel = this->soundBuffers_.find(bufferDel->getFilename());
+                    if (itDel != this->soundBuffers_.end())
+                        this->soundBuffers_.erase(itDel);
+                }
+                // Put buffer into the pool
+                this->effectsPoolSize_ += it->second->getSize();
+                this->effectsPool_.push_front(it->second);
+                it->second->poolIterator_ = this->effectsPool_.begin();
+            }
+            else
+                this->soundBuffers_.erase(it);
+        }
+    }
+
+    ALuint SoundManager::getSoundSource(BaseSound* object)
+    {
+        if (!this->availableSoundSources_.empty())
+        {
+            ALuint source = this->availableSoundSources_.back();
+            this->availableSoundSources_.pop_back();
+            this->usedSoundSources_.push_back(std::make_pair(source, object));
+            return source;
+        }
+        else
+        {
+            if (this->usedSoundSources_.size() < this->maxSources_)
+            {
+                ALuint source;
+                alGenSources(1, &source);
+                // Try to create new sources (50% more, but at least one)
+                if (alIsSource(source) && !alGetError())
+                {
+                    this->usedSoundSources_.push_back(std::make_pair(source, object));
+                    return source;
+                }
+            }
+            // Return no source ID
+            ALuint source = 123456789;
+            while (alIsSource(++source));
+            return source;
+        }
+    }
+
+    void SoundManager::releaseSoundSource(ALuint source)
+    {
+#ifndef NDEBUG
+        for (std::vector<ALuint>::const_iterator it = this->availableSoundSources_.begin(); it != this->availableSoundSources_.end(); ++it)
+            assert((*it) != source);
+#endif
+        this->availableSoundSources_.push_back(source);
+        for (std::vector<std::pair<ALuint, BaseSound*> >::iterator it = this->usedSoundSources_.begin();
+            it != this->usedSoundSources_.end(); ++it)
+        {
+            if (it->first == source)
+            {
+                this->usedSoundSources_.erase(it);
+                break;
+            }
+        }
+        int used = std::max((unsigned int)(this->usedSoundSources_.size()), this->minSources_);
+        // Subtract those we added in the statement above trough std::max
+        int available = (int)this->availableSoundSources_.size() - (used - (int)this->usedSoundSources_.size());
+        // Delete sources again to free resources if appropriate (more than 50% more available than used)
+        int toDelete = available - used / 2;
+        while (toDelete-- > 0)
+        {
+            alDeleteSources(1, &this->availableSoundSources_.back());
+            if (alGetError())
+                COUT(1) << "Sound Error: Failed to delete a source --> lost forever" << std::endl;
+            this->availableSoundSources_.pop_back();
+        }
+    }
+
+    unsigned int SoundManager::createSoundSources(unsigned int n)
+    {
+        unsigned int count = this->availableSoundSources_.size() + this->usedSoundSources_.size();
+        while (count < this->maxSources_ && count <= n)
+        {
+            ALuint source;
+            alGenSources(1, &source);
+            if (alIsSource(source) && !alGetError())
+                this->availableSoundSources_.push_back(source);
+            else
+                break;
+            ++count;
+        }
+        return count - this->availableSoundSources_.size() - this->usedSoundSources_.size();
+    }
+}
Index: /code/branches/rocket2/src/orxonox/sound/SoundManager.h
===================================================================
--- /code/branches/rocket2/src/orxonox/sound/SoundManager.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/sound/SoundManager.h	(revision 6952)
@@ -0,0 +1,153 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *       Erwin 'vaiursch' Herrsche
+ *       Kevin Young
+ *       Reto Grieder
+ *   Co-authors:
+ *      ...
+ */
+
+#ifndef _SoundManager_H__
+#define _SoundManager_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <list>
+#include <map>
+#include <string>
+#include <boost/shared_ptr.hpp>
+
+#include "util/Singleton.h"
+#include "core/OrxonoxClass.h"
+#include "core/SmartPtr.h"
+
+// tolua_begin
+namespace orxonox
+{
+    //! Enum for the sound type.
+    namespace SoundType
+    {
+        enum Value
+        {
+            All     = 0,
+            Music   = 1,
+            Effects = 2
+        };
+    }
+
+    //! The SoundManager class manages the OpenAL device, context and listener position.
+    class _OrxonoxExport SoundManager
+    // tolua_end
+        : public Singleton<SoundManager>, public OrxonoxClass
+    { // tolua_export
+        friend class Singleton<SoundManager>;
+
+    public:
+        SoundManager();
+        ~SoundManager();
+
+        void preUpdate(const Clock& time);
+        void setConfigValues();
+
+        // tolua_begin
+        static SoundManager& getInstance() { return Singleton<SoundManager>::getInstance(); }
+
+        std::string getDeviceName(unsigned int index) const
+            { return index < this->deviceNames_.size() ? this->deviceNames_[index] : std::string(); }
+        // tolua_end
+
+        void setListenerPosition(const Vector3& position);
+        void setListenerOrientation(const Quaternion& orientation);
+
+        void registerAmbientSound(AmbientSound* newAmbient);
+        void unregisterAmbientSound(AmbientSound* oldAmbient);
+        void pauseAmbientSound(AmbientSound* ambient);
+
+        // tolua_begin
+        void setVolume(float vol, SoundType::Value type);
+        float getVolume(SoundType::Value type);
+        float getRealVolume(SoundType::Value type);
+
+        void toggleMute(SoundType::Value type);
+        bool getMute(SoundType::Value type);
+        // tolua_end
+
+        shared_ptr<SoundBuffer> getSoundBuffer(const std::string& filename);
+        void releaseSoundBuffer(const shared_ptr<SoundBuffer>& buffer, bool bPoolBuffer);
+
+        ALuint getSoundSource(BaseSound* object);
+        void releaseSoundSource(ALuint source);
+
+        static std::string getALErrorString(ALenum error);
+
+    private:
+        void processCrossFading(float dt);
+        void fadeIn(const SmartPtr<AmbientSound>& sound);
+        void fadeOut(const SmartPtr<AmbientSound>& sound);
+
+        void checkFadeStepValidity();
+
+        void checkVolumeValidity(SoundType::Value type);
+        void checkSoundVolumeValidity()   { this->checkVolumeValidity(SoundType::All); }
+        void checkAmbientVolumeValidity() { this->checkVolumeValidity(SoundType::Music); }
+        void checkEffectsVolumeValidity() { this->checkVolumeValidity(SoundType::Effects); }
+        void updateVolume(SoundType::Value type);
+
+        unsigned int createSoundSources(unsigned int n);
+
+        // OpenAL device/context related
+        std::vector<std::string> deviceNames_;
+        ALCdevice* device_;
+        ALCcontext* context_;
+
+        // Ambient sound related
+        typedef std::list<std::pair<AmbientSound*, bool> > AmbientList;
+        AmbientList                        ambientSounds_;
+        //! Absolute change per second (0.1 means 10% of the nominal volume) for cross fading
+        float                              crossFadeStep_;
+        std::list<SmartPtr<AmbientSound> > fadeInList_;
+        std::list<SmartPtr<AmbientSound> > fadeOutList_;
+
+        // Volume related
+        float volume_[3];
+        float mute_[3];
+
+        // Sound buffer related
+        static const unsigned int maxEffectsPoolSize_s = 40 * 1024 * 1024;
+        unsigned int effectsPoolSize_;
+        typedef std::list<shared_ptr<SoundBuffer> > EffectsPoolList;
+        EffectsPoolList effectsPool_;
+        typedef std::map<std::string, shared_ptr<SoundBuffer> > SoundBufferMap;
+        SoundBufferMap soundBuffers_;
+
+        // Sound source related
+        unsigned int minSources_;
+        unsigned int maxSources_;
+        std::vector<ALuint> availableSoundSources_;
+        std::vector<std::pair<ALuint, BaseSound*> > usedSoundSources_;
+
+        static SoundManager* singletonPtr_s;
+    }; // tolua_export
+} // tolua_export
+
+#endif /* _SoundManager_H__ */
Index: /code/branches/rocket2/src/orxonox/sound/SoundStreamer.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/sound/SoundStreamer.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/sound/SoundStreamer.cc	(revision 6952)
@@ -0,0 +1,128 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Erwin 'vaiursch' Herrsche
+ *   Co-authors:
+ *
+ */
+#include "SoundStreamer.h"
+
+#include <al.h>
+#include <vorbis/vorbisfile.h>
+#include "SoundManager.h"
+
+namespace orxonox
+{
+    // vorbis callbacks
+    size_t readVorbis(void* ptr, size_t size, size_t nmemb, void* datasource);
+    int seekVorbis(void* datasource, ogg_int64_t offset, int whence);
+    long tellVorbis(void* datasource);
+
+    void orxonox::SoundStreamer::operator()(ALuint audioSource, DataStreamPtr dataStream)
+    {
+        // Open file with custom streaming
+        ov_callbacks vorbisCallbacks;
+        vorbisCallbacks.read_func  = &readVorbis;
+        vorbisCallbacks.seek_func  = &seekVorbis;
+        vorbisCallbacks.tell_func  = &tellVorbis;
+        vorbisCallbacks.close_func = NULL;
+
+        OggVorbis_File vf;
+        int ret = ov_open_callbacks(dataStream.get(), &vf, NULL, 0, vorbisCallbacks);
+        if (ret < 0)
+        {
+            COUT(2) << "Sound: libvorbisfile: File does not seem to be an Ogg Vorbis bitstream" << std::endl;
+            ov_clear(&vf);
+            return;
+        }
+        vorbis_info* vorbisInfo;
+        vorbisInfo = ov_info(&vf, -1);
+        ALenum format;
+        if (vorbisInfo->channels == 1)
+            format = AL_FORMAT_MONO16;
+        else
+            format = AL_FORMAT_STEREO16;
+
+        char inbuffer[256*1024];
+        ALuint initbuffers[4];
+        alGenBuffers(4, initbuffers);
+        int current_section;
+
+        for(int i = 0; i < 4; i++)
+        {
+            long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, &current_section);
+            if (ret == 0)
+            {
+                return;
+            }
+            else if (ret < 0)
+            {
+                COUT(2) << "Sound: libvorbisfile: error reading the file" << std::endl;
+                ov_clear(&vf);
+                return;
+            }
+
+            alBufferData(initbuffers[i], format, &inbuffer, ret, vorbisInfo->rate);
+        }
+        alSourceQueueBuffers(audioSource, 4, initbuffers);
+
+        while(true) // Stream forever, control through thread control
+        {
+            int processed;
+            alGetSourcei(audioSource, AL_BUFFERS_PROCESSED, &processed);
+            if (ALint error = alGetError())
+            COUT(2) << "Sound Warning: Couldn't get number of processed buffers: "
+                    << SoundManager::getALErrorString(error) << std::endl;
+
+            if(processed > 0)
+            {
+                ALuint* buffers = new ALuint[processed];
+                alSourceUnqueueBuffers(audioSource, processed, buffers);
+                if (ALint error = alGetError())
+                    COUT(2) << "Sound Warning: Couldn't unqueue buffers: "
+                    << SoundManager::getALErrorString(error) << std::endl;
+
+                for(int i = 0; i < processed; i++)
+                {
+                    long ret = ov_read(&vf, inbuffer, sizeof(inbuffer), 0, 2, 1, &current_section);
+                    if (ret == 0)
+                    {
+                        return;
+                    }
+                    else if (ret < 0)
+                    {
+                        COUT(2) << "Sound: libvorbisfile: error reading the file" << std::endl;
+                        ov_clear(&vf);
+                        return;
+                    }
+
+                    alBufferData(buffers[i], format, &inbuffer, ret, vorbisInfo->rate);
+                }
+
+                alSourceQueueBuffers(audioSource, processed, buffers);
+                if (ALint error = alGetError())
+                    COUT(2) << "Sound Warning: Couldn't queue buffers: "
+                    << SoundManager::getALErrorString(error) << std::endl;
+            }
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/sound/SoundStreamer.h
===================================================================
--- /code/branches/rocket2/src/orxonox/sound/SoundStreamer.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/sound/SoundStreamer.h	(revision 6952)
@@ -0,0 +1,46 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Erwin 'vaiursch' Herrsche
+ *   Co-authors:
+ *
+ */
+
+#ifndef _SoundStreamer_H__
+#define _SoundStreamer_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include <OgreDataStream.h>
+#include "core/CorePrereqs.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport SoundStreamer // class for stream threads
+    {
+    public:
+        void operator()(ALuint audioSource, DataStreamPtr dataStream);
+    };
+}
+
+#endif /* _SoundStreamer_H__ */
Index: /code/branches/rocket2/src/orxonox/sound/WorldSound.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/sound/WorldSound.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/sound/WorldSound.cc	(revision 6952)
@@ -0,0 +1,126 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Erwin 'vaiursch' Herrsche
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "WorldSound.h"
+
+#include <AL/alut.h>
+#include "util/Math.h"
+#include "core/CoreIncludes.h"
+#include "core/EventIncludes.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+#include "SoundManager.h"
+#include <core/ConsoleCommandCompilation.h>
+
+namespace orxonox
+{
+    CreateFactory(WorldSound);
+
+    WorldSound::WorldSound(BaseObject* creator)
+        : StaticEntity(creator)
+    {
+        RegisterObject(WorldSound);
+        // WorldSound buffers should be pooled when they're not used anymore
+        this->bPooling_ = true;
+        this->registerVariables();
+    }
+
+    void WorldSound::registerVariables()
+    {
+        registerVariable(volume_,   ObjectDirection::ToClient, new NetworkCallback<WorldSound>(this, &WorldSound::volumeChanged));
+        registerVariable(source_,   ObjectDirection::ToClient, new NetworkCallback<WorldSound>(this, &WorldSound::sourceChanged));
+        registerVariable(bLooping_, ObjectDirection::ToClient, new NetworkCallback<WorldSound>(this, &WorldSound::loopingChanged));
+        registerVariable(pitch_,    ObjectDirection::ToClient, new NetworkCallback<WorldSound>(this, &WorldSound::pitchChanged));
+        registerVariable((int&)(BaseSound::state_), ObjectDirection::ToClient, new NetworkCallback<WorldSound>(this, &WorldSound::stateChanged));
+    }
+
+    void WorldSound::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(WorldSound, XMLPort, xmlelement, mode);
+        BaseSound::XMLPortExtern(xmlelement, mode);
+    }
+
+    void WorldSound::XMLEventPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(WorldSound, XMLEventPort, xmlelement, mode);
+        XMLPortEventState(WorldSound, BaseObject, "play", play, xmlelement, mode);
+    }
+
+    void WorldSound::initialiseSource()
+    {
+        BaseSound::initialiseSource();
+        if (this->getScene())
+        {
+            float refDist = this->getScene()->getSoundReferenceDistance();
+            alSourcef(this->audioSource_, AL_REFERENCE_DISTANCE, refDist);
+            // TODO: 500 is very magical here. Derive something better
+            alSourcef(this->audioSource_, AL_MAX_DISTANCE, refDist * 500);
+        }
+        this->tick(0); // update position, orientation and velocity
+    }
+
+    void WorldSound::tick(float dt)
+    {
+        if (alIsSource(this->audioSource_))
+        {
+            const Vector3& pos = this->getWorldPosition();
+            alSource3f(this->audioSource_, AL_POSITION, pos.x, pos.y, pos.z);
+            ALenum error = alGetError();
+            if (error == AL_INVALID_VALUE)
+                COUT(2) << "Sound: OpenAL: Invalid sound position" << std::endl;
+
+            const Vector3& vel = this->getVelocity();
+            alSource3f(this->audioSource_, AL_VELOCITY, vel.x, vel.y, vel.z);
+            error = alGetError();
+            if (error == AL_INVALID_VALUE)
+                COUT(2) << "Sound: OpenAL: Invalid sound velocity" << std::endl;
+
+            const Vector3& direction = -this->getWorldOrientation().zAxis();
+            alSource3f(this->audioSource_, AL_DIRECTION, direction.x, direction.y, direction.z);
+            error = alGetError();
+            if (error == AL_INVALID_VALUE)
+                COUT(2) << "Sound: OpenAL: Invalid sound direction" << std::endl;
+        }
+    }
+
+    void WorldSound::changedActivity()
+    {
+        SUPER(WorldSound, changedActivity);
+        if (this->isActive())
+            this->play();
+        else
+            this->stop();
+    }
+
+    float WorldSound::getRealVolume()
+    {
+        assert(GameMode::playsSound());
+        return SoundManager::getInstance().getRealVolume(SoundType::Effects);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/sound/WorldSound.h
===================================================================
--- /code/branches/rocket2/src/orxonox/sound/WorldSound.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/sound/WorldSound.h	(revision 6952)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _WorldSound_H__
+#define _WorldSound_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "tools/interfaces/Tickable.h"
+#include "sound/BaseSound.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    /*
+    @brief
+        The WorldSound class is to be used for sounds with position and orientation.
+    */
+    class _OrxonoxExport WorldSound : public StaticEntity, public BaseSound, public Tickable
+    {
+    public:
+        WorldSound(BaseObject* creator);
+
+        void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+        void XMLEventPort(Element& xmlelement, XMLPort::Mode mode);
+        void changedActivity();
+
+        void tick(float dt);
+
+    protected:
+        ~WorldSound() {}
+
+    private:
+        void registerVariables();
+        void initialiseSource();
+        float getRealVolume();
+    };
+}
+
+#endif /* _WorldSound_H__ */
Index: /code/branches/rocket2/src/orxonox/weaponsystem/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,10 @@
+ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+  Munition.cc
+  Weapon.cc
+  WeaponMode.cc
+  WeaponPack.cc
+  WeaponSet.cc
+  WeaponSlot.cc
+  WeaponSystem.cc
+  DefaultWeaponmodeLink.cc
+)
Index: /code/branches/rocket2/src/orxonox/weaponsystem/DefaultWeaponmodeLink.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/DefaultWeaponmodeLink.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/DefaultWeaponmodeLink.cc	(revision 6952)
@@ -0,0 +1,58 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "DefaultWeaponmodeLink.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "WeaponSystem.h"
+
+namespace orxonox
+{
+    CreateFactory(DefaultWeaponmodeLink);
+
+    DefaultWeaponmodeLink::DefaultWeaponmodeLink(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(DefaultWeaponmodeLink);
+
+        this->firemode_ = WeaponSystem::FIRE_MODE_UNASSIGNED;
+        this->weaponmode_ = WeaponSystem::WEAPON_MODE_UNASSIGNED;
+    }
+
+    DefaultWeaponmodeLink::~DefaultWeaponmodeLink()
+    {
+    }
+
+    void DefaultWeaponmodeLink::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(DefaultWeaponmodeLink, XMLPort, xmlelement, mode);
+
+        XMLPortParam(DefaultWeaponmodeLink, "firemode",   setFiremode,   getFiremode,   xmlelement, mode);
+        XMLPortParam(DefaultWeaponmodeLink, "weaponmode", setWeaponmode, getWeaponmode, xmlelement, mode);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/weaponsystem/DefaultWeaponmodeLink.h
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/DefaultWeaponmodeLink.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/DefaultWeaponmodeLink.h	(revision 6952)
@@ -0,0 +1,62 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#ifndef _DefaultWeaponmodeLink_H__
+#define _DefaultWeaponmodeLink_H__
+
+#include "OrxonoxPrereqs.h"
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport DefaultWeaponmodeLink : public BaseObject
+    {
+        public:
+            DefaultWeaponmodeLink(BaseObject* creator);
+            virtual ~DefaultWeaponmodeLink();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            inline void setFiremode(const unsigned int firemode)
+                { this->firemode_ = firemode; }
+            inline unsigned int getFiremode() const
+                { return this->firemode_; }
+
+            inline void setWeaponmode(const unsigned int weaponmode)
+                { this->weaponmode_ = weaponmode; }
+            inline unsigned int getWeaponmode() const
+                { return this->weaponmode_; }
+
+        private:
+            unsigned int firemode_;
+            unsigned int weaponmode_;
+    };
+}
+
+#endif /* _DefaultWeaponmodeLink_H__ */
Index: /code/branches/rocket2/src/orxonox/weaponsystem/Munition.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/Munition.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/Munition.cc	(revision 6952)
@@ -0,0 +1,477 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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.
+ *
+ *   Authors:
+ *      Martin Polak
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Munition.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    CreateFactory(Munition);
+
+    Munition::Munition(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(Munition);
+
+        this->maxMunitionPerMagazine_ = 10;
+        this->maxMagazines_ = 10;
+        this->magazines_ = 10;
+
+        this->bUseSeparateMagazines_ = false;
+        this->bStackMunition_ = true;
+        this->bAllowMunitionRefilling_ = true;
+        this->bAllowMultiMunitionRemovementUnderflow_ = true;
+
+        this->reloadTime_ = 0;
+    }
+
+    Munition::~Munition()
+    {
+        for (std::map<WeaponMode*, Magazine*>::iterator it = this->currentMagazines_.begin(); it != this->currentMagazines_.end(); ++it)
+            delete it->second;
+    }
+
+    Munition::Magazine* Munition::getMagazine(WeaponMode* user) const
+    {
+        if (this->bUseSeparateMagazines_)
+        {
+            // For separated magazines we definitively need a given user
+            if (!user)
+                return 0;
+
+            // Use the map to get the magazine assigned to the given user
+            std::map<WeaponMode*, Magazine*>::const_iterator it = this->currentMagazines_.find(user);
+            if (it != this->currentMagazines_.end())
+                return it->second;
+        }
+        else
+        {
+            // We don't use separate magazines for each user, so just take the first magazine
+            if (this->currentMagazines_.size() > 0)
+                return this->currentMagazines_.begin()->second;
+        }
+
+        return 0;
+    }
+
+    unsigned int Munition::getNumMunition(WeaponMode* user) const
+    {
+        Magazine* magazine = this->getMagazine(user);
+        if (magazine)
+        {
+            if (this->bStackMunition_)
+                // With stacked munition every magazine contributes to the total amount
+                return this->maxMunitionPerMagazine_ * this->magazines_ + magazine->munition_;
+            else
+                // Wihtout stacked munition we just consider the current magazine
+                return magazine->munition_;
+        }
+        return 0;
+    }
+
+    unsigned int Munition::getNumMunitionInCurrentMagazine(WeaponMode* user) const
+    {
+        // In contrast to getNumMunition() we really just consider the current magazine, even if we're stacking munition
+        Magazine* magazine = this->getMagazine(user);
+        if (magazine)
+            return magazine->munition_;
+        else
+            return 0;
+    }
+
+    unsigned int Munition::getNumMagazines() const
+    {
+        if (this->bStackMunition_)
+        {
+            // If we stack munition and the current magazine is still full, it counts too
+            Magazine* magazine = this->getMagazine(0);
+            if (magazine && magazine->munition_ == this->maxMunitionPerMagazine_)
+                return this->magazines_ + 1;
+        }
+
+        return this->magazines_;
+    }
+
+    unsigned int Munition::getMaxMunition() const
+    {
+        if (this->bStackMunition_)
+            return this->maxMunitionPerMagazine_ * this->maxMagazines_;
+        else
+            return this->maxMunitionPerMagazine_;
+    }
+
+    bool Munition::canTakeMunition(unsigned int amount, WeaponMode* user) const
+    {
+        Magazine* magazine = this->getMagazine(user);
+        if (magazine && magazine->bLoaded_)
+        {
+            unsigned int munition = magazine->munition_;
+
+            // If we stack munition, we con't care about the current magazine - we just need enough munition in total
+            if (this->bStackMunition_)
+                munition += this->maxMunitionPerMagazine_ * this->magazines_;
+
+            if (munition == 0)
+                // Absolutely no munition - no chance to take munition
+                return false;
+            else if (this->bAllowMultiMunitionRemovementUnderflow_)
+                // We're not empty AND we allow underflow, so this will always work
+                return true;
+            else
+                // We don't allow underflow, so we have to check the amount
+                return (munition >= amount);
+        }
+        return false;
+    }
+
+    bool Munition::takeMunition(unsigned int amount, WeaponMode* user)
+    {
+        if (!this->canTakeMunition(amount, user))
+            return false;
+
+        Magazine* magazine = this->getMagazine(user);
+        if (magazine && magazine->bLoaded_)
+        {
+            if (magazine->munition_ >= amount)
+            {
+                // Enough munition
+                magazine->munition_ -= amount;
+                return true;
+            }
+            else
+            {
+                // Not enough munition
+                if (this->bStackMunition_)
+                {
+                    // We stack munition, so just take what we can and then load the next magazine
+                    amount -= magazine->munition_;
+                    magazine->munition_ = 0;
+
+                    if (this->reload(0))
+                        // Successfully reloaded, continue recursively
+                        return this->takeMunition(amount, 0);
+                    else
+                        // We don't have more magazines, so let's just hope we allow underflow
+                        return this->bAllowMultiMunitionRemovementUnderflow_;
+                }
+                else
+                {
+                    // We don't stack, so we can only take munition if this is allowed
+                    if (magazine->munition_ > 0 && this->bAllowMultiMunitionRemovementUnderflow_)
+                    {
+                        magazine->munition_ -= 0;
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    bool Munition::canReload() const
+    {
+        // As long as we have enough magazines (and don't stack munition) we can reload
+        return (this->magazines_ > 0 && !this->bStackMunition_);
+    }
+
+    bool Munition::needReload(WeaponMode* user) const
+    {
+        Magazine* magazine = this->getMagazine(user);
+        if (magazine)
+        {
+            if (this->bStackMunition_)
+                // With stacked munition, we never have to reload
+                return false;
+            else
+                // We need to reload if an already loaded magazine is empty
+                return (magazine->bLoaded_ && magazine->munition_ == 0);
+        }
+        else
+            // No magazine - we definitively need to reload
+            return true;
+    }
+
+    bool Munition::reload(WeaponMode* user, bool bUseReloadTime)
+    {
+        // Don't reload if we're already reloading
+        Magazine* magazine = this->getMagazine(user);
+        if (magazine && !magazine->bLoaded_)
+            return false;
+
+        // Check if we actually can reload
+        if (this->magazines_ == 0)
+            return false;
+
+        // If we use separate magazines for each user, we definitively need a user given
+        if (this->bUseSeparateMagazines_ && !user)
+            return false;
+
+        // If we don't use separate magazines, set user to 0
+        if (!this->bUseSeparateMagazines_)
+            user = 0;
+
+        // Remove the current magazine for the given user
+        std::map<WeaponMode*, Magazine*>::iterator it = this->currentMagazines_.find(user);
+        if (it != this->currentMagazines_.end())
+        {
+            delete it->second;
+            this->currentMagazines_.erase(it);
+        }
+
+        // Load a new magazine
+        this->currentMagazines_[user] = new Magazine(this, bUseReloadTime);
+        this->magazines_--;
+
+        return true;
+    }
+
+    bool Munition::canAddMunition(unsigned int amount) const
+    {
+        if (!this->bAllowMunitionRefilling_)
+            return false;
+
+        if (this->bStackMunition_)
+        {
+            // If we stack munition, we can always add munition until we reach the limit
+            return (this->getNumMunition(0) < this->getMaxMunition());
+        }
+        else
+        {
+            // Return true if any of the current magazines is not full (loading counts as full although it returns 0 munition)
+            for (std::map<WeaponMode*, Magazine*>::const_iterator it = this->currentMagazines_.begin(); it != this->currentMagazines_.end(); ++it)
+                if (it->second->munition_ < this->maxMunitionPerMagazine_ && it->second->bLoaded_)
+                    return true;
+        }
+
+        return false;
+    }
+
+    bool Munition::addMunition(unsigned int amount)
+    {
+        if (!this->canAddMunition(amount))
+            return false;
+
+        if (this->bStackMunition_)
+        {
+            // Stacking munition means, if a magazine gets full, the munition adds to a new magazine
+            Magazine* magazine = this->getMagazine(0);
+            if (magazine)
+            {
+                // Add the whole amount
+                magazine->munition_ += amount;
+
+                // Add new magazines if the current magazine is overfull
+                while (magazine->munition_ > this->maxMunitionPerMagazine_)
+                {
+                    magazine->munition_ -= this->maxMunitionPerMagazine_;
+                    this->magazines_++;
+                }
+
+                // If we reached the limit, reduze both magazines and munition to the maximum
+                if (this->magazines_ >= this->maxMagazines_)
+                {
+                    this->magazines_ = this->maxMagazines_ - 1;
+                    magazine->munition_ = this->maxMunitionPerMagazine_;
+                }
+
+                return true;
+            }
+
+            // Something went wrong
+            return false;
+        }
+        else
+        {
+            // Share the munition equally to the current magazines
+            while (amount > 0)
+            {
+                bool change = false;
+                for (std::map<WeaponMode*, Magazine*>::iterator it = this->currentMagazines_.begin(); it != this->currentMagazines_.end(); ++it)
+                {
+                    // Add munition if the magazine isn't full (but only to loaded magazines)
+                    if (amount > 0 && it->second->munition_ < this->maxMunitionPerMagazine_ && it->second->bLoaded_)
+                    {
+                        it->second->munition_++;
+                        amount--;
+                        change = true;
+                    }
+                }
+
+                // If there was no change in a loop, all magazines are full (or locked due to loading)
+                if (!change)
+                    break;
+            }
+
+            return true;
+        }
+    }
+
+    bool Munition::canAddMagazines(unsigned int amount) const
+    {
+        if (this->bStackMunition_)
+            // If we stack munition, we can always add new magazines because they contribute directly to the munition
+            return (this->getNumMunition(0) < this->getMaxMunition());
+        else
+            // If we don't stack munition, we're more limited
+            return ((this->currentMagazines_.size() + this->magazines_) < this->maxMagazines_);
+    }
+
+    bool Munition::addMagazines(unsigned int amount)
+    {
+        if (!this->canAddMagazines(amount))
+            return false;
+
+        // Calculate how many magazines are needed
+        int needed_magazines = this->maxMagazines_ - this->magazines_ - this->currentMagazines_.size();
+
+        // If zero or less magazines are needed, we definitively don't need more magazines (unless we stack munition - then a magazine contributes directly to the munition)
+        if (needed_magazines <= 0 && !this->bStackMunition_)
+            return false;
+
+        if (amount <= static_cast<unsigned int>(needed_magazines))
+        {
+            // We need more magazines than we get, so just add them
+            this->magazines_ += amount;
+        }
+        else
+        {
+            // We get more magazines than we need, so just add the needed amount
+            this->magazines_ += needed_magazines;
+            if (this->bStackMunition_)
+            {
+                // We stack munition, so the additional amount contributes directly to the munition of the current magazine
+                Magazine* magazine = this->getMagazine(0);
+                if (magazine)
+                    magazine->munition_ = this->maxMunitionPerMagazine_;
+            }
+        }
+
+        return true;
+    }
+
+    bool Munition::canRemoveMagazines(unsigned int amount) const
+    {
+        if (this->bStackMunition_)
+        {
+            if (this->magazines_ >= amount)
+            {
+                // We have enough magazines
+                return true;
+            }
+            else if (this->magazines_ == amount - 1)
+            {
+                // We lack one magazine, check if the current magazine is still full, if yes we're fine
+                Magazine* magazine = this->getMagazine(0);
+                if (magazine && magazine->munition_ == this->maxMunitionPerMagazine_)
+                    return true;
+            }
+            else
+            {
+                // We don't have enough magazines
+                return false;
+            }
+        }
+        else
+        {
+            // In case we're not stacking munition, just check the number of magazines
+            return (this->magazines_ >= amount);
+        }
+
+        return false;
+    }
+
+    bool Munition::removeMagazines(unsigned int amount)
+    {
+        if (!this->canRemoveMagazines(amount))
+            return false;
+
+        if (this->magazines_ >= amount)
+        {
+            // We have enough magazines, just remove the amount
+            this->magazines_ -= amount;
+        }
+        else if (this->bStackMunition_)
+        {
+            // We don't have enough magazines, but we're stacking munition, so additionally remove the bullets from the current magazine
+            this->magazines_ = 0;
+            Magazine* magazine = this->getMagazine(0);
+            if (magazine)
+                magazine->munition_ = 0;
+        }
+
+        return true;
+    }
+
+    bool Munition::dropMagazine(WeaponMode* user)
+    {
+        // If we use separate magazines, we need a user
+        if (this->bUseSeparateMagazines_ && !user)
+            return false;
+
+        // If we don't use separate magazines, set user to 0
+        if (!this->bUseSeparateMagazines_)
+            user = 0;
+
+        // Remove the current magazine for the given user
+        std::map<WeaponMode*, Magazine*>::iterator it = this->currentMagazines_.find(user);
+        if (it != this->currentMagazines_.end())
+        {
+            delete it->second;
+            this->currentMagazines_.erase(it);
+            return true;
+        }
+
+        return false;
+    }
+
+
+    /////////////////////
+    // Magazine struct //
+    /////////////////////
+    Munition::Magazine::Magazine(Munition* munition, bool bUseReloadTime)
+    {
+        this->munition_ = 0;
+        this->bLoaded_ = false;
+
+        if (bUseReloadTime && (munition->reloadTime_ > 0 || munition->bStackMunition_))
+        {
+            Executor* executor = createExecutor(createFunctor(&Magazine::loaded, this));
+            executor->setDefaultValues(munition);
+
+            this->loadTimer_.setTimer(munition->reloadTime_, false, executor);
+        }
+        else
+            this->loaded(munition);
+    }
+
+    void Munition::Magazine::loaded(Munition* munition)
+    {
+        this->bLoaded_ = true;
+        this->munition_ = munition->maxMunitionPerMagazine_;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/weaponsystem/Munition.h
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/Munition.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/Munition.h	(revision 6952)
@@ -0,0 +1,108 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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.
+ *
+ *   Authors:
+ *      Martin Polak
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Munition_H__
+#define _Munition_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <map>
+#include "core/BaseObject.h"
+#include "tools/Timer.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Munition : public BaseObject
+    {
+        struct Magazine
+        {
+            public:
+                Magazine(Munition* munition, bool bUseReloadTime = true);
+
+                unsigned int munition_;
+                Timer loadTimer_;
+                bool bLoaded_;
+
+            private:
+                void loaded(Munition* munition);
+        };
+
+        public:
+            Munition(BaseObject* creator);
+            virtual ~Munition();
+
+            unsigned int getNumMunition(WeaponMode* user) const;
+            unsigned int getNumMunitionInCurrentMagazine(WeaponMode* user) const;
+            unsigned int getNumMagazines() const;
+
+            unsigned int getMaxMunition() const;
+            inline unsigned int getMaxMagazines() const
+                { return this->maxMagazines_; }
+            inline unsigned int getMaxMunitionPerMagazine() const
+                { return this->maxMunitionPerMagazine_; }
+
+            bool canTakeMunition(unsigned int amount, WeaponMode* user) const;
+            bool takeMunition(unsigned int amount, WeaponMode* user);
+
+            bool canReload() const;
+            bool needReload(WeaponMode* user) const;
+            bool reload(WeaponMode* user, bool bUseReloadTime = true);
+            inline float getReloadTime() const
+                { return this->reloadTime_; }
+
+            bool canAddMunition(unsigned int amount) const;
+            bool addMunition(unsigned int amount);
+
+            bool canAddMagazines(unsigned int amount) const;
+            bool addMagazines(unsigned int amount);
+
+            bool canRemoveMagazines(unsigned int amount) const;
+            bool removeMagazines(unsigned int amount);
+
+            bool dropMagazine(WeaponMode* user);
+
+        protected:
+            unsigned int maxMunitionPerMagazine_;
+            unsigned int maxMagazines_;
+            unsigned int magazines_;
+            std::map<WeaponMode*, Magazine*> currentMagazines_;
+
+            bool bUseSeparateMagazines_;
+            bool bStackMunition_;
+            bool bAllowMunitionRefilling_;
+            bool bAllowMultiMunitionRemovementUnderflow_;
+
+            float reloadTime_;
+
+        private:
+            Magazine* getMagazine(WeaponMode* user) const;
+    };
+}
+
+#endif /* _Munition_H__ */
Index: /code/branches/rocket2/src/orxonox/weaponsystem/Weapon.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/Weapon.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/Weapon.cc	(revision 6952)
@@ -0,0 +1,149 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Weapon.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+#include "WeaponMode.h"
+#include "WeaponPack.h"
+#include "WeaponSystem.h"
+
+namespace orxonox
+{
+    CreateFactory(Weapon);
+
+    Weapon::Weapon(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(Weapon);
+
+        this->weaponPack_ = 0;
+        this->weaponSlot_ = 0;
+        this->bReloading_ = false;
+        this->reloadingWeaponmode_ = WeaponSystem::WEAPON_MODE_UNASSIGNED;
+
+        this->reloadTimer_.setTimer(0.0f, false, createExecutor(createFunctor(&Weapon::reloaded, this)));
+        this->reloadTimer_.stopTimer();
+    }
+
+    Weapon::~Weapon()
+    {
+        if (this->isInitialized())
+        {
+            if (this->weaponPack_)
+                this->weaponPack_->removeWeapon(this);
+
+            for (std::multimap<unsigned int, WeaponMode*>::iterator it = this->weaponmodes_.begin(); it != this->weaponmodes_.end(); ++it)
+                it->second->destroy();
+        }
+    }
+
+    void Weapon::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Weapon, XMLPort, xmlelement, mode);
+
+        XMLPortObject(Weapon, WeaponMode, "", addWeaponmode, getWeaponmode, xmlelement, mode);
+    }
+
+    void Weapon::addWeaponmode(WeaponMode* weaponmode)
+    {
+        if (!weaponmode)
+            return;
+
+        this->weaponmodes_.insert(std::pair<unsigned int, WeaponMode*>(weaponmode->getMode(), weaponmode));
+        weaponmode->setWeapon(this);
+    }
+
+    WeaponMode* Weapon::getWeaponmode(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::multimap<unsigned int, WeaponMode*>::const_iterator it = this->weaponmodes_.begin(); it != this->weaponmodes_.end(); ++it)
+        {
+            if (i == index)
+                return it->second;
+
+            ++i;
+        }
+        return 0;
+    }
+
+    void Weapon::fire(unsigned int mode)
+    {
+        // To avoid firing with more than one mode at the same time, we lock the weapon (reloading) for
+        // all modes except the one which is currently reloading.
+        //
+        // Example:
+        // WeaponMode A -> mode 0
+        // WeaponMode B -> mode 0
+        // WeaponMode C -> mode 1
+        //
+        // -> A and B can fire at the same time, but C has to wait until both (A and B) have reloaded
+        // -> If C fires, A and B have to wait until C has reloaded
+        //
+        // Note: The reloading of each WeaponMode is internally handled by each A, B and C.
+        //       The reloading of the weapon is only performed to avoid firing with different modes at the same time.
+        if (this->bReloading_ && this->reloadingWeaponmode_ != mode)
+            return;
+
+        std::multimap<unsigned int, WeaponMode*>::iterator start = this->weaponmodes_.lower_bound(mode);
+        std::multimap<unsigned int, WeaponMode*>::iterator end   = this->weaponmodes_.upper_bound(mode);
+
+        for (std::multimap<unsigned int, WeaponMode*>::iterator it = start; it != end; ++it)
+        {
+            float reloading_time = 0;
+            if (it->second->fire(&reloading_time))
+            {
+                this->bReloading_ = true;
+                this->reloadingWeaponmode_ = mode;
+
+                this->reloadTimer_.setInterval(reloading_time);
+                this->reloadTimer_.startTimer();
+            }
+        }
+    }
+
+    void Weapon::reload()
+    {
+        for (std::multimap<unsigned int, WeaponMode*>::iterator it = this->weaponmodes_.begin(); it != this->weaponmodes_.end(); ++it)
+            it->second->reload();
+    }
+
+    void Weapon::reloaded()
+    {
+        this->bReloading_ = false;
+        this->reloadingWeaponmode_ = WeaponSystem::WEAPON_MODE_UNASSIGNED;
+    }
+
+    void Weapon::notifyWeaponModes()
+    {
+        for (std::multimap<unsigned int, WeaponMode*>::iterator it = this->weaponmodes_.begin(); it != this->weaponmodes_.end(); ++it)
+            it->second->setWeapon(this);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/weaponsystem/Weapon.h
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/Weapon.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/Weapon.h	(revision 6952)
@@ -0,0 +1,79 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Weapon_H__
+#define _Weapon_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <map>
+#include "tools/Timer.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Weapon : public StaticEntity
+    {
+        public:
+            Weapon(BaseObject* creator);
+            virtual ~Weapon();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            void fire(unsigned int mode);
+            void reload();
+
+            void addWeaponmode(WeaponMode* weaponmode);
+            WeaponMode* getWeaponmode(unsigned int index) const;
+
+            inline void setWeaponPack(WeaponPack * weaponPack)
+                { this->weaponPack_ = weaponPack; this->notifyWeaponModes(); }
+            inline WeaponPack * getWeaponPack() const
+                { return this->weaponPack_; }
+
+            inline void setWeaponSlot(WeaponSlot * wSlot)
+                { this->weaponSlot_ = wSlot; }
+            inline WeaponSlot * getWeaponSlot() const
+                { return this->weaponSlot_; }
+
+        private:
+            void reloaded();
+            void notifyWeaponModes();
+
+            WeaponPack* weaponPack_;
+            WeaponSlot* weaponSlot_;
+            std::multimap<unsigned int, WeaponMode*> weaponmodes_;
+
+            Timer reloadTimer_;
+            bool bReloading_;
+            unsigned int reloadingWeaponmode_;
+    };
+}
+
+#endif /* _Weapon_H__ */
Index: /code/branches/rocket2/src/orxonox/weaponsystem/WeaponMode.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/WeaponMode.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/WeaponMode.cc	(revision 6952)
@@ -0,0 +1,276 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "WeaponMode.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "controllers/Controller.h"
+#include "worldentities/pawns/Pawn.h"
+
+#include "Munition.h"
+#include "Weapon.h"
+#include "WeaponPack.h"
+#include "WeaponSystem.h"
+#include "WeaponSlot.h"
+
+#include "sound/WorldSound.h"
+
+namespace orxonox
+{
+    WeaponMode::WeaponMode(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(WeaponMode);
+
+        this->weapon_ = 0;
+        this->mode_ = WeaponSystem::WEAPON_MODE_UNASSIGNED;
+
+        this->munition_ = 0;
+        this->initialMunition_ = 0;
+        this->initialMagazines_ = 0;
+        this->munitionPerShot_ = 1;
+
+        this->reloadTime_ = 0.25;
+        this->bReloading_ = false;
+        this->bAutoReload_ = true;
+        this->bParallelReload_ = true;
+
+        this->reloadTimer_.setTimer(0.0f, false, createExecutor(createFunctor(&WeaponMode::reloaded, this)));
+        this->reloadTimer_.stopTimer();
+
+        this->damage_ = 0;
+
+        this->muzzleOffset_ = Vector3::ZERO;
+        this->muzzlePosition_ = Vector3::ZERO;
+        this->muzzleOrientation_ = Quaternion::IDENTITY;
+
+        if( GameMode::isMaster() )
+        {
+            this->defSndWpnFire_ = new WorldSound(this);
+            this->defSndWpnFire_->setLooping(false);
+            this->bSoundAttached_ = false;
+        }
+        else
+            this->defSndWpnFire_ = 0;
+    }
+
+    WeaponMode::~WeaponMode()
+    {
+        if (this->isInitialized())
+        {
+            if (this->defSndWpnFire_)
+                this->defSndWpnFire_->destroy();
+        }
+    }
+
+    void WeaponMode::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(WeaponMode, XMLPort, xmlelement, mode);
+
+        XMLPortParam(WeaponMode, "mode",             setMode,             getMode,             xmlelement, mode);
+
+        XMLPortParam(WeaponMode, "munitiontype",     setMunitionName,     getMunitionName,     xmlelement, mode);
+        XMLPortParam(WeaponMode, "initialmunition",  setInitialMunition,  getInitialMunition,  xmlelement, mode);
+        XMLPortParam(WeaponMode, "initialmagazines", setInitialMagazines, getInitialMagazines, xmlelement, mode);
+        XMLPortParam(WeaponMode, "munitionpershot",  setMunitionPerShot,  getMunitionPerShot,  xmlelement, mode);
+
+        XMLPortParam(WeaponMode, "reloadtime",       setReloadTime,       getReloadTime,       xmlelement, mode);
+        XMLPortParam(WeaponMode, "autoreload",       setAutoReload,       getAutoReload,       xmlelement, mode).description("If true, the weapon reloads the magazine automatically");
+        XMLPortParam(WeaponMode, "parallelreload",   setParallelReload,   getParallelReload,   xmlelement, mode).description("If true, the weapon reloads in parallel to the magazine reloading");
+
+        XMLPortParam(WeaponMode, "damage",           setDamage,           getDamage,           xmlelement, mode);
+        XMLPortParam(WeaponMode, "muzzleoffset",     setMuzzleOffset,     getMuzzleOffset,     xmlelement, mode);
+    }
+
+    bool WeaponMode::fire(float* reloadTime)
+    {
+        (*reloadTime) = this->reloadTime_;
+        if( !this->bSoundAttached_ && GameMode::isMaster() )
+        {
+            assert(this->getWeapon());
+            this->getWeapon()->attach(this->defSndWpnFire_);
+            this->bSoundAttached_ = true;
+        }
+
+        if (!this->bReloading_ && this->munition_ && this->munition_->takeMunition(this->munitionPerShot_, this))
+        {
+            float reloadtime = this->reloadTime_;
+
+            if (this->bAutoReload_ && this->munition_->needReload(this))
+            {
+                if (this->munition_->reload(this))
+                {
+                    if (!this->bParallelReload_)
+                        reloadtime += this->munition_->getReloadTime();
+                }
+            }
+
+            this->bReloading_ = true;
+            this->reloadTimer_.setInterval(reloadtime);
+            this->reloadTimer_.startTimer();
+
+            if( this->defSndWpnFire_ && !(this->defSndWpnFire_->isPlaying()))
+            {
+                this->defSndWpnFire_->play();
+            }
+
+            this->fire();
+
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    bool WeaponMode::reload()
+    {
+        if (this->munition_ && this->munition_->reload(this))
+        {
+            if (!this->bParallelReload_)
+            {
+                this->bReloading_ = true;
+                this->reloadTimer_.setInterval(this->reloadTime_ + this->munition_->getReloadTime());
+                this->reloadTimer_.startTimer();
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    void WeaponMode::setMunitionType(Identifier* identifier)
+    {
+        this->munitionname_ = identifier->getName();
+        this->munitiontype_ = identifier;
+        this->updateMunition();
+    }
+
+    void WeaponMode::setMunitionName(const std::string& munitionname)
+    {
+        this->munitionname_ = munitionname;
+        Identifier* identifier = ClassByString(this->munitionname_);
+        if (identifier)
+            this->munitiontype_ = identifier;
+        else
+            COUT(2) << "Warning: No munition class defined in WeaponMode " << this->getName() << std::endl;
+        this->updateMunition();
+    }
+
+    void WeaponMode::updateMunition()
+    {
+        if (this->munitiontype_ && this->weapon_ && this->weapon_->getWeaponPack() && this->weapon_->getWeaponPack()->getWeaponSystem())
+        {
+            this->munition_ = this->weapon_->getWeaponPack()->getWeaponSystem()->getMunition(&this->munitiontype_);
+
+            if (this->munition_)
+            {
+                // Add the initial magazines
+                this->munition_->addMagazines(this->initialMagazines_);
+
+                // Maybe we have to reload (if this munition is used the first time or if there weren't any magazines available before)
+                if (this->munition_->needReload(this))
+                    this->munition_->reload(this, false);
+
+                // Add the initial munition
+                if (this->initialMunition_ > 0 && this->munition_->getNumMunitionInCurrentMagazine(this) == this->munition_->getMaxMunitionPerMagazine())
+                {
+                    // The current magazine is still full, so let's just add another magazine to
+                    // the stack and reduce the current magazine to the given amount of munition
+
+                    unsigned int initialmunition = this->initialMunition_;
+                    if (initialmunition > this->munition_->getMaxMunitionPerMagazine())
+                        initialmunition = this->munition_->getMaxMunitionPerMagazine();
+
+                    this->munition_->takeMunition(this->munition_->getMaxMunitionPerMagazine() - initialmunition, this);
+                    this->munition_->addMagazines(1);
+                }
+                else
+                {
+                    // The current magazine isn't full, add the munition directly
+
+                    this->munition_->addMunition(this->initialMunition_);
+                }
+            }
+        }
+        else
+            this->munition_ = 0;
+    }
+
+    void WeaponMode::reloaded()
+    {
+        if( this->defSndWpnFire_ && this->defSndWpnFire_->isPlaying())
+        {
+            this->defSndWpnFire_->stop();
+        }
+        this->bReloading_ = false;
+    }
+
+    void WeaponMode::computeMuzzleParameters(const Vector3& target)
+    {
+        if (this->weapon_)
+        {
+            this->muzzlePosition_ = this->weapon_->getWorldPosition() + this->weapon_->getWorldOrientation() * this->muzzleOffset_;
+
+            Vector3 muzzleDirection;
+            muzzleDirection = target - this->muzzlePosition_;
+//             COUT(0) << "muzzleDirection " << muzzleDirection << endl;
+            this->muzzleOrientation_ = (this->weapon_->getWorldOrientation() * WorldEntity::FRONT).getRotationTo(muzzleDirection) * this->weapon_->getWorldOrientation();
+        }
+        else
+        {
+            this->muzzlePosition_ = this->muzzleOffset_;
+            this->muzzleOrientation_ = Quaternion::IDENTITY;
+        }
+    }
+
+    Vector3 WeaponMode::getMuzzleDirection() const
+    {
+        if (this->weapon_)
+            return (this->getMuzzleOrientation() * WorldEntity::FRONT);
+        else
+            return WorldEntity::FRONT;
+    }
+
+    void WeaponMode::setDefaultSound(const std::string& soundPath)
+    {
+        if( this->defSndWpnFire_ )
+            this->defSndWpnFire_->setSource(soundPath);
+    }
+
+    const std::string& WeaponMode::getDefaultSound()
+    {
+        if( this->defSndWpnFire_ )
+            return this->defSndWpnFire_->getSource();
+        else
+            return BLANKSTRING;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/weaponsystem/WeaponMode.h
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/WeaponMode.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/WeaponMode.h	(revision 6952)
@@ -0,0 +1,172 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _WeaponMode_H__
+#define _WeaponMode_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "util/Math.h"
+#include "core/BaseObject.h"
+#include "core/SubclassIdentifier.h"
+#include "tools/Timer.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport WeaponMode : public BaseObject
+    {
+        public:
+            WeaponMode(BaseObject* creator);
+            virtual ~WeaponMode();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            bool fire(float* reloadTime);
+            bool reload();
+
+            // Interacting with the default Firing sound
+            void setDefaultSound(const std::string& soundPath);
+            const std::string& getDefaultSound();
+
+
+            // Munition
+            inline Munition* getMunition() const
+                { return this->munition_; }
+
+            void setMunitionType(Identifier* identifier);
+            inline Identifier* getMunitionType() const
+                { return this->munitiontype_; }
+
+            void setMunitionName(const std::string& munitionname);
+            inline const std::string& getMunitionName() const
+                { return this->munitionname_; }
+
+            inline void setInitialMunition(unsigned int amount)
+                { this->initialMunition_ = amount; }
+            inline unsigned int getInitialMunition() const
+                { return this->initialMunition_; }
+
+            inline void setInitialMagazines(unsigned int amount)
+                { this->initialMagazines_ = amount; }
+            inline unsigned int getInitialMagazines() const
+                { return this->initialMagazines_; }
+
+            inline void setMunitionPerShot(unsigned int amount)
+                { this->munitionPerShot_ = amount; }
+            inline unsigned int getMunitionPerShot() const
+                { return this->munitionPerShot_; }
+
+
+            // Reloading
+            inline void setReloadTime(float time)
+                { this->reloadTime_ = time; }
+            inline float getReloadTime() const
+                { return this->reloadTime_; }
+
+            inline void setAutoReload(bool autoreload)
+                { this->bAutoReload_ = autoreload; }
+            inline bool getAutoReload() const
+                { return this->bAutoReload_; }
+
+            inline void setParallelReload(bool parallelreload)
+                { this->bParallelReload_ = parallelreload; }
+            inline bool getParallelReload() const
+                { return this->bParallelReload_; }
+
+
+            // Fire
+            inline void setDamage(float damage)
+                { this->damage_ = damage; }
+            inline float getDamage() const
+                { return this->damage_; }
+
+            inline void setMuzzleOffset(const Vector3& offset)
+                { this->muzzleOffset_ = offset; }
+            inline const Vector3& getMuzzleOffset() const
+                { return this->muzzleOffset_; }
+
+            void computeMuzzleParameters(const Vector3& target);
+            const Vector3& getMuzzlePosition() const
+                { return this->muzzlePosition_; }
+            const Quaternion& getMuzzleOrientation() const
+                { return this->muzzleOrientation_; }
+            Vector3 getMuzzleDirection() const;
+
+
+            // Weapon
+            inline void setWeapon(Weapon* weapon)
+                { this->weapon_ = weapon; this->updateMunition(); }
+            inline Weapon* getWeapon() const
+                { return this->weapon_; }
+
+            inline void setMode(unsigned int mode)
+                { this->mode_ = mode; }
+            inline unsigned int getMode() const
+                { return this->mode_; }
+
+            Vector3 getTarget();
+
+        protected:
+            virtual void fire() = 0;
+
+            unsigned int initialMunition_;
+            unsigned int initialMagazines_;
+            unsigned int munitionPerShot_;
+
+            float reloadTime_;
+            bool bAutoReload_;
+            bool bParallelReload_;
+
+            float damage_;
+            Vector3 muzzleOffset_;
+
+        private:
+            void updateMunition();
+            void reloaded();
+
+            Weapon* weapon_;
+            unsigned int mode_;
+
+            Munition* munition_;
+            SubclassIdentifier<Munition> munitiontype_;
+            std::string munitionname_;
+
+            Timer reloadTimer_;
+            bool bReloading_;
+
+            Vector3 muzzlePosition_;
+            Quaternion muzzleOrientation_;
+
+            WorldSound* defSndWpnFire_;
+            bool        bSoundAttached_;
+    };
+}
+
+#endif /* _WeaponMode_H__ */
Index: /code/branches/rocket2/src/orxonox/weaponsystem/WeaponPack.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/WeaponPack.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/WeaponPack.cc	(revision 6952)
@@ -0,0 +1,150 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "WeaponPack.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+#include "Weapon.h"
+#include "WeaponSystem.h"
+#include "DefaultWeaponmodeLink.h"
+
+namespace orxonox
+{
+    CreateFactory(WeaponPack);
+
+    WeaponPack::WeaponPack(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(WeaponPack);
+
+        this->weaponSystem_ = 0;
+    }
+
+    WeaponPack::~WeaponPack()
+    {
+        if (this->isInitialized())
+        {
+            if( this->weaponSystem_ )
+                this->weaponSystem_->removeWeaponPack(this);
+
+            while (!this->weapons_.empty())
+                (*this->weapons_.begin())->destroy();
+
+            for (std::set<DefaultWeaponmodeLink*>::iterator it = this->links_.begin(); it != this->links_.end(); )
+                (*(it++))->destroy();
+        }
+    }
+
+    void WeaponPack::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(WeaponPack, XMLPort, xmlelement, mode);
+
+        XMLPortObjectExtended(WeaponPack, Weapon, "", addWeapon, getWeapon, xmlelement, mode, false, false);
+        XMLPortObject(WeaponPack, DefaultWeaponmodeLink, "links", addDefaultWeaponmodeLink, getDefaultWeaponmodeLink, xmlelement, mode);
+    }
+
+    void WeaponPack::fire(unsigned int weaponmode)
+    {
+        for (std::vector<Weapon *>::iterator it = this->weapons_.begin(); it != this->weapons_.end(); ++it)
+            (*it)->fire(weaponmode);
+    }
+
+    void WeaponPack::reload()
+    {
+        for (std::vector<Weapon *>::iterator it = this->weapons_.begin(); it != this->weapons_.end(); ++it)
+            (*it)->reload();
+    }
+
+    void WeaponPack::addWeapon(Weapon * weapon)
+    {
+        if (!weapon)
+            return;
+
+        this->weapons_.push_back(weapon);
+        weapon->setWeaponPack(this);
+    }
+
+    void WeaponPack::removeWeapon(Weapon * weapon)
+    {
+        if (!weapon)
+            return;
+
+        std::vector<Weapon*>::iterator it = std::find(this->weapons_.begin(), this->weapons_.end(), weapon);
+        assert(it != this->weapons_.end());
+        this->weapons_.erase(it);
+        weapon->setWeaponPack(0);
+    }
+
+    Weapon * WeaponPack::getWeapon(unsigned int index) const
+    {
+        unsigned int i = 0;
+
+        for (std::vector<Weapon *>::const_iterator it = this->weapons_.begin(); it != this->weapons_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+            ++i;
+        }
+
+        return 0;
+    }
+
+    void WeaponPack::addDefaultWeaponmodeLink(DefaultWeaponmodeLink* link)
+    {
+        this->links_.insert(link);
+    }
+
+    DefaultWeaponmodeLink* WeaponPack::getDefaultWeaponmodeLink(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::set<DefaultWeaponmodeLink*>::const_iterator it = this->links_.begin(); it != this->links_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+
+            ++i;
+        }
+        return 0;
+    }
+
+    unsigned int WeaponPack::getDesiredWeaponmode(unsigned int firemode) const
+    {
+        for (std::set<DefaultWeaponmodeLink*>::const_iterator it = this->links_.begin(); it != this->links_.end(); ++it)
+            if ((*it)->getFiremode() == firemode)
+                return (*it)->getWeaponmode();
+
+        return WeaponSystem::WEAPON_MODE_UNASSIGNED;
+    }
+
+    void WeaponPack::notifyWeapons()
+    {
+        for (std::vector<Weapon *>::const_iterator it = this->weapons_.begin(); it != this->weapons_.end(); ++it)
+            (*it)->setWeaponPack(this);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/weaponsystem/WeaponPack.h
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/WeaponPack.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/WeaponPack.h	(revision 6952)
@@ -0,0 +1,77 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#ifndef _WeaponPack_H__
+#define _WeaponPack_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <set>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport WeaponPack : public BaseObject
+    {
+        public:
+            WeaponPack(BaseObject* creator);
+            virtual ~WeaponPack();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            void fire(unsigned int weaponmode);
+            void reload();
+
+            void addWeapon(Weapon * weapon);
+            void removeWeapon(Weapon * weapon);
+            Weapon * getWeapon(unsigned int index) const;
+
+            inline size_t getNumWeapons() const
+                { return this->weapons_.size(); }
+
+            void addDefaultWeaponmodeLink(DefaultWeaponmodeLink* link);
+            DefaultWeaponmodeLink* getDefaultWeaponmodeLink(unsigned int index) const;
+
+            unsigned int getDesiredWeaponmode(unsigned int firemode) const;
+
+            inline void setWeaponSystem(WeaponSystem * weaponSystem)
+                { this->weaponSystem_ = weaponSystem; this->notifyWeapons(); }
+            inline WeaponSystem * getWeaponSystem() const
+                { return this->weaponSystem_; }
+
+        private:
+            void notifyWeapons();
+
+            std::vector<Weapon *> weapons_;
+            std::set<DefaultWeaponmodeLink *> links_;
+            WeaponSystem * weaponSystem_;
+    };
+}
+
+#endif /* _WeaponPack_H__ */
Index: /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSet.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSet.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSet.cc	(revision 6952)
@@ -0,0 +1,95 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "WeaponSet.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+#include "WeaponSystem.h"
+#include "WeaponPack.h"
+
+namespace orxonox
+{
+    CreateFactory(WeaponSet);
+
+    WeaponSet::WeaponSet(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(WeaponSet);
+
+        this->weaponSystem_ = 0;
+        this->desiredFiremode_ = WeaponSystem::FIRE_MODE_UNASSIGNED;
+    }
+
+    WeaponSet::~WeaponSet()
+    {
+        if (this->isInitialized() && this->weaponSystem_)
+            this->weaponSystem_->removeWeaponSet(this);
+    }
+
+    void WeaponSet::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(WeaponSet, XMLPort, xmlelement, mode);
+
+        XMLPortParam(WeaponSet, "firemode", setDesiredFiremode, getDesiredFiremode, xmlelement, mode);
+    }
+
+    void WeaponSet::fire()
+    {
+        // fire all WeaponPacks with their defined weaponmode
+        for (std::map<WeaponPack*, unsigned int>::iterator it = this->weaponpacks_.begin(); it != this->weaponpacks_.end(); ++it)
+            if (it->second != WeaponSystem::WEAPON_MODE_UNASSIGNED)
+                it->first->fire(it->second);
+    }
+
+    void WeaponSet::reload()
+    {
+        // fire all WeaponPacks with their defined weaponmode
+        for (std::map<WeaponPack*, unsigned int>::iterator it = this->weaponpacks_.begin(); it != this->weaponpacks_.end(); ++it)
+            it->first->reload();
+    }
+
+    void WeaponSet::setWeaponmodeLink(WeaponPack* weaponpack, unsigned int weaponmode)
+    {
+        this->weaponpacks_[weaponpack] = weaponmode;
+    }
+
+    void WeaponSet::removeWeaponmodeLink(WeaponPack* weaponpack)
+    {
+        this->weaponpacks_.erase(weaponpack);
+    }
+
+    unsigned int WeaponSet::getWeaponmodeLink(WeaponPack* weaponpack)
+    {
+        std::map<WeaponPack*, unsigned int>::iterator it = this->weaponpacks_.find(weaponpack);
+        if (it != this->weaponpacks_.end())
+            return it->second;
+        else
+            return WeaponSystem::WEAPON_MODE_UNASSIGNED;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSet.h
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSet.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSet.h	(revision 6952)
@@ -0,0 +1,72 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#ifndef _WeaponSet_H__
+#define _WeaponSet_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <map>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport WeaponSet : public BaseObject
+    {
+        public:
+            WeaponSet(BaseObject* creator);
+            virtual ~WeaponSet();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            void fire();
+            void reload();
+
+            void setWeaponmodeLink(WeaponPack* weaponpack, unsigned int weaponmode);
+            void removeWeaponmodeLink(WeaponPack* weaponpack);
+            unsigned int getWeaponmodeLink(WeaponPack* weaponpack);
+
+            inline void setDesiredFiremode(const unsigned int firemode)
+                { this->desiredFiremode_ = firemode; }
+            inline unsigned int getDesiredFiremode() const
+                { return this->desiredFiremode_; }
+
+            inline void setWeaponSystem(WeaponSystem *weaponSystem)
+                { this->weaponSystem_ = weaponSystem; }
+            inline WeaponSystem * getWeaponSystem() const
+                { return this->weaponSystem_; }
+
+        private:
+            WeaponSystem * weaponSystem_;
+            unsigned int desiredFiremode_;
+            std::map<WeaponPack*, unsigned int> weaponpacks_;
+    };
+}
+
+#endif /* _WeaponSet_H__ */
Index: /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSlot.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSlot.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSlot.cc	(revision 6952)
@@ -0,0 +1,86 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "WeaponSlot.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+#include "Weapon.h"
+#include "WeaponSystem.h"
+
+namespace orxonox
+{
+    CreateFactory(WeaponSlot);
+
+    WeaponSlot::WeaponSlot(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(WeaponSlot);
+
+        this->weaponSystem_ = 0;
+        this->weapon_ = 0;
+
+        this->setSyncMode(0x0);
+    }
+
+    WeaponSlot::~WeaponSlot()
+    {
+        if (this->isInitialized() && this->weaponSystem_)
+            this->weaponSystem_->removeWeaponSlot(this);
+    }
+
+    void WeaponSlot::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(WeaponSlot, XMLPort, xmlelement, mode);
+
+        // In the future, there might be parameters like allowed weapon types or max size of the weapon
+    }
+
+    void WeaponSlot::attachWeapon(Weapon *weapon)
+    {
+        if (this->weapon_)
+            this->removeWeapon();
+
+        this->weapon_ = weapon;
+
+        if (this->weapon_)
+        {
+            this->weapon_->setWeaponSlot(this);
+            this->weapon_->setPosition(this->getPosition());
+        }
+    }
+
+    void WeaponSlot::removeWeapon()
+    {
+        if (this->weapon_)
+        {
+            this->weapon_->setWeaponSlot(0);
+            this->weapon_ = 0;
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSlot.h
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSlot.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSlot.h	(revision 6952)
@@ -0,0 +1,65 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _WeaponSlot_H__
+#define _WeaponSlot_H__
+
+#include "OrxonoxPrereqs.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport WeaponSlot : public StaticEntity
+    {
+        public:
+            WeaponSlot(BaseObject* creator);
+            virtual ~WeaponSlot();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            void attachWeapon(Weapon * weapon);
+            void removeWeapon();
+            Weapon * getWeapon() const
+                { return this->weapon_; }
+
+            inline bool isOccupied() const
+                { return (this->weapon_ != 0); }
+
+            inline void setWeaponSystem(WeaponSystem * weaponSystem)
+                { this->weaponSystem_ = weaponSystem; }
+            inline WeaponSystem * getWeaponSystem() const
+                { return this->weaponSystem_; }
+
+
+        private:
+            WeaponSystem * weaponSystem_;
+            Weapon * weapon_;
+    };
+}
+
+#endif /* _WeaponSlot_H__ */
Index: /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSystem.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSystem.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSystem.cc	(revision 6952)
@@ -0,0 +1,317 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "WeaponSystem.h"
+
+#include "core/CoreIncludes.h"
+#include "worldentities/pawns/Pawn.h"
+
+#include "WeaponSlot.h"
+#include "WeaponPack.h"
+#include "WeaponSet.h"
+#include "Weapon.h"
+#include "Munition.h"
+
+/* WeaponSystem
+ *
+ *  www.orxonox.net/wiki/WeaponSystem
+ */
+
+namespace orxonox
+{
+    CreateFactory(WeaponSystem);
+
+    WeaponSystem::WeaponSystem(BaseObject* creator) : BaseObject(creator)
+    {
+        RegisterObject(WeaponSystem);
+
+        this->pawn_ = 0;
+    }
+
+    WeaponSystem::~WeaponSystem()
+    {
+        if (this->isInitialized())
+        {
+            if (this->pawn_)
+                this->pawn_->setWeaponSystem(0);
+
+            while (!this->weaponSets_.empty())
+                this->weaponSets_.begin()->second->destroy();
+
+            while (!this->weaponPacks_.empty())
+                (*this->weaponPacks_.begin())->destroy();
+
+            while (!this->weaponSlots_.empty())
+                (*this->weaponSlots_.begin())->destroy();
+
+            while (!this->munitions_.empty())
+                { this->munitions_.begin()->second->destroy(); this->munitions_.erase(this->munitions_.begin()); }
+        }
+    }
+
+    void WeaponSystem::addWeaponSlot(WeaponSlot * wSlot)
+    {
+        if (!wSlot)
+            return;
+
+        this->weaponSlots_.push_back(wSlot);
+        wSlot->setWeaponSystem(this);
+    }
+
+    void WeaponSystem::removeWeaponSlot(WeaponSlot * wSlot)
+    {
+        if (!wSlot)
+            return;
+
+        if (wSlot->getWeapon())
+            this->removeWeaponPack(wSlot->getWeapon()->getWeaponPack());
+
+        for (std::vector<WeaponSlot*>::iterator it = this->weaponSlots_.begin(); it != this->weaponSlots_.end(); ++it)
+        {
+            if ((*it) == wSlot)
+            {
+                this->weaponSlots_.erase(it);
+                break;
+            }
+        }
+    }
+
+    WeaponSlot * WeaponSystem::getWeaponSlot(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::vector<WeaponSlot*>::const_iterator it = this->weaponSlots_.begin(); it != this->weaponSlots_.end(); ++it)
+        {
+            ++i;
+            if (i > index)
+                return (*it);
+        }
+        return 0;
+    }
+
+    bool WeaponSystem::addWeaponSet(WeaponSet * wSet)
+    {
+        if (wSet)
+            return this->addWeaponSet(wSet, wSet->getDesiredFiremode());
+        else
+            return false;
+    }
+
+    bool WeaponSystem::addWeaponSet(WeaponSet * wSet, unsigned int firemode)
+    {
+        if (!wSet || firemode >= WeaponSystem::MAX_FIRE_MODES)
+            return false;
+
+        std::map<unsigned int, WeaponSet*>::const_iterator it = this->weaponSets_.find(firemode);
+        if (it == this->weaponSets_.end())
+        {
+            this->weaponSets_[firemode] = wSet;
+            wSet->setWeaponSystem(this);
+            return true;
+        }
+
+        return false;
+    }
+
+    void WeaponSystem::removeWeaponSet(WeaponSet * wSet)
+    {
+        for (std::map<unsigned int, WeaponSet*>::iterator it = this->weaponSets_.begin(); it != this->weaponSets_.end(); )
+        {
+            if (it->second == wSet)
+                this->weaponSets_.erase(it++);
+            else
+                ++it;
+        }
+    }
+
+    WeaponSet * WeaponSystem::getWeaponSet(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::map<unsigned int, WeaponSet*>::const_iterator it = this->weaponSets_.begin(); it != this->weaponSets_.end(); ++it)
+        {
+            ++i;
+            if (i > index)
+                return it->second;
+        }
+        return 0;
+    }
+
+    bool WeaponSystem::canAddWeaponPack(WeaponPack * wPack)
+    {
+        if (!wPack)
+            return false;
+
+        unsigned int freeSlots = 0;
+        for (std::vector<WeaponSlot*>::iterator it = this->weaponSlots_.begin(); it != this->weaponSlots_.end(); ++it)
+        {
+            if (!(*it)->isOccupied())
+                ++freeSlots;
+        }
+
+        return (freeSlots >= wPack->getNumWeapons());
+    }
+
+    bool WeaponSystem::addWeaponPack(WeaponPack * wPack)
+    {
+        if (!this->canAddWeaponPack(wPack))
+            return false;
+
+        // Attach all weapons to the first free slots (and to the Pawn)
+        unsigned int i = 0;
+        for (std::vector<WeaponSlot*>::iterator it = this->weaponSlots_.begin(); it != this->weaponSlots_.end(); ++it)
+        {
+            if (!(*it)->isOccupied() && i < wPack->getNumWeapons())
+            {
+                Weapon* weapon = wPack->getWeapon(i);
+                (*it)->attachWeapon(weapon);
+                this->getPawn()->attach(weapon);
+                ++i;
+            }
+        }
+
+        // Assign the desired weaponmode to the firemodes
+        for (std::map<unsigned int, WeaponSet *>::iterator it = this->weaponSets_.begin(); it != this->weaponSets_.end(); ++it)
+        {
+            unsigned int weaponmode = wPack->getDesiredWeaponmode(it->first);
+            if (weaponmode != WeaponSystem::WEAPON_MODE_UNASSIGNED)
+                it->second->setWeaponmodeLink(wPack, weaponmode);
+        }
+
+        this->weaponPacks_.push_back(wPack);
+        wPack->setWeaponSystem(this);
+
+        return true;
+    }
+
+    void WeaponSystem::removeWeaponPack(WeaponPack * wPack)
+    {
+        // Remove all weapons from their WeaponSlot
+        unsigned int i = 0;
+        Weapon* weapon = 0;
+        while ((weapon = wPack->getWeapon(i++)))
+            weapon->getWeaponSlot()->removeWeapon();
+
+        // Remove all added links from the WeaponSets
+        for (std::map<unsigned int, WeaponSet *>::iterator it = this->weaponSets_.begin(); it != this->weaponSets_.end(); ++it)
+            it->second->removeWeaponmodeLink(wPack);
+
+        // Remove the WeaponPack from the WeaponSystem
+        std::vector<WeaponPack*>::iterator it = std::find(this->weaponPacks_.begin(),this->weaponPacks_.end(), wPack);
+        assert(it !=this->weaponPacks_.end());
+        this->weaponPacks_.erase(it);
+    }
+
+    WeaponPack * WeaponSystem::getWeaponPack(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::vector<WeaponPack*>::const_iterator it = this->weaponPacks_.begin(); it != this->weaponPacks_.end(); ++it)
+        {
+            ++i;
+            if (i > index)
+                return (*it);
+        }
+        return 0;
+    }
+
+    bool WeaponSystem::swapWeaponSlots(WeaponSlot * wSlot1, WeaponSlot * wSlot2)
+    {
+        if (!wSlot1 || !wSlot2)
+            return false;
+
+        Weapon* weapon1 = wSlot1->getWeapon();
+        Weapon* weapon2 = wSlot2->getWeapon();
+
+        wSlot1->attachWeapon(weapon2);
+        wSlot2->attachWeapon(weapon1);
+
+        return true;
+        // In the future, certain weapons might not fit to some slots. Swapping would then be
+        // impossible and the returnvalue would be false.
+    }
+
+    void WeaponSystem::changeWeaponmode(WeaponPack * wPack, WeaponSet * wSet, unsigned int weaponmode)
+    {
+        if (!wPack || !wSet)
+            return;
+
+        // Check if the WeaponPack belongs to this WeaponSystem
+        std::vector<WeaponPack *>::iterator it1 = std::find( this->weaponPacks_.begin(), this->weaponPacks_.end(), wPack );
+        if (it1 == this->weaponPacks_.end())
+            return;
+
+        // Check if the WeaponSet belongs to this WeaponSystem
+        bool foundWeaponSet = false;
+        for (std::map<unsigned int, WeaponSet *>::iterator it2 = this->weaponSets_.begin(); it2 != this->weaponSets_.end(); ++it2)
+        {
+            if (it2->second == wSet)
+            {
+                foundWeaponSet = true;
+                break;
+            }
+        }
+        if (!foundWeaponSet)
+            return;
+
+        // Finally set the link between firemode and weaponmode
+        wSet->setWeaponmodeLink(wPack, weaponmode);
+    }
+
+    void WeaponSystem::fire(unsigned int firemode)
+    {
+        std::map<unsigned int, WeaponSet *>::iterator it = this->weaponSets_.find(firemode);
+        if (it != this->weaponSets_.end() && it->second)
+            it->second->fire();
+    }
+
+    void WeaponSystem::reload()
+    {
+        for (std::map<unsigned int, WeaponSet *>::iterator it = this->weaponSets_.begin(); it != this->weaponSets_.end(); ++it)
+            it->second->reload();
+    }
+
+    Munition * WeaponSystem::getMunition(SubclassIdentifier<Munition> * identifier)
+    {
+        if (!identifier || !identifier->getIdentifier())
+            return 0;
+
+        std::map<Identifier *, Munition *>::iterator it = this->munitions_.find(identifier->getIdentifier());
+        if (it != this->munitions_.end())
+        {
+            return it->second;
+        }
+        else if (identifier->getIdentifier()->isA(Class(Munition)))
+        {
+            Munition* munition = identifier->fabricate(this);
+            this->munitions_[identifier->getIdentifier()] = munition;
+            return munition;
+        }
+        else
+        {
+            return 0;
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSystem.h
===================================================================
--- /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSystem.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/weaponsystem/WeaponSystem.h	(revision 6952)
@@ -0,0 +1,100 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Martin Polak
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#ifndef _WeaponSystem_H__
+#define _WeaponSystem_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <map>
+#include <set>
+#include <vector>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport WeaponSystem : public BaseObject
+    {
+        public:
+            WeaponSystem(BaseObject* creator);
+            virtual ~WeaponSystem();
+
+            // adding and removing WeaponSlots
+            void addWeaponSlot(WeaponSlot * wSlot);
+            void removeWeaponSlot(WeaponSlot * wSlot);
+            WeaponSlot * getWeaponSlot(unsigned int index) const;
+
+            // adding and removing WeaponSets
+            bool addWeaponSet(WeaponSet * wSet);
+            bool addWeaponSet(WeaponSet * wSet, unsigned int firemode);
+            void removeWeaponSet(WeaponSet * wSet);
+            WeaponSet * getWeaponSet(unsigned int index) const;
+
+            // adding and removing WeaponPacks
+            bool canAddWeaponPack(WeaponPack * wPack);
+            bool addWeaponPack(WeaponPack * wPack);
+            void removeWeaponPack(WeaponPack * wPack);
+            WeaponPack * getWeaponPack(unsigned int index) const;
+
+            // configure slots and firemodes
+            bool swapWeaponSlots(WeaponSlot * wSlot1, WeaponSlot * wSlot2);
+            void changeWeaponmode(WeaponPack * wPack, WeaponSet * wSet, unsigned int weaponmode);
+
+            void fire(unsigned int firemode);
+            void reload();
+
+            Munition * getMunition(SubclassIdentifier<Munition> * identifier);
+
+            inline void setPawn(Pawn * pawn)
+                { this->pawn_ = pawn; }
+            inline Pawn * getPawn() const
+                { return this->pawn_; }
+
+            inline int getWeaponSlotSize() const
+                { return this->weaponSlots_.size(); }
+
+            static inline unsigned int getFiremodeMask(unsigned int firemode)
+                { return (0x1 << firemode); }
+
+            static const unsigned int MAX_FIRE_MODES = 8;
+            static const unsigned int FIRE_MODE_UNASSIGNED = static_cast<unsigned int>(-1);
+
+            static const unsigned int MAX_WEAPON_MODES = 8;
+            static const unsigned int WEAPON_MODE_UNASSIGNED = static_cast<unsigned int>(-1);
+
+        private:
+            std::map<unsigned int, WeaponSet *> weaponSets_;
+            std::vector<WeaponSlot *> weaponSlots_;
+            std::vector<WeaponPack *> weaponPacks_;
+            std::map<Identifier *, Munition *> munitions_;
+            Pawn * pawn_;
+    };
+}
+
+#endif /* _WeaponSystem_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/BigExplosion.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/BigExplosion.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/BigExplosion.cc	(revision 6952)
@@ -0,0 +1,373 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin de Capitani
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "BigExplosion.h"
+
+//#include <sstream>
+
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "core/CommandExecutor.h"
+#include "core/Executor.h"
+#include "core/GameMode.h"
+#include "tools/ParticleInterface.h"
+#include "Scene.h"
+#include "graphics/ParticleSpawner.h"
+#include "graphics/Model.h"
+
+namespace orxonox
+{
+    CreateFactory(BigExplosion);
+
+    BigExplosion::BigExplosion(BaseObject* creator) : MovableEntity(creator)
+    {
+        RegisterObject(BigExplosion);
+
+        if ( GameMode::showsGraphics() && ( !this->getScene() || !this->getScene()->getSceneManager() ) )
+            ThrowException(AbortLoading, "Can't create BigExplosion, no scene or no scene manager given.");
+/*
+        this->cps_ = 1;
+        this->firstTick_ = true;
+*/
+        this->bStop_ = false;
+        this->LOD_ = LODParticle::Normal;
+
+/*      this->stf_ = "setTimeFactor ";
+        this->timeFactor_ =  1;
+        std::ostringstream o;
+        o << stf_ << this->timeFactor_;
+        CommandExecutor::execute(o.str() ,false);
+        this->timeFactor_ = 0.1;
+*/
+
+        if ( GameMode::showsGraphics() )
+        {
+            try
+            {
+                this->init();
+            }
+            catch (...)
+            {
+                COUT(1) << "Error: Couln't load particle effect in BigExplosion: " << Exception::handleMessage() << std::endl;
+                this->initZero();
+            }
+        }
+        else
+        {
+            this->initZero();
+        }
+
+        if (GameMode::isMaster())
+        {
+            Vector3 velocity(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1));
+            velocity.normalise();
+            velocity *= rnd(20, 30);
+            this->setVelocity(velocity);
+
+            this->destroyTimer_.setTimer(rnd(2, 4), false, createExecutor(createFunctor(&BigExplosion::stop, this)));
+        }
+        this->registerVariables();
+    }
+
+    void BigExplosion::init()
+    {
+        this->debrisEntity1_ = new MovableEntity(this);
+        this->debrisEntity2_ = new MovableEntity(this);
+        this->debrisEntity3_ = new MovableEntity(this);
+        this->debrisEntity4_ = new MovableEntity(this);
+
+        this->debris1_ = new Model(this);
+        this->debris2_ = new Model(this);
+        this->debris3_ = new Model(this);
+        this->debris4_ = new Model(this);
+
+        this->explosion_ = new StaticEntity(this);
+
+        this->debrisSmoke1_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/smoke7", this->LOD_);
+        this->debrisSmoke2_ =  new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/smoke7", this->LOD_);
+        this->debrisSmoke3_ =  new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/smoke7", this->LOD_);
+        this->debrisSmoke4_ =  new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/smoke7", this->LOD_);
+
+        this->debrisFire1_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/fire4", this->LOD_);
+        this->debrisFire2_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/fire4", this->LOD_);
+        this->debrisFire3_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/fire4", this->LOD_);
+        this->debrisFire4_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/fire4", this->LOD_);
+
+        this->debris1_->attachOgreObject(this->debrisSmoke1_->getParticleSystem());
+        this->debris1_->attachOgreObject(this->debrisFire1_->getParticleSystem());
+        this->debris2_->attachOgreObject(this->debrisSmoke2_->getParticleSystem());
+        this->debris2_->attachOgreObject(this->debrisFire2_->getParticleSystem());
+        this->debris3_->attachOgreObject(this->debrisSmoke3_->getParticleSystem());
+        this->debris3_->attachOgreObject(this->debrisFire3_->getParticleSystem());
+        this->debris4_->attachOgreObject(this->debrisSmoke4_->getParticleSystem());
+        this->debris4_->attachOgreObject(this->debrisFire4_->getParticleSystem());
+
+        this->debris1_->setMeshSource("CockpitDebris.mesh");
+        this->debris2_->setMeshSource("WingDebris1.mesh");
+        this->debris3_->setMeshSource("BodyDebris1.mesh");
+        this->debris4_->setMeshSource("WingDebris2.mesh");
+
+        this->debrisEntity1_->setVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1))*rnd(50,100));
+        this->debrisEntity1_->setAngularVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1)).normalisedCopy() * Degree(400).valueRadians());
+        this->debrisEntity1_->setScale(4);
+
+        this->debrisEntity2_->setVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1))*rnd(50,100));
+        this->debrisEntity2_->setAngularVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1)).normalisedCopy() * Degree(400).valueRadians());
+        this->debrisEntity2_->setScale(4);
+
+        this->debrisEntity3_->setVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1))*rnd(50,100));
+        this->debrisEntity3_->setAngularVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1)).normalisedCopy() * Degree(400).valueRadians());
+        this->debrisEntity3_->setScale(4);
+
+        this->debrisEntity4_->setVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1))*rnd(50,100));
+        this->debrisEntity4_->setAngularVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1)).normalisedCopy() * Degree(400).valueRadians());
+        this->debrisEntity4_->setScale(4);
+
+        this->debrisEntity1_->attach(debris1_);
+        this->debrisEntity2_->attach(debris2_);
+        this->debrisEntity3_->attach(debris3_);
+        this->debrisEntity4_->attach(debris4_);
+
+        ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
+        effect->setDestroyAfterLife(true);
+        effect->setSource("Orxonox/explosion2b");
+        effect->setLifetime(4.0f);
+
+        ParticleSpawner* effect2 = new ParticleSpawner(this->getCreator());
+        effect2->setDestroyAfterLife(true);
+        effect2->setSource("Orxonox/smoke6");
+        effect2->setLifetime(4.0f);
+
+        this->explosion_->attach(effect);
+        this->explosion_->attach(effect2);
+
+        this->attach(explosion_);
+        this->attach(debrisEntity1_);
+        this->attach(debrisEntity2_);
+        this->attach(debrisEntity3_);
+        this->attach(debrisEntity4_);
+
+
+        for(int i=0;i<10;i++)
+        {
+            Model* part1 = new Model(this);
+            Model* part2 = new Model(this);
+
+            MovableEntity* partEntity1 = new MovableEntity(this);
+            MovableEntity* partEntity2 = new MovableEntity(this);
+
+            partEntity1->setVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1))*rnd(10,100));
+            partEntity1->setAngularVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1)).normalisedCopy() * Degree(400).valueRadians());
+            partEntity1->setScale(rnd(1, 3));
+
+            partEntity2->setVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1))*rnd(10, 100));
+            partEntity2->setAngularVelocity(Vector3(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1)).normalisedCopy() * Degree(400).valueRadians());
+            partEntity2->setScale(rnd(1, 3));
+
+            part1->setMeshSource("SmallPart1.mesh");
+            part2->setMeshSource("SmallPart2.mesh");
+
+            partEntity1->attach(part1);
+            partEntity2->attach(part2);
+
+            this->attach(partEntity1);
+            this->attach(partEntity2);
+        }
+    }
+
+    void BigExplosion::initZero()
+    {
+        this->debrisFire1_ = 0;
+        this->debrisFire2_ = 0;
+        this->debrisFire3_ = 0;
+        this->debrisFire4_ = 0;
+
+        this->debrisSmoke1_ = 0;
+        this->debrisSmoke2_ = 0;
+        this->debrisSmoke3_ = 0;
+        this->debrisSmoke4_ = 0;
+
+        this->explosionSmoke_=0;
+        this->explosionFire_=0;
+    }
+
+    BigExplosion::~BigExplosion()
+    {
+        CommandExecutor::execute("setTimeFactor 1", false);
+
+        if (this->isInitialized())
+        {
+            if (this->debrisFire1_)
+            {
+                this->debris1_->detachOgreObject(this->debrisFire1_->getParticleSystem());
+                this->debrisFire1_->destroy();
+            }
+            if (this->debrisSmoke1_)
+            {
+                this->debris1_->detachOgreObject(this->debrisSmoke1_->getParticleSystem());
+                this->debrisSmoke1_->destroy();
+            }
+
+            if (this->debrisFire2_)
+            {
+                this->debris2_->detachOgreObject(this->debrisFire2_->getParticleSystem());
+                this->debrisFire2_->destroy();
+            }
+            if (this->debrisSmoke2_)
+            {
+                this->debris2_->detachOgreObject(this->debrisSmoke2_->getParticleSystem());
+                this->debrisSmoke2_->destroy();
+            }
+
+            if (this->debrisFire3_)
+            {
+                this->debris3_->detachOgreObject(this->debrisFire3_->getParticleSystem());
+                this->debrisFire3_->destroy();
+            }
+            if (this->debrisSmoke3_)
+            {
+                this->debris3_->detachOgreObject(this->debrisSmoke3_->getParticleSystem());
+                this->debrisSmoke3_->destroy();
+            }
+
+            if (this->debrisFire4_)
+            {
+                this->debris4_->detachOgreObject(this->debrisFire4_->getParticleSystem());
+                this->debrisFire4_->destroy();
+            }
+            if (this->debrisSmoke4_)
+            {
+                this->debris4_->detachOgreObject(this->debrisSmoke4_->getParticleSystem());
+                this->debrisSmoke4_->destroy();
+            }
+        }
+    }
+
+    void BigExplosion::registerVariables()
+    {
+        registerVariable((int&)(this->LOD_), VariableDirection::ToClient, new NetworkCallback<BigExplosion>(this, &BigExplosion::LODchanged));
+        registerVariable(this->bStop_,       VariableDirection::ToClient, new NetworkCallback<BigExplosion>(this, &BigExplosion::checkStop));
+    }
+
+    void BigExplosion::LODchanged()
+    {
+        if (this->debrisFire1_)
+            this->debrisFire1_->setDetailLevel(this->LOD_);
+        if (this->debrisSmoke1_)
+            this->debrisSmoke1_->setDetailLevel(this->LOD_);
+
+        if (this->debrisFire2_)
+            this->debrisFire2_->setDetailLevel(this->LOD_);
+        if (this->debrisSmoke2_)
+            this->debrisSmoke2_->setDetailLevel(this->LOD_);
+
+        if (this->debrisFire3_)
+            this->debrisFire3_->setDetailLevel(this->LOD_);
+        if (this->debrisSmoke3_)
+            this->debrisSmoke3_->setDetailLevel(this->LOD_);
+
+        if (this->debrisFire4_)
+            this->debrisFire4_->setDetailLevel(this->LOD_);
+        if (this->debrisSmoke4_)
+            this->debrisSmoke4_->setDetailLevel(this->LOD_);
+    }
+
+    void BigExplosion::checkStop()
+    {
+        if (this->bStop_)
+            this->stop();
+    }
+
+    void BigExplosion::stop()
+    {
+        if (this->debrisFire1_)
+            this->debrisFire1_->setEnabled(false);
+        if (this->debrisSmoke1_)
+            this->debrisSmoke1_->setEnabled(false);
+
+        if (this->debrisFire2_)
+            this->debrisFire2_->setEnabled(false);
+        if (this->debrisSmoke2_)
+            this->debrisSmoke2_->setEnabled(false);
+
+        if (this->debrisFire3_)
+            this->debrisFire3_->setEnabled(false);
+        if (this->debrisSmoke3_)
+            this->debrisSmoke3_->setEnabled(false);
+
+        if (this->debrisFire4_)
+            this->debrisFire4_->setEnabled(false);
+        if (this->debrisSmoke4_)
+            this->debrisSmoke4_->setEnabled(false);
+
+        if (GameMode::isMaster())
+        {
+            this->bStop_ = true;
+            this->destroyTimer_.setTimer(1.0f, false, createExecutor(createFunctor(&BigExplosion::destroy, this)));
+        }
+    }
+
+/* TODO
+
+    void BigExplosion::setDebrisMeshes()
+    {
+
+    }
+    void BigExplosion::getDebrisMeshes()
+    {
+
+    }
+*/
+
+     void BigExplosion::tick(float dt)
+    {
+//        static const unsigned int CHANGES_PER_SECOND = 10;
+
+
+/*        if (GameMode::isMaster() && rnd() < dt*(this->cps_))
+        {
+
+            if(this->timeFactor_ < 1 )
+                this->timeFactor_ += 0.05;
+
+            if(this->firstTick_)
+                this->cps_ = 256;
+
+            std::ostringstream o;
+            o << this->stf_ << this->timeFactor_;
+            CommandExecutor::execute(o.str() ,false);
+            if(this->cps_>50)
+                this->cps_/=2;
+            this->firstTick_ = false;
+            COUT(0) << timeFactor_ << std::endl;
+        }
+*/
+
+        SUPER(BigExplosion, tick, dt);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/BigExplosion.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/BigExplosion.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/BigExplosion.h	(revision 6952)
@@ -0,0 +1,104 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Benjamin de Capitani
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _BigExplosion_H__
+#define _BigExplosion_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "tools/Timer.h"
+#include "MovableEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport BigExplosion : public MovableEntity
+    {
+        public:
+            BigExplosion(BaseObject* creator);
+            virtual ~BigExplosion();
+
+            virtual void tick(float dt);
+            void registerVariables();
+
+            inline void setLOD(LODParticle::Value level)
+                { this->LOD_ = level; this->LODchanged(); }
+            inline LODParticle::Value getLOD() const
+                { return this->LOD_; }
+
+        private:
+
+            void LODchanged();
+            void checkStop();
+            void stop();
+            void init();
+            void initZero();
+
+
+            bool                  bStop_;
+            bool                  firstTick_;
+
+            std::string           stf_;
+
+            unsigned int          cps_;
+
+            double                timeFactor_;
+
+            StaticEntity*         explosion_;
+
+            MovableEntity*        debrisEntity1_;
+            MovableEntity*        debrisEntity2_;
+            MovableEntity*        debrisEntity3_;
+            MovableEntity*        debrisEntity4_;
+
+            Model*                debris1_;
+            Model*                debris2_;
+            Model*                debris3_;
+            Model*                debris4_;
+
+
+
+            ParticleInterface*    debrisSmoke1_;
+            ParticleInterface*    debrisSmoke2_;
+            ParticleInterface*    debrisSmoke3_;
+            ParticleInterface*    debrisSmoke4_;
+
+            ParticleInterface*    debrisFire1_;
+            ParticleInterface*    debrisFire2_;
+            ParticleInterface*    debrisFire3_;
+            ParticleInterface*    debrisFire4_;
+
+            ParticleInterface*    explosionSmoke_;
+            ParticleInterface*    explosionFire_;
+
+            LODParticle::Value    LOD_;
+            Timer                 destroyTimer_;
+    };
+}
+
+#endif /* _BigExplosion_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,17 @@
+ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+  WorldEntity.cc
+  StaticEntity.cc
+  MovableEntity.cc
+  MobileEntity.cc
+  ControllableEntity.cc
+
+  BigExplosion.cc
+  EffectContainer.cc
+  ExplosionChunk.cc
+  CameraPosition.cc
+  SpawnPoint.cc
+  TeamSpawnPoint.cc
+  Drone.cc
+)
+
+ADD_SUBDIRECTORY(pawns)
Index: /code/branches/rocket2/src/orxonox/worldentities/CameraPosition.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/CameraPosition.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/CameraPosition.cc	(revision 6952)
@@ -0,0 +1,80 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "CameraPosition.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "graphics/Camera.h"
+
+namespace orxonox
+{
+    CreateFactory(CameraPosition);
+
+    CameraPosition::CameraPosition(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(CameraPosition);
+
+        this->bDrag_ = false;
+        this->bAllowMouseLook_ = false;
+        this->bAbsolute_ = false;
+        this->bRenderCamera_ = false;
+
+        this->setSyncMode(0x0);
+    }
+
+    CameraPosition::~CameraPosition()
+    {
+    }
+
+    void CameraPosition::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(CameraPosition, XMLPort, xmlelement, mode);
+
+        XMLPortParam(CameraPosition, "drag", setDrag, getDrag, xmlelement, mode).defaultValues(false);
+        XMLPortParam(CameraPosition, "mouselook", setAllowMouseLook, getAllowMouseLook, xmlelement, mode).defaultValues(false);
+        XMLPortParam(CameraPosition, "absolute", setIsAbsolute, getIsAbsolute, xmlelement, mode).defaultValues(false);
+        XMLPortParam(CameraPosition, "rendercamera", setRenderCamera, getRenderCamera, xmlelement, mode).defaultValues(false);
+    }
+
+    void CameraPosition::attachCamera(Camera* camera)
+    {
+        if (!this->bDrag_)
+            camera->setDrag(false);
+
+        this->attach(camera);
+
+        if (this->bDrag_)
+            camera->setDrag(true);
+    }
+
+    void CameraPosition::attachCamera(Ogre::Camera* camera)
+    {
+        this->attachOgreObject(camera);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/CameraPosition.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/CameraPosition.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/CameraPosition.h	(revision 6952)
@@ -0,0 +1,76 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _CameraPosition_H__
+#define _CameraPosition_H__
+
+#include "OrxonoxPrereqs.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport CameraPosition : public StaticEntity
+    {
+        public:
+            CameraPosition(BaseObject* creator);
+            virtual ~CameraPosition();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            inline void setDrag(bool bDrag)
+                { this->bDrag_ = bDrag; }
+            inline bool getDrag() const
+                { return this->bDrag_; }
+
+            inline void setAllowMouseLook(bool bAllow)
+                { this->bAllowMouseLook_ = bAllow; }
+            inline bool getAllowMouseLook() const
+                { return this->bAllowMouseLook_; }
+
+            inline void setIsAbsolute(bool bAbsolute)
+                { this->bAbsolute_ = bAbsolute; }
+            inline bool getIsAbsolute() const
+                { return this->bAbsolute_; }
+
+            inline void setRenderCamera(bool bRenderCamera)
+                { this->bRenderCamera_ = bRenderCamera; }
+            inline bool getRenderCamera() const
+                { return this->bRenderCamera_; }
+
+            void attachCamera(Camera* camera);
+            void attachCamera(Ogre::Camera* camera);
+
+        private:
+            bool bDrag_;
+            bool bAllowMouseLook_;
+            bool bAbsolute_;
+            bool bRenderCamera_;
+    };
+}
+
+#endif /* _CameraPosition_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/ControllableEntity.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/ControllableEntity.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/ControllableEntity.cc	(revision 6952)
@@ -0,0 +1,601 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#include "ControllableEntity.h"
+
+#include <OgreSceneManager.h>
+#include <OgreSceneNode.h>
+
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+#include "network/NetworkFunction.h"
+
+#include "Scene.h"
+#include "infos/PlayerInfo.h"
+#include "controllers/Controller.h"
+#include "graphics/Camera.h"
+#include "worldentities/CameraPosition.h"
+#include "overlays/OverlayGroup.h"
+
+namespace orxonox
+{
+    CreateFactory(ControllableEntity);
+
+    registerMemberNetworkFunction( ControllableEntity, fire );
+    registerMemberNetworkFunction( ControllableEntity, setTargetInternal );
+
+    ControllableEntity::ControllableEntity(BaseObject* creator) : MobileEntity(creator)
+    {
+        RegisterObject(ControllableEntity);
+
+        this->bHasLocalController_ = false;
+        this->bHasHumanController_ = false;
+
+        this->server_overwrite_ = 0;
+        this->client_overwrite_ = 0;
+        this->player_ = 0;
+        this->playerID_ = OBJECTID_UNKNOWN;
+        this->hud_ = 0;
+        this->camera_ = 0;
+        this->xmlcontroller_ = 0;
+        this->controller_ = 0;
+        this->reverseCamera_ = 0;
+        this->bDestroyWhenPlayerLeft_ = false;
+        this->cameraPositionRootNode_ = this->node_->createChildSceneNode();
+        this->currentCameraPosition_ = 0;
+        this->bMouseLook_ = false;
+        this->mouseLookSpeed_ = 200;
+
+        this->server_position_         = Vector3::ZERO;
+        this->client_position_         = Vector3::ZERO;
+        this->server_linear_velocity_  = Vector3::ZERO;
+        this->client_linear_velocity_  = Vector3::ZERO;
+        this->server_orientation_      = Quaternion::IDENTITY;
+        this->client_orientation_      = Quaternion::IDENTITY;
+        this->server_angular_velocity_ = Vector3::ZERO;
+        this->client_angular_velocity_ = Vector3::ZERO;
+
+
+        this->setConfigValues();
+        this->setPriority( Priority::VeryHigh );
+        this->registerVariables();
+    }
+
+    ControllableEntity::~ControllableEntity()
+    {
+        if (this->isInitialized())
+        {
+            this->bDestroyWhenPlayerLeft_ = false;
+
+            if (this->bHasLocalController_ && this->bHasHumanController_)
+                this->stopLocalHumanControl();
+
+            if (this->getPlayer() && this->getPlayer()->getControllableEntity() == this)
+                this->getPlayer()->stopControl();
+
+            if (this->xmlcontroller_)
+                this->xmlcontroller_->destroy();
+
+            if (this->hud_)
+                this->hud_->destroy();
+
+            if (this->camera_)
+                this->camera_->destroy();
+
+            for (std::list<SmartPtr<CameraPosition> >::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
+                (*it)->destroy();
+
+            if (this->getScene()->getSceneManager())
+                this->getScene()->getSceneManager()->destroySceneNode(this->cameraPositionRootNode_->getName());
+        }
+    }
+
+    void ControllableEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(ControllableEntity, XMLPort, xmlelement, mode);
+
+        XMLPortParam(ControllableEntity, "hudtemplate", setHudTemplate, getHudTemplate, xmlelement, mode);
+        XMLPortParam(ControllableEntity, "camerapositiontemplate", setCameraPositionTemplate, getCameraPositionTemkplate, xmlelement, mode);
+
+        XMLPortObject(ControllableEntity, CameraPosition, "camerapositions", addCameraPosition, getCameraPosition, xmlelement, mode);
+        XMLPortObject(ControllableEntity, Controller,     "controller",      setXMLController,  getXMLController,  xmlelement, mode);
+    }
+
+    void ControllableEntity::setConfigValues()
+    {
+        SetConfigValue(mouseLookSpeed_, 3.0f);
+    }
+
+    void ControllableEntity::addCameraPosition(CameraPosition* position)
+    {
+        if (!position->getIsAbsolute())
+        {
+            if (position->getAllowMouseLook())
+                position->attachToNode(this->cameraPositionRootNode_);
+            else
+                this->attach(position);
+        }
+        else
+        {
+            WorldEntity* parent = this->getParent();
+            if (parent)
+                parent->attach(position);
+        }
+
+        if (!position->getRenderCamera())
+            this->cameraPositions_.push_back(position);
+        else
+            this->setReverseCamera(position);
+    }
+
+    CameraPosition* ControllableEntity::getCameraPosition(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::list<SmartPtr<CameraPosition> >::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+            ++i;
+        }
+        return 0;
+    }
+
+    void ControllableEntity::switchCamera()
+    {
+        if (this->camera_)
+        {
+            if (this->camera_->getParent() == this && this->cameraPositions_.size() > 0)
+            {
+                this->cameraPositions_.front()->attachCamera(this->camera_);
+                this->currentCameraPosition_ = this->cameraPositions_.front().get();
+            }
+            else if (this->cameraPositions_.size() > 0)
+            {
+                for (std::list<SmartPtr<CameraPosition> >::const_iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
+                {
+                    if ((*it) == this->camera_->getParent())
+                    {
+                        ++it;
+                        if (it != this->cameraPositions_.end())
+                        {
+                            (*it)->attachCamera(this->camera_);
+                            this->currentCameraPosition_ = *it;
+                        }
+                        else
+                        {
+                            (*this->cameraPositions_.begin())->attachCamera(this->camera_);
+                            this->currentCameraPosition_ = *this->cameraPositions_.begin();
+                        }
+                        break;
+                    }
+                }
+            }
+            else
+            {
+                this->camera_->attachToNode(this->cameraPositionRootNode_);
+                this->currentCameraPosition_ = 0;
+            }
+        }
+    }
+
+    void ControllableEntity::mouseLook()
+    {
+        this->bMouseLook_ = !this->bMouseLook_;
+
+        if (!this->bMouseLook_)
+            this->cameraPositionRootNode_->setOrientation(Quaternion::IDENTITY);
+        if (this->getCamera())
+        {
+            if (!this->bMouseLook_&& this->currentCameraPosition_->getDrag())
+                this->getCamera()->setDrag(true);
+            else
+                this->getCamera()->setDrag(false);
+        }
+    }
+
+    void ControllableEntity::rotateYaw(const Vector2& value)
+    {
+        if (this->bMouseLook_)
+            this->cameraPositionRootNode_->yaw(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
+    }
+
+    void ControllableEntity::rotatePitch(const Vector2& value)
+    {
+        if (this->bMouseLook_)
+            this->cameraPositionRootNode_->pitch(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
+    }
+
+    void ControllableEntity::rotateRoll(const Vector2& value)
+    {
+        if (this->bMouseLook_)
+            this->cameraPositionRootNode_->roll(Radian(value.y * this->mouseLookSpeed_), Ogre::Node::TS_LOCAL);
+    }
+
+    void ControllableEntity::fire(unsigned int firemode)
+    {
+        if(GameMode::isMaster())
+        {
+            this->fired(firemode);
+        }
+        else
+        {
+            callMemberNetworkFunction(ControllableEntity, fire, this->getObjectID(), 0, firemode);
+        }
+    }
+
+    void ControllableEntity::setTarget( WorldEntity* target )
+    {
+        this->target_ = target;
+        if ( !GameMode::isMaster() )
+        {
+            if ( target != 0 )
+            {
+                callMemberNetworkFunction(ControllableEntity, setTargetInternal, this->getObjectID(), 0, target->getObjectID() );
+            }
+           else
+           {
+                callMemberNetworkFunction(ControllableEntity, setTargetInternal, this->getObjectID(), 0, OBJECTID_UNKNOWN );
+           }
+        }
+    }
+
+    void ControllableEntity::setTargetInternal( uint32_t targetID )
+    {
+        this->setTarget( orxonox_cast<WorldEntity*>(Synchronisable::getSynchronisable(targetID)) );
+    }
+
+    void ControllableEntity::setPlayer(PlayerInfo* player)
+    {
+        if (!player)
+        {
+            this->removePlayer();
+            return;
+        }
+
+        this->player_ = player;
+        this->playerID_ = player->getObjectID();
+        this->bHasLocalController_ = player->isLocalPlayer();
+        this->bHasHumanController_ = player->isHumanPlayer();
+
+        if (this->bHasLocalController_ && this->bHasHumanController_)
+        {
+            this->startLocalHumanControl();
+
+            if (!GameMode::isMaster())
+            {
+                this->client_overwrite_ = this->server_overwrite_;
+                this->setSyncMode(ObjectDirection::Bidirectional);
+            }
+        }
+
+        this->changedPlayer();
+    }
+
+    void ControllableEntity::removePlayer()
+    {
+        if (this->bHasLocalController_ && this->bHasHumanController_)
+            this->stopLocalHumanControl();
+
+        this->player_ = 0;
+        this->playerID_ = OBJECTID_UNKNOWN;
+        this->bHasLocalController_ = false;
+        this->bHasHumanController_ = false;
+        this->setSyncMode(ObjectDirection::ToClient);
+
+        this->changedPlayer();
+
+        if (this->bDestroyWhenPlayerLeft_)
+            this->destroy();
+    }
+
+    void ControllableEntity::networkcallback_changedplayerID()
+    {
+        // just do this in case the entity wasn't yet synchronized when the corresponding PlayerInfo got our objectID
+        if (this->playerID_ != OBJECTID_UNKNOWN)
+        {
+            this->player_ = orxonox_cast<PlayerInfo*>(Synchronisable::getSynchronisable(this->playerID_));
+            if (this->player_ && (this->player_->getControllableEntity() != this))
+                this->player_->startControl(this);
+        }
+    }
+
+    void ControllableEntity::startLocalHumanControl()
+    {
+        if (!this->camera_ && GameMode::showsGraphics())
+        {
+            this->camera_ = new Camera(this);
+            this->camera_->requestFocus();
+            if (!this->cameraPositionTemplate_.empty())
+                this->addTemplate(this->cameraPositionTemplate_);
+            if (this->cameraPositions_.size() > 0)
+            {
+                this->cameraPositions_.front()->attachCamera(this->camera_);
+                this->currentCameraPosition_ = this->cameraPositions_.front();
+            }
+            else
+            {
+                this->camera_->attachToNode(this->cameraPositionRootNode_);
+                this->currentCameraPosition_ = 0;
+            }
+        }
+
+        if (!this->hud_ && GameMode::showsGraphics())
+        {
+            if (!this->hudtemplate_.empty())
+            {
+                this->hud_ = new OverlayGroup(this);
+                this->hud_->addTemplate(this->hudtemplate_);
+                this->hud_->setOwner(this);
+            }
+        }
+    }
+
+    void ControllableEntity::stopLocalHumanControl()
+    {
+        if (this->camera_)
+        {
+            this->camera_->detachFromParent();
+            this->camera_->destroy();
+            this->camera_ = 0;
+        }
+
+        if (this->hud_)
+        {
+            this->hud_->destroy();
+            this->hud_ = 0;
+        }
+    }
+
+    void ControllableEntity::setXMLController(Controller* controller)
+    {
+        if (!this->xmlcontroller_)
+        {
+            this->xmlcontroller_ = controller;
+            this->bHasLocalController_ = true;
+            this->xmlcontroller_->setControllableEntity(this);
+        }
+        else
+            COUT(2) << "Warning: ControllableEntity \"" << this->getName() << "\" already has a Controller." << std::endl;
+    }
+
+    void ControllableEntity::parentChanged()
+    {
+        WorldEntity::parentChanged();
+
+        WorldEntity* parent = this->getParent();
+        if (parent)
+        {
+            for (std::list<SmartPtr<CameraPosition> >::iterator it = this->cameraPositions_.begin(); it != this->cameraPositions_.end(); ++it)
+                if ((*it)->getIsAbsolute())
+                    parent->attach((*it));
+        }
+    }
+
+    void ControllableEntity::tick(float dt)
+    {
+        MobileEntity::tick(dt);
+
+        if (this->isActive())
+        {
+            // Check whether Bullet doesn't do the physics for us
+            if (!this->isDynamic())
+            {
+                if (GameMode::isMaster())
+                {
+                    this->server_position_ = this->getPosition();
+                    this->server_orientation_ = this->getOrientation();
+                    this->server_linear_velocity_ = this->getVelocity();
+                    this->server_angular_velocity_ = this->getAngularVelocity();
+                }
+                else if (this->bHasLocalController_)
+                {
+                    this->client_position_ = this->getPosition();
+                    this->client_orientation_ = this->getOrientation();
+                    this->client_linear_velocity_ = this->getVelocity();
+                    this->client_angular_velocity_ = this->getAngularVelocity();
+                }
+            }
+        }
+    }
+
+    void ControllableEntity::registerVariables()
+    {
+        registerVariable(this->cameraPositionTemplate_,  VariableDirection::ToClient);
+        registerVariable(this->hudtemplate_,             VariableDirection::ToClient);
+
+        registerVariable(this->server_position_,         VariableDirection::ToClient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerPosition));
+        registerVariable(this->server_linear_velocity_,  VariableDirection::ToClient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerLinearVelocity));
+        registerVariable(this->server_orientation_,      VariableDirection::ToClient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerOrientation));
+        registerVariable(this->server_angular_velocity_, VariableDirection::ToClient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processServerAngularVelocity));
+
+        registerVariable(this->server_overwrite_,        VariableDirection::ToClient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processOverwrite));
+        registerVariable(this->client_overwrite_,        VariableDirection::ToServer);
+
+        registerVariable(this->client_position_,         VariableDirection::ToServer, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientPosition));
+        registerVariable(this->client_linear_velocity_,  VariableDirection::ToServer, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientLinearVelocity));
+        registerVariable(this->client_orientation_,      VariableDirection::ToServer, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientOrientation));
+        registerVariable(this->client_angular_velocity_, VariableDirection::ToServer, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::processClientAngularVelocity));
+
+
+        registerVariable(this->playerID_,                VariableDirection::ToClient, new NetworkCallback<ControllableEntity>(this, &ControllableEntity::networkcallback_changedplayerID));
+    }
+
+    void ControllableEntity::processServerPosition()
+    {
+        if (!this->bHasLocalController_)
+            MobileEntity::setPosition(this->server_position_);
+    }
+
+    void ControllableEntity::processServerLinearVelocity()
+    {
+        if (!this->bHasLocalController_)
+            MobileEntity::setVelocity(this->server_linear_velocity_);
+    }
+
+    void ControllableEntity::processServerOrientation()
+    {
+        if (!this->bHasLocalController_)
+            MobileEntity::setOrientation(this->server_orientation_);
+    }
+
+    void ControllableEntity::processServerAngularVelocity()
+    {
+        if (!this->bHasLocalController_)
+            MobileEntity::setAngularVelocity(this->server_angular_velocity_);
+    }
+
+    void ControllableEntity::processOverwrite()
+    {
+        if (this->bHasLocalController_)
+        {
+            this->setPosition(this->server_position_);
+            this->setOrientation(this->server_orientation_);
+            this->setVelocity(this->server_linear_velocity_);
+            this->setAngularVelocity(this->server_angular_velocity_);
+
+            this->client_overwrite_ = this->server_overwrite_;
+        }
+    }
+
+    void ControllableEntity::processClientPosition()
+    {
+        if (this->server_overwrite_ == this->client_overwrite_)
+        {
+            MobileEntity::setPosition(this->client_position_);
+            this->server_position_ = this->getPosition();
+        }
+    }
+
+    void ControllableEntity::processClientLinearVelocity()
+    {
+        if (this->server_overwrite_ == this->client_overwrite_)
+        {
+            MobileEntity::setVelocity(this->client_linear_velocity_);
+            this->server_linear_velocity_ = this->getVelocity();
+        }
+    }
+
+    void ControllableEntity::processClientOrientation()
+    {
+        if (this->server_overwrite_ == this->client_overwrite_)
+        {
+            MobileEntity::setOrientation(this->client_orientation_);
+            this->server_orientation_ = this->getOrientation();
+        }
+    }
+
+    void ControllableEntity::processClientAngularVelocity()
+    {
+        if (this->server_overwrite_ == this->client_overwrite_)
+        {
+            MobileEntity::setAngularVelocity(this->client_angular_velocity_);
+            this->server_angular_velocity_ = this->getAngularVelocity();
+        }
+    }
+
+    void ControllableEntity::setPosition(const Vector3& position)
+    {
+        if (GameMode::isMaster())
+        {
+            MobileEntity::setPosition(position);
+            this->server_position_ = this->getPosition();
+            ++this->server_overwrite_;
+        }
+        else if (this->bHasLocalController_)
+        {
+            MobileEntity::setPosition(position);
+            this->client_position_ = this->getPosition();
+        }
+    }
+
+    void ControllableEntity::setOrientation(const Quaternion& orientation)
+    {
+        if (GameMode::isMaster())
+        {
+            MobileEntity::setOrientation(orientation);
+            this->server_orientation_ = this->getOrientation();
+            ++this->server_overwrite_;
+        }
+        else if (this->bHasLocalController_)
+        {
+            MobileEntity::setOrientation(orientation);
+            this->client_orientation_ = this->getOrientation();
+        }
+    }
+
+    void ControllableEntity::setVelocity(const Vector3& velocity)
+    {
+        if (GameMode::isMaster())
+        {
+            MobileEntity::setVelocity(velocity);
+            this->server_linear_velocity_ = this->getVelocity();
+            ++this->server_overwrite_;
+        }
+        else if (this->bHasLocalController_)
+        {
+            MobileEntity::setVelocity(velocity);
+            this->client_linear_velocity_ = this->getVelocity();
+        }
+    }
+
+    void ControllableEntity::setAngularVelocity(const Vector3& velocity)
+    {
+        if (GameMode::isMaster())
+        {
+            MobileEntity::setAngularVelocity(velocity);
+            this->server_angular_velocity_ = this->getAngularVelocity();
+            ++this->server_overwrite_;
+        }
+        else if (this->bHasLocalController_)
+        {
+            MobileEntity::setAngularVelocity(velocity);
+            this->client_angular_velocity_ = this->getAngularVelocity();
+        }
+    }
+
+    void ControllableEntity::setWorldTransform(const btTransform& worldTrans)
+    {
+        MobileEntity::setWorldTransform(worldTrans);
+        if (GameMode::isMaster())
+        {
+            this->server_position_ = this->getPosition();
+            this->server_orientation_ = this->getOrientation();
+            this->server_linear_velocity_ = this->getVelocity();
+            this->server_angular_velocity_ = this->getAngularVelocity();
+        }
+        else if (this->bHasLocalController_)
+        {
+            this->client_position_ = this->getPosition();
+            this->client_orientation_ = this->getOrientation();
+            this->client_linear_velocity_ = this->getVelocity();
+            this->client_angular_velocity_ = this->getAngularVelocity();
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/ControllableEntity.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/ControllableEntity.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/ControllableEntity.h	(revision 6952)
@@ -0,0 +1,221 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      Reto Grieder
+ *
+ */
+
+#ifndef _ControllableEntity_H__
+#define _ControllableEntity_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <list>
+#include <string>
+#include "util/Math.h"
+#include "MobileEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport ControllableEntity : public MobileEntity
+    {
+        friend class PlayerInfo; // PlayerInfo uses setPlayer and removePlayer
+
+        public:
+            ControllableEntity(BaseObject* creator);
+            virtual ~ControllableEntity();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void tick(float dt);
+            void registerVariables();
+            void setConfigValues();
+
+            virtual void changedPlayer() {}
+
+            inline PlayerInfo* getPlayer() const
+                { return this->player_; }
+
+            inline void setDestroyWhenPlayerLeft(bool bDestroy)
+                { this->bDestroyWhenPlayerLeft_ = bDestroy; }
+            inline bool getDestroyWhenPlayerLeft() const
+                { return this->bDestroyWhenPlayerLeft_; }
+
+            virtual void moveFrontBack(const Vector2& value) {}
+            virtual void moveRightLeft(const Vector2& value) {}
+            virtual void moveUpDown(const Vector2& value) {}
+
+            virtual void rotateYaw(const Vector2& value);
+            virtual void rotatePitch(const Vector2& value);
+            virtual void rotateRoll(const Vector2& value);
+
+            inline void moveFrontBack(float value)
+                { this->moveFrontBack(Vector2(value, 0)); }
+            inline void moveRightLeft(float value)
+                { this->moveRightLeft(Vector2(value, 0)); }
+            inline void moveUpDown(float value)
+                { this->moveUpDown(Vector2(value, 0)); }
+
+            inline void rotateYaw(float value)
+                { this->rotateYaw(Vector2(value, 0)); }
+            inline void rotatePitch(float value)
+                { this->rotatePitch(Vector2(value, 0)); }
+            inline void rotateRoll(float value)
+                { this->rotateRoll(Vector2(value, 0)); }
+
+            void fire(unsigned int firemode);
+            virtual void fired(unsigned int firemode) {}
+            virtual void reload() {}
+
+            virtual void boost() {}
+            virtual void greet() {}
+            virtual void useItem() {}
+            virtual void dropItems() {}
+            virtual void switchCamera();
+            virtual void mouseLook();
+
+            inline const std::string& getHudTemplate() const
+                { return this->hudtemplate_; }
+
+            inline Camera* getCamera() const
+                { return this->camera_; }
+            inline OverlayGroup* getHUD() const
+                { return this->hud_; }
+
+            void addCameraPosition(CameraPosition* position);
+            CameraPosition* getCameraPosition(unsigned int index) const;
+            inline const std::list<SmartPtr<CameraPosition> >& getCameraPositions() const
+                { return this->cameraPositions_; }
+
+            inline void setCameraPositionTemplate(const std::string& name)
+                { this->cameraPositionTemplate_ = name; }
+            inline const std::string& getCameraPositionTemkplate() const
+                { return this->cameraPositionTemplate_; }
+
+            inline void setReverseCamera(CameraPosition* camera)
+                { this->reverseCamera_ = camera; }
+            inline CameraPosition* getReverseCamera() const
+                { return this->reverseCamera_; }
+
+            using WorldEntity::setPosition;
+            using WorldEntity::setOrientation;
+            using MobileEntity::setVelocity;
+            using MobileEntity::setAngularVelocity;
+
+            void setPosition(const Vector3& position);
+            void setOrientation(const Quaternion& orientation);
+            void setVelocity(const Vector3& velocity);
+            void setAngularVelocity(const Vector3& velocity);
+
+            inline bool hasLocalController() const
+                { return this->bHasLocalController_; }
+            inline bool hasHumanController() const
+                { return this->bHasHumanController_; }
+
+            inline bool isInMouseLook() const
+                { return this->bMouseLook_; }
+            inline float getMouseLookSpeed() const
+                { return this->mouseLookSpeed_; }
+
+            inline Controller* getXMLController() const
+                { return this->xmlcontroller_; }
+
+            inline Controller* getController() const
+                { return this->controller_; }
+            inline void setController(Controller* val)
+                { this->controller_ = val; }
+
+            virtual void setTarget( WorldEntity* target );
+            virtual WorldEntity* getTarget()
+                { return this->target_.get(); }
+            void setTargetInternal( uint32_t targetID );
+
+        protected:
+            virtual void setPlayer(PlayerInfo* player); // don't call this directly, use friend class PlayerInfo instead
+            virtual void removePlayer();                // don't call this directly, use friend class PlayerInfo instead
+
+            virtual void startLocalHumanControl();
+            virtual void stopLocalHumanControl();
+            virtual void parentChanged();
+
+            inline void setHudTemplate(const std::string& name)
+                { this->hudtemplate_ = name; }
+
+        private:
+            void setXMLController(Controller* controller);
+
+            void overwrite();
+            void processOverwrite();
+
+            void processServerPosition();
+            void processServerLinearVelocity();
+            void processServerOrientation();
+            void processServerAngularVelocity();
+
+            void processClientPosition();
+            void processClientLinearVelocity();
+            void processClientOrientation();
+            void processClientAngularVelocity();
+
+            void networkcallback_changedplayerID();
+
+            // Bullet btMotionState related
+            void setWorldTransform(const btTransform& worldTrans);
+
+            unsigned int server_overwrite_;
+            unsigned int client_overwrite_;
+
+            bool bHasLocalController_;
+            bool bHasHumanController_;
+            bool bDestroyWhenPlayerLeft_;
+
+            Vector3 server_position_;
+            Vector3 client_position_;
+            Vector3 server_linear_velocity_;
+            Vector3 client_linear_velocity_;
+            Quaternion server_orientation_;
+            Quaternion client_orientation_;
+            Vector3 server_angular_velocity_;
+            Vector3 client_angular_velocity_;
+
+            PlayerInfo* player_;
+            unsigned int playerID_;
+
+            std::string hudtemplate_;
+            OverlayGroup* hud_;
+
+            Camera* camera_;
+            bool bMouseLook_;
+            float mouseLookSpeed_;
+            Ogre::SceneNode* cameraPositionRootNode_;
+            std::list<SmartPtr<CameraPosition> > cameraPositions_;
+            CameraPosition* currentCameraPosition_;
+            std::string cameraPositionTemplate_;
+            Controller* xmlcontroller_;
+            Controller* controller_;
+            CameraPosition* reverseCamera_;
+            WeakPtr<WorldEntity> target_;
+    };
+}
+
+#endif /* _ControllableEntity_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/Drone.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/Drone.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/Drone.cc	(revision 6952)
@@ -0,0 +1,185 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oli Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Drone.h"
+
+#include "core/XMLPort.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+
+namespace orxonox
+{
+	CreateFactory(Drone);
+    // put your code in here:
+    // create the factory for the drone
+
+    /**
+    @brief
+        Constructor. Registers the object and initializes some default values.
+    */
+    Drone::Drone(BaseObject* creator) : ControllableEntity(creator)
+    {
+		RegisterObject(Drone);
+        // put your code in here:
+        // - register the drone class to the core
+        this->myController_ = 0;
+        
+        this->localLinearAcceleration_.setValue(1, 1, 1);
+        this->localAngularAcceleration_.setValue(0, 0, 0);
+        this->primaryThrust_  = 100;
+        this->auxilaryThrust_ = 100;
+        this->rotationThrust_ = 10;
+        
+        this->setCollisionType(WorldEntity::Dynamic);
+        
+        myController_ = new DroneController(static_cast<BaseObject*>(this)); //!< Creates a new controller and passes our this pointer to it as creator.
+    }
+
+    /**
+    @brief
+        Destructor. Destroys controller, if present.
+    */
+    Drone::~Drone()
+    {
+        if( this->isInitialized() && this->myController_ )
+            delete this->myController_;
+    }
+
+    /**
+    @brief
+        Method for creating a Drone through XML.
+    */
+    void Drone::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        // this calls the XMLPort function of the parent class
+        SUPER(Drone, XMLPort, xmlelement, mode);
+
+        // put your code in here:
+        // make sure you add the variables primaryThrust_, auxilaryThrust_ and rotationThrust_ to xmlport 
+        // make sure that the set- and get-functions exist.
+        // variables can be added by the following command 
+        // XMLPortParam(Classname, "xml-attribute-name (i.e. variablename)", setFunction, getFunction, xmlelement, mode)
+		XMLPortParam(Drone, "primaryThrust_", setPrimaryThrust, getPrimaryThrust, xmlelement, mode);
+		XMLPortParam(Drone, "auxilaryThrust_", setAuxilaryThrust, getAuxilaryThrust, xmlelement, mode);
+		XMLPortParam(Drone, "rotationThrust_", setRotationThrust, getRotationThrust, xmlelement, mode);
+ 
+    }
+
+    /**
+    @brief
+        Defines which actions the Drone has to take in each tick.
+    @param dt
+        The length of the tick.
+    */
+    void Drone::tick(float dt)
+    {
+        SUPER(Drone, tick, dt);
+        
+        //if (this->hasLocalController())
+        //{
+            this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() * getMass() * this->auxilaryThrust_);
+            this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() * getMass() * this->auxilaryThrust_);
+            if (this->localLinearAcceleration_.z() > 0)
+              this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() * getMass() * this->auxilaryThrust_);
+            else
+              this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() * getMass() * this->primaryThrust_);
+            this->physicalBody_->applyCentralForce(physicalBody_->getWorldTransform().getBasis() * this->localLinearAcceleration_);
+            this->localLinearAcceleration_.setValue(0, 0, 0);
+        
+            this->localAngularAcceleration_ *= this->getLocalInertia() * this->rotationThrust_;
+            this->physicalBody_->applyTorque(physicalBody_->getWorldTransform().getBasis() * this->localAngularAcceleration_);
+            this->localAngularAcceleration_.setValue(0, 0, 0);
+        //}
+    }
+    
+    /**
+    @brief
+        Moves the Drone in the negative z-direction (Front/Back) by an amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the movement.
+    */
+    void Drone::moveFrontBack(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() - value.x);
+    }
+
+    /**
+    @brief
+        Moves the Drone in the x-direction (Right/Left) by an amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the movement.
+    */
+    void Drone::moveRightLeft(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() + value.x);
+    }
+
+    /**
+    @brief
+        Moves the Drone in the y-direction (Up/Down) by an amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the movement.
+    */
+    void Drone::moveUpDown(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() + value.x);
+    }
+
+    /**
+    @brief
+        Rotates the Drone around the y-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void Drone::rotateYaw(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setY(this->localAngularAcceleration_.y() - value.x);
+    }
+
+    /**
+    @brief
+        Rotates the Drone around the x-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void Drone::rotatePitch(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setX(this->localAngularAcceleration_.x() + value.x);
+    }
+
+    /**
+    @brief
+        Rotates the Drone around the z-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void Drone::rotateRoll(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setZ(this->localAngularAcceleration_.z() + value.x);
+    }
+    
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/Drone.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/Drone.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/Drone.h	(revision 6952)
@@ -0,0 +1,137 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oli Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Drone_H__
+#define _Drone_H__
+
+#include "OrxonoxPrereqs.h"
+#include "worldentities/ControllableEntity.h"
+#include "controllers/DroneController.h"
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        Drone, that is made to move upon a specified pattern.
+        This class was constructed for the PPS tutorial.
+    @author
+        Oli Scheuss
+    */
+    class _OrxonoxExport Drone : public ControllableEntity
+    {
+        public:
+            Drone(BaseObject* creator);
+            virtual ~Drone();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a Drone through XML.
+            virtual void tick(float dt); //!< Defines which actions the Drone has to take in each tick.
+
+            
+            virtual void moveFrontBack(const Vector2& value);
+            virtual void moveRightLeft(const Vector2& value);
+            virtual void moveUpDown(const Vector2& value);
+
+            virtual void rotateYaw(const Vector2& value);
+            virtual void rotatePitch(const Vector2& value);
+            virtual void rotateRoll(const Vector2& value);
+            
+            /**
+            @brief Moves the Drone in the Front/Back-direction by the specifed amount.
+            @param value  The amount by which the drone is to be moved.
+            */
+            inline void moveFrontBack(float value)
+            { this->moveFrontBack(Vector2(value, 0)); }
+            /**
+            @brief Moves the Drone in the Right/Left-direction by the specifed amount.
+            @param value  The amount by which the drone is to be moved.
+            */
+            inline void moveRightLeft(float value)
+            { this->moveRightLeft(Vector2(value, 0)); }
+            /**
+            @brief Moves the Drone in the Up/Down-direction by the specifed amount.
+            @param value  The amount by which the drone is to be moved.
+            */
+            inline void moveUpDown(float value)
+            { this->moveUpDown(Vector2(value, 0)); }
+            
+            /**
+            @brief Rotates the Drone around the y-axis by the specifed amount.
+            @param value  The amount by which the drone is to be rotated.
+            */
+            inline void rotateYaw(float value)
+            { this->rotateYaw(Vector2(value, 0)); }
+            /**
+            @brief Rotates the Drone around the x-axis by the specifed amount.
+            @param value  The amount by which the drone is to be rotated.
+            */
+            inline void rotatePitch(float value)
+            { this->rotatePitch(Vector2(value, 0)); }
+            /**
+            @brief Rotates the Drone around the z-axis by the specifed amount.
+            @param value  The amount by which the drone is to be rotated.
+            */
+            inline void rotateRoll(float value)
+            { this->rotateRoll(Vector2(value, 0)); }
+            
+            /**
+            @brief Sets the primary thrust to the input amount.
+            @param thrust The amount of thrust.
+            */
+            inline void setPrimaryThrust( float thrust )
+                { this->primaryThrust_=thrust; }      
+            // place your set-functions here.
+            // - hint: auxiliary thrust, rotation thrust.
+            inline void setAuxilaryThrust( float thrust )
+                { this->primaryThrust_=thrust; }
+			inline void setRotationThrust( float thrust )
+                { this->rotationThrust_=thrust; }
+			/**
+            @brief Gets the primary thrust to the input amount.
+            @preturn The amount of thrust.
+            */
+            inline float getPrimaryThrust()
+                { return this->primaryThrust_; }
+            // place your get-functions here.
+            inline float getAuxilaryThrust()
+                { return this->auxilaryThrust_; }
+			inline float getRotationThrust()
+                { return this->rotationThrust_; }
+        private:
+            DroneController *myController_; //!< The controller of the Drone.
+            
+            btVector3 localLinearAcceleration_; //!< The linear acceleration that is used to move the Drone the next tick.
+            btVector3 localAngularAcceleration_; //!< The linear angular acceleration that is used to move the Drone the next tick.
+            float primaryThrust_; //!< The amount of primary thrust. This is just used, when moving forward. 
+            float auxilaryThrust_; //!< The amount of auxilary thrust. Used for all other movements (except for rotations).
+            float rotationThrust_; //!< The amount of rotation thrust. Used for rotations only.
+    };
+
+}
+
+#endif /* _Drone_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/EffectContainer.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/EffectContainer.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/EffectContainer.cc	(revision 6952)
@@ -0,0 +1,111 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "EffectContainer.h"
+
+extern "C" {
+#include <lua.h>
+}
+
+#include "core/CoreIncludes.h"
+#include "core/LuaState.h"
+#include "core/XMLPort.h"
+#include "worldentities/WorldEntity.h"
+
+namespace orxonox
+{
+    CreateFactory(EffectContainer);
+
+    EffectContainer::EffectContainer(BaseObject* creator)
+        : BaseObject(creator)
+        , lua_(NULL)
+    {
+        RegisterObject(EffectContainer);
+    }
+
+    EffectContainer::~EffectContainer()
+    {
+    }
+
+    void EffectContainer::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(EffectContainer, XMLPort, xmlelement, mode);
+        XMLPortParam(EffectContainer, "condition", setCondition, getCondition, xmlelement, mode);
+        XMLPortObject(EffectContainer, WorldEntity, "", addEffect, getEffect, xmlelement, mode);
+    }
+
+    void EffectContainer::setCondition(const std::string& condition)
+    {
+        // TODO: Watch out for code injection!
+        this->condition_ = condition;
+        if (this->lua_)
+        {
+            this->lua_->doString(
+                this->functionName_ + " = function() \n"
+                "    return (" + condition + ") \n"
+                "end"
+            );
+        }
+    }
+
+    void EffectContainer::setLuaState(LuaState* state, const std::string& functionName)
+    {
+        this->functionName_ = functionName;
+        this->lua_ = state;
+        this->setCondition(this->condition_);
+    }
+
+    void EffectContainer::addEffect(WorldEntity* effect)
+    {
+        this->effects_.push_back(effect);
+    }
+
+    WorldEntity* EffectContainer::getEffect(unsigned int index) const
+    {
+        unsigned int i = 0;
+        for (std::vector<WorldEntity*>::const_iterator it = this->effects_.begin(); it != this->effects_.end(); ++it)
+            if (i == index)
+                return (*it);
+        return NULL;
+    }
+
+    void EffectContainer::updateCondition()
+    {
+        if (this->lua_)
+        {
+            lua_getglobal(this->lua_->getInternalLuaState(), this->functionName_.c_str());
+            lua_call(this->lua_->getInternalLuaState(), 0, 1);
+            bool result = (bool)lua_toboolean(this->lua_->getInternalLuaState(), -1);
+            lua_pop(this->lua_->getInternalLuaState(), 1);
+            for (std::vector<WorldEntity*>::const_iterator it = this->effects_.begin(); it != this->effects_.end(); ++it)
+            {
+                (*it)->setMainState(result);
+            }
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/EffectContainer.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/EffectContainer.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/EffectContainer.h	(revision 6952)
@@ -0,0 +1,71 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _EffectContainer_H__
+#define _EffectContainer_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <vector>
+#include "core/BaseObject.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport EffectContainer : public BaseObject
+    {
+        public:
+            EffectContainer(BaseObject* creator);
+            virtual ~EffectContainer();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            void setLuaState(LuaState* state, const std::string& functionName);
+
+            void setCondition(const std::string& condition);
+            inline const std::string& getCondition() const
+                { return this->condition_; }
+
+            void addEffect(WorldEntity* effect);
+            WorldEntity* getEffect(unsigned int index) const;
+
+            inline std::vector<WorldEntity*>::const_iterator getEffectsBegin()
+                { return this->effects_.begin(); }
+            inline std::vector<WorldEntity*>::const_iterator getEffectsEnd()
+                { return this->effects_.end(); }
+
+            void updateCondition();
+
+        private:
+            std::string               condition_;
+            std::string               functionName_;
+            LuaState*                 lua_;
+            std::vector<WorldEntity*> effects_;
+    };
+}
+
+#endif /* _EffectContainer_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/ExplosionChunk.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/ExplosionChunk.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/ExplosionChunk.cc	(revision 6952)
@@ -0,0 +1,160 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ExplosionChunk.h"
+
+#include "core/CoreIncludes.h"
+#include "core/Executor.h"
+#include "core/GameMode.h"
+#include "util/Exception.h"
+#include "Scene.h"
+#include "tools/ParticleInterface.h"
+
+namespace orxonox
+{
+    CreateFactory(ExplosionChunk);
+
+    ExplosionChunk::ExplosionChunk(BaseObject* creator) : MovableEntity(creator)
+    {
+        RegisterObject(ExplosionChunk);
+
+        if ( GameMode::showsGraphics() && ( !this->getScene() || !this->getScene()->getSceneManager() ) )
+            ThrowException(AbortLoading, "Can't create ExplosionChunk, no scene or no scene manager given.");
+
+        this->bStop_ = false;
+        this->LOD_ = LODParticle::Normal;
+
+        if ( GameMode::showsGraphics() )
+        {
+            try
+            {
+                this->fire_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/fire4", this->LOD_);
+                this->attachOgreObject(this->fire_->getParticleSystem());
+                this->smoke_ = new ParticleInterface(this->getScene()->getSceneManager(), "Orxonox/smoke7", this->LOD_);
+                this->attachOgreObject(this->smoke_->getParticleSystem());
+            }
+            catch (...)
+            {
+                COUT(1) << "Error: Couln't load particle effect in ExplosionChunk: " << Exception::handleMessage() << std::endl;
+                this->fire_ = 0;
+                this->smoke_ = 0;
+            }
+        }
+        else
+        {
+            this->fire_ = 0;
+            this->smoke_ = 0;
+        }
+
+        if (GameMode::isMaster())
+        {
+            Vector3 velocity(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1));
+            velocity.normalise();
+            velocity *= rnd(60, 80);
+            this->setVelocity(velocity);
+
+            this->destroyTimer_.setTimer(rnd(1, 2), false, createExecutor(createFunctor(&ExplosionChunk::stop, this)));
+        }
+
+        this->registerVariables();
+    }
+
+    ExplosionChunk::~ExplosionChunk()
+    {
+        if (this->isInitialized())
+        {
+            if (this->fire_)
+            {
+                this->detachOgreObject(this->fire_->getParticleSystem());
+                this->fire_->destroy();
+            }
+            if (this->smoke_)
+            {
+                this->detachOgreObject(this->smoke_->getParticleSystem());
+                this->smoke_->destroy();
+            }
+        }
+    }
+
+    void ExplosionChunk::registerVariables()
+    {
+        registerVariable((int&)(this->LOD_), VariableDirection::ToClient, new NetworkCallback<ExplosionChunk>(this, &ExplosionChunk::LODchanged));
+        registerVariable(this->bStop_,       VariableDirection::ToClient, new NetworkCallback<ExplosionChunk>(this, &ExplosionChunk::checkStop));
+    }
+
+    void ExplosionChunk::LODchanged()
+    {
+        if (this->fire_)
+            this->fire_->setDetailLevel(this->LOD_);
+        if (this->smoke_)
+            this->smoke_->setDetailLevel(this->LOD_);
+    }
+
+    void ExplosionChunk::checkStop()
+    {
+        if (this->bStop_)
+            this->stop();
+    }
+
+    void ExplosionChunk::stop()
+    {
+        if (this->fire_)
+            this->fire_->setEnabled(false);
+        if (this->smoke_)
+            this->smoke_->setEnabled(false);
+
+        if (GameMode::isMaster())
+        {
+            this->bStop_ = true;
+            this->destroyTimer_.setTimer(1.0f, false, createExecutor(createFunctor(&ExplosionChunk::destroy, this)));
+        }
+    }
+
+    void ExplosionChunk::tick(float dt)
+    {
+        static const unsigned int CHANGES_PER_SECOND = 5;
+
+        if (GameMode::isMaster() && rnd() < dt*CHANGES_PER_SECOND)
+        {
+            float length = this->getVelocity().length();
+
+            Vector3 change(rnd(-1, 1), rnd(-1, 1), rnd(-1, 1));
+            change.normalise();
+            change *= rnd(0.4f, 0.8f);
+            Vector3 velocity = this->getVelocity();
+            velocity.normalise();
+            velocity += change;
+            velocity.normalise();
+            velocity *= length * rnd(0.8f, 1.0f);
+
+            this->setVelocity(velocity);
+        }
+
+        SUPER(ExplosionChunk, tick, dt);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/ExplosionChunk.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/ExplosionChunk.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/ExplosionChunk.h	(revision 6952)
@@ -0,0 +1,66 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _ExplosionChunk_H__
+#define _ExplosionChunk_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "tools/Timer.h"
+#include "MovableEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport ExplosionChunk : public MovableEntity
+    {
+        public:
+            ExplosionChunk(BaseObject* creator);
+            virtual ~ExplosionChunk();
+
+            virtual void tick(float dt);
+            void registerVariables();
+
+            inline void setLOD(LODParticle::Value level)
+                { this->LOD_ = level; this->LODchanged(); }
+            inline LODParticle::Value getLOD() const
+                { return this->LOD_; }
+
+        private:
+            void LODchanged();
+            void checkStop();
+            void stop();
+
+            bool                  bStop_;
+            ParticleInterface*    fire_;
+            ParticleInterface*    smoke_;
+            LODParticle::Value    LOD_;
+            Timer                 destroyTimer_;
+    };
+}
+
+#endif /* _ExplosionChunk_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/MobileEntity.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/MobileEntity.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/MobileEntity.cc	(revision 6952)
@@ -0,0 +1,208 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      Martin Stypinski
+ *
+ */
+
+#include "MobileEntity.h"
+
+#include <OgreSceneNode.h>
+#include <BulletDynamics/Dynamics/btRigidBody.h>
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+
+namespace orxonox
+{
+    MobileEntity::MobileEntity(BaseObject* creator) : WorldEntity(creator)
+    {
+        RegisterObject(MobileEntity);
+
+        this->linearAcceleration_  = Vector3::ZERO;
+        this->linearVelocity_      = Vector3::ZERO;
+        this->angularAcceleration_ = Vector3::ZERO;
+        this->angularVelocity_     = Vector3::ZERO;
+
+        this->registerVariables();
+    }
+
+    MobileEntity::~MobileEntity()
+    {
+    }
+
+    void MobileEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(MobileEntity, XMLPort, xmlelement, mode);
+
+        XMLPortParamTemplate(MobileEntity, "velocity",     setVelocity,     getVelocity,     xmlelement, mode, const Vector3&);
+
+        Vector3 rotationAxis(this->getRotationAxis());
+        Degree rotationRate = this->getRotationRate();
+        XMLPortParamVariable(MobileEntity, "rotationaxis", rotationAxis, xmlelement, mode);
+        XMLPortParamVariable(MobileEntity, "rotationrate", rotationRate, xmlelement, mode);
+        if (mode == XMLPort::LoadObject)
+        {
+            if (rotationAxis == Vector3::ZERO)
+                this->setAngularVelocity(Vector3::ZERO);
+            else
+                this->setAngularVelocity(rotationAxis.normalisedCopy() * rotationRate.valueRadians());
+        }
+    }
+
+    void MobileEntity::tick(float dt)
+    {
+        if (this->isActive())
+        {
+            // Check whether Bullet doesn't do the physics for us
+            if (!this->isDynamic())
+            {
+                // Linear part
+                this->linearVelocity_.x += this->linearAcceleration_.x * dt;
+                this->linearVelocity_.y += this->linearAcceleration_.y * dt;
+                this->linearVelocity_.z += this->linearAcceleration_.z * dt;
+                this->node_->translate(this->linearVelocity_ * dt);
+
+                // Angular part
+                // Note: angularVelocity_ is a Quaternion with w = 0 while angularAcceleration_ is a Vector3
+                this->angularVelocity_.x += angularAcceleration_.x * dt;
+                this->angularVelocity_.y += angularAcceleration_.y * dt;
+                this->angularVelocity_.z += angularAcceleration_.z * dt;
+                // Calculate new orientation with quaternion derivative. This is about 30% faster than with angle/axis method.
+                float mult = dt * 0.5f;
+                // TODO: this could be optimized by writing it out. The calls currently create 4 new Quaternions!
+                Quaternion newOrientation(0.0f, this->angularVelocity_.x * mult, this->angularVelocity_.y * mult, this->angularVelocity_.z * mult);
+                newOrientation = this->node_->getOrientation() + newOrientation * this->node_->getOrientation();
+                newOrientation.normalise();
+                this->node_->setOrientation(newOrientation);
+            }
+        }
+    }
+
+    void MobileEntity::setPosition(const Vector3& position)
+    {
+        if (this->isDynamic())
+        {
+            btTransform transf = this->physicalBody_->getWorldTransform();
+            transf.setOrigin(btVector3(position.x, position.y, position.z));
+            this->physicalBody_->setWorldTransform(transf);
+        }
+
+        this->node_->setPosition(position);
+    }
+
+    void MobileEntity::setOrientation(const Quaternion& orientation)
+    {
+        if (this->isDynamic())
+        {
+            btTransform transf = this->physicalBody_->getWorldTransform();
+            transf.setRotation(btQuaternion(orientation.x, orientation.y, orientation.z, orientation.w));
+            this->physicalBody_->setWorldTransform(transf);
+        }
+
+        this->node_->setOrientation(orientation);
+    }
+
+    void MobileEntity::setVelocity(const Vector3& velocity)
+    {
+        if (this->isDynamic())
+            this->physicalBody_->setLinearVelocity(btVector3(velocity.x, velocity.y, velocity.z));
+
+        this->linearVelocity_ = velocity;
+    }
+
+    void MobileEntity::setAngularVelocity(const Vector3& velocity)
+    {
+        if (this->isDynamic())
+            this->physicalBody_->setAngularVelocity(btVector3(velocity.x, velocity.y, velocity.z));
+
+        this->angularVelocity_ = velocity;
+    }
+
+    void MobileEntity::setAcceleration(const Vector3& acceleration)
+    {
+        if (this->isDynamic())
+            this->physicalBody_->applyCentralForce(btVector3(acceleration.x * this->getMass(), acceleration.y * this->getMass(), acceleration.z * this->getMass()));
+
+        this->linearAcceleration_ = acceleration;
+    }
+
+    void MobileEntity::setAngularAcceleration(const Vector3& acceleration)
+    {
+        if (this->isDynamic())
+        {
+            btVector3 inertia(btVector3(1, 1, 1) / this->physicalBody_->getInvInertiaDiagLocal());
+            this->physicalBody_->applyTorque(btVector3(acceleration.x, acceleration.y, acceleration.z) * inertia);
+        }
+
+        this->angularAcceleration_ = acceleration;
+    }
+
+    void MobileEntity::applyCentralForce(const Vector3& force)
+    {
+        if (this->isDynamic())
+            this->physicalBody_->applyCentralForce(btVector3(force.x * this->getMass(), force.y * this->getMass(), force.z * this->getMass()));
+    }
+
+    bool MobileEntity::isCollisionTypeLegal(WorldEntity::CollisionType type) const
+    {
+        if (type == WorldEntity::Static)
+        {
+            CCOUT(1) << "Error: Cannot tell a MobileEntity to have static collision type! Ignoring." << std::endl;
+            assert(false); // Only in debug mode
+            return false;
+        }
+        else
+            return true;
+    }
+
+    void MobileEntity::setWorldTransform(const btTransform& worldTrans)
+    {
+        // We use a dynamic body. So we translate our node accordingly.
+        this->node_->setPosition(Vector3(worldTrans.getOrigin().x(), worldTrans.getOrigin().y(), worldTrans.getOrigin().z()));
+        btQuaternion temp(worldTrans.getRotation());
+        this->node_->setOrientation(Quaternion(temp.w(), temp.x(), temp.y(), temp.z()));
+        this->linearVelocity_.x = this->physicalBody_->getLinearVelocity().x();
+        this->linearVelocity_.y = this->physicalBody_->getLinearVelocity().y();
+        this->linearVelocity_.z = this->physicalBody_->getLinearVelocity().z();
+        this->angularVelocity_.x = this->physicalBody_->getAngularVelocity().x();
+        this->angularVelocity_.y = this->physicalBody_->getAngularVelocity().y();
+        this->angularVelocity_.z = this->physicalBody_->getAngularVelocity().z();
+    }
+
+    void MobileEntity::getWorldTransform(btTransform& worldTrans) const
+    {
+        // We use a kinematic body
+        worldTrans.setOrigin(btVector3(node_->getPosition().x, node_->getPosition().y, node_->getPosition().z));
+        worldTrans.setRotation(btQuaternion(node_->getOrientation().x, node_->getOrientation().y, node_->getOrientation().z, node_->getOrientation().w));
+        if (this->isDynamic())
+        {
+            // This function gets called only once for dynamic objects to set the initial conditions
+            // We have to set the velocities too.
+            this->physicalBody_->setLinearVelocity(btVector3(linearVelocity_.x, linearVelocity_.y, linearVelocity_.z));
+            this->physicalBody_->setAngularVelocity(btVector3(angularVelocity_.x, angularVelocity_.y, angularVelocity_.z));
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/MobileEntity.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/MobileEntity.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/MobileEntity.h	(revision 6952)
@@ -0,0 +1,107 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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
+ *   Co-authors:
+ *      Martin Stypinski
+ *
+ */
+
+#ifndef _MobileEntity_H__
+#define _MobileEntity_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/Math.h"
+#include "tools/interfaces/Tickable.h"
+#include "WorldEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport MobileEntity : public WorldEntity, public Tickable
+    {
+        public:
+            MobileEntity(BaseObject* creator);
+            virtual ~MobileEntity();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void tick(float dt);
+
+            virtual void setPosition(const Vector3& position);
+            virtual void setOrientation(const Quaternion& orientation);
+
+            virtual void setVelocity(const Vector3& velocity);
+            inline void setVelocity(float x, float y, float z)
+                { this->setVelocity(Vector3(x, y, z)); }
+            inline const Vector3& getVelocity() const
+                { return this->linearVelocity_; }
+            inline Vector3 getLocalVelocity() const
+                { return (this->getOrientation().Inverse() * this->getVelocity()); }
+
+            virtual void setAngularVelocity(const Vector3& velocity);
+            inline void setAngularVelocity(float x, float y, float z)
+                { this->setAngularVelocity(Vector3(x, y, z)); }
+            inline const Vector3& getAngularVelocity() const
+                { return this->angularVelocity_; }
+
+            void setAcceleration(const Vector3& acceleration);
+            inline void setAcceleration(float x, float y, float z)
+                { this->setAcceleration(Vector3(x, y, z)); }
+            inline const Vector3& getAcceleration() const
+                { return this->linearAcceleration_; }
+
+            void setAngularAcceleration(const Vector3& acceleration);
+            inline void setAngularAcceleration(float x, float y, float z)
+                { this->setAngularAcceleration(Vector3(x, y, z)); }
+            inline const Vector3& getAngularAcceleration() const
+                { return this->angularAcceleration_; }
+
+            void applyCentralForce(const Vector3& force);
+            inline void applyCentralForce(float x, float y, float z)
+                { this->applyCentralForce(Vector3(x, y, z)); }
+
+            inline void setRotationRate(Degree rate)
+                { this->setAngularVelocity(this->getAngularVelocity().normalisedCopy() * rate.valueRadians()); }
+            inline Degree getRotationRate() const
+                { return Degree(this->getAngularVelocity().length()); }
+
+            inline void setRotationAxis(const Vector3& axis)
+                { this->setAngularVelocity(axis * this->getAngularVelocity().length()); }
+            inline Vector3 getRotationAxis() const
+                { return this->getAngularVelocity().normalisedCopy(); }
+
+        protected:
+            // Bullet btMotionState related
+            virtual void setWorldTransform(const btTransform& worldTrans);
+            void getWorldTransform(btTransform& worldTrans) const;
+
+            Vector3 linearAcceleration_;
+            Vector3 linearVelocity_;
+            Vector3 angularAcceleration_;
+            Vector3 angularVelocity_;
+
+        private:
+            virtual bool isCollisionTypeLegal(WorldEntity::CollisionType type) const;
+    };
+}
+
+#endif /* _MobileEntity_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/MovableEntity.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/MovableEntity.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/MovableEntity.cc	(revision 6952)
@@ -0,0 +1,120 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "MovableEntity.h"
+
+#include "core/CoreIncludes.h"
+#include "core/Executor.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    static const float MAX_RESYNCHRONIZE_TIME = 3.0f;
+    static const float CONTINUOUS_SYNCHRONIZATION_TIME = 10.0f;
+
+    CreateFactory(MovableEntity);
+
+    MovableEntity::MovableEntity(BaseObject* creator) : MobileEntity(creator)
+    {
+        RegisterObject(MovableEntity);
+
+        this->overwrite_position_    = Vector3::ZERO;
+        this->overwrite_orientation_ = Quaternion::IDENTITY;
+
+        this->continuousResynchroTimer_ = 0;
+
+        this->setPriority(Priority::Low);
+
+        this->registerVariables();
+    }
+
+    MovableEntity::~MovableEntity()
+    {
+        if (this->isInitialized())
+            if (this->continuousResynchroTimer_)
+                this->continuousResynchroTimer_->destroy();
+    }
+
+    void MovableEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(MovableEntity, XMLPort, xmlelement, mode);
+
+        XMLPortParam(MovableEntity, "enablecollisiondamage", setEnableCollisionDamage, getEnableCollisionDamage, xmlelement, mode).defaultValues(false);
+        XMLPortParam(MovableEntity, "collisiondamage", setCollisionDamage, getCollisionDamage, xmlelement, mode).defaultValues(1);
+    }
+
+    bool MovableEntity::collidesAgainst(WorldEntity* otherObject, btManifoldPoint& contactPoint)
+    {
+        if (GameMode::isMaster() && enableCollisionDamage_)
+        {
+            Pawn* victim = orxonox_cast<Pawn*>(otherObject);
+            if (victim)
+            {
+                float damage = this->collisionDamage_ * (victim->getVelocity() - this->getVelocity()).length();
+                victim->hit(0, contactPoint, damage);
+            }
+        }
+
+        return false;
+    }
+
+
+    void MovableEntity::registerVariables()
+    {
+        registerVariable(this->linearVelocity_,        VariableDirection::ToClient, new NetworkCallback<MovableEntity>(this, &MovableEntity::processLinearVelocity));
+        registerVariable(this->angularVelocity_,       VariableDirection::ToClient, new NetworkCallback<MovableEntity>(this, &MovableEntity::processAngularVelocity));
+
+        registerVariable(this->overwrite_position_,    VariableDirection::ToClient, new NetworkCallback<MovableEntity>(this, &MovableEntity::overwritePosition));
+        registerVariable(this->overwrite_orientation_, VariableDirection::ToClient, new NetworkCallback<MovableEntity>(this, &MovableEntity::overwriteOrientation));
+    }
+
+    void MovableEntity::clientConnected(unsigned int clientID)
+    {
+        this->resynchronizeTimer_.setTimer(rnd() * MAX_RESYNCHRONIZE_TIME, false, createExecutor(createFunctor(&MovableEntity::resynchronize, this)));
+    }
+
+    void MovableEntity::clientDisconnected(unsigned int clientID)
+    {
+    }
+
+    void MovableEntity::resynchronize()
+    {
+        if (GameMode::isMaster() && !this->continuousResynchroTimer_)
+        {
+            // Resynchronise every few seconds because we only work with velocities (no positions)
+            continuousResynchroTimer_ = new Timer(CONTINUOUS_SYNCHRONIZATION_TIME + rnd(-1, 1),
+                true, createExecutor(createFunctor(&MovableEntity::resynchronize, this)), false);
+        }
+
+        this->overwrite_position_ = this->getPosition();
+        this->overwrite_orientation_ = this->getOrientation();
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/MovableEntity.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/MovableEntity.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/MovableEntity.h	(revision 6952)
@@ -0,0 +1,107 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _MovableEntity_H__
+#define _MovableEntity_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/Math.h"
+#include "network/ClientConnectionListener.h"
+#include "tools/Timer.h"
+#include "MobileEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport MovableEntity : public MobileEntity, public ClientConnectionListener
+    {
+        public:
+            MovableEntity(BaseObject* creator);
+            virtual ~MovableEntity();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual bool collidesAgainst(WorldEntity* otherObject, btManifoldPoint& contactPoint);
+            void registerVariables();
+
+            using WorldEntity::setPosition;
+            using WorldEntity::setOrientation;
+
+            inline void setPosition(const Vector3& position)
+                { MobileEntity::setPosition(position); this->overwrite_position_ = this->getPosition(); }
+            inline void setOrientation(const Quaternion& orientation)
+                { MobileEntity::setOrientation(orientation); this->overwrite_orientation_ = this->getOrientation(); }
+
+            inline void setOwner(Pawn* owner)
+                { this->owner_ = owner; }
+            inline Pawn* getOwner() const
+                { return this->owner_; }
+
+            inline void setCollisionDamage(float c)
+                { this->collisionDamage_ = c; }
+
+            inline float getCollisionDamage()
+                { return this->collisionDamage_; }
+
+            inline void setEnableCollisionDamage(bool c)
+            {
+                this->enableCollisionDamage_ = c;
+                this->enableCollisionCallback();
+            }
+
+            inline bool getEnableCollisionDamage()
+                { return this->enableCollisionDamage_; }
+
+        private:
+            void clientConnected(unsigned int clientID);
+            void clientDisconnected(unsigned int clientID);
+            void resynchronize();
+
+            inline void processLinearVelocity()
+                { this->setVelocity(this->linearVelocity_); }
+            inline void processAngularVelocity()
+                { this->setAngularVelocity(this->angularVelocity_); }
+
+            inline void overwritePosition()
+                { this->setPosition(this->overwrite_position_); }
+            inline void overwriteOrientation()
+                { this->setOrientation(this->overwrite_orientation_); }
+
+            Vector3    overwrite_position_;
+            Quaternion overwrite_orientation_;
+
+            Timer resynchronizeTimer_;
+            Timer* continuousResynchroTimer_;
+
+            Pawn* owner_;
+            float collisionDamage_;
+            bool enableCollisionDamage_;
+    };
+}
+
+#endif /* _MovableEntity_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/RocketDrone.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/RocketDrone.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/RocketDrone.cc	(revision 6952)
@@ -0,0 +1,192 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oli Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "RocketDrone.h"
+
+#include "core/XMLPort.h"
+#include "BulletDynamics/Dynamics/btRigidBody.h"
+#include "graphics/Model.h"
+
+namespace orxonox
+{
+	CreateFactory(RocketDrone);
+    // put your code in here:
+    // create the factory for the drone
+
+    /**
+    @brief
+        Constructor. Registers the object and initializes some default values.
+    */
+    RocketDrone::RocketDrone(BaseObject* creator) : ControllableEntity(creator)
+    {
+		RegisterObject(RocketDrone);
+        // put your code in here:
+        // - register the drone class to the core
+        this->myController_ = 0;
+        this->localLinearAcceleration_.setValue(0, 0, 0);
+        this->localAngularAcceleration_.setValue(0, 0, 0);
+        this->primaryThrust_  = 100;
+        this->auxilaryThrust_ = 100;
+        this->rotationThrust_ = 10;
+        Model *model = new Model(this);
+            model->setMeshSource("rocket.mesh");
+            model->scale(0.7f);
+        this->setCollisionType(WorldEntity::Dynamic);
+        
+        myController_ = new RocketController(static_cast<BaseObject*>(this)); //!< Creates a new controller and passes our this pointer to it as creator.
+    }
+
+    /**
+    @brief
+        Destructor. Destroys controller, if present.
+    */
+    RocketDrone::~RocketDrone()
+    {
+        if( this->isInitialized() && this->myController_ )
+            delete this->myController_;
+    }
+
+    /**
+    @brief
+        Method for creating a Drone through XML.
+    */
+    void RocketDrone::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        // this calls the XMLPort function of the parent class
+        SUPER(RocketDrone, XMLPort, xmlelement, mode);
+
+        // put your code in here:
+        // make sure you add the variables primaryThrust_, auxilaryThrust_ and rotationThrust_ to xmlport 
+        // make sure that the set- and get-functions exist.
+        // variables can be added by the following command 
+        // XMLPortParam(Classname, "xml-attribute-name (i.e. variablename)", setFunction, getFunction, xmlelement, mode)
+		XMLPortParam(RocketDrone, "primaryThrust_", setPrimaryThrust, getPrimaryThrust, xmlelement, mode);
+		XMLPortParam(RocketDrone, "auxilaryThrust_", setAuxilaryThrust, getAuxilaryThrust, xmlelement, mode);
+		XMLPortParam(RocketDrone, "rotationThrust_", setRotationThrust, getRotationThrust, xmlelement, mode);
+ 
+    }
+
+    /**
+    @brief
+        Defines which actions the Drone has to take in each tick.
+    @param dt
+        The length of the tick.
+    */
+    void RocketDrone::tick(float dt)
+    {
+        SUPER(RocketDrone, tick, dt);
+        
+        //if (this->hasLocalController())
+        //{
+            this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() * getMass() * this->auxilaryThrust_);
+            this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() * getMass() * this->auxilaryThrust_);
+            if (this->localLinearAcceleration_.z() > 0)
+              this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() * getMass() * this->auxilaryThrust_);
+            else
+              this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() * getMass() * this->primaryThrust_);
+            this->physicalBody_->applyCentralForce(physicalBody_->getWorldTransform().getBasis() * this->localLinearAcceleration_);
+            this->localLinearAcceleration_.setValue(0, 0, 0);
+        
+            this->localAngularAcceleration_ *= this->getLocalInertia() * this->rotationThrust_;
+            this->physicalBody_->applyTorque(physicalBody_->getWorldTransform().getBasis() * this->localAngularAcceleration_);
+            this->localAngularAcceleration_.setValue(0, 0, 0);
+        //}
+    }
+    
+    /**
+    @brief
+        Moves the Drone in the negative z-direction (Front/Back) by an amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the movement.
+    */
+    void RocketDrone::moveFrontBack(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() - value.x);
+    }
+
+    /**
+    @brief
+        Moves the Drone in the x-direction (Right/Left) by an amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the movement.
+    */
+    void RocketDrone::moveRightLeft(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() + value.x);
+    }
+
+    /**
+    @brief
+        Moves the Drone in the y-direction (Up/Down) by an amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the movement.
+    */
+    void RocketDrone::moveUpDown(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() + value.x);
+    }
+
+    /**
+    @brief
+        Rotates the Drone around the y-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void RocketDrone::rotateYaw(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setY(this->localAngularAcceleration_.y() - value.x);
+    }
+
+    /**
+    @brief
+        Rotates the Drone around the x-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void RocketDrone::rotatePitch(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setX(this->localAngularAcceleration_.x() + value.x);
+    }
+
+    /**
+    @brief
+        Rotates the Drone around the z-axis by the amount specified by the first component of the input 2-dim vector.
+    @param value
+        The vector determining the amount of the angular movement.
+    */
+    void RocketDrone::rotateRoll(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setZ(this->localAngularAcceleration_.z() + value.x);
+    }
+
+	//void RocketDrone::setOwner(Pawn* owner)
+    //{
+    //    this->owner_ = owner;
+	//}
+    
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/RocketDrone.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/RocketDrone.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/RocketDrone.h	(revision 6952)
@@ -0,0 +1,139 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Oli Scheuss
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _RocketDrone_H__
+#define _RocketDrone_H__
+
+#include "OrxonoxPrereqs.h"
+#include "worldentities/ControllableEntity.h"
+#include "controllers/RocketController.h"
+
+namespace orxonox
+{
+
+    /**
+    @brief
+        Drone, that is made to move upon a specified pattern.
+        This class was constructed for the PPS tutorial.
+    @author
+        Oli Scheuss
+    */
+    class _OrxonoxExport RocketDrone : public ControllableEntity
+    {
+        public:
+            RocketDrone(BaseObject* creator);
+            virtual ~RocketDrone();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode); //!< Method for creating a Drone through XML.
+            virtual void tick(float dt); //!< Defines which actions the Drone has to take in each tick.
+
+            
+            virtual void moveFrontBack(const Vector2& value);
+            virtual void moveRightLeft(const Vector2& value);
+            virtual void moveUpDown(const Vector2& value);
+
+            virtual void rotateYaw(const Vector2& value);
+            virtual void rotatePitch(const Vector2& value);
+            virtual void rotateRoll(const Vector2& value);
+            
+            /**
+            @brief Moves the Drone in the Front/Back-direction by the specifed amount.
+            @param value  The amount by which the drone is to be moved.
+            */
+            inline void moveFrontBack(float value)
+            { this->moveFrontBack(Vector2(value, 0)); }
+            /**
+            @brief Moves the Drone in the Right/Left-direction by the specifed amount.
+            @param value  The amount by which the drone is to be moved.
+            */
+            inline void moveRightLeft(float value)
+            { this->moveRightLeft(Vector2(value, 0)); }
+            /**
+            @brief Moves the Drone in the Up/Down-direction by the specifed amount.
+            @param value  The amount by which the drone is to be moved.
+            */
+            inline void moveUpDown(float value)
+            { this->moveUpDown(Vector2(value, 0)); }
+            
+            /**
+            @brief Rotates the Drone around the y-axis by the specifed amount.
+            @param value  The amount by which the drone is to be rotated.
+            */
+            inline void rotateYaw(float value)
+            { this->rotateYaw(Vector2(value, 0)); }
+            /**
+            @brief Rotates the Drone around the x-axis by the specifed amount.
+            @param value  The amount by which the drone is to be rotated.
+            */
+            inline void rotatePitch(float value)
+            { this->rotatePitch(Vector2(value, 0)); }
+            /**
+            @brief Rotates the Drone around the z-axis by the specifed amount.
+            @param value  The amount by which the drone is to be rotated.
+            */
+            inline void rotateRoll(float value)
+            { this->rotateRoll(Vector2(value, 0)); }
+            
+            /**
+            @brief Sets the primary thrust to the input amount.
+            @param thrust The amount of thrust.
+            */
+            inline void setPrimaryThrust( float thrust )
+                { this->primaryThrust_=thrust; }      
+            // place your set-functions here.
+            // - hint: auxiliary thrust, rotation thrust.
+            inline void setAuxilaryThrust( float thrust )
+                { this->primaryThrust_=thrust; }
+			inline void setRotationThrust( float thrust )
+                { this->rotationThrust_=thrust; }
+			/**
+            @brief Gets the primary thrust to the input amount.
+            @preturn The amount of thrust.
+            */
+            inline float getPrimaryThrust()
+                { return this->primaryThrust_; }
+            // place your get-functions here.
+            inline float getAuxilaryThrust()
+                { return this->auxilaryThrust_; }
+			inline float getRotationThrust()
+                { return this->rotationThrust_; }
+
+			//void setOwner(Pawn* owner);
+        private:
+            RocketController *myController_; //!< The controller of the Drone.
+            
+            btVector3 localLinearAcceleration_; //!< The linear acceleration that is used to move the Drone the next tick.
+            btVector3 localAngularAcceleration_; //!< The linear angular acceleration that is used to move the Drone the next tick.
+            float primaryThrust_; //!< The amount of primary thrust. This is just used, when moving forward. 
+            float auxilaryThrust_; //!< The amount of auxilary thrust. Used for all other movements (except for rotations).
+            float rotationThrust_; //!< The amount of rotation thrust. Used for rotations only.
+    };
+
+}
+
+#endif /* _RocketDrone_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/SpawnPoint.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/SpawnPoint.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/SpawnPoint.cc	(revision 6952)
@@ -0,0 +1,107 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "SpawnPoint.h"
+
+#include "core/CoreIncludes.h"
+#include "core/Template.h"
+#include "core/XMLPort.h"
+#include "gametypes/Gametype.h"
+#include "worldentities/pawns/Pawn.h"
+
+namespace orxonox
+{
+    CreateFactory(SpawnPoint);
+
+    SpawnPoint::SpawnPoint(BaseObject* creator) : StaticEntity(creator)
+    {
+        RegisterObject(SpawnPoint);
+
+        this->template_ = 0;
+
+        if (this->getGametype())
+            this->getGametype()->registerSpawnPoint(this);
+        else
+            COUT(1) << "Error: SpawnPoint has no Gametype" << std::endl;
+
+        this->setSyncMode(0x0);
+    }
+
+    void SpawnPoint::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(SpawnPoint, XMLPort, xmlelement, mode);
+
+        XMLPortParam(SpawnPoint, "spawnclass", setSpawnClassName, getSpawnClassName, xmlelement, mode);
+        XMLPortParam(SpawnPoint, "pawndesign", setTemplateName, getTemplateName, xmlelement, mode);
+    }
+
+    void SpawnPoint::setSpawnClassName(const std::string& name)
+    {
+        this->spawnclassname_ = name;
+        this->spawnclass_ = ClassByString(name);
+    }
+
+    void SpawnPoint::setTemplateName(const std::string& name)
+    {
+        this->templatename_ = name;
+        this->template_ = Template::getTemplate(name);
+    }
+
+    void SpawnPoint::setTemplate(Template* temp)
+    {
+        this->template_ = temp;
+        this->templatename_ = temp->getName();
+    }
+
+    Pawn* SpawnPoint::spawn()
+    {
+        Pawn* entity = this->spawnclass_.fabricate(this);
+        if (entity)
+        {
+            this->getGametype()->pawnPreSpawn(entity);
+
+            this->spawn(entity);
+
+            if (this->template_)
+                entity->addTemplate(this->template_);
+
+            entity->postSpawn();
+
+            this->getGametype()->pawnPostSpawn(entity);
+
+            this->fireEvent();
+        }
+        return entity;
+    }
+
+    void SpawnPoint::spawn(ControllableEntity* entity)
+    {
+        entity->setPosition(this->getWorldPosition());
+        entity->setOrientation(this->getWorldOrientation());
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/SpawnPoint.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/SpawnPoint.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/SpawnPoint.h	(revision 6952)
@@ -0,0 +1,76 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _SpawnPoint_H__
+#define _SpawnPoint_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "core/SubclassIdentifier.h"
+#include "worldentities/StaticEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport SpawnPoint : public StaticEntity
+    {
+        public:
+            SpawnPoint(BaseObject* creator);
+            virtual ~SpawnPoint() {}
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            inline void setSpawnClass(Identifier* identifier)
+                { this->spawnclass_ = identifier; this->spawnclassname_ = identifier->getName(); }
+            inline Identifier* getSpawnClass() const
+                { return this->spawnclass_; }
+
+            void setTemplate(Template* temp);
+            inline Template* getTemplate() const
+                { return this->template_; }
+
+            Pawn* spawn();
+            void spawn(ControllableEntity* entity);
+
+        private:
+            void setSpawnClassName(const std::string& name);
+            inline const std::string& getSpawnClassName() const
+                { return this->spawnclassname_; }
+
+            void setTemplateName(const std::string& name);
+            inline const std::string& getTemplateName() const
+                { return this->templatename_; }
+
+            SubclassIdentifier<Pawn> spawnclass_;
+            std::string spawnclassname_;
+            Template* template_;
+            std::string templatename_;
+    };
+}
+
+#endif /* _SpawnPoint_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/StaticEntity.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/StaticEntity.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/StaticEntity.cc	(revision 6952)
@@ -0,0 +1,117 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder (physics)
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "StaticEntity.h"
+
+#include <OgreSceneNode.h>
+#include <BulletDynamics/Dynamics/btRigidBody.h>
+#include "util/OrxAssert.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+    CreateFactory(StaticEntity);
+
+    StaticEntity::StaticEntity(BaseObject* creator) : WorldEntity(creator)
+    {
+        RegisterObject(StaticEntity);
+
+        this->setPriority(Priority::VeryLow);
+
+        this->registerVariables();
+    }
+
+    StaticEntity::~StaticEntity()
+    {
+    }
+
+    void StaticEntity::registerVariables()
+    {
+        registerVariable(this->getPosition(),    VariableDirection::ToClient, new NetworkCallback<StaticEntity>(this, &StaticEntity::positionChanged));
+        registerVariable(this->getOrientation(), VariableDirection::ToClient, new NetworkCallback<StaticEntity>(this, &StaticEntity::orientationChanged));
+    }
+
+
+    void StaticEntity::setPosition(const Vector3& position)
+    {
+        if (this->addedToPhysicalWorld())
+        {
+            CCOUT(2) << "Warning: Attempting to change the position of a StaticEntity at physics run time. Ignoring change." << std::endl;
+            return;
+        }
+        if (this->isStatic())
+        {
+            btTransform transf = this->physicalBody_->getWorldTransform();
+            transf.setOrigin(btVector3(position.x, position.y, position.z));
+            this->physicalBody_->setWorldTransform(transf);
+        }
+
+        this->node_->setPosition(position);
+    }
+
+    void StaticEntity::setOrientation(const Quaternion& orientation)
+    {
+        if (this->addedToPhysicalWorld())
+        {
+            CCOUT(2) << "Warning: Attempting to change the orientation of a StaticEntity at physics run time. Ignoring change." << std::endl;
+            return;
+        }
+        if (this->isStatic())
+        {
+            btTransform transf = this->physicalBody_->getWorldTransform();
+            transf.setRotation(btQuaternion(orientation.x, orientation.y, orientation.z, orientation.w));
+            this->physicalBody_->setWorldTransform(transf);
+        }
+
+        this->node_->setOrientation(orientation);
+    }
+
+    bool StaticEntity::isCollisionTypeLegal(WorldEntity::CollisionType type) const
+    {
+        if (type == WorldEntity::Kinematic || type == WorldEntity::Dynamic)
+        {
+            CCOUT(1) << "Error: Cannot tell a StaticEntity to have kinematic or dynamic collision type! Ignoring." << std::endl;
+            assert(false); // Only in debug mode
+            return false;
+        }
+        else
+            return true;
+    }
+
+    void StaticEntity::setWorldTransform(const btTransform& worldTrans)
+    {
+        OrxAssert(false, "Setting world transform of a StaticEntity, which is CF_STATIC!");
+    }
+
+    void StaticEntity::getWorldTransform(btTransform& worldTrans) const
+    {
+        worldTrans.setOrigin(btVector3(node_->getPosition().x, node_->getPosition().y, node_->getPosition().z));
+        worldTrans.setRotation(btQuaternion(node_->getOrientation().x, node_->getOrientation().y, node_->getOrientation().z, node_->getOrientation().w));
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/StaticEntity.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/StaticEntity.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/StaticEntity.h	(revision 6952)
@@ -0,0 +1,67 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _StaticEntity_H__
+#define _StaticEntity_H__
+
+#include "OrxonoxPrereqs.h"
+#include "WorldEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport StaticEntity : public WorldEntity
+    {
+        public:
+            StaticEntity(BaseObject* creator);
+            virtual ~StaticEntity();
+
+            void registerVariables();
+
+            using WorldEntity::setPosition;
+            using WorldEntity::setOrientation;
+
+            void setPosition(const Vector3& position);
+            void setOrientation(const Quaternion& orientation);
+
+        private:
+            bool isCollisionTypeLegal(CollisionType type) const;
+
+            // network callbacks
+            inline void positionChanged()
+                { this->setPosition(this->getPosition()); }
+            inline void orientationChanged()
+                { this->setOrientation(this->getOrientation()); }
+
+            // Bullet btMotionState related
+            void setWorldTransform(const btTransform& worldTrans);
+            void getWorldTransform(btTransform& worldTrans) const;
+    };
+}
+
+#endif /* _StaticEntity_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/TeamSpawnPoint.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/TeamSpawnPoint.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/TeamSpawnPoint.cc	(revision 6952)
@@ -0,0 +1,51 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "TeamSpawnPoint.h"
+
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+
+namespace orxonox
+{
+    CreateFactory(TeamSpawnPoint);
+
+    TeamSpawnPoint::TeamSpawnPoint(BaseObject* creator) : SpawnPoint(creator)
+    {
+        RegisterObject(TeamSpawnPoint);
+
+        this->teamNumber_ = 0;
+    }
+
+    void TeamSpawnPoint::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(TeamSpawnPoint, XMLPort, xmlelement, mode);
+
+        XMLPortParam(TeamSpawnPoint, "team", setTeamNumber, getTeamNumber, xmlelement, mode).defaultValues(0);
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/TeamSpawnPoint.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/TeamSpawnPoint.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/TeamSpawnPoint.h	(revision 6952)
@@ -0,0 +1,57 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TeamSpawnPoint_H__
+#define _TeamSpawnPoint_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "worldentities/pawns/Pawn.h"
+#include "SpawnPoint.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport TeamSpawnPoint : public SpawnPoint
+    {
+        public:
+            TeamSpawnPoint(BaseObject* creator);
+            virtual ~TeamSpawnPoint() {}
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+
+            void setTeamNumber(unsigned int team)
+                { this->teamNumber_ = team; }
+            unsigned int getTeamNumber() const
+                { return this->teamNumber_; }
+
+        private:
+            unsigned int teamNumber_;
+    };
+}
+
+#endif /* _TeamSpawnPoint_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/WorldEntity.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/WorldEntity.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/WorldEntity.cc	(revision 6952)
@@ -0,0 +1,982 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder (physics)
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "WorldEntity.h"
+
+#include <OgreBillboardSet.h>
+#include <OgreCamera.h>
+#include <OgreEntity.h>
+#include <OgreParticleSystem.h>
+#include <OgreSceneManager.h>
+#include <OgreSceneNode.h>
+#include <BulletDynamics/Dynamics/btRigidBody.h>
+#include <boost/static_assert.hpp>
+
+#include "util/OrxAssert.h"
+#include "util/Convert.h"
+#include "util/Exception.h"
+#include "core/CoreIncludes.h"
+#include "core/XMLPort.h"
+#include "Scene.h"
+#include "collisionshapes/WorldEntityCollisionShape.h"
+
+namespace orxonox
+{
+    const Vector3 WorldEntity::FRONT = Vector3::NEGATIVE_UNIT_Z;
+    const Vector3 WorldEntity::BACK  = Vector3::UNIT_Z;
+    const Vector3 WorldEntity::LEFT  = Vector3::NEGATIVE_UNIT_X;
+    const Vector3 WorldEntity::RIGHT = Vector3::UNIT_X;
+    const Vector3 WorldEntity::DOWN  = Vector3::NEGATIVE_UNIT_Y;
+    const Vector3 WorldEntity::UP    = Vector3::UNIT_Y;
+
+    // Be sure we don't do bad conversions
+    BOOST_STATIC_ASSERT((int)Ogre::Node::TS_LOCAL  == (int)WorldEntity::Local);
+    BOOST_STATIC_ASSERT((int)Ogre::Node::TS_PARENT == (int)WorldEntity::Parent);
+    BOOST_STATIC_ASSERT((int)Ogre::Node::TS_WORLD  == (int)WorldEntity::World);
+
+    /**
+    @brief
+        Creates a new WorldEntity that may immediately be used.
+        All the default values are being set here.
+    */
+    WorldEntity::WorldEntity(BaseObject* creator) : BaseObject(creator), Synchronisable(creator)
+    {
+        RegisterObject(WorldEntity);
+
+        if (!this->getScene() || !this->getScene()->getRootSceneNode())
+            ThrowException(AbortLoading, "Can't create WorldEntity, no scene or no root-scenenode given.");
+
+        this->node_ = this->getScene()->getRootSceneNode()->createChildSceneNode();
+
+        this->parent_ = 0;
+        this->parentID_ = OBJECTID_UNKNOWN;
+        this->bDeleteWithParent_ = true;
+
+        this->node_->setPosition(Vector3::ZERO);
+        this->node_->setOrientation(Quaternion::IDENTITY);
+        
+        // Activity and visibility memory.
+        this->bActiveMem_ = true;
+        this->bVisibleMem_ = true;
+
+
+        // Default behaviour does not include physics
+        this->physicalBody_   = 0;
+        this->bPhysicsActive_ = false;
+        this->bPhysicsActiveSynchronised_    = false;
+        this->bPhysicsActiveBeforeAttaching_ = false;
+        this->collisionShape_ = new WorldEntityCollisionShape(this);
+        this->collisionType_             = None;
+        this->collisionTypeSynchronised_ = None;
+        this->mass_           = 0;
+        this->childrenMass_   = 0;
+        // Using bullet default values
+        this->restitution_    = 0;
+        this->angularFactor_  = 1;
+        this->linearDamping_  = 0;
+        this->angularDamping_ = 0;
+        this->friction_       = 0.5;
+        this->bCollisionCallbackActive_ = false;
+        this->bCollisionResponseActive_ = true;
+
+        this->registerVariables();
+    }
+
+    /**
+    @brief
+        Destroys the WorldEntity AND ALL its children with it.
+    */
+    WorldEntity::~WorldEntity()
+    {
+        if (this->isInitialized())
+        {
+            if (this->parent_)
+                this->detachFromParent();
+
+            for (std::set<WorldEntity*>::const_iterator it = this->children_.begin(); it != this->children_.end(); )
+            {
+                if ((*it)->getDeleteWithParent())
+                    (*(it++))->destroy();
+                else
+                {
+                    (*it)->setPosition(this->getWorldPosition());
+                    this->detach(*(it++));
+                }
+            }
+
+            if (this->physicalBody_)
+            {
+                this->deactivatePhysics();
+                delete this->physicalBody_;
+            }
+            this->collisionShape_->destroy();
+
+            this->node_->detachAllObjects();
+            this->node_->removeAllChildren();
+
+            OrxAssert(this->getScene()->getSceneManager(), "No SceneManager defined in a WorldEntity.");
+            this->getScene()->getSceneManager()->destroySceneNode(this->node_->getName());
+        }
+    }
+
+    void WorldEntity::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(WorldEntity, XMLPort, xmlelement, mode);
+
+        XMLPortParamTemplate(WorldEntity, "position",    setPosition,    getPosition,    xmlelement, mode, const Vector3&);
+        XMLPortParamTemplate(WorldEntity, "orientation", setOrientation, getOrientation, xmlelement, mode, const Quaternion&);
+        XMLPortParamTemplate(WorldEntity, "scale3D",     setScale3D,     getScale3D,     xmlelement, mode, const Vector3&);
+        XMLPortParam        (WorldEntity, "scale",       setScale,       getScale,       xmlelement, mode);
+        XMLPortParamLoadOnly(WorldEntity, "lookat",      lookAt_xmlport,       xmlelement, mode);
+        XMLPortParamLoadOnly(WorldEntity, "direction",   setDirection_xmlport, xmlelement, mode);
+        XMLPortParamLoadOnly(WorldEntity, "yaw",         yaw_xmlport,          xmlelement, mode);
+        XMLPortParamLoadOnly(WorldEntity, "pitch",       pitch_xmlport,        xmlelement, mode);
+        XMLPortParamLoadOnly(WorldEntity, "roll",        roll_xmlport,         xmlelement, mode);
+        XMLPortParam        (WorldEntity, "deletewithparent", setDeleteWithParent, getDeleteWithParent, xmlelement, mode);
+
+        // Physics
+        XMLPortParam(WorldEntity, "collisionType",     setCollisionTypeStr,  getCollisionTypeStr,  xmlelement, mode);
+        XMLPortParam(WorldEntity, "collisionResponse", setCollisionResponse, hasCollisionResponse, xmlelement, mode);
+        XMLPortParam(WorldEntity, "mass",              setMass,              getMass,              xmlelement, mode);
+        XMLPortParam(WorldEntity, "restitution",       setRestitution,       getRestitution,       xmlelement, mode);
+        XMLPortParam(WorldEntity, "angularFactor",     setAngularFactor,     getAngularFactor,     xmlelement, mode);
+        XMLPortParam(WorldEntity, "linearDamping",     setLinearDamping,     getLinearDamping,     xmlelement, mode);
+        XMLPortParam(WorldEntity, "angularDamping",    setAngularDamping,    getAngularDamping,    xmlelement, mode);
+        XMLPortParam(WorldEntity, "friction",          setFriction,          getFriction,          xmlelement, mode);
+
+        // Other attached WorldEntities
+        XMLPortObject(WorldEntity, WorldEntity, "attached", attach, getAttachedObject, xmlelement, mode);
+        // Attached collision shapes
+        XMLPortObject(WorldEntity, CollisionShape, "collisionShapes", attachCollisionShape, getAttachedCollisionShape, xmlelement, mode);
+    }
+
+    void WorldEntity::registerVariables()
+    {
+        registerVariable(this->mainStateName_,  VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedMainStateName));
+
+        registerVariable(this->bActive_,        VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedActivity));
+        registerVariable(this->bVisible_,       VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::changedVisibility));
+
+        registerVariable(this->getScale3D(),    VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::scaleChanged));
+
+        // Physics stuff
+        registerVariable(this->mass_,           VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::massChanged));
+        registerVariable(this->restitution_,    VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::restitutionChanged));
+        registerVariable(this->angularFactor_,  VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::angularFactorChanged));
+        registerVariable(this->linearDamping_,  VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::linearDampingChanged));
+        registerVariable(this->angularDamping_, VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::angularDampingChanged));
+        registerVariable(this->friction_,       VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::frictionChanged));
+        registerVariable(this->bCollisionCallbackActive_,
+                                                VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::collisionCallbackActivityChanged));
+        registerVariable(this->bCollisionResponseActive_,
+                                                VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::collisionResponseActivityChanged));
+        registerVariable((int&)this->collisionTypeSynchronised_,
+                                                VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::collisionTypeChanged));
+        registerVariable(this->bPhysicsActiveSynchronised_,
+                                                VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::physicsActivityChanged));
+
+        // Attach to parent if necessary
+        registerVariable(this->parentID_,       VariableDirection::ToClient, new NetworkCallback<WorldEntity>(this, &WorldEntity::networkcallback_parentChanged));
+    }
+    
+    /**
+    @brief
+        When the activity is changed, it is changed for all attached objects as well.
+    */
+    void WorldEntity::changedActivity(void)
+    {
+        SUPER(WorldEntity, changedActivity);
+        
+        for (std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin(); it != this->getAttachedObjects().end(); it++)
+        {
+            if(!this->isActive())
+            {
+                (*it)->bActiveMem_ = (*it)->isActive();
+                (*it)->setActive(this->isActive());
+            }
+            else
+            {
+                (*it)->setActive((*it)->bActiveMem_);
+            }
+        }
+    }
+    
+    /**
+    @brief
+        When the visibility is changed, it is changed for all attached objects as well.
+    */
+    void WorldEntity::changedVisibility(void)
+    {
+        SUPER(WorldEntity, changedVisibility);
+        
+        for (std::set<WorldEntity*>::const_iterator it = this->getAttachedObjects().begin(); it != this->getAttachedObjects().end(); it++)
+        {
+            if(!this->isVisible())
+            {
+                (*it)->bVisibleMem_ = (*it)->isVisible();
+                (*it)->setVisible(this->isVisible());
+            }
+            else
+            {
+                (*it)->setVisible((*it)->bVisibleMem_);
+            }
+        }
+    }
+
+    /**
+    @brief
+        Network function that object this instance to its correct parent.
+    */
+    void WorldEntity::networkcallback_parentChanged()
+    {
+        if (this->parentID_ != OBJECTID_UNKNOWN)
+        {
+            WorldEntity* parent = orxonox_cast<WorldEntity*>(Synchronisable::getSynchronisable(this->parentID_));
+            if (parent)
+                this->attachToParent(parent);
+        }
+    }
+
+    /**
+    @brief
+        Attaches this object to a parent SceneNode.
+    @Remarks
+        Only use this method if you know exactly what you're doing!
+        Normally, attaching works internally by attaching WE's.
+    */
+    void WorldEntity::attachToNode(Ogre::SceneNode* node)
+    {
+        Ogre::Node* parent = this->node_->getParent();
+        if (parent)
+            parent->removeChild(this->node_);
+        node->addChild(this->node_);
+    }
+
+    /**
+    @brief
+        Detaches this object from a parent SceneNode.
+    @Remarks
+        Only use this method if you know exactly what you're doing!
+        Normally, attaching works internally by attaching WE's.
+    */
+    void WorldEntity::detachFromNode(Ogre::SceneNode* node)
+    {
+        node->removeChild(this->node_);
+//        this->getScene()->getRootSceneNode()->addChild(this->node_);
+    }
+
+    /**
+    @brief
+        Network callback for the collision type. Only change the type if it was valid.
+    */
+    void WorldEntity::collisionTypeChanged()
+    {
+        if (this->collisionTypeSynchronised_ != Dynamic &&
+            this->collisionTypeSynchronised_ != Kinematic &&
+            this->collisionTypeSynchronised_ != Static &&
+            this->collisionTypeSynchronised_ != None)
+        {
+            CCOUT(1) << "Error when collsion Type was received over network. Unknown enum value:" << this->collisionTypeSynchronised_ << std::endl;
+        }
+        else if (this->collisionTypeSynchronised_ != collisionType_)
+        {
+            if (this->parent_)
+                CCOUT(2) << "Warning: Network connection tried to set the collision type of an attached WE. Ignoring." << std::endl;
+            else
+                this->setCollisionType(this->collisionTypeSynchronised_);
+        }
+    }
+
+    //! Network callback for this->bPhysicsActive_
+    void WorldEntity::physicsActivityChanged()
+    {
+        if (this->bPhysicsActiveSynchronised_)
+            this->activatePhysics();
+        else
+            this->deactivatePhysics();
+    }
+
+    //! Function sets whether Bullet should issue a callback on collisions
+    void WorldEntity::collisionCallbackActivityChanged()
+    {
+        if (this->hasPhysics())
+        {
+            if (this->bCollisionCallbackActive_)
+                this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() |
+                    btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
+            else
+                this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() &
+                    ~btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK);
+        }
+    }
+
+    //! Function sets whether Bullet should react itself to a collision
+    void WorldEntity::collisionResponseActivityChanged()
+    {
+        if (this->hasPhysics())
+        {
+            if (this->bCollisionResponseActive_)
+                this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() &
+                    ~btCollisionObject::CF_NO_CONTACT_RESPONSE);
+            else
+                this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() |
+                    btCollisionObject::CF_NO_CONTACT_RESPONSE);
+        }
+    }
+
+    /**
+    @brief
+        Attaches a child WorldEntity to this object. This calls notifyBeingAttached()
+        of the child WE.
+    @Note
+        The collision shape of the child object gets attached nevertheless. That also means
+        that you can change the collision shape of the child and it correctly cascadeds the changes to this instance.
+        Be aware of this implication: When implementing attaching of kinematic objects to others, you have to change
+        this behaviour because you then might not want to merge the collision shapes.
+    */
+    void WorldEntity::attach(WorldEntity* object)
+    {
+        if (object == this)
+        {
+            COUT(2) << "Warning: Can't attach a WorldEntity to itself." << std::endl;
+            return;
+        }
+
+        if (!object->notifyBeingAttached(this))
+            return;
+
+        this->attachNode(object->node_);
+        this->children_.insert(object);
+
+        this->attachCollisionShape(object->collisionShape_);
+        // mass
+        this->childrenMass_ += object->getMass();
+        recalculateMassProps();
+    }
+
+    /**
+    @brief
+        Function gets called when this object is being attached to a new parent.
+
+        This operation is only allowed if the collision types "like" each other.
+        - You cannot a attach a non physical object to a physical one.
+        - Dynamic object can NOT be attached at all.
+        - It is also not possible to attach a kinematic to a dynamic one.
+        - Attaching of kinematic objects otherwise is not yet supported.
+    */
+    bool WorldEntity::notifyBeingAttached(WorldEntity* newParent)
+    {
+        // check first whether attaching is even allowed
+        if (this->hasPhysics())
+        {
+            if (!newParent->hasPhysics())
+            {
+                COUT(2) << "Warning: Cannot attach a physical object to a non physical one." << std::endl;
+                return false;
+            }
+            else if (this->isDynamic())
+            {
+                COUT(2) << "Warning: Cannot attach a dynamic object to a WorldEntity." << std::endl;
+                return false;
+            }
+            else if (this->isKinematic() && newParent->isDynamic())
+            {
+                COUT(2) << "Warning: Cannot attach a kinematic object to a dynamic one." << std::endl;
+                return false;
+            }
+            else if (this->isKinematic())
+            {
+                COUT(2) << "Warning: Cannot attach a kinematic object to a static or kinematic one: Not yet implemented." << std::endl;
+                return false;
+            }
+        }
+
+        if (this->isPhysicsActive())
+            this->bPhysicsActiveBeforeAttaching_ = true;
+        this->deactivatePhysics();
+
+        if (this->parent_)
+            this->detachFromParent();
+
+        this->parent_ = newParent;
+        this->parentID_ = newParent->getObjectID();
+
+        this->parentChanged();
+
+        // apply transform to collision shape
+        this->collisionShape_->setPosition(this->getPosition());
+        this->collisionShape_->setOrientation(this->getOrientation());
+        // TODO: Scale
+
+        return true;
+    }
+
+    /**
+    @brief
+        Detaches a child WorldEntity from this instance.
+    */
+    void WorldEntity::detach(WorldEntity* object)
+    {
+        if (this->children_.find(object) == this->children_.end())
+        {
+            CCOUT(2) << "Warning: Cannot detach an object that is not a child." << std::endl;
+            return;
+        }
+
+        // collision shapes
+        this->detachCollisionShape(object->collisionShape_);
+
+        // mass
+        if (object->getMass() > 0.0f)
+        {
+            this->childrenMass_ -= object->getMass();
+            recalculateMassProps();
+        }
+
+        this->detachNode(object->node_);
+        this->children_.erase(object);
+
+        object->notifyDetached();
+    }
+
+    /**
+    @brief
+        Function gets called when the object has been detached from its parent.
+    */
+    void WorldEntity::notifyDetached()
+    {
+        this->parent_ = 0;
+        this->parentID_ = OBJECTID_UNKNOWN;
+
+        this->parentChanged();
+
+        // reset orientation of the collisionShape (cannot be set within a WE usually)
+        this->collisionShape_->setPosition(Vector3::ZERO);
+        this->collisionShape_->setOrientation(Quaternion::IDENTITY);
+        // TODO: Scale
+
+        if (this->bPhysicsActiveBeforeAttaching_)
+        {
+            this->activatePhysics();
+            this->bPhysicsActiveBeforeAttaching_ = false;
+        }
+    }
+
+    //! Returns an attached object (merely for XMLPort).
+    WorldEntity* WorldEntity::getAttachedObject(unsigned int index)
+    {
+        unsigned int i = 0;
+        for (std::set<WorldEntity*>::const_iterator it = this->children_.begin(); it != this->children_.end(); ++it)
+        {
+            if (i == index)
+                return (*it);
+            ++i;
+        }
+        return 0;
+    }
+
+    //! Attaches an Ogre::SceneNode to this WorldEntity.
+    void WorldEntity::attachNode(Ogre::SceneNode* node)
+    {
+        Ogre::Node* parent = node->getParent();
+        if (parent)
+            parent->removeChild(node);
+        this->node_->addChild(node);
+    }
+
+    //! Detaches an Ogre::SceneNode from this WorldEntity.
+    void WorldEntity::detachNode(Ogre::SceneNode* node)
+    {
+        this->node_->removeChild(node);
+//        this->getScene()->getRootSceneNode()->addChild(node);
+    }
+
+    //! Attaches an Ogre::MovableObject to this WorldEntity.
+    void WorldEntity::attachOgreObject(Ogre::MovableObject* object)
+    {
+        this->node_->attachObject(object);
+        object->setUserAny(Ogre::Any(static_cast<OrxonoxClass*>(this)));
+    }
+
+    void WorldEntity::attachOgreObject(Ogre::BillboardSet* object)
+        { this->attachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
+    void WorldEntity::attachOgreObject(Ogre::Camera* object)
+        { this->attachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
+    void WorldEntity::attachOgreObject(Ogre::Entity* object)
+        { this->attachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
+    void WorldEntity::attachOgreObject(Ogre::ParticleSystem* object)
+        { this->attachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
+
+    //! Detaches an Ogre::MovableObject from this WorldEntity.
+    void WorldEntity::detachOgreObject(Ogre::MovableObject* object)
+    {
+        object->setUserAny(Ogre::Any(static_cast<OrxonoxClass*>(NULL)));
+        this->node_->detachObject(object);
+    }
+
+    void WorldEntity::detachOgreObject(Ogre::BillboardSet* object)
+        { this->detachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
+    void WorldEntity::detachOgreObject(Ogre::Camera* object)
+        { this->detachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
+    void WorldEntity::detachOgreObject(Ogre::Entity* object)
+        { this->detachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
+    void WorldEntity::detachOgreObject(Ogre::ParticleSystem* object)
+        { this->detachOgreObject(static_cast<Ogre::MovableObject*>(object)); }
+
+    //! Detaches an Ogre::MovableObject (by string) from this WorldEntity.
+    Ogre::MovableObject* WorldEntity::detachOgreObject(const Ogre::String& name)
+    {
+        return this->node_->detachObject(name);
+    }
+
+    //! Attaches a collision Shape to this object (delegated to the internal CompoundCollisionShape)
+    void WorldEntity::attachCollisionShape(CollisionShape* shape)
+    {
+        this->collisionShape_->attach(shape);
+        // Note: this->collisionShape_ already notifies us of any changes.
+    }
+
+    //! Detaches a collision Shape from this object (delegated to the internal CompoundCollisionShape)
+    void WorldEntity::detachCollisionShape(CollisionShape* shape)
+    {
+        // Note: The collision shapes may not be detached with this function!
+        this->collisionShape_->detach(shape);
+        // Note: this->collisionShape_ already notifies us of any changes.
+    }
+
+    //! Returns an attached collision Shape of this object (delegated to the internal CompoundCollisionShape)
+    CollisionShape* WorldEntity::getAttachedCollisionShape(unsigned int index)
+    {
+        return this->collisionShape_->getAttachedShape(index);
+    }
+
+    // Note: These functions are placed in WorldEntity.h as inline functions for the release build.
+#ifndef ORXONOX_RELEASE
+    const Vector3& WorldEntity::getPosition() const
+    {
+        return this->node_->getPosition();
+    }
+
+    const Quaternion& WorldEntity::getOrientation() const
+    {
+        return this->node_->getOrientation();
+    }
+
+    const Vector3& WorldEntity::getScale3D() const
+    {
+        return this->node_->getScale();
+    }
+#endif
+
+    //! Returns the position relative to the root space
+    const Vector3& WorldEntity::getWorldPosition() const
+    {
+        return this->node_->_getDerivedPosition();
+    }
+
+    //! Returns the orientation relative to the root space
+    const Quaternion& WorldEntity::getWorldOrientation() const
+    {
+        return this->node_->_getDerivedOrientation();
+    }
+
+    //! Returns the scaling applied relative to the root space in 3 coordinates
+    const Vector3& WorldEntity::getWorldScale3D() const
+    {
+        return this->node_->_getDerivedScale();
+    }
+
+    /**
+    @brief
+        Returns the scaling applied relative to the root space in 3 coordinates
+    @return
+        Returns the scaling if it is uniform, 1.0f otherwise.
+    */
+    float WorldEntity::getWorldScale() const
+    {
+        Vector3 scale = this->getWorldScale3D();
+        return (scale.x == scale.y && scale.x == scale.z) ? scale.x : 1;
+    }
+
+    /**
+    @brief
+        Sets the three dimensional scaling of this object.
+    @Note
+        Scaling physical objects has not yet been implemented and is therefore forbidden.
+    */
+    void WorldEntity::setScale3D(const Vector3& scale)
+    {
+/*
+HACK HACK HACK
+        if (bScalePhysics && this->hasPhysics() && scale != Vector3::UNIT_SCALE)
+        {
+            CCOUT(2) << "Warning: Cannot set the scale of a physical object: Not yet implemented. Ignoring scaling." << std::endl;
+            return;
+        }
+HACK HACK HACK
+*/
+        this->node_->setScale(scale);
+
+        this->changedScale();
+    }
+
+    /**
+    @brief
+        Translates this WorldEntity by a vector.
+    @param relativeTo
+        @see WorldEntity::TransformSpace
+    */
+    void WorldEntity::translate(const Vector3& distance, TransformSpace relativeTo)
+    {
+        switch (relativeTo)
+        {
+        case WorldEntity::Local:
+            // position is relative to parent so transform downwards
+            this->setPosition(this->getPosition() + this->getOrientation() * distance);
+            break;
+        case WorldEntity::Parent:
+            this->setPosition(this->getPosition() + distance);
+            break;
+        case WorldEntity::World:
+            // position is relative to parent so transform upwards
+            if (this->node_->getParent())
+                setPosition(getPosition() + (node_->getParent()->_getDerivedOrientation().Inverse() * distance)
+                    / node_->getParent()->_getDerivedScale());
+            else
+                this->setPosition(this->getPosition() + distance);
+            break;
+        }
+    }
+
+    /**
+    @brief
+        Rotates this WorldEntity by a quaternion.
+    @param relativeTo
+        @see WorldEntity::TransformSpace
+    */
+    void WorldEntity::rotate(const Quaternion& rotation, TransformSpace relativeTo)
+    {
+        switch(relativeTo)
+        {
+        case WorldEntity::Local:
+            this->setOrientation(this->getOrientation() * rotation);
+            break;
+        case WorldEntity::Parent:
+            // Rotations are normally relative to local axes, transform up
+            this->setOrientation(rotation * this->getOrientation());
+            break;
+        case WorldEntity::World:
+            // Rotations are normally relative to local axes, transform up
+            this->setOrientation(this->getOrientation() * this->getWorldOrientation().Inverse()
+                * rotation * this->getWorldOrientation());
+            break;
+        }
+    }
+
+    /**
+    @brief
+        Makes this WorldEntity look at a specific target location.
+    @param relativeTo
+        @see WorldEntity::TransformSpace
+    @param localDirectionVector
+        The vector which normally describes the natural direction of the object, usually -Z.
+    */
+    void WorldEntity::lookAt(const Vector3& target, TransformSpace relativeTo, const Vector3& localDirectionVector)
+    {
+        Vector3 origin(0, 0, 0);
+        switch (relativeTo)
+        {
+        case WorldEntity::Local:
+            origin = Vector3::ZERO;
+            break;
+        case WorldEntity::Parent:
+            origin = this->getPosition();
+            break;
+        case WorldEntity::World:
+            origin = this->getWorldPosition();
+            break;
+        }
+        this->setDirection(target - origin, relativeTo, localDirectionVector);
+    }
+
+    /**
+    @brief
+        Makes this WorldEntity look in specific direction.
+    @param relativeTo
+        @see WorldEntity::TransformSpace
+    @param localDirectionVector
+        The vector which normally describes the natural direction of the object, usually -Z.
+    */
+    void WorldEntity::setDirection(const Vector3& direction, TransformSpace relativeTo, const Vector3& localDirectionVector)
+    {
+        Quaternion savedOrientation(this->getOrientation());
+        this->node_->setDirection(direction, static_cast<Ogre::Node::TransformSpace>(relativeTo), localDirectionVector);
+        Quaternion newOrientation(this->node_->getOrientation());
+        this->node_->setOrientation(savedOrientation);
+        this->setOrientation(newOrientation);
+    }
+
+    //! Activates physics if the CollisionType is not None.
+    void WorldEntity::activatePhysics()
+    {
+        if (this->isActive() && this->hasPhysics() && !this->isPhysicsActive() && !this->parent_)
+        {
+            this->getScene()->addPhysicalObject(this);
+            this->bPhysicsActive_ = true;
+            this->bPhysicsActiveSynchronised_ = true;
+        }
+    }
+
+    //! Deactivates physics but the CollisionType does not change.
+    void WorldEntity::deactivatePhysics()
+    {
+        if (this->isPhysicsActive())
+        {
+            this->getScene()->removePhysicalObject(this);
+            this->bPhysicsActive_ = false;
+            this->bPhysicsActiveSynchronised_ = false;
+        }
+    }
+
+    //! Tells whether the object has already been added to the Bullet physics World.
+    bool WorldEntity::addedToPhysicalWorld() const
+    {
+        return this->physicalBody_ && this->physicalBody_->isInWorld();
+    }
+
+    /**
+    @brief
+        Sets the CollisionType. This alters the object significantly! @see CollisionType.
+    @Note
+        Operation does not work on attached WorldEntities.
+    */
+    void WorldEntity::setCollisionType(CollisionType type)
+    {
+        if (this->collisionType_ == type)
+            return;
+
+        // If we are already attached to a parent, this would be a bad idea..
+        if (this->parent_)
+        {
+            CCOUT(2) << "Warning: Cannot set the collision type of a WorldEntity with a parent." << std::endl;
+            return;
+        }
+
+        // Check for type legality. Could be StaticEntity or MobileEntity.
+        if (!this->isCollisionTypeLegal(type))
+            return;
+
+        if (this->isPhysicsActive())
+            this->deactivatePhysics();
+
+        bool bReactivatePhysics = true;
+        if (this->hasPhysics() && !this->isPhysicsActive())
+            bReactivatePhysics = false;
+
+        // Check whether we have to create or destroy.
+        if (type != None && this->collisionType_ == None)
+        {
+/*
+HACK HACK HACK
+            // Check whether there was some scaling applied.
+            if (!this->node_->getScale().positionEquals(Vector3(1, 1, 1), 0.001))
+            {
+                CCOUT(2) << "Warning: Cannot create a physical body if there is scaling applied to the node: Not yet implemented." << std::endl;
+                return;
+            }
+HACK HACK HACK
+*/
+            // Create new rigid body
+            btRigidBody::btRigidBodyConstructionInfo bodyConstructionInfo(0, this, this->collisionShape_->getCollisionShape());
+            this->physicalBody_ = new btRigidBody(bodyConstructionInfo);
+            this->physicalBody_->setUserPointer(this);
+            this->physicalBody_->setActivationState(DISABLE_DEACTIVATION);
+        }
+        else if (type == None && this->collisionType_ != None)
+        {
+            // Destroy rigid body
+            assert(this->physicalBody_);
+            deactivatePhysics();
+            delete this->physicalBody_;
+            this->physicalBody_ = 0;
+            this->collisionType_ = None;
+            this->collisionTypeSynchronised_ = None;
+            return;
+        }
+
+        // Change type
+        switch (type)
+        {
+        case Dynamic:
+            this->physicalBody_->setCollisionFlags(this->physicalBody_->getCollisionFlags() & !btCollisionObject::CF_STATIC_OBJECT & !btCollisionObject::CF_KINEMATIC_OBJECT);
+            break;
+        case Kinematic:
+            this->physicalBody_->setCollisionFlags((this->physicalBody_->getCollisionFlags() & !btCollisionObject::CF_STATIC_OBJECT) | btCollisionObject::CF_KINEMATIC_OBJECT);
+            break;
+        case Static:
+            this->physicalBody_->setCollisionFlags((this->physicalBody_->getCollisionFlags() & !btCollisionObject::CF_KINEMATIC_OBJECT) | btCollisionObject::CF_STATIC_OBJECT);
+            break;
+        case None:
+            assert(false); // Doesn't happen
+            return;
+        }
+        this->collisionType_ = type;
+        this->collisionTypeSynchronised_ = type;
+
+        // update mass and inertia tensor
+        recalculateMassProps();
+        internalSetPhysicsProps();
+        collisionCallbackActivityChanged();
+        collisionResponseActivityChanged();
+        if (bReactivatePhysics)
+            activatePhysics();
+    }
+
+    //! Sets the CollisionType by string (used for the XMLPort)
+    void WorldEntity::setCollisionTypeStr(const std::string& typeStr)
+    {
+        const std::string& typeStrLower = getLowercase(typeStr);
+        CollisionType type;
+        if (typeStrLower == "dynamic")
+            type = Dynamic;
+        else if (typeStrLower == "static")
+            type = Static;
+        else if (typeStrLower == "kinematic")
+            type = Kinematic;
+        else if (typeStrLower == "none")
+            type = None;
+        else
+            ThrowException(ParseError, std::string("Attempting to set an unknown collision type: '") + typeStr + "'.");
+        this->setCollisionType(type);
+    }
+
+    //! Gets the CollisionType by string (used for the XMLPort)
+    std::string WorldEntity::getCollisionTypeStr() const
+    {
+        switch (this->getCollisionType())
+        {
+            case Dynamic:
+                return "dynamic";
+            case Kinematic:
+                return "kinematic";
+            case Static:
+                return "static";
+            case None:
+                return "none";
+            default:
+                assert(false);
+                return "";
+        }
+    }
+
+    /**
+    @brief
+        Recalculates the accumulated child mass and calls recalculateMassProps()
+        and notifies the parent of the change.
+    @Note
+        Called by a child WE
+    */
+    void WorldEntity::notifyChildMassChanged()
+    {
+        // Note: CollisionShape changes of a child get handled over the internal CompoundCollisionShape already
+        // Recalculate mass
+        this->childrenMass_ = 0.0f;
+        for (std::set<WorldEntity*>::const_iterator it = this->children_.begin(); it != this->children_.end(); ++it)
+            this->childrenMass_ += (*it)->getMass();
+        recalculateMassProps();
+        // Notify parent WE
+        if (this->parent_)
+            parent_->notifyChildMassChanged();
+    }
+
+    /**
+    @brief
+        Undertakes the necessary steps to change the collision shape in Bullet, even at runtime.
+    @Note
+        - called by this->collisionShape_
+        - May have a REALLY big overhead when called continuously at runtime, because then we need
+          to remove the physical body from Bullet and add it again.
+    */
+    void WorldEntity::notifyCollisionShapeChanged()
+    {
+        if (hasPhysics())
+        {
+            // Bullet doesn't like sudden changes of the collision shape, so we remove and add it again
+            if (this->addedToPhysicalWorld())
+            {
+                this->deactivatePhysics();
+                this->physicalBody_->setCollisionShape(this->collisionShape_->getCollisionShape());
+                this->activatePhysics();
+            }
+            else
+                this->physicalBody_->setCollisionShape(this->collisionShape_->getCollisionShape());
+        }
+        recalculateMassProps();
+    }
+
+    //! Updates all mass dependent parameters (mass, inertia tensor and child mass)
+    void WorldEntity::recalculateMassProps()
+    {
+        // Store local inertia for faster access. Evaluates to (0,0,0) if there is no collision shape.
+        float totalMass = this->mass_ + this->childrenMass_;
+        this->collisionShape_->calculateLocalInertia(totalMass, this->localInertia_);
+        if (this->hasPhysics())
+        {
+            if (this->isStatic())
+            {
+                // Just set everything to zero
+                this->physicalBody_->setMassProps(0.0f, btVector3(0, 0, 0));
+            }
+            else if ((this->mass_ + this->childrenMass_) == 0.0f)
+            {
+                // Use default values to avoid very large or very small values
+                CCOUT(4) << "Warning: Setting the internal physical mass to 1.0 because mass_ is 0.0" << std::endl;
+                btVector3 inertia(0, 0, 0);
+                this->collisionShape_->calculateLocalInertia(1.0f, inertia);
+                this->physicalBody_->setMassProps(1.0f, inertia);
+            }
+            else
+            {
+                this->physicalBody_->setMassProps(totalMass, this->localInertia_);
+            }
+        }
+    }
+
+    //! Copies our own parameters for restitution, angular factor, damping and friction to the bullet rigid body.
+    void WorldEntity::internalSetPhysicsProps()
+    {
+        if (this->hasPhysics())
+        {
+            this->physicalBody_->setRestitution(this->restitution_);
+            this->physicalBody_->setAngularFactor(this->angularFactor_);
+            this->physicalBody_->setDamping(this->linearDamping_, this->angularDamping_);
+            this->physicalBody_->setFriction(this->friction_);
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/WorldEntity.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/WorldEntity.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/WorldEntity.h	(revision 6952)
@@ -0,0 +1,472 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *      Reto Grieder (physics)
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _WorldEntity_H__
+#define _WorldEntity_H__
+
+#include "OrxonoxPrereqs.h"
+
+#ifdef ORXONOX_RELEASE
+#  include <OgreSceneNode.h>
+#endif
+#include <LinearMath/btMotionState.h>
+
+#include "util/Math.h"
+#include "util/OgreForwardRefs.h"
+#include "core/BaseObject.h"
+#include "network/synchronisable/Synchronisable.h"
+
+namespace orxonox
+{
+    /**
+    @brief
+        The WorldEntity represents everything that can be put in a Scene at a certain location.
+
+        It is supposed to be the base class of everything you would call an 'object' in a Scene.
+        The class itself is abstract which means you cannot use it directly. You may use StaticEntity
+        as the simplest derivative or (derived from MobileEntity) MovableEntity and ControllableEntity
+        as more advanced ones.
+
+        The basic task of the WorldEntity is provide a location, a direction and a scaling and the possibility
+        to create an entire hierarchy of derived objects.
+        It is also the basis for the physics interface to the Bullet physics engine.
+        Every WorldEntity can have a specific collision type: @see CollisionType
+        This would then imply that every scene object could have any collision type. To limit this, you can always
+        override this->isCollisionTypeLegal(CollisionType). Return false if the collision type is not supported
+        for a specific object.
+        There is also support for attaching WorldEntities with physics to each other. Currently, the collision shape
+        of both objects simply get merged into one larger shape (for static collision type).
+        The physical body that is internally stored and administrated has the following supported properties:
+        - Restitution, angular factor, linear damping, angular damping, friction, mass and collision shape.
+        You can get more information at the corresponding set function.
+
+        Collision shapes: These are controlled by the internal WorldEntityCollisionShape. @see WorldEntityCollisionShape.
+    */
+    class _OrxonoxExport WorldEntity : public BaseObject, public Synchronisable, public btMotionState
+    {
+        friend class Scene;
+
+        public:
+            // Define our own transform space enum to avoid Ogre includes here
+            /**
+            @brief
+                Enumeration denoting the spaces which a transform can be relative to.
+            */
+            enum TransformSpace
+            {
+                //! Transform is relative to the local space
+                Local,
+                //! Transform is relative to the space of the parent node
+                Parent,
+                //! Transform is relative to world space
+                World
+            };
+
+        public:
+            WorldEntity(BaseObject* creator);
+            virtual ~WorldEntity();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            void registerVariables();
+
+            inline const Ogre::SceneNode* getNode() const
+                { return this->node_; }
+
+            static const Vector3 FRONT;
+            static const Vector3 BACK;
+            static const Vector3 LEFT;
+            static const Vector3 RIGHT;
+            static const Vector3 DOWN;
+            static const Vector3 UP;
+            
+            virtual void changedActivity(void);
+            virtual void changedVisibility(void);
+
+            virtual void setPosition(const Vector3& position) = 0;
+            inline void setPosition(float x, float y, float z)
+                { this->setPosition(Vector3(x, y, z)); }
+            const Vector3& getPosition() const;
+            const Vector3& getWorldPosition() const;
+
+            void translate(const Vector3& distance, TransformSpace relativeTo = WorldEntity::Parent);
+            inline void translate(float x, float y, float z, TransformSpace relativeTo = WorldEntity::Parent)
+                { this->translate(Vector3(x, y, z), relativeTo); }
+
+            virtual inline const Vector3& getVelocity() const
+                { return Vector3::ZERO; }
+
+            virtual void setOrientation(const Quaternion& orientation) = 0;
+            inline void setOrientation(float w, float x, float y, float z)
+                { this->setOrientation(Quaternion(w, x, y, z)); }
+            inline void setOrientation(const Vector3& axis, const Radian& angle)
+                { this->setOrientation(Quaternion(angle, axis)); }
+            inline void setOrientation(const Vector3& axis, const Degree& angle)
+                { this->setOrientation(Quaternion(angle, axis)); }
+            const Quaternion& getOrientation() const;
+            const Quaternion& getWorldOrientation() const;
+
+            void rotate(const Quaternion& rotation, TransformSpace relativeTo = WorldEntity::Local);
+            inline void rotate(const Vector3& axis, const Degree& angle, TransformSpace relativeTo = WorldEntity::Local)
+                { this->rotate(Quaternion(angle, axis), relativeTo); }
+
+            inline void yaw(const Degree& angle, TransformSpace relativeTo = WorldEntity::Local)
+                { this->rotate(Quaternion(angle, Vector3::UNIT_Y), relativeTo); }
+            inline void pitch(const Degree& angle, TransformSpace relativeTo = WorldEntity::Local)
+                { this->rotate(Quaternion(angle, Vector3::UNIT_X), relativeTo); }
+            inline void roll(const Degree& angle, TransformSpace relativeTo = WorldEntity::Local)
+                { this->rotate(Quaternion(angle, Vector3::UNIT_Z), relativeTo); }
+
+            void lookAt(const Vector3& target, TransformSpace relativeTo = WorldEntity::Parent, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z);
+            void setDirection(const Vector3& direction, TransformSpace relativeTo = WorldEntity::Local, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z);
+            inline void setDirection(float x, float y, float z, TransformSpace relativeTo = WorldEntity::Local, const Vector3& localDirectionVector = Vector3::NEGATIVE_UNIT_Z)
+                { this->setDirection(Vector3(x, y, z), relativeTo, localDirectionVector); }
+
+            virtual void setScale3D(const Vector3& scale);
+            inline void setScale3D(float x, float y, float z)
+                { this->setScale3D(Vector3(x, y, z)); }
+            const Vector3& getScale3D() const;
+            const Vector3& getWorldScale3D() const;
+
+            inline void setScale(float scale)
+                { this->setScale3D(scale, scale, scale); }
+            inline float getScale() const
+                { Vector3 scale = this->getScale3D(); return (scale.x == scale.y && scale.x == scale.z) ? scale.x : 1; }
+            float getWorldScale() const;
+
+            inline void scale3D(const Vector3& scale)
+                { this->setScale3D(this->getScale3D() * scale); }
+            inline void scale3D(float x, float y, float z)
+                { this->scale3D(Vector3(x, y, z)); }
+            inline void scale(float scale)
+                { this->scale3D(scale, scale, scale); }
+
+            virtual void changedScale() {}
+
+            void attach(WorldEntity* object);
+            void detach(WorldEntity* object);
+            WorldEntity* getAttachedObject(unsigned int index);
+            inline const std::set<WorldEntity*>& getAttachedObjects() const
+                { return this->children_; }
+
+            void attachOgreObject(Ogre::MovableObject*  object);
+            void attachOgreObject(Ogre::BillboardSet*   object);
+            void attachOgreObject(Ogre::Camera*         object);
+            void attachOgreObject(Ogre::Entity*         object);
+            void attachOgreObject(Ogre::ParticleSystem* object);
+
+            void detachOgreObject(Ogre::MovableObject*  object);
+            void detachOgreObject(Ogre::BillboardSet*   object);
+            void detachOgreObject(Ogre::Camera*         object);
+            void detachOgreObject(Ogre::Entity*         object);
+            void detachOgreObject(Ogre::ParticleSystem* object);
+
+            Ogre::MovableObject* detachOgreObject(const Ogre::String& name);
+
+            inline void attachToParent(WorldEntity* parent)
+                { parent->attach(this); }
+            inline void detachFromParent()
+                { if (this->parent_) { this->parent_->detach(this); } }
+            inline WorldEntity* getParent() const
+                { return this->parent_; }
+
+            void attachNode(Ogre::SceneNode* node);
+            void detachNode(Ogre::SceneNode* node);
+            void attachToNode(Ogre::SceneNode* node);
+            void detachFromNode(Ogre::SceneNode* node);
+
+            inline void setDeleteWithParent(bool value)
+                { this->bDeleteWithParent_ = value; }
+            inline bool getDeleteWithParent() const
+                { return this->bDeleteWithParent_; }
+
+            void notifyChildPropsChanged();
+
+        protected:
+            virtual void parentChanged() {}
+
+            Ogre::SceneNode* node_;
+
+        private:
+            inline void lookAt_xmlport(const Vector3& target)
+                { this->lookAt(target); }
+            inline void setDirection_xmlport(const Vector3& direction)
+                { this->setDirection(direction); }
+            inline void yaw_xmlport(const Degree& angle)
+                { this->yaw(angle); }
+            inline void pitch_xmlport(const Degree& angle)
+                { this->pitch(angle); }
+            inline void roll_xmlport(const Degree& angle)
+                { this->roll(angle); }
+
+            // network callbacks
+            void networkcallback_parentChanged();
+            inline void scaleChanged()
+                { this->setScale3D(this->getScale3D()); }
+
+            WorldEntity* parent_;
+            unsigned int parentID_;
+            std::set<WorldEntity*> children_;
+            bool bDeleteWithParent_;
+            
+            bool bActiveMem_;
+            bool bVisibleMem_;
+
+
+        /////////////
+        // Physics //
+        /////////////
+
+        public:
+            /**
+            @brief
+                Denotes the possible types of physical objects in a Scene.
+
+                Dynamic:   The object is influenced by its physical environment, like for instance little ball.
+                Kinematic: The object can only influence other dynamic objects. It's movement is coordinated by your own saying.
+                Static:    Like kinematic but the object is not allowed to move during the simulation.
+                None:      The object has no physics at all.
+            */
+            enum CollisionType
+            {
+                Dynamic,
+                Kinematic,
+                Static,
+                None
+            };
+
+            //! Tells whether the object has any connection to the Bullet physics engine. If hasPhysics() is false, the object may still have a velocity.
+            bool hasPhysics()       const { return getCollisionType() != None     ; }
+            //! @see CollisionType
+            bool isStatic()         const { return getCollisionType() == Static   ; }
+            //! @see CollisionType
+            bool isKinematic()      const { return getCollisionType() == Kinematic; }
+            //! @see CollisionType
+            bool isDynamic()        const { return getCollisionType() == Dynamic  ; }
+            //! Tells whether physics has been activated (you can temporarily deactivate it)
+            bool isPhysicsActive()  const { return this->bPhysicsActive_; }
+            bool addedToPhysicalWorld() const;
+
+            void activatePhysics();
+            void deactivatePhysics();
+
+            //! Returns the CollisionType. @see CollisionType.
+            inline CollisionType getCollisionType() const
+                { return this->collisionType_; }
+            void setCollisionType(CollisionType type);
+
+            void setCollisionTypeStr(const std::string& type);
+            std::string getCollisionTypeStr() const;
+
+            //! Sets the mass of this object. Note that the total mass may be influenced by attached objects!
+            inline void setMass(float mass)
+                { this->mass_ = mass; recalculateMassProps(); }
+            //! Returns the mass of this object without its children.
+            inline float getMass() const
+                { return this->mass_; }
+
+            //! Returns the total mass of this object with all its attached children.
+            inline float getTotalMass() const
+                { return this->mass_ + this->childrenMass_; }
+
+            /**
+            @brief
+                Returns the diagonal elements of the inertia tensor when calculated in local coordinates.
+            @Note
+                The local inertia tensor cannot be set, but is calculated by Bullet according to the collisionShape.
+                With compound collision shapes, an approximation is used.
+            */
+            inline const btVector3& getLocalInertia() const
+                { return this->localInertia_; }
+
+            /**
+            @brief
+                Sets how much reaction is applied in a collision.
+
+                Consider two equal spheres colliding with equal velocities:
+                Restitution 1 means that both spheres simply reverse their velocity (no loss of energy)
+                Restitution 0 means that both spheres will immediately stop moving
+                (maximum loss of energy without violating of the preservation of momentum)
+            */
+            inline void setRestitution(float restitution)
+                { this->restitution_ = restitution; internalSetPhysicsProps(); }
+            //! Returns the restitution parameter. @see setRestitution.
+            inline float getRestitution() const
+                { return this->restitution_; }
+
+            /**
+            @brief
+                Sets an artificial parameter that tells how much torque is applied when you apply a non-central force.
+
+                Normally the angular factor is 1, which means it's physically 'correct'. However if you have a player
+                character that should not rotate when hit sideways, you can set the angular factor to 0.
+            */
+            inline void setAngularFactor(float angularFactor)
+                { this->angularFactor_ = angularFactor; internalSetPhysicsProps(); }
+            //! Returns the angular factor. @see setAngularFactor.
+            inline float getAngularFactor() const
+                { return this->angularFactor_; }
+
+            //! Applies a mass independent damping. Velocities will simply diminish exponentially.
+            inline void setLinearDamping(float linearDamping)
+                { this->linearDamping_ = linearDamping; internalSetPhysicsProps(); }
+            //! Returns the linear damping. @see setLinearDamping.
+            inline float getLinearDamping() const
+                { return this->linearDamping_; }
+
+            //! Applies a tensor independent rotation damping. Angular velocities will simply diminish exponentially.
+            inline void setAngularDamping(float angularDamping)
+                { this->angularDamping_ = angularDamping; internalSetPhysicsProps(); }
+            //! Returns the angular damping. @see setAngularDamping.
+            inline float getAngularDamping() const
+                { return this->angularDamping_; }
+
+            //! Applies friction to the object. Friction occurs when two objects collide.
+            inline void setFriction(float friction)
+                { this->friction_ = friction; internalSetPhysicsProps(); }
+            //! Returns the amount of friction applied to the object.
+            inline float getFriction() const
+                { return this->friction_; }
+
+            void attachCollisionShape(CollisionShape* shape);
+            void detachCollisionShape(CollisionShape* shape);
+            CollisionShape* getAttachedCollisionShape(unsigned int index);
+
+            void notifyCollisionShapeChanged();
+            void notifyChildMassChanged();
+
+            /**
+            @brief
+                Virtual function that gets called when this object collides with another.
+            @param otherObject
+                The object this one has collided into.
+            @pram contactPoint
+                Contact point provided by Bullet. Holds more information and can me modified. See return value.
+            @Return
+                Returning false means that no modification to the contactPoint has been made. Return true otherwise!
+            @Note
+                Condition is that enableCollisionCallback() was called.
+            */
+            virtual inline bool collidesAgainst(WorldEntity* otherObject, btManifoldPoint& contactPoint)
+                { return false; } /* With false, Bullet assumes no modification to the collision objects. */
+
+            //! Enables the collidesAgainst(.) function. The object doesn't respond to collision otherwise!
+            inline void enableCollisionCallback()
+                { this->bCollisionCallbackActive_ = true; this->collisionCallbackActivityChanged(); }
+            //! Disables the collidesAgainst(.) function. @see enableCollisionCallback()
+            inline void disableCollisionCallback()
+                { this->bCollisionCallbackActive_ = false; this->collisionCallbackActivityChanged(); }
+            //! Tells whether there could be a collision callback via collidesAgainst(.)
+            inline bool isCollisionCallbackActive() const
+                { return this->bCollisionCallbackActive_; }
+
+            //! Enables or disables collision response (default is of course on)
+            inline void setCollisionResponse(bool value)
+                { this->bCollisionResponseActive_ = value; this->collisionResponseActivityChanged(); }
+            //! Tells whether there could be a collision response
+            inline bool hasCollisionResponse()
+                { return this->bCollisionResponseActive_; }
+
+        protected:
+            /**
+            @brief
+                Function checks whether the requested collision type is legal to this object.
+
+                You can override this function in a derived class to constrain the collision to e.g. None or Dynamic.
+                A projectile may not prove very useful if there is no physical body. Simply set the CollisionType
+                in its constructor and override this method. But be careful that a derived class's virtual functions
+                don't yet exist in the constructor if a base class.
+            */
+            virtual bool isCollisionTypeLegal(CollisionType type) const = 0;
+
+            btRigidBody*  physicalBody_; //!< Bullet rigid body. Everything physical is applied to this instance.
+
+        private:
+            void recalculateMassProps();
+            void internalSetPhysicsProps();
+
+            bool notifyBeingAttached(WorldEntity* newParent);
+            void notifyDetached();
+
+            // network callbacks
+            void collisionTypeChanged();
+            void physicsActivityChanged();
+            void collisionCallbackActivityChanged();
+            void collisionResponseActivityChanged();
+            //! Network callback workaround to call a function when the value changes.
+            inline void massChanged()
+                { this->setMass(this->mass_); }
+            //! Network callback workaround to call a function when the value changes.
+            inline void restitutionChanged()
+                { this->setRestitution(this->restitution_); }
+            //! Network callback workaround to call a function when the value changes.
+            inline void angularFactorChanged()
+                { this->setAngularFactor(this->angularFactor_); }
+            //! Network callback workaround to call a function when the value changes.
+            inline void linearDampingChanged()
+                { this->setLinearDamping(this->linearDamping_); }
+            //! Network callback workaround to call a function when the value changes.
+            inline void angularDampingChanged()
+                { this->setAngularDamping(this->angularDamping_); }
+            //! Network callback workaround to call a function when the value changes.
+            inline void frictionChanged()
+                { this->setFriction(this->friction_); }
+
+            CollisionType                collisionType_;                 //!< @see setCollisionType
+            CollisionType                collisionTypeSynchronised_;     //!< Network synchronised variable for collisionType_
+            bool                         bPhysicsActive_;                //!< @see isPhysicsActive
+            bool                         bPhysicsActiveSynchronised_;    //!< Network synchronised variable for bPhysicsActive_
+            //! When attaching objects hierarchically this variable tells this object (as child) whether physics was activated before attaching (because the deactivate physics while being attached).
+            bool                         bPhysicsActiveBeforeAttaching_;
+            WorldEntityCollisionShape*   collisionShape_;                //!< Attached collision shapes go here
+            btScalar                     mass_;                          //!< @see setMass
+            btVector3                    localInertia_;                  //!< @see getLocalInertia
+            btScalar                     restitution_;                   //!< @see setRestitution
+            btScalar                     angularFactor_;                 //!< @see setAngularFactor
+            btScalar                     linearDamping_;                 //!< @see setLinearDamping
+            btScalar                     angularDamping_;                //!< @see setAngularDamping
+            btScalar                     friction_;                      //!< @see setFriction
+            btScalar                     childrenMass_;                  //!< Sum of all the children's masses
+            bool                         bCollisionCallbackActive_;      //!< @see enableCollisionCallback
+            bool                         bCollisionResponseActive_;      //!< Tells whether the object should respond to collisions
+    };
+
+    // Inline heavily used functions for release builds. In debug, we better avoid including OgreSceneNode here.
+#ifdef ORXONOX_RELEASE
+    inline const Vector3& WorldEntity::getPosition() const
+        { return this->node_->getPosition(); }
+    inline const Quaternion& WorldEntity::getOrientation() const
+        { return this->node_->getOrientation(); }
+    inline const Vector3& WorldEntity::getScale3D() const
+        { return this->node_->getScale(); }
+#endif
+
+    SUPER_FUNCTION(5, WorldEntity, changedScale, false);
+}
+
+#endif /* _WorldEntity_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/pawns/CMakeLists.txt
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/pawns/CMakeLists.txt	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/pawns/CMakeLists.txt	(revision 6952)
@@ -0,0 +1,7 @@
+ADD_SOURCE_FILES(ORXONOX_SRC_FILES
+  Spectator.cc
+  Pawn.cc
+  SpaceShip.cc
+  TeamBaseMatchBase.cc
+  Destroyer.cc
+)
Index: /code/branches/rocket2/src/orxonox/worldentities/pawns/Destroyer.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/pawns/Destroyer.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/pawns/Destroyer.cc	(revision 6952)
@@ -0,0 +1,48 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Matthias Mock
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Destroyer.h"
+
+#include "core/CoreIncludes.h"
+#include "gametypes/UnderAttack.h"
+
+namespace orxonox
+{
+    CreateFactory(Destroyer);
+
+    Destroyer::Destroyer(BaseObject* creator) : SpaceShip(creator)
+    {
+        RegisterObject(Destroyer);
+
+        UnderAttack* gametype = orxonox_cast<UnderAttack*>(this->getGametype().get());
+        if (gametype)
+        {
+            gametype->addDestroyer(this);
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/pawns/Destroyer.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/pawns/Destroyer.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/pawns/Destroyer.h	(revision 6952)
@@ -0,0 +1,47 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Matthias Mock
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Destroyer_H__
+#define _Destroyer_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "SpaceShip.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Destroyer : public SpaceShip
+    {
+        public:
+            Destroyer(BaseObject* creator);
+            virtual ~Destroyer() {};
+
+    };
+}
+
+#endif /* _Destroyer_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/pawns/Pawn.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/pawns/Pawn.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/pawns/Pawn.cc	(revision 6952)
@@ -0,0 +1,365 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Pawn.h"
+
+#include <algorithm>
+
+#include "core/CoreIncludes.h"
+#include "core/GameMode.h"
+#include "core/XMLPort.h"
+#include "network/NetworkFunction.h"
+
+#include "PawnManager.h"
+#include "infos/PlayerInfo.h"
+#include "controllers/Controller.h"
+#include "gametypes/Gametype.h"
+#include "graphics/ParticleSpawner.h"
+#include "worldentities/ExplosionChunk.h"
+#include "worldentities/BigExplosion.h"
+#include "weaponsystem/WeaponSystem.h"
+#include "weaponsystem/WeaponSlot.h"
+#include "weaponsystem/WeaponPack.h"
+#include "weaponsystem/WeaponSet.h"
+
+
+namespace orxonox
+{
+    CreateFactory(Pawn);
+
+    Pawn::Pawn(BaseObject* creator) 
+        : ControllableEntity(creator)
+        , RadarViewable(creator)
+    {
+        RegisterObject(Pawn);
+
+        PawnManager::touch();
+        this->bAlive_ = true;
+        this->bReload_ = false;
+
+        this->health_ = 0;
+        this->maxHealth_ = 0;
+        this->initialHealth_ = 0;
+
+        this->lastHitOriginator_ = 0;
+
+        this->spawnparticleduration_ = 3.0f;
+
+        this->aimPosition_ = Vector3::ZERO;
+
+        if (GameMode::isMaster())
+        {
+            this->weaponSystem_ = new WeaponSystem(this);
+            this->weaponSystem_->setPawn(this);
+        }
+        else
+            this->weaponSystem_ = 0;
+        
+        this->setCarrierName("Pawn");
+
+        this->setRadarObjectColour(ColourValue::Red);
+        this->setRadarObjectShape(RadarViewable::Dot);
+
+        this->registerVariables();
+
+        this->isHumanShip_ = this->hasLocalController();
+    }
+
+    Pawn::~Pawn()
+    {
+        if (this->isInitialized())
+        {
+            if (this->weaponSystem_)
+                this->weaponSystem_->destroy();
+        }
+    }
+
+    void Pawn::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(Pawn, XMLPort, xmlelement, mode);
+
+        XMLPortParam(Pawn, "health", setHealth, getHealth, xmlelement, mode).defaultValues(100);
+        XMLPortParam(Pawn, "maxhealth", setMaxHealth, getMaxHealth, xmlelement, mode).defaultValues(200);
+        XMLPortParam(Pawn, "initialhealth", setInitialHealth, getInitialHealth, xmlelement, mode).defaultValues(100);
+        XMLPortParam(Pawn, "spawnparticlesource", setSpawnParticleSource, getSpawnParticleSource, xmlelement, mode);
+        XMLPortParam(Pawn, "spawnparticleduration", setSpawnParticleDuration, getSpawnParticleDuration, xmlelement, mode).defaultValues(3.0f);
+        XMLPortParam(Pawn, "explosionchunks", setExplosionChunks, getExplosionChunks, xmlelement, mode).defaultValues(7);
+
+        XMLPortObject(Pawn, WeaponSlot, "weaponslots", addWeaponSlot, getWeaponSlot, xmlelement, mode);
+        XMLPortObject(Pawn, WeaponSet, "weaponsets", addWeaponSet, getWeaponSet, xmlelement, mode);
+        XMLPortObject(Pawn, WeaponPack, "weapons", addWeaponPackXML, getWeaponPack, xmlelement, mode);
+    }
+
+    void Pawn::registerVariables()
+    {
+        registerVariable(this->bAlive_,        VariableDirection::ToClient);
+        registerVariable(this->health_,        VariableDirection::ToClient);
+        registerVariable(this->initialHealth_, VariableDirection::ToClient);
+        registerVariable(this->bReload_,       VariableDirection::ToServer);
+        registerVariable(this->aimPosition_,   Bidirectionality::ServerMaster, 0, true);
+    }
+
+    void Pawn::tick(float dt)
+    {
+        SUPER(Pawn, tick, dt);
+
+        this->bReload_ = false;
+
+        if (GameMode::isMaster())
+            if (this->health_ <= 0 && bAlive_)
+            {
+                this->fireEvent(); // Event to notify anyone who want's to know about the death.
+                this->death();
+            }
+    }
+
+    void Pawn::setPlayer(PlayerInfo* player)
+    {
+        ControllableEntity::setPlayer(player);
+
+        if (this->getGametype())
+            this->getGametype()->playerStartsControllingPawn(player, this);
+    }
+
+    void Pawn::removePlayer()
+    {
+        if (this->getGametype())
+            this->getGametype()->playerStopsControllingPawn(this->getPlayer(), this);
+
+        ControllableEntity::removePlayer();
+    }
+
+    void Pawn::setHealth(float health)
+    {
+        this->health_ = std::min(health, this->maxHealth_);
+    }
+
+    void Pawn::damage(float damage, Pawn* originator)
+    {
+        if (this->getGametype() && this->getGametype()->allowPawnDamage(this, originator))
+        {
+            this->setHealth(this->health_ - damage);
+            this->lastHitOriginator_ = originator;
+
+            // play damage effect
+        }
+    }
+
+    void Pawn::hit(Pawn* originator, const Vector3& force, float damage)
+    {
+        if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
+        {
+            this->damage(damage, originator);
+            this->setVelocity(this->getVelocity() + force);
+
+            // play hit effect
+        }
+    }
+
+    void Pawn::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage)
+    {
+        if (this->getGametype() && this->getGametype()->allowPawnHit(this, originator) && (!this->getController() || !this->getController()->getGodMode()) )
+        {
+            this->damage(damage, originator);
+
+            if ( this->getController() )
+                this->getController()->hit(originator, contactpoint, damage);
+
+            // play hit effect
+        }
+    }
+
+    void Pawn::kill()
+    {
+        this->damage(this->health_);
+        this->death();
+    }
+
+    void Pawn::spawneffect()
+    {
+        // play spawn effect
+        if (!this->spawnparticlesource_.empty())
+        {
+            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
+            effect->setPosition(this->getPosition());
+            effect->setOrientation(this->getOrientation());
+            effect->setDestroyAfterLife(true);
+            effect->setSource(this->spawnparticlesource_);
+            effect->setLifetime(this->spawnparticleduration_);
+        }
+    }
+
+    void Pawn::death()
+    {
+        this->setHealth(1);
+        if (this->getGametype() && this->getGametype()->allowPawnDeath(this, this->lastHitOriginator_))
+        {
+            // Set bAlive_ to false and wait for PawnManager to do the destruction
+            this->bAlive_ = false;
+
+            this->setDestroyWhenPlayerLeft(false);
+
+            this->dropItems();
+
+            if (this->getGametype())
+                this->getGametype()->pawnKilled(this, this->lastHitOriginator_);
+
+            if (this->getPlayer() && this->getPlayer()->getControllableEntity() == this)
+                this->getPlayer()->stopControl();
+
+            if (GameMode::isMaster())
+            {
+//                this->deathEffect();
+                this->goWithStyle();
+            }
+        }
+    }
+    void Pawn::goWithStyle()
+    {
+        this->bAlive_ = false;
+        this->setDestroyWhenPlayerLeft(false);
+
+        BigExplosion* chunk = new BigExplosion(this->getCreator());
+        chunk->setPosition(this->getPosition());
+
+    }
+    void Pawn::deatheffect()
+    {
+        // play death effect
+        {
+            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
+            effect->setPosition(this->getPosition());
+            effect->setOrientation(this->getOrientation());
+            effect->setDestroyAfterLife(true);
+            effect->setSource("Orxonox/explosion2b");
+            effect->setLifetime(4.0f);
+        }
+        {
+            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
+            effect->setPosition(this->getPosition());
+            effect->setOrientation(this->getOrientation());
+            effect->setDestroyAfterLife(true);
+            effect->setSource("Orxonox/smoke6");
+            effect->setLifetime(4.0f);
+        }
+        {
+            ParticleSpawner* effect = new ParticleSpawner(this->getCreator());
+            effect->setPosition(this->getPosition());
+            effect->setOrientation(this->getOrientation());
+            effect->setDestroyAfterLife(true);
+            effect->setSource("Orxonox/sparks");
+            effect->setLifetime(4.0f);
+        }
+        for (unsigned int i = 0; i < this->numexplosionchunks_; ++i)
+        {
+            ExplosionChunk* chunk = new ExplosionChunk(this->getCreator());
+            chunk->setPosition(this->getPosition());
+        }
+    }
+
+    void Pawn::fired(unsigned int firemode)
+    {
+        if (this->weaponSystem_)
+            this->weaponSystem_->fire(firemode);
+    }
+
+    void Pawn::reload()
+    {
+        this->bReload_ = true;
+    }
+
+    void Pawn::postSpawn()
+    {
+        this->setHealth(this->initialHealth_);
+        if (GameMode::isMaster())
+            this->spawneffect();
+    }
+
+    /* WeaponSystem:
+    *   functions load Slot, Set, Pack from XML and make sure all parent-pointers are set.
+    *   with setWeaponPack you can not just load a Pack from XML but if a Pack already exists anywhere, you can attach it.
+    *       --> e.g. Pickup-Items
+    */
+    void Pawn::addWeaponSlot(WeaponSlot * wSlot)
+    {
+        this->attach(wSlot);
+        if (this->weaponSystem_)
+            this->weaponSystem_->addWeaponSlot(wSlot);
+    }
+
+    WeaponSlot * Pawn::getWeaponSlot(unsigned int index) const
+    {
+        if (this->weaponSystem_)
+            return this->weaponSystem_->getWeaponSlot(index);
+        else
+            return 0;
+    }
+
+    void Pawn::addWeaponSet(WeaponSet * wSet)
+    {
+        if (this->weaponSystem_)
+            this->weaponSystem_->addWeaponSet(wSet);
+    }
+
+    WeaponSet * Pawn::getWeaponSet(unsigned int index) const
+    {
+        if (this->weaponSystem_)
+            return this->weaponSystem_->getWeaponSet(index);
+        else
+            return 0;
+    }
+
+    void Pawn::addWeaponPack(WeaponPack * wPack)
+    {
+        if (this->weaponSystem_)
+            this->weaponSystem_->addWeaponPack(wPack);
+    }
+
+    void Pawn::addWeaponPackXML(WeaponPack * wPack)
+    {
+        if (this->weaponSystem_)
+            if (!this->weaponSystem_->addWeaponPack(wPack))
+                wPack->destroy();
+    }
+
+    WeaponPack * Pawn::getWeaponPack(unsigned int index) const
+    {
+        if (this->weaponSystem_)
+            return this->weaponSystem_->getWeaponPack(index);
+        else
+            return 0;
+    }
+
+    //Tell the Map (RadarViewable), if this is a playership
+    void Pawn::startLocalHumanControl()
+    {
+//        SUPER(ControllableEntity, changedPlayer());
+        ControllableEntity::startLocalHumanControl();
+        this->isHumanShip_ = true;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/pawns/Pawn.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/pawns/Pawn.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/pawns/Pawn.h	(revision 6952)
@@ -0,0 +1,161 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Pawn_H__
+#define _Pawn_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include "interfaces/PickupCarrier.h"
+#include "interfaces/RadarViewable.h"
+#include "worldentities/ControllableEntity.h"
+
+namespace orxonox // tolua_export
+{ // tolua_export
+    class _OrxonoxExport Pawn // tolua_export
+        : public ControllableEntity, public RadarViewable, public PickupCarrier
+    { // tolua_export
+        friend class WeaponSystem;
+
+        public:
+            Pawn(BaseObject* creator);
+            virtual ~Pawn();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void tick(float dt);
+            void registerVariables();
+
+            inline bool isAlive() const
+                { return this->bAlive_; }
+
+            virtual void setHealth(float health);
+            inline void addHealth(float health)
+                { this->setHealth(this->health_ + health); }
+            inline void removeHealth(float health)
+                { this->setHealth(this->health_ - health); }
+            inline float getHealth() const
+                { return this->health_; }
+
+            inline void setMaxHealth(float maxhealth)
+                { this->maxHealth_ = maxhealth; this->setHealth(this->health_); }
+            inline float getMaxHealth() const
+                { return this->maxHealth_; }
+
+            inline void setInitialHealth(float initialhealth)
+                { this->initialHealth_ = initialhealth; this->setHealth(initialhealth); }
+            inline float getInitialHealth() const
+                { return this->initialHealth_; }
+
+            inline ControllableEntity* getLastHitOriginator() const
+                { return this->lastHitOriginator_; }
+
+            virtual void hit(Pawn* originator, const Vector3& force, float damage);
+            virtual void hit(Pawn* originator, btManifoldPoint& contactpoint, float damage);
+            virtual void kill();
+
+            virtual void fired(unsigned int firemode);
+            virtual void reload();
+            virtual void postSpawn();
+
+            void addWeaponSlot(WeaponSlot * wSlot);
+            WeaponSlot * getWeaponSlot(unsigned int index) const;
+            void addWeaponSet(WeaponSet * wSet);
+            WeaponSet * getWeaponSet(unsigned int index) const;
+            void addWeaponPack(WeaponPack * wPack);
+            void addWeaponPackXML(WeaponPack * wPack);
+            WeaponPack * getWeaponPack(unsigned int index) const;
+
+            inline const WorldEntity* getWorldEntity() const
+                { return const_cast<Pawn*>(this); }
+
+            inline void setSpawnParticleSource(const std::string& source)
+                { this->spawnparticlesource_ = source; }
+            inline const std::string& getSpawnParticleSource() const
+                { return this->spawnparticlesource_; }
+
+            inline void setSpawnParticleDuration(float duration)
+                { this->spawnparticleduration_ = duration; }
+            inline float getSpawnParticleDuration() const
+                { return this->spawnparticleduration_; }
+
+            inline void setExplosionChunks(unsigned int chunks)
+                { this->numexplosionchunks_ = chunks; }
+            inline unsigned int getExplosionChunks() const
+                { return this->numexplosionchunks_; }
+
+            virtual void startLocalHumanControl();
+
+            void setAimPosition( Vector3 position )
+                { this->aimPosition_ = position; }
+            Vector3 getAimPosition()
+                { return this->aimPosition_; }
+                
+            virtual const Vector3& getCarrierPosition(void)
+                { return this->getWorldPosition(); };
+
+        protected:
+            virtual void setPlayer(PlayerInfo* player);
+            virtual void removePlayer();
+
+            virtual void death();
+            virtual void goWithStyle();
+            virtual void deatheffect();
+            virtual void spawneffect();
+
+            virtual void damage(float damage, Pawn* originator = 0);
+
+            bool bAlive_;
+
+            virtual std::vector<PickupCarrier*>* getCarrierChildren(void)
+                { return new std::vector<PickupCarrier*>(); }
+            virtual PickupCarrier* getCarrierParent(void)
+                { return NULL; }
+
+            float health_;
+            float maxHealth_;
+            float initialHealth_;
+
+            Pawn* lastHitOriginator_;
+
+            WeaponSystem* weaponSystem_;
+            bool bReload_;
+
+            std::string spawnparticlesource_;
+            float spawnparticleduration_;
+            unsigned int numexplosionchunks_;
+
+        private:
+            inline void setWeaponSystem(WeaponSystem* weaponsystem)
+                { this->weaponSystem_ = weaponsystem; }
+
+            Vector3 aimPosition_;
+    }; // tolua_export
+} // tolua_export
+
+#endif /* _Pawn_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/pawns/SpaceShip.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/pawns/SpaceShip.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/pawns/SpaceShip.cc	(revision 6952)
@@ -0,0 +1,229 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "SpaceShip.h"
+
+#include <BulletDynamics/Dynamics/btRigidBody.h>
+
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/Template.h"
+#include "core/XMLPort.h"
+#include "items/Engine.h"
+
+namespace orxonox
+{
+    const float orientationGain = 100;
+    CreateFactory(SpaceShip);
+
+    SpaceShip::SpaceShip(BaseObject* creator) : Pawn(creator)
+    {
+        RegisterObject(SpaceShip);
+
+        this->primaryThrust_  = 100;
+        this->auxilaryThrust_ =  30;
+        this->rotationThrust_ =  10;
+
+        this->localLinearAcceleration_.setValue(0, 0, 0);
+        this->localAngularAcceleration_.setValue(0, 0, 0);
+        this->bBoost_ = false;
+        this->bPermanentBoost_ = false;
+        this->steering_ = Vector3::ZERO;
+        this->engine_ = 0;
+
+
+        this->bInvertYAxis_ = false;
+
+        this->setDestroyWhenPlayerLeft(true);
+
+        // SpaceShip is always a physical object per default
+        // Be aware of this call: The collision type legality check will not reach derived classes!
+        this->setCollisionType(WorldEntity::Dynamic);
+        // Get notification about collisions
+        this->enableCollisionCallback();
+
+        this->setConfigValues();
+        this->registerVariables();
+    }
+
+    SpaceShip::~SpaceShip()
+    {
+        if (this->isInitialized() && this->engine_)
+            this->engine_->destroy();
+    }
+
+    void SpaceShip::XMLPort(Element& xmlelement, XMLPort::Mode mode)
+    {
+        SUPER(SpaceShip, XMLPort, xmlelement, mode);
+
+        XMLPortParam(SpaceShip, "engine",            setEngineTemplate,    getEngineTemplate,    xmlelement, mode);
+        XMLPortParamVariable(SpaceShip, "primaryThrust",  primaryThrust_,  xmlelement, mode);
+        XMLPortParamVariable(SpaceShip, "auxilaryThrust", auxilaryThrust_, xmlelement, mode);
+        XMLPortParamVariable(SpaceShip, "rotationThrust", rotationThrust_, xmlelement, mode);
+    }
+
+    void SpaceShip::registerVariables()
+    {
+        registerVariable(this->primaryThrust_,  VariableDirection::ToClient);
+        registerVariable(this->auxilaryThrust_, VariableDirection::ToClient);
+        registerVariable(this->rotationThrust_, VariableDirection::ToClient);
+    }
+
+    void SpaceShip::setConfigValues()
+    {
+        SetConfigValue(bInvertYAxis_, false).description("Set this to true for joystick-like mouse behaviour (mouse up = ship down).");
+    }
+
+    bool SpaceShip::isCollisionTypeLegal(WorldEntity::CollisionType type) const
+    {
+        if (type != WorldEntity::Dynamic)
+        {
+            CCOUT(1) << "Error: Cannot tell a SpaceShip not to be dynamic! Ignoring." << std::endl;
+            assert(false); // Only in debug mode
+            return false;
+        }
+        else
+            return true;
+    }
+
+    void SpaceShip::tick(float dt)
+    {
+        SUPER(SpaceShip, tick, dt);
+
+        if (this->hasLocalController())
+        {
+/*
+            this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() * getMass() * this->auxilaryThrust_);
+            this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() * getMass() * this->auxilaryThrust_);
+            if (this->localLinearAcceleration_.z() > 0)
+                this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() * getMass() * this->auxilaryThrust_);
+            else
+                this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() * getMass() * this->primaryThrust_);
+            this->physicalBody_->applyCentralForce(physicalBody_->getWorldTransform().getBasis() * this->localLinearAcceleration_);
+            this->localLinearAcceleration_.setValue(0, 0, 0);
+*/
+            if (!this->isInMouseLook())
+            {
+                this->localAngularAcceleration_ *= this->getLocalInertia() * this->rotationThrust_;
+                this->physicalBody_->applyTorque(physicalBody_->getWorldTransform().getBasis() * this->localAngularAcceleration_);
+                this->localAngularAcceleration_.setValue(0, 0, 0);
+            }
+        }
+    }
+
+    void SpaceShip::moveFrontBack(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setZ(this->localLinearAcceleration_.z() - value.x);
+        this->steering_.z = -value.x;
+    }
+
+    void SpaceShip::moveRightLeft(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setX(this->localLinearAcceleration_.x() + value.x);
+        this->steering_.x = value.x;
+    }
+
+    void SpaceShip::moveUpDown(const Vector2& value)
+    {
+        this->localLinearAcceleration_.setY(this->localLinearAcceleration_.y() + value.x);
+        this->steering_.y = value.x;
+    }
+
+    void SpaceShip::rotateYaw(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setY(this->localAngularAcceleration_.y() + value.x);
+
+        Pawn::rotateYaw(value);
+    }
+
+    void SpaceShip::rotatePitch(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setX(this->localAngularAcceleration_.x() + value.x);
+
+        Pawn::rotatePitch(value);
+    }
+
+    void SpaceShip::rotateRoll(const Vector2& value)
+    {
+        this->localAngularAcceleration_.setZ(this->localAngularAcceleration_.z() + value.x);
+
+        Pawn::rotateRoll(value);
+    }
+
+    void SpaceShip::fire()
+    {
+    }
+
+    void SpaceShip::boost()
+    {
+        this->bBoost_ = true;
+    }
+
+    void SpaceShip::loadEngineTemplate()
+    {
+        if (!this->enginetemplate_.empty())
+        {
+            Template* temp = Template::getTemplate(this->enginetemplate_);
+
+            if (temp)
+            {
+                Identifier* identifier = temp->getBaseclassIdentifier();
+
+                if (identifier)
+                {
+                    BaseObject* object = identifier->fabricate(this);
+                    this->engine_ = orxonox_cast<Engine*>(object);
+
+                    if (this->engine_)
+                    {
+                        this->engine_->addTemplate(temp);
+                        this->engine_->addToSpaceShip(this);
+                    }
+                    else
+                    {
+                        object->destroy();
+                    }
+                }
+            }
+        }
+    }
+
+    void SpaceShip::setEngine(Engine* engine)
+    {
+        this->engine_ = engine;
+        if (engine && engine->getShip() != this)
+            engine->addToSpaceShip(this);
+    }
+
+    std::vector<PickupCarrier*>* SpaceShip::getCarrierChildren(void)
+    {
+        std::vector<PickupCarrier*>* list = new std::vector<PickupCarrier*>();
+        list->push_back(this->engine_);
+        return list;
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/pawns/SpaceShip.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/pawns/SpaceShip.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/pawns/SpaceShip.h	(revision 6952)
@@ -0,0 +1,111 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _SpaceShip_H__
+#define _SpaceShip_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include <string>
+#include <LinearMath/btVector3.h>
+#include "util/Math.h"
+#include "Pawn.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport SpaceShip : public Pawn
+    {
+        public:
+            SpaceShip(BaseObject* creator);
+            virtual ~SpaceShip();
+
+            virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
+            virtual void tick(float dt);
+            void registerVariables();
+            void setConfigValues();
+
+            virtual void moveFrontBack(const Vector2& value);
+            virtual void moveRightLeft(const Vector2& value);
+            virtual void moveUpDown(const Vector2& value);
+
+            virtual void rotateYaw(const Vector2& value);
+            virtual void rotatePitch(const Vector2& value);
+            virtual void rotateRoll(const Vector2& value);
+
+            virtual void fire();
+            virtual void boost();
+
+            void setEngine(Engine* engine);
+            inline Engine* getEngine() const
+                { return this->engine_; }
+
+            inline void setSteeringDirection(const Vector3& direction)
+                { this->steering_ = direction; }
+            inline const Vector3& getSteeringDirection() const
+                { return this->steering_; }
+
+            inline void setBoost(bool bBoost)
+                { this->bBoost_ = bBoost; }
+            inline bool getBoost() const
+                { return this->bBoost_; }
+
+            inline void setEngineTemplate(const std::string& temp)
+                { this->enginetemplate_ = temp; this->loadEngineTemplate(); }
+            inline const std::string& getEngineTemplate() const
+                { return this->enginetemplate_; }
+
+            inline void setPermanentBoost(bool bPermanent)
+                { this->bPermanentBoost_ = bPermanent; }
+            inline bool getPermanentBoost() const
+                { return this->bPermanentBoost_; }
+
+        protected:
+            virtual std::vector<PickupCarrier*>* getCarrierChildren(void);
+            bool bInvertYAxis_;
+
+            bool bBoost_;
+            bool bPermanentBoost_;
+            Vector3 steering_;
+            float primaryThrust_;
+            float auxilaryThrust_;
+            float rotationThrust_;
+            btVector3 localLinearAcceleration_;
+            btVector3 localAngularAcceleration_;
+
+        private:
+            virtual bool isCollisionTypeLegal(WorldEntity::CollisionType type) const;
+
+        private:
+            void loadEngineTemplate();
+
+            std::string enginetemplate_;
+            Engine* engine_;
+    };
+}
+
+#endif /* _SpaceShip_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/pawns/Spectator.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/pawns/Spectator.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/pawns/Spectator.cc	(revision 6952)
@@ -0,0 +1,207 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "Spectator.h"
+
+#include "core/CoreIncludes.h"
+#include "core/ConfigValueIncludes.h"
+#include "core/GameMode.h"
+
+#include "tools/BillboardSet.h"
+#include "Scene.h"
+#include "infos/PlayerInfo.h"
+
+namespace orxonox
+{
+    CreateFactory(Spectator);
+
+    Spectator::Spectator(BaseObject* creator) : ControllableEntity(creator)
+    {
+        RegisterObject(Spectator);
+
+        this->speed_ = 200;
+
+        this->yaw_ = 0;
+        this->pitch_ = 0;
+        this->roll_ = 0;
+        this->localVelocity_ = Vector3::ZERO;
+        this->setHudTemplate("spectatorhud");
+        this->greetingFlare_ = 0;
+
+        this->setDestroyWhenPlayerLeft(true);
+
+        if (GameMode::showsGraphics())
+        {
+            this->greetingFlare_ = new BillboardSet();
+            this->greetingFlare_->setBillboardSet(this->getScene()->getSceneManager(), "Examples/Flare", ColourValue(1.0f, 1.0f, 0.8f), Vector3(0, 20, 0), 1);
+            if (this->greetingFlare_->getBillboardSet())
+                this->attachOgreObject(this->greetingFlare_->getBillboardSet());
+            this->greetingFlare_->setVisible(false);
+        }
+
+        this->bGreetingFlareVisible_ = false;
+        this->bGreeting_ = false;
+
+        this->setConfigValues();
+        this->registerVariables();
+    }
+
+    Spectator::~Spectator()
+    {
+        if (this->isInitialized())
+        {
+            if (this->greetingFlare_)
+            {
+                if (this->greetingFlare_->getBillboardSet())
+                    this->detachOgreObject(this->greetingFlare_->getBillboardSet());
+
+                delete this->greetingFlare_;
+            }
+        }
+    }
+
+    void Spectator::setConfigValues()
+    {
+        SetConfigValue(speed_, 200.0f);
+    }
+
+    void Spectator::registerVariables()
+    {
+        registerVariable(this->bGreetingFlareVisible_, VariableDirection::ToClient, new NetworkCallback<Spectator>(this, &Spectator::changedFlareVisibility));
+        registerVariable(this->bGreeting_,             VariableDirection::ToServer, new NetworkCallback<Spectator>(this, &Spectator::changedGreeting));
+    }
+
+    void Spectator::changedGreeting()
+    {
+        this->bGreetingFlareVisible_ = this->bGreeting_;
+        this->changedFlareVisibility();
+    }
+
+    void Spectator::changedFlareVisibility()
+    {
+        if (this->greetingFlare_)
+            this->greetingFlare_->setVisible(this->bGreetingFlareVisible_);
+    }
+
+    void Spectator::tick(float dt)
+    {
+        if (this->hasLocalController())
+        {
+            float localSpeedSquared = this->localVelocity_.squaredLength();
+            float localSpeed;
+            if (localSpeedSquared > 1.0)
+                localSpeed = this->speed_ / sqrtf(localSpeedSquared);
+            else
+                localSpeed = this->speed_;
+
+            this->localVelocity_.x *= localSpeed;
+            this->localVelocity_.y *= localSpeed;
+            this->localVelocity_.z *= localSpeed;
+            this->setVelocity(this->getOrientation() * this->localVelocity_);
+            this->localVelocity_.x = 0;
+            this->localVelocity_.y = 0;
+            this->localVelocity_.z = 0;
+
+            if (!this->isInMouseLook())
+            {
+                this->yaw(Radian(this->yaw_ * this->getMouseLookSpeed()));
+                this->pitch(Radian(this->pitch_ * this->getMouseLookSpeed()));
+                this->roll(Radian(this->roll_ * this->getMouseLookSpeed()));
+            }
+
+            this->yaw_ = this->pitch_ = this->roll_ = 0;
+        }
+
+        SUPER(Spectator, tick, dt);
+    }
+
+    void Spectator::setPlayer(PlayerInfo* player)
+    {
+        ControllableEntity::setPlayer(player);
+
+//        this->setSyncMode(ObjectDirection::ToClient);
+    }
+
+    void Spectator::startLocalHumanControl()
+    {
+        ControllableEntity::startLocalHumanControl();
+    }
+
+    void Spectator::moveFrontBack(const Vector2& value)
+    {
+        this->localVelocity_.z -= value.x;
+    }
+
+    void Spectator::moveRightLeft(const Vector2& value)
+    {
+        this->localVelocity_.x += value.x;
+    }
+
+    void Spectator::moveUpDown(const Vector2& value)
+    {
+        this->localVelocity_.y += value.x;
+    }
+
+    void Spectator::rotateYaw(const Vector2& value)
+    {
+        this->yaw_ += value.y;
+
+        ControllableEntity::rotateYaw(value);
+    }
+
+    void Spectator::rotatePitch(const Vector2& value)
+    {
+        this->pitch_ += value.y;
+
+        ControllableEntity::rotatePitch(value);
+    }
+
+    void Spectator::rotateRoll(const Vector2& value)
+    {
+        this->roll_ += value.y;
+
+        ControllableEntity::rotateRoll(value);
+    }
+
+    void Spectator::fired(unsigned int firemode)
+    {
+        if (this->getPlayer())
+            this->getPlayer()->setReadyToSpawn(true);
+    }
+
+    void Spectator::greet()
+    {
+        this->bGreeting_ = !this->bGreeting_;
+
+        if (GameMode::isMaster())
+        {
+            this->bGreetingFlareVisible_ = this->bGreeting_;
+            this->changedFlareVisibility();
+        }
+    }
+}
Index: /code/branches/rocket2/src/orxonox/worldentities/pawns/Spectator.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/pawns/Spectator.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/pawns/Spectator.h	(revision 6952)
@@ -0,0 +1,82 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _Spectator_H__
+#define _Spectator_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "util/Math.h"
+#include "worldentities/ControllableEntity.h"
+
+namespace orxonox
+{
+    class _OrxonoxExport Spectator : public ControllableEntity
+    {
+        public:
+            Spectator(BaseObject* creator);
+            virtual ~Spectator();
+
+            void setConfigValues();
+            void registerVariables();
+            virtual void tick(float dt);
+
+            virtual void moveFrontBack(const Vector2& value);
+            virtual void moveRightLeft(const Vector2& value);
+            virtual void moveUpDown(const Vector2& value);
+
+            virtual void rotateYaw(const Vector2& value);
+            virtual void rotatePitch(const Vector2& value);
+            virtual void rotateRoll(const Vector2& value);
+
+            virtual void fired(unsigned int firemode);
+            virtual void greet();
+
+        protected:
+            virtual void setPlayer(PlayerInfo* player);
+            virtual void startLocalHumanControl();
+
+        private:
+            void changedGreeting();
+            void changedFlareVisibility();
+
+            BillboardSet* greetingFlare_;
+            bool bGreetingFlareVisible_;
+            bool bGreeting_;
+
+            float speed_;
+
+            float yaw_;
+            float pitch_;
+            float roll_;
+
+            Vector3 localVelocity_;
+    };
+}
+
+#endif /* _Spectator_H__ */
Index: /code/branches/rocket2/src/orxonox/worldentities/pawns/TeamBaseMatchBase.cc
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/pawns/TeamBaseMatchBase.cc	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/pawns/TeamBaseMatchBase.cc	(revision 6952)
@@ -0,0 +1,98 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Val Mikos
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+
+#include "TeamBaseMatchBase.h"
+
+#include "core/CoreIncludes.h"
+#include "controllers/ArtificialController.h"
+#include "interfaces/TeamColourable.h"
+#include "gametypes/TeamBaseMatch.h"
+
+namespace orxonox
+{
+    CreateFactory(TeamBaseMatchBase);
+
+    TeamBaseMatchBase::TeamBaseMatchBase(BaseObject* creator) : Pawn(creator)
+    {
+        RegisterObject(TeamBaseMatchBase);
+
+        this->state_ = BaseState::Uncontrolled;
+
+        TeamBaseMatch* gametype = orxonox_cast<TeamBaseMatch*>(this->getGametype().get());
+        if (gametype)
+        {
+            gametype->addBase(this);
+        }
+
+        this->setRadarObjectShape(RadarViewable::Triangle);
+    }
+
+    void TeamBaseMatchBase::changeTeamColour()
+    {
+        this->fireEvent();
+
+        TeamDeathmatch* gametype = orxonox_cast<TeamDeathmatch*>(this->getGametype().get());
+        if (!gametype)
+            return;
+
+        ColourValue colour;
+
+        switch (this->state_)
+        {
+            case BaseState::ControlTeam1:
+                colour = gametype->getTeamColour(0);
+                break;
+            case BaseState::ControlTeam2:
+                colour = gametype->getTeamColour(1);
+                break;
+            case BaseState::Uncontrolled:
+            default:
+                colour = ColourValue(0.5, 0.5, 0.5, 1.0);
+                break;
+        }
+
+
+        std::set<WorldEntity*> attachments = this->getAttachedObjects();
+        for (std::set<WorldEntity*>::iterator it = attachments.begin(); it != attachments.end(); ++it)
+        {
+            if ((*it)->isA(Class(TeamColourable)))
+            {
+                TeamColourable* tc = orxonox_cast<TeamColourable*>(*it);
+                tc->setTeamColour(colour);
+            }
+        }
+
+        this->setRadarObjectColour(colour);
+
+        // Call this so bots stop shooting at the base after they converted it
+        for (ObjectList<ArtificialController>::iterator it = ObjectList<ArtificialController>::begin(); it != ObjectList<ArtificialController>::end(); ++it)
+            it->abandonTarget(this);
+    }
+}
+
Index: /code/branches/rocket2/src/orxonox/worldentities/pawns/TeamBaseMatchBase.h
===================================================================
--- /code/branches/rocket2/src/orxonox/worldentities/pawns/TeamBaseMatchBase.h	(revision 6952)
+++ /code/branches/rocket2/src/orxonox/worldentities/pawns/TeamBaseMatchBase.h	(revision 6952)
@@ -0,0 +1,81 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   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:
+ *      Val Mikos
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _TeamBaseMatchBase_H__
+#define _TeamBaseMatchBase_H__
+
+#include "OrxonoxPrereqs.h"
+
+#include "Pawn.h"
+
+namespace orxonox
+{
+    namespace BaseState
+    {
+        enum Value
+        {
+            Uncontrolled,
+            ControlTeam1,
+            ControlTeam2,
+        };
+    }
+
+
+    class _OrxonoxExport TeamBaseMatchBase : public Pawn
+    {
+        public:
+            TeamBaseMatchBase(BaseObject* creator);
+
+            // if class closes, close everything
+            virtual ~TeamBaseMatchBase() {}
+
+
+
+            // Set the state of a base to whatever the argument of the function is
+            void setState(BaseState::Value state)
+            {
+                this->state_ = state;
+                this->changeTeamColour();
+            }
+
+
+            // Get the state of a base as a return value
+            BaseState::Value getState() const
+            {
+                return this->state_;
+            }
+
+
+        protected:
+            void changeTeamColour();
+
+            BaseState::Value state_;
+    };
+}
+
+#endif /* _TeamBaseMatchBase_H__ */
